Decompiled source of FogMod v0.1.2

FogMod.dll

Decompiled an hour ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.Rendering;
using UnityEngine.UI;

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace FogMod
{
	internal static class FogBanner
	{
		private const float ShowAt = 2f;

		private const float FadeIn = 0.6f;

		private const float Hold = 4f;

		private const float FadeOut = 1.2f;

		private const float Width = 900f;

		private static Texture2D texture;

		private static GameObject canvasObject;

		private static RawImage image;

		internal static void Tick(float levelTime)
		{
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			float num = levelTime - 2f;
			if (num < 0f || num > 5.8f)
			{
				Hide();
			}
			else if (!((Object)(object)image == (Object)null) || Create())
			{
				float num2 = ((num < 0.6f) ? (num / 0.6f) : ((num < 4.6f) ? 1f : (1f - (num - 0.6f - 4f) / 1.2f)));
				((Graphic)image).color = new Color(1f, 1f, 1f, Mathf.Clamp01(num2));
				((Transform)((Graphic)image).rectTransform).localScale = Vector3.one * Mathf.Lerp(0.96f, 1.02f, num / 5.8f);
			}
		}

		internal static void Hide()
		{
			if ((Object)(object)canvasObject != (Object)null)
			{
				Object.Destroy((Object)(object)canvasObject);
				canvasObject = null;
				image = null;
			}
		}

		private static bool Create()
		{
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Expected O, but got Unknown
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Expected O, but got Unknown
			if ((Object)(object)texture == (Object)null)
			{
				using Stream stream = typeof(FogBanner).Assembly.GetManifestResourceStream("FogMod.fog_banner.png");
				if (stream == null)
				{
					Plugin.Log.LogError((object)"Dimbannern saknas i DLL:en.");
					return false;
				}
				byte[] array = new byte[stream.Length];
				stream.Read(array, 0, array.Length);
				texture = new Texture2D(2, 2, (TextureFormat)4, false);
				if (!ImageConversion.LoadImage(texture, array))
				{
					Plugin.Log.LogError((object)"Kunde inte läsa dimbannern.");
					return false;
				}
				((Texture)texture).wrapMode = (TextureWrapMode)1;
				Object.DontDestroyOnLoad((Object)(object)texture);
			}
			canvasObject = new GameObject("FogMod Banner");
			Canvas obj = canvasObject.AddComponent<Canvas>();
			obj.renderMode = (RenderMode)0;
			obj.sortingOrder = 50;
			CanvasScaler obj2 = canvasObject.AddComponent<CanvasScaler>();
			obj2.uiScaleMode = (ScaleMode)1;
			obj2.referenceResolution = new Vector2(1920f, 1080f);
			obj2.matchWidthOrHeight = 0.5f;
			GameObject val = new GameObject("Image", new Type[1] { typeof(RectTransform) });
			val.transform.SetParent(canvasObject.transform, false);
			image = val.AddComponent<RawImage>();
			image.texture = (Texture)(object)texture;
			((Graphic)image).raycastTarget = false;
			RectTransform rectTransform = ((Graphic)image).rectTransform;
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(0.5f, 1f);
			rectTransform.anchorMax = val2;
			rectTransform.anchorMin = val2;
			rectTransform.pivot = new Vector2(0.5f, 1f);
			rectTransform.anchoredPosition = new Vector2(0f, -60f);
			rectTransform.sizeDelta = new Vector2(900f, 900f * (float)((Texture)texture).height / (float)((Texture)texture).width);
			return true;
		}
	}
	[HarmonyPatch(typeof(EnvironmentDirector), "Setup")]
	internal static class EnvironmentSetupPatch
	{
		private static void Postfix()
		{
			FogState.OnLevelSetup();
		}
	}
	[HarmonyPatch(typeof(EnvironmentDirector), "Update")]
	internal static class EnvironmentUpdatePatch
	{
		private static void Postfix(EnvironmentDirector __instance)
		{
			FogState.Update(__instance);
		}
	}
	[HarmonyPatch(typeof(EnemyDirector), "AmountSetup")]
	internal static class EnemyAmountPatch
	{
		private static void Postfix(EnemyDirector __instance)
		{
			if (Plugin.DisableEnemies.Value && SemiFunc.RunIsLevel() && FogState.IsFogLevel())
			{
				__instance.enemyListCurrent.Clear();
				__instance.totalAmount = 0;
				Plugin.Log.LogInfo((object)"Dimnivå: inga vanliga fiender.");
			}
		}
	}
	internal static class FogState
	{
		private const string RoomKey = "kinglir.fog";

		private static bool foggy;

		private static bool active;

		private static float levelTimer;

		private static float levelStart;

		private static float levelEnd;

		private static int chosenMoon = -1;

		private static int chosenLevel = -1;

		internal static void OnLevelSetup()
		{
			levelTimer = 0f;
			foggy = false;
			active = SemiFunc.RunIsLevel();
			FogBanner.Hide();
			if (active)
			{
				Level level = LevelGenerator.Instance.Level;
				levelStart = level.FogStartDistance;
				levelEnd = level.FogEndDistance;
				int levelsCompleted = RunManager.instance.levelsCompleted;
				if (SemiFunc.IsMasterClientOrSingleplayer())
				{
					ChooseIfNeeded(levelsCompleted);
				}
				Plugin.Log.LogInfo((object)$"Nivå {levelsCompleted + 1}, månnivå {Moon(levelsCompleted)}.");
			}
		}

		private static int Moon(int levelsCompleted)
		{
			return RunManager.instance.CalculateMoonLevel(levelsCompleted);
		}

		private static void ChooseIfNeeded(int levelsCompleted)
		{
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Expected O, but got Unknown
			//IL_00f3: Expected O, but got Unknown
			int num = Moon(levelsCompleted);
			int num2 = levelsCompleted;
			while (num2 > 0 && Moon(num2 - 1) == num)
			{
				num2--;
			}
			int i;
			for (i = levelsCompleted; Moon(i + 1) == num; i++)
			{
			}
			int num3 = ((num > 0) ? (num2 + 1) : num2);
			ReadChoice(out var moon, out var _);
			if (levelsCompleted == num2 || moon != num)
			{
				int num4 = Random.Range(Mathf.Max(num3, levelsCompleted), i + 1);
				chosenMoon = num;
				chosenLevel = num4;
				Plugin.Log.LogInfo((object)$"Måncykel {num}: dimma på nivå {num4 + 1} (av {num3 + 1}-{i + 1}).");
				if (SemiFunc.IsMultiplayer() && PhotonNetwork.InRoom)
				{
					Room currentRoom = PhotonNetwork.CurrentRoom;
					Hashtable val = new Hashtable();
					((Dictionary<object, object>)val).Add((object)"kinglir.fog", (object)$"{num}:{num4}");
					currentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null);
				}
			}
		}

		private static void ReadChoice(out int moon, out int level)
		{
			moon = chosenMoon;
			level = chosenLevel;
			if (!SemiFunc.IsMultiplayer() || SemiFunc.IsMasterClient())
			{
				return;
			}
			moon = (level = -1);
			if (PhotonNetwork.CurrentRoom != null && ((Dictionary<object, object>)(object)((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties).TryGetValue((object)"kinglir.fog", out object value) && value is string text)
			{
				string[] array = text.Split(':');
				if (array.Length == 2)
				{
					int.TryParse(array[0], out moon);
					int.TryParse(array[1], out level);
				}
			}
		}

		internal static bool IsFogLevel()
		{
			if (Plugin.TestFogEveryLevel.Value)
			{
				return true;
			}
			int levelsCompleted = RunManager.instance.levelsCompleted;
			ReadChoice(out var moon, out var level);
			if (moon == Moon(levelsCompleted))
			{
				return level == levelsCompleted;
			}
			return false;
		}

		internal static void Update(EnvironmentDirector director)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Invalid comparison between Unknown and I4
			if (!active || !director.SetupDone || (int)GameDirector.instance.currentState < 2)
			{
				return;
			}
			if (!foggy && levelTimer < 5f && IsFogLevel())
			{
				foggy = true;
				Plugin.Log.LogInfo((object)"Dimman rullar in.");
			}
			levelTimer += Time.deltaTime;
			if (foggy)
			{
				ApplyFog(director);
				FogBanner.Tick(levelTimer);
				if (Plugin.TentacleEnabled.Value && levelTimer >= Plugin.FadeInSeconds.Value)
				{
					Tentacle.Create();
				}
			}
		}

		private static void ApplyFog(EnvironmentDirector director)
		{
			//IL_0068: 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_0082: 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_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			float value = Plugin.FadeInSeconds.Value;
			float num = ((value > 0f) ? Mathf.Clamp01(levelTimer / value) : 1f);
			num = num * num * (3f - 2f * num);
			float num2 = Mathf.Lerp(levelStart, Plugin.FogStart.Value, num);
			float num3 = Mathf.Lerp(levelEnd, Plugin.FogEnd.Value, num);
			director.OverrideFogDistance(new Vector2(num2, num3), 0.2f);
			director.OverrideFogColor(Color.Lerp(RenderSettings.fogColor, Plugin.FogColor.Value, num), 0.2f);
			float num4 = Mathf.Lerp(1f, Plugin.AmbientMultiplier.Value, num);
			RenderSettings.ambientLight *= num4;
		}
	}
	[BepInPlugin("kinglir.fogmod", "FogMod", "0.1.2")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string Guid = "kinglir.fogmod";

		public const string Name = "FogMod";

		public const string Version = "0.1.2";

		internal static ManualLogSource Log;

		internal static ConfigEntry<bool> TestFogEveryLevel;

		internal static ConfigEntry<float> FogStart;

		internal static ConfigEntry<float> FogEnd;

		internal static ConfigEntry<Color> FogColor;

		internal static ConfigEntry<float> FadeInSeconds;

		internal static ConfigEntry<float> AmbientMultiplier;

		internal static ConfigEntry<bool> DisableEnemies;

		internal static ConfigEntry<bool> TentacleEnabled;

		internal static ConfigEntry<bool> SmashObjects;

		internal static ConfigEntry<float> AggressionStep;

		internal static ConfigEntry<float> FirstDelayMin;

		internal static ConfigEntry<float> FirstDelayMax;

		internal static ConfigEntry<float> CooldownMin;

		internal static ConfigEntry<float> CooldownMax;

		internal static ConfigEntry<float> StalkSpeed;

		internal static ConfigEntry<float> LungeSpeed;

		internal static ConfigEntry<float> Thickness;

		internal static ConfigEntry<float> DragSpeed;

		internal static ConfigEntry<float> MaxDragSeconds;

		internal static ConfigEntry<float> Clumsiness;

		internal static ConfigEntry<float> SpeedPerSpawn;

		internal static ConfigEntry<float> ClumsinessPerSpawn;

		internal static ConfigEntry<int> RescueGrabbers;

		internal static ConfigEntry<Color> TentacleColor;

		internal static ConfigEntry<float> SoundVolume;

		internal static ConfigEntry<float> AmbientVolume;

		internal static ConfigEntry<float> AmbientPitch;

		internal static ConfigEntry<float> AmbientLowPass;

		internal static ConfigEntry<float> DragVolume;

		internal static ConfigEntry<float> DragPitch;

		private void Awake()
		{
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_036b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0471: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			TestFogEveryLevel = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "TestFogEveryLevel", false, "Endast för test: dimma på varje nivå. Normalt kommer dimman en gång per måncykel (var 5:e nivå), på en slumpad nivå som inte är månbytet.");
			FogStart = ((BaseUnityPlugin)this).Config.Bind<float>("Fog", "FogStart", 0f, "Avstånd (m) där dimman börjar.");
			FogEnd = ((BaseUnityPlugin)this).Config.Bind<float>("Fog", "FogEnd", 6f, "Avstånd (m) där dimman är helt tät. Nivåernas normala värde är runt 15.");
			FogColor = ((BaseUnityPlugin)this).Config.Bind<Color>("Fog", "FogColor", new Color(0.2f, 0.21f, 0.23f, 1f), "Dimmans färg. Mörkare färg = mörkare och mer instängd dimma.");
			FadeInSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Fog", "FadeInSeconds", 8f, "Sekunder som dimman tar på sig att rulla in när nivån startar.");
			AmbientMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Fog", "AmbientMultiplier", 0.25f, "Omgivningsljus under dimma (1 = oförändrat, 0.5 = halva, 0 = kolsvart utanför lampor och ficklampa).");
			DisableEnemies = ((BaseUnityPlugin)this).Config.Bind<bool>("Fog", "DisableEnemies", true, "Inga vanliga fiender spawnar på dimnivåer, bara tentakeln.");
			TentacleEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Tentacle", "Enabled", true, "Tentakel i dimman som griper och drar iväg spelare.");
			SmashObjects = ((BaseUnityPlugin)this).Config.Bind<bool>("Tentacle", "SmashObjects", true, "Tentakeln slår sönder dörrar och slår till föremål i vägen (värdesaker kan tappa värde eller gå sönder).");
			AggressionStep = ((BaseUnityPlugin)this).Config.Bind<float>("Tentacle", "AggressionStep", 0.25f, "Hur mycket aggressivare tentakeln blir varje gång den undviks (max 1 = full ilska). Nollställs när den tar någon.");
			FirstDelayMin = ((BaseUnityPlugin)this).Config.Bind<float>("Tentacle", "FirstDelayMin", 45f, "Minsta tid (s) efter att dimman rullat in innan första attacken.");
			FirstDelayMax = ((BaseUnityPlugin)this).Config.Bind<float>("Tentacle", "FirstDelayMax", 90f, "Längsta tid (s) efter att dimman rullat in innan första attacken.");
			CooldownMin = ((BaseUnityPlugin)this).Config.Bind<float>("Tentacle", "CooldownMin", 90f, "Minsta tid (s) mellan attacker.");
			CooldownMax = ((BaseUnityPlugin)this).Config.Bind<float>("Tentacle", "CooldownMax", 150f, "Längsta tid (s) mellan attacker.");
			StalkSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Tentacle", "StalkSpeed", 1.5f, "Hur snabbt tentakeln smyger mot offret (m/s).");
			LungeSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Tentacle", "LungeSpeed", 16f, "Hastighet (m/s) när offret springer ifrån och tentakeln gör ett utfall.");
			Thickness = ((BaseUnityPlugin)this).Config.Bind<float>("Tentacle", "Thickness", 1f, "Tjockleksmultiplikator för tentakeln.");
			DragSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Tentacle", "DragSpeed", 9f, "Hur snabbt offret dras (m/s, ungefär).");
			MaxDragSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Tentacle", "MaxDragSeconds", 20f, "Tentakeln släpper senast efter så här många sekunder.");
			Clumsiness = ((BaseUnityPlugin)this).Config.Bind<float>("Tentacle", "Clumsiness", 10f, "Styrka på de slumpmässiga rycken och slagen som slår offret mot väggar, golv och tak.");
			SpeedPerSpawn = ((BaseUnityPlugin)this).Config.Bind<float>("Tentacle", "SpeedPerSpawn", 0.2f, "Ökning av tentakelns fart (jakt och dragning) för varje gång den dykt upp på nivån (max x2).");
			ClumsinessPerSpawn = ((BaseUnityPlugin)this).Config.Bind<float>("Tentacle", "ClumsinessPerSpawn", 0.35f, "Ökning av klumpigheten för varje gång den dykt upp på nivån (max x3).");
			RescueGrabbers = ((BaseUnityPlugin)this).Config.Bind<int>("Tentacle", "RescueGrabbers", 2, "Antal lagkamrater som måste hålla i offret (1,5 s) för att tentakeln ska släppa.");
			TentacleColor = ((BaseUnityPlugin)this).Config.Bind<Color>("Tentacle", "Color", new Color(0.16f, 0.12f, 0.13f, 1f), "Tentakelns färg.");
			SoundVolume = ((BaseUnityPlugin)this).Config.Bind<float>("Tentacle", "SoundVolume", 1f, "Volym för tentakelns väsande när den belyses, 0-1.");
			AmbientVolume = ((BaseUnityPlugin)this).Config.Bind<float>("Tentacle", "AmbientVolume", 1f, "Volym för morret från tentakelns bas (hörs långt, avtar med avståndet), 0-1.");
			AmbientPitch = ((BaseUnityPlugin)this).Config.Bind<float>("Tentacle", "AmbientPitch", 0.55f, "Tonhöjd och tempo för morret (1 = original, lägre = djupare och långsammare andetag).");
			AmbientLowPass = ((BaseUnityPlugin)this).Config.Bind<float>("Tentacle", "AmbientLowPass", 650f, "Lågpassfilter för morret i Hz (lägre = mörkare och mer bas). Läses när nivån startar.");
			DragVolume = ((BaseUnityPlugin)this).Config.Bind<float>("Tentacle", "DragVolume", 1f, "Volym för ljudet medan tentakeln drar en spelare, 0-1.");
			DragPitch = ((BaseUnityPlugin)this).Config.Bind<float>("Tentacle", "DragPitch", 1.5f, "Tonhöjd och tempo för dragljudet (1 = original, 1.5 = högre och snabbare).");
			SoundLibrary.Load(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location));
			new Harmony("kinglir.fogmod").PatchAll();
			Log.LogInfo((object)"FogMod 0.1.2 laddad.");
		}
	}
	internal static class SoundLibrary
	{
		internal static readonly List<AudioClip> Ambient = new List<AudioClip>();

		internal static readonly List<AudioClip> Drag = new List<AudioClip>();

		internal static readonly List<AudioClip> Hiss = new List<AudioClip>();

		internal static void Load(string pluginDirectory)
		{
			string path = Path.Combine(pluginDirectory, "sounds");
			LoadInto(Path.Combine(path, "ambient_1.mp3"), Ambient);
			LoadInto(Path.Combine(path, "ambient_2.mp3"), Ambient);
			LoadInto(Path.Combine(path, "drag_1.mp3"), Drag);
			LoadInto(Path.Combine(path, "drag_2.mp3"), Drag);
			LoadInto(Path.Combine(path, "hiss.mp3"), Hiss);
		}

		internal static AudioClip Random(List<AudioClip> clips)
		{
			if (clips.Count <= 0)
			{
				return null;
			}
			return clips[Random.Range(0, clips.Count)];
		}

		private static void LoadInto(string path, List<AudioClip> target)
		{
			if (!File.Exists(path))
			{
				Plugin.Log.LogWarning((object)("Ljudfil saknas: " + path));
				return;
			}
			UnityWebRequest request = UnityWebRequestMultimedia.GetAudioClip(new Uri(path).AbsoluteUri, (AudioType)13);
			((AsyncOperation)request.SendWebRequest()).completed += delegate
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: Invalid comparison between Unknown and I4
				if ((int)request.result == 1)
				{
					AudioClip content = DownloadHandlerAudioClip.GetContent(request);
					((Object)content).name = Path.GetFileNameWithoutExtension(path);
					Object.DontDestroyOnLoad((Object)(object)content);
					target.Add(content);
				}
				else
				{
					Plugin.Log.LogWarning((object)("Kunde inte läsa " + Path.GetFileName(path) + ": " + request.error));
				}
				request.Dispose();
			};
		}
	}
	public static class SoundSynth
	{
		public const int Rate = 44100;

		private const float Pi = MathF.PI;

		public static float[] Hiss()
		{
			int num = 70560;
			float[] array = new float[num];
			Random random = new Random(1337);
			float num2 = 0f;
			float num3 = 0f;
			float num4 = 0f;
			float num5 = 0f;
			for (int i = 0; i < num; i++)
			{
				float num6 = (float)i / 44100f;
				float num7 = (float)(random.NextDouble() * 2.0 - 1.0);
				num3 = 0.6f * (num3 + num7 - num4);
				num4 = num7;
				num2 += 0.35f * (num3 - num2);
				float num8 = num2 * (0.75f + 0.25f * Sin(num6 * 2f * MathF.PI * 9f));
				num5 += (60f + 15f * Sin(num6 * 2f * MathF.PI * 3f)) / 44100f;
				float num9 = (2f * (num5 - (float)Math.Floor(num5)) - 1f) * (0.5f + 0.5f * Math.Abs(num7)) * 0.45f;
				float num10 = Clamp01(num6 / 0.06f) * Clamp01((1.6f - num6) / 0.7f);
				array[i] = Tanh((num8 * 2.2f + num9) * num10 * 1.4f) * 0.9f;
			}
			return array;
		}

		private static float Sin(float x)
		{
			return (float)Math.Sin(x);
		}

		private static float Clamp01(float x)
		{
			if (!(x < 0f))
			{
				if (!(x > 1f))
				{
					return x;
				}
				return 1f;
			}
			return 0f;
		}

		private static float Tanh(float x)
		{
			return (float)Math.Tanh(x);
		}
	}
	internal sealed class SoundVoice
	{
		private readonly AudioSource[] sources = (AudioSource[])(object)new AudioSource[2];

		private readonly List<AudioClip> clips;

		private readonly float fade;

		private readonly float gapMin;

		private readonly float gapMax;

		private int current;

		private float master;

		private float nextStart;

		internal Transform Transform { get; }

		internal bool Active { get; set; }

		internal float Volume { get; set; } = 1f;

		internal float Pitch { get; set; } = 1f;

		internal SoundVoice(Transform parent, string name, List<AudioClip> clips, float minDistance, float maxDistance, float fade, float gapMin, float gapMax)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Expected O, but got Unknown
			this.clips = clips;
			this.fade = fade;
			this.gapMin = gapMin;
			this.gapMax = gapMax;
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent, false);
			Transform = val.transform;
			for (int i = 0; i < sources.Length; i++)
			{
				GameObject val2 = new GameObject($"{name} {i}");
				val2.transform.SetParent(val.transform, false);
				sources[i] = TentacleSounds.CreateSource(val2, minDistance, maxDistance, (AudioRolloffMode)0);
			}
		}

		internal void AddLowPass(float cutoff, float resonance)
		{
			AudioSource[] array = sources;
			for (int i = 0; i < array.Length; i++)
			{
				AudioLowPassFilter obj = ((Component)array[i]).gameObject.AddComponent<AudioLowPassFilter>();
				obj.cutoffFrequency = cutoff;
				obj.lowpassResonanceQ = resonance;
			}
		}

		internal void Update()
		{
			master = Mathf.MoveTowards(master, Active ? 1f : 0f, Time.deltaTime / fade);
			AudioSource val = sources[current];
			if (Active)
			{
				float num = ((val.isPlaying && (Object)(object)val.clip != (Object)null) ? ((val.clip.length - val.time) / Mathf.Max(val.pitch, 0.01f)) : 0f);
				if ((!val.isPlaying || (gapMax <= 0f && num <= fade)) && Time.time >= nextStart)
				{
					StartNext();
				}
			}
			for (int i = 0; i < sources.Length; i++)
			{
				AudioSource val2 = sources[i];
				if (val2.isPlaying && !((Object)(object)val2.clip == (Object)null))
				{
					val2.pitch = Pitch;
					float length = val2.clip.length;
					float num2 = Mathf.Min(new float[3]
					{
						1f,
						val2.time / fade,
						(length - val2.time) / fade
					});
					val2.volume = Mathf.Clamp01(num2) * master * Volume;
					if (master <= 0f)
					{
						val2.Stop();
					}
				}
			}
		}

		private void StartNext()
		{
			AudioClip val = SoundLibrary.Random(clips);
			if (!((Object)(object)val == (Object)null))
			{
				current = 1 - current;
				AudioSource obj = sources[current];
				obj.clip = val;
				obj.pitch = Pitch;
				obj.volume = 0f;
				obj.Play();
				float num = val.length / Mathf.Max(Pitch, 0.01f);
				nextStart = ((gapMax > 0f) ? (Time.time + num + Random.Range(gapMin, gapMax)) : Time.time);
			}
		}
	}
	internal sealed class Tentacle : MonoBehaviour
	{
		private enum State
		{
			Idle,
			Stalk,
			Grab,
			Retract
		}

		private const byte EventStalk = 153;

		private const byte EventGrab = 154;

		private const byte EventRelease = 155;

		private const byte EventTip = 156;

		private const byte EventHiss = 157;

		private const float HissCooldown = 1f;

		private const float ReachLength = 12f;

		private const float RetractSeconds = 1.5f;

		private const float CoilSeconds = 0.6f;

		private const float GrabDistance = 1.1f;

		private const float MaxStalkSeconds = 90f;

		private const float BaseMinDistance = 25f;

		private const float LockDistance = 20f;

		private const float RetargetInterval = 1f;

		private const float NearPlayerDistance = 15f;

		private const float TravelSpeed = 6f;

		private const float StrikeDistance = 2.5f;

		private const float StrikeVisibleRange = 6f;

		private const float StrikeCreepSeconds = 3f;

		private const float StrikeWindup = 0.8f;

		private const float StrikeDuration = 1.2f;

		private const float StrikeCooldown = 2.5f;

		private const float TipSendInterval = 0.1f;

		private const float TrailSpacing = 0.4f;

		private const float TipRadius = 0.15f;

		private const int LinePoints = 48;

		private const float LightRange = 4.5f;

		private const float LightGiveUpSeconds = 2.5f;

		private const float LightReleaseSeconds = 2f;

		private const float RetreatSpeed = 7f;

		private static Tentacle instance;

		private static bool eventsRegistered;

		private State state;

		private PlayerAvatar victim;

		private readonly List<Vector3> path = new List<Vector3>();

		private readonly List<Vector3> trail = new List<Vector3>();

		private float stateTime;

		private Vector3 tip;

		private Vector3 shownTip;

		private readonly List<Vector3> retractShape = new List<Vector3>();

		private float visualAggression;

		private float nextTwitch;

		private float twitchStart = -10f;

		private float twitchCenter;

		private Vector3 twitchOffset;

		private float aggression;

		private float nextAttack;

		private bool lunging;

		private bool locked;

		private Vector3 progressPosition;

		private float progressTime;

		private float nextDebugLog;

		private float nextRetarget;

		private float strikeStart = -10f;

		private bool strikeAimed;

		private Vector3 strikePoint;

		private float creepTime;

		private float nextStrike;

		private float runningTimer;

		private float lastDistance;

		private float nextTipSend;

		private float litTimer;

		private float nextHiss;

		private float hissStart = -10f;

		private float retreatUntil = -10f;

		private float lastLit = -10f;

		private List<Vector3> route;

		private float nextRoute;

		private int pathIndex;

		private float nextJolt;

		private float nextWhip;

		private float rescueTimer;

		private int spawns;

		private bool litThisFrame;

		private bool litSent;

		private bool hissLit;

		private AudioSource hissSource;

		private LineRenderer line;

		private SoundVoice ambientVoice;

		private SoundVoice dragVoice;

		private readonly List<Vector3> shape = new List<Vector3>();

		private readonly Dictionary<PhysGrabObject, float> smashed = new Dictionary<PhysGrabObject, float>();

		private float SpeedScale => Mathf.Min(1f + Plugin.SpeedPerSpawn.Value * (float)Mathf.Max(0, spawns - 1), 2f);

		private float ClumsyScale => Mathf.Min(1f + Plugin.ClumsinessPerSpawn.Value * (float)Mathf.Max(0, spawns - 1), 3f);

		internal static void Create()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)instance != (Object)null))
			{
				instance = new GameObject("FogMod Tentacle").AddComponent<Tentacle>();
			}
		}

		private void Awake()
		{
			//IL_0092: 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_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Expected O, but got Unknown
			if (!eventsRegistered && PhotonNetwork.NetworkingClient != null)
			{
				PhotonNetwork.NetworkingClient.EventReceived += OnEvent;
				eventsRegistered = true;
			}
			line = ((Component)this).gameObject.AddComponent<LineRenderer>();
			line.positionCount = 0;
			line.numCapVertices = 8;
			line.numCornerVertices = 6;
			((Renderer)line).shadowCastingMode = (ShadowCastingMode)0;
			line.widthCurve = new AnimationCurve((Keyframe[])(object)new Keyframe[3]
			{
				new Keyframe(0f, 0.18f),
				new Keyframe(0.15f, 0.32f),
				new Keyframe(1f, 0.75f)
			});
			line.widthMultiplier = Plugin.Thickness.Value;
			((Renderer)line).material = CreateMaterial();
			ambientVoice = new SoundVoice(((Component)this).transform, "Ambient", SoundLibrary.Ambient, 4f, 60f, 0.8f, 0.3f, 2.5f);
			ambientVoice.AddLowPass(Plugin.AmbientLowPass.Value, 1.8f);
			dragVoice = new SoundVoice(((Component)this).transform, "Drag", SoundLibrary.Drag, 3f, 40f, 0.25f, 0f, 0f);
			nextAttack = Time.time + Random.Range(Plugin.FirstDelayMin.Value, Plugin.FirstDelayMax.Value);
		}

		private void OnDestroy()
		{
			if ((Object)(object)instance == (Object)(object)this)
			{
				instance = null;
			}
		}

		private static Material CreateMaterial()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			Material val = new Material(Shader.Find("Standard") ?? Shader.Find("Legacy Shaders/Diffuse") ?? Shader.Find("Sprites/Default"));
			val.color = Plugin.TentacleColor.Value;
			if (val.HasProperty("_Glossiness"))
			{
				val.SetFloat("_Glossiness", 0.75f);
			}
			return val;
		}

		private static bool CanTarget(PlayerAvatar player)
		{
			if ((Object)(object)player != (Object)null && !player.isDisabled && !player.deadSet)
			{
				return (Object)(object)player.tumble != (Object)null;
			}
			return false;
		}

		private static Vector3 BodyCenter(PlayerAvatar player)
		{
			//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_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_0046: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)player.tumble != (Object)null) || !player.tumble.isTumbling)
			{
				return ((Component)player).transform.position + Vector3.up * 0.8f;
			}
			return ((Component)player.tumble).transform.position;
		}

		private void Update()
		{
			if (SemiFunc.IsMasterClientOrSingleplayer())
			{
				litThisFrame = false;
				if (state == State.Idle && Time.time >= nextAttack)
				{
					TryAttack();
				}
				else if (state == State.Stalk)
				{
					StalkLogic();
				}
				else if (state == State.Grab)
				{
					GrabLightLogic();
				}
				if (litThisFrame != litSent)
				{
					litSent = litThisFrame;
					hissLit = litThisFrame;
					Send(157, new float[1] { litThisFrame ? 1f : 0f });
				}
			}
			Draw();
			UpdateHissSound();
		}

		private void TryAttack()
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Invalid comparison between Unknown and I4
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			nextAttack = Time.time + Random.Range(Plugin.CooldownMin.Value, Plugin.CooldownMax.Value) * (1f - 0.5f * aggression);
			if ((int)GameDirector.instance.currentState != 2)
			{
				return;
			}
			PlayerAvatar val = MostIsolated();
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			List<Vector3> list = new List<Vector3>();
			foreach (PlayerAvatar player in GameDirector.instance.PlayerList)
			{
				if ((Object)(object)player != (Object)null && !player.isDisabled)
				{
					list.Add(((Component)player).transform.position);
				}
			}
			Vector3? val2 = TentaclePath.FarPoint(list, 25f);
			if (val2.HasValue)
			{
				spawns++;
				Plugin.Log.LogInfo((object)$"Tentakeln vaknar {Mathf.RoundToInt(Vector3.Distance(val2.Value, ((Component)val).transform.position))} m bort och jagar {val.playerName} (gång {spawns}: fart x{SpeedScale:0.00}, klumpighet x{ClumsyScale:0.00}).");
				Send(153, new object[4]
				{
					val.photonView.ViewID,
					new float[0],
					Flatten(val2.Value),
					aggression
				});
				OnStalk(val, new List<Vector3>(), val2.Value, aggression);
			}
		}

		private static PlayerAvatar MostIsolated()
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			PlayerAvatar result = null;
			float num = -1f;
			foreach (PlayerAvatar player in GameDirector.instance.PlayerList)
			{
				if (!CanTarget(player) || TentaclePath.Build(((Component)player).transform.position) == null)
				{
					continue;
				}
				float num2 = float.MaxValue;
				foreach (PlayerAvatar player2 in GameDirector.instance.PlayerList)
				{
					if ((Object)(object)player2 != (Object)(object)player && (Object)(object)player2 != (Object)null && !player2.isDisabled)
					{
						num2 = Mathf.Min(num2, Vector3.Distance(((Component)player2).transform.position, ((Component)player).transform.position));
					}
				}
				if (num2 > num)
				{
					num = num2;
					result = player;
				}
			}
			return result;
		}

		private void StalkLogic()
		{
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: 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_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e6: Unknown result type (might be due to invalid IL or missing references)
			if (!CanTarget(victim))
			{
				SendRelease();
				return;
			}
			if (Time.time - stateTime > 90f)
			{
				SendRelease(evaded: true);
				return;
			}
			if (!locked)
			{
				if (Time.time >= nextRetarget)
				{
					nextRetarget = Time.time + 1f;
					PlayerAvatar val = MostIsolated();
					if ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)victim)
					{
						Plugin.Log.LogInfo((object)("Tentakeln byter mål till " + val.playerName + "."));
						victim = val;
						lastDistance = Vector3.Distance(tip, BodyCenter(victim));
					}
				}
				if (Vector3.Distance(tip, BodyCenter(victim)) <= 20f)
				{
					locked = true;
					Plugin.Log.LogInfo((object)("Tentakeln har låst " + victim.playerName + "."));
				}
			}
			float num = Time.time - strikeStart;
			bool flag = num < 0.8f;
			bool flag2 = !flag && num < 2f;
			float num2 = Vector3.Distance(tip, BodyCenter(victim));
			if (Time.time >= nextDebugLog)
			{
				nextDebugLog = Time.time + 5f;
				Plugin.Log.LogInfo((object)$"Tentakeln: {num2:0.0} m från {victim.playerName}, låst {locked}, ilska {aggression:0.00}.");
			}
			if (!flag2 && !flag && Time.time - lastLit >= 1f)
			{
				Unstick(BodyCenter(victim));
			}
			if (!flag2 && IsLit(4f))
			{
				if (flag)
				{
					strikeStart = Time.time - 0.8f - 1.2f;
					creepTime = 0f;
					flag = false;
					Plugin.Log.LogInfo((object)"Hugget avbröts: ficklampa.");
				}
				LitHiss();
				lastLit = Time.time;
				litTimer += Time.deltaTime;
				lunging = false;
				if (litTimer >= 2.5f * (1f + aggression))
				{
					Plugin.Log.LogInfo((object)"Tentakeln gav upp: ficklampa.");
					SendRelease(evaded: true);
					return;
				}
			}
			if (!flag2 && (Time.time - lastLit < 1f - 0.6f * aggression || Time.time < retreatUntil))
			{
				Retreat();
			}
			else
			{
				Advance();
			}
			if (Vector3.Distance(tip, BodyCenter(victim)) <= 1.1f)
			{
				List<Vector3> list = TentaclePath.Build(((Component)victim).transform.position) ?? new List<Vector3>(path);
				Plugin.Log.LogInfo((object)$"Tentakeln tar {victim.playerName} (ilska {aggression:0.00}).");
				float num3 = aggression;
				aggression = 0f;
				Send(154, new object[3]
				{
					victim.photonView.ViewID,
					Flatten(list),
					num3
				});
				OnGrab(victim, list, num3);
			}
			else if (Time.time >= nextTipSend)
			{
				nextTipSend = Time.time + 0.1f;
				Send(156, new float[4] { tip.x, tip.y, tip.z, visualAggression }, reliable: false);
			}
		}

		private void Advance()
		{
			//IL_0006: 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_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: 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_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: 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_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: 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_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0377: Unknown result type (might be due to invalid IL or missing references)
			//IL_0378: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = BodyCenter(victim);
			float num = Vector3.Distance(tip, val);
			if (locked && num <= 6f)
			{
				creepTime += Time.deltaTime;
			}
			float num2 = Time.time - strikeStart;
			if (locked && num <= 2.5f && num2 > 2f && Time.time >= nextStrike && creepTime >= 3f * (1f - 0.5f * aggression) && TentaclePath.Passable(tip, val, 0.15f))
			{
				strikeStart = Time.time;
				num2 = 0f;
				strikeAimed = false;
				nextStrike = Time.time + 0.8f + 1.2f + 2.5f * (1f - 0.5f * aggression);
				Hiss();
				Plugin.Log.LogInfo((object)"Tentakeln laddar ett hugg.");
			}
			Vector3 val3;
			if (num2 < 0.8f)
			{
				Vector3 val2 = tip;
				val3 = tip - val;
				MoveTip(val2 + ((Vector3)(ref val3)).normalized, 1.2f * Time.deltaTime);
				lastDistance = num;
				return;
			}
			if (num2 < 2f)
			{
				if (!strikeAimed)
				{
					strikeAimed = true;
					val3 = val - tip;
					strikePoint = val + ((Vector3)(ref val3)).normalized * 0.8f;
				}
				MoveTip(strikePoint, Plugin.LungeSpeed.Value * 1.4f * (1f + 0.3f * aggression) * Time.deltaTime);
				if (Vector3.Distance(tip, strikePoint) < 0.2f)
				{
					strikeStart = Time.time - 0.8f - 1.2f;
					creepTime = 0f;
					Plugin.Log.LogInfo((object)"Tentakeln missade hugget.");
				}
				lastDistance = num;
				return;
			}
			if (!locked && NearestPlayerDistance(tip) > 15f)
			{
				MoveTip(Steer(val), 6f * (1f + 0.5f * aggression) * SpeedScale * Time.deltaTime);
				lastDistance = num;
				return;
			}
			if (!lunging && locked)
			{
				float num3 = (num - lastDistance) / Mathf.Max(Time.deltaTime, 0.0001f);
				runningTimer = ((victim.isSprinting || num3 > 1.5f) ? (runningTimer + Time.deltaTime) : 0f);
				if (runningTimer > 0.25f * (1f - 0.6f * aggression))
				{
					lunging = true;
					Plugin.Log.LogInfo((object)"Tentakeln gör ett utfall.");
				}
			}
			lastDistance = num;
			float num4 = 1f + 0.5f * Mathf.Clamp01((Time.time - stateTime) / 30f);
			float num5 = (lunging ? (Plugin.LungeSpeed.Value * (1f + 0.3f * aggression)) : (Plugin.StalkSpeed.Value * (1f + 1.5f * aggression) * num4)) * SpeedScale;
			MoveTip(Steer(val), num5 * Time.deltaTime);
		}

		private static float NearestPlayerDistance(Vector3 position)
		{
			//IL_0032: 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)
			float num = float.MaxValue;
			foreach (PlayerAvatar player in GameDirector.instance.PlayerList)
			{
				if ((Object)(object)player != (Object)null && !player.isDisabled)
				{
					num = Mathf.Min(num, Vector3.Distance(position, BodyCenter(player)));
				}
			}
			return num;
		}

		private Vector3 Steer(Vector3 target)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: 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_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			if (TentaclePath.Passable(tip, target, 0.15f))
			{
				return target;
			}
			if (route == null || Time.time >= nextRoute)
			{
				route = TentaclePath.Route(tip, target);
				nextRoute = Time.time + 0.5f;
			}
			for (int num = route.Count - 1; num >= 0; num--)
			{
				if (TentaclePath.Passable(tip, route[num], 0.15f))
				{
					return route[num];
				}
			}
			if (route.Count <= 0)
			{
				return target;
			}
			return route[0];
		}

		private void MoveTip(Vector3 towards, float step)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: 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_000c: 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_0023: 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_0059: 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_006c: 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_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: 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)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: 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_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: 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)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = towards - tip;
			if (((Vector3)(ref val)).sqrMagnitude < 0.0001f)
			{
				return;
			}
			Vector3 normalized = ((Vector3)(ref val)).normalized;
			step = Mathf.Min(step, ((Vector3)(ref val)).magnitude);
			bool heavy = lunging || Time.time - strikeStart < 2f;
			SmashAlong(tip, normalized, step, heavy);
			RaycastHit val2 = default(RaycastHit);
			if (Physics.SphereCast(tip, 0.15f, normalized, ref val2, step, TentaclePath.WallMask, (QueryTriggerInteraction)1))
			{
				float num = Mathf.Max(0f, ((RaycastHit)(ref val2)).distance - 0.05f);
				tip += normalized * num;
				Vector3 val3 = Vector3.ProjectOnPlane(normalized, ((RaycastHit)(ref val2)).normal);
				float num2 = step - num;
				if (((Vector3)(ref val3)).sqrMagnitude > 0.0001f && num2 > 0f)
				{
					((Vector3)(ref val3)).Normalize();
					RaycastHit val4 = default(RaycastHit);
					if (!Physics.SphereCast(tip, 0.15f, val3, ref val4, num2, TentaclePath.WallMask, (QueryTriggerInteraction)1))
					{
						tip += val3 * num2;
					}
				}
			}
			else
			{
				tip += normalized * step;
			}
			ExtendTrail(tip);
		}

		private void Unstick(Vector3 target)
		{
			//IL_0001: 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_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)
			//IL_0044: 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_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: 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)
			if (Vector3.Distance(tip, progressPosition) > 0.3f)
			{
				progressPosition = tip;
				progressTime = Time.time;
			}
			else
			{
				if (Time.time - progressTime < 2f || NearestPlayerDistance(tip) < 8f)
				{
					return;
				}
				route = TentaclePath.Route(tip, target);
				nextRoute = Time.time + 0.5f;
				foreach (Vector3 item in route)
				{
					if (Vector3.Distance(item, tip) > 1f)
					{
						Plugin.Log.LogInfo((object)$"Tentakeln fastnade vid {tip}, hoppar till {item}.");
						tip = item;
						ExtendTrail(tip);
						break;
					}
				}
				progressPosition = tip;
				progressTime = Time.time;
			}
		}

		private void SmashAlong(Vector3 from, Vector3 dir, float distance, bool heavy)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: 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_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			if (Plugin.SmashObjects.Value)
			{
				RaycastHit[] array = Physics.SphereCastAll(from, 0.35f, dir, distance + 0.3f, TentaclePath.SmashMask, (QueryTriggerInteraction)1);
				for (int i = 0; i < array.Length; i++)
				{
					RaycastHit val = array[i];
					Smash(((RaycastHit)(ref val)).collider, (((RaycastHit)(ref val)).point == Vector3.zero) ? from : ((RaycastHit)(ref val)).point, dir, heavy);
				}
			}
		}

		private void SmashAround(Vector3 center, float radius, Vector3 dir)
		{
			//IL_000d: 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_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)
			if (Plugin.SmashObjects.Value)
			{
				Collider[] array = Physics.OverlapSphere(center, radius, TentaclePath.SmashMask, (QueryTriggerInteraction)1);
				foreach (Collider val in array)
				{
					Smash(val, val.ClosestPoint(center), dir, heavy: false);
				}
			}
		}

		private void Smash(Collider collider, Vector3 point, Vector3 dir, bool heavy)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: 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_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			PhysGrabHinge componentInParent = ((Component)collider).GetComponentInParent<PhysGrabHinge>();
			if ((Object)(object)componentInParent != (Object)null && !componentInParent.broken && !componentInParent.dead)
			{
				if ((Object)(object)componentInParent.joint != (Object)null)
				{
					Object.Destroy((Object)(object)componentInParent.joint);
				}
				componentInParent.broken = true;
				componentInParent.HingeBreakImpulse();
				componentInParent.physGrabObject.rb.AddForce(dir * 8f + Vector3.up * 2f, (ForceMode)2);
				Plugin.Log.LogInfo((object)"Tentakeln slog sönder en dörr.");
				return;
			}
			PhysGrabObject componentInParent2 = ((Component)collider).GetComponentInParent<PhysGrabObject>();
			if ((Object)(object)componentInParent2 == (Object)null || componentInParent2.isPlayer || (Object)(object)componentInParent2.rb == (Object)null || (smashed.TryGetValue(componentInParent2, out var value) && Time.time < value))
			{
				return;
			}
			smashed[componentInParent2] = Time.time + 0.6f;
			componentInParent2.rb.AddForce(dir * (heavy ? 7f : 4f) + Vector3.up * 2f, (ForceMode)2);
			componentInParent2.rb.AddTorque(Random.onUnitSphere * 5f, (ForceMode)2);
			if ((Object)(object)componentInParent2.impactDetector != (Object)null)
			{
				if (heavy)
				{
					componentInParent2.impactDetector.BreakHeavy(point, false, 0f);
				}
				else
				{
					componentInParent2.impactDetector.BreakMedium(point, false);
				}
			}
		}

		private void Retreat()
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//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_00aa: 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_0097: 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_009e: 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)
			float num = Mathf.Clamp01((Time.time - hissStart) / Mathf.Max(0.1f, retreatUntil - hissStart));
			float num2 = 0.2f + 0.8f * (1f - num) * (1f - num);
			float num3 = 7f * num2 * (1f - 0.5f * aggression) * Time.deltaTime;
			while (num3 > 0f && trail.Count > 1)
			{
				Vector3 val = trail[trail.Count - 1];
				float num4 = Vector3.Distance(tip, val);
				if (num4 > num3)
				{
					tip = Vector3.MoveTowards(tip, val, num3);
					break;
				}
				tip = val;
				num3 -= num4;
				trail.RemoveAt(trail.Count - 1);
			}
		}

		private void GrabLightLogic()
		{
			if (IsLit(4f))
			{
				LitHiss();
				litTimer += Time.deltaTime;
				if (litTimer >= 2f)
				{
					Plugin.Log.LogInfo((object)"Tentakeln släppte: ficklampa.");
					SendRelease(evaded: true);
				}
			}
		}

		private void LitHiss()
		{
			if (Time.time - lastLit > 0.5f)
			{
				hissStart = Time.time;
				retreatUntil = Time.time + 0.8f * (1f - 0.6f * aggression);
			}
			litThisFrame = true;
		}

		private void UpdateHissSound()
		{
			//IL_00af: 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_003a: Expected O, but got Unknown
			if (state == State.Idle || state == State.Retract)
			{
				hissLit = false;
			}
			if ((Object)(object)hissSource == (Object)null)
			{
				if (!hissLit)
				{
					return;
				}
				GameObject val = new GameObject("Lit Hiss");
				val.transform.SetParent(((Component)this).transform, false);
				hissSource = TentacleSounds.CreateSource(val, 3f, 35f, (AudioRolloffMode)1);
				hissSource.clip = TentacleSounds.HissLoopClip();
				hissSource.loop = true;
				hissSource.volume = 0f;
			}
			if (shape.Count > 0)
			{
				((Component)hissSource).transform.position = shape[0];
			}
			float num = (hissLit ? Plugin.SoundVolume.Value : 0f);
			float num2 = (hissLit ? (Plugin.SoundVolume.Value / 0.08f) : (Plugin.SoundVolume.Value / 0.35f));
			hissSource.volume = Mathf.MoveTowards(hissSource.volume, num, num2 * Time.deltaTime);
			if (hissLit && !hissSource.isPlaying)
			{
				hissSource.pitch = Random.Range(0.92f, 1.05f);
				hissSource.time = 0f;
				hissSource.Play();
			}
			else if (!hissLit && hissSource.isPlaying && hissSource.volume <= 0f)
			{
				hissSource.Stop();
			}
		}

		private void Hiss()
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			if (!(Time.time < nextHiss) && shape.Count != 0)
			{
				float hissLength = TentacleSounds.HissLength;
				nextHiss = Time.time + Mathf.Max(1f, hissLength + 0.3f);
				hissStart = Time.time;
				retreatUntil = Time.time + hissLength * (1f - 0.6f * aggression);
				Vector3 val = shape[0];
				Send(157, Flatten(val));
				TentacleSounds.PlayHiss(val);
			}
		}

		private bool IsLit(float length)
		{
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: 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_00f9: Unknown result type (might be due to invalid IL or missing references)
			if (shape.Count < 2)
			{
				return false;
			}
			float num = TentaclePath.Length(shape);
			foreach (PlayerAvatar player in GameDirector.instance.PlayerList)
			{
				FlashlightController val = (((Object)(object)player != (Object)null && !player.isDisabled) ? player.flashlightController : null);
				if ((Object)(object)val == (Object)null || !val.LightActive || (Object)(object)val.spotlight == (Object)null)
				{
					continue;
				}
				Vector3 position = ((Component)val.spotlight).transform.position;
				Vector3 forward = ((Component)val.spotlight).transform.forward;
				float num2 = val.spotlight.spotAngle * 0.5f + 5f;
				for (float num3 = 0f; num3 <= Mathf.Min(length, num); num3 += 0.5f)
				{
					Vector3 val2 = TentaclePath.Sample(shape, num3);
					Vector3 val3 = val2 - position;
					if (((Vector3)(ref val3)).magnitude <= 4.5f && Vector3.Angle(forward, val3) <= num2 && TentaclePath.Visible(position, val2))
					{
						return true;
					}
				}
			}
			return false;
		}

		private void FixedUpdate()
		{
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: 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_01cf: 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_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0290: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0326: Unknown result type (might be due to invalid IL or missing references)
			//IL_0327: Unknown result type (might be due to invalid IL or missing references)
			//IL_032e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0338: Unknown result type (might be due to invalid IL or missing references)
			//IL_0349: 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)
			//IL_035a: Unknown result type (might be due to invalid IL or missing references)
			if (state != State.Grab || !SemiFunc.IsMasterClientOrSingleplayer())
			{
				return;
			}
			if (!CanTarget(victim) || Time.time - stateTime > Plugin.MaxDragSeconds.Value || pathIndex >= path.Count)
			{
				SendRelease();
				return;
			}
			PlayerTumble tumble = victim.tumble;
			int count = tumble.physGrabObject.playerGrabbing.Count;
			rescueTimer = ((count >= Plugin.RescueGrabbers.Value) ? (rescueTimer + Time.fixedDeltaTime) : 0f);
			if (rescueTimer >= 1.5f)
			{
				Plugin.Log.LogInfo((object)"Tentakeln släppte: offret räddades.");
				SendRelease(evaded: true);
				return;
			}
			if (!tumble.isTumbling)
			{
				tumble.TumbleRequest(true, false);
			}
			tumble.TumbleOverrideTime(1f);
			victim.FallDamageResetSet(0.1f);
			tumble.physGrabObject.OverrideMass(1f, 0.1f);
			tumble.physGrabObject.OverrideDrag(0.5f, 0.1f);
			tumble.physGrabObject.OverrideAngularDrag(1f, 0.1f);
			if (Time.time - stateTime < 0.6f)
			{
				return;
			}
			Vector3 position = ((Component)tumble).transform.position;
			while (pathIndex < path.Count && Vector3.Distance(position, path[pathIndex]) < 1.5f)
			{
				pathIndex++;
			}
			if (pathIndex < path.Count)
			{
				float num = ((count > 0) ? 0.5f : 1f);
				float num2 = Plugin.DragSpeed.Value * num * (1f + Mathf.Clamp01(visualAggression)) * SpeedScale;
				Vector3 val = SemiFunc.PhysFollowPosition(position, path[pathIndex], tumble.physGrabObject.rbVelocity, num2);
				tumble.rb.AddForce(val * (10f * Time.fixedDeltaTime * num), (ForceMode)1);
				Vector3 val2 = path[pathIndex] - position;
				SmashAround(position, 1.1f, ((Vector3)(ref val2)).normalized);
				float num3 = Plugin.Clumsiness.Value * ClumsyScale;
				if (Time.time >= nextJolt)
				{
					nextJolt = Time.time + Random.Range(0.2f, 0.5f) / Mathf.Sqrt(ClumsyScale);
					Vector3 onUnitSphere = Random.onUnitSphere;
					onUnitSphere.y = Mathf.Abs(onUnitSphere.y) + 0.3f;
					tumble.rb.AddForce(((Vector3)(ref onUnitSphere)).normalized * num3 * 1.3f, (ForceMode)1);
					tumble.rb.AddTorque(Random.onUnitSphere * num3 * 2f, (ForceMode)1);
				}
				if (Time.time >= nextWhip)
				{
					nextWhip = Time.time + Random.Range(0.8f, 1.6f) / ClumsyScale;
					tumble.rb.AddForce(WhipDirection(position) * num3 * 2f, (ForceMode)1);
					tumble.rb.AddTorque(Random.onUnitSphere * num3 * 3f, (ForceMode)1);
				}
			}
		}

		private static Vector3 WhipDirection(Vector3 from)
		{
			//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)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: 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_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: 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_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			int mask = LayerMask.GetMask(new string[1] { "Default" });
			float num = float.MaxValue;
			Vector3 val = Vector3.zero;
			float num2 = Random.Range(0f, 360f);
			RaycastHit val3 = default(RaycastHit);
			for (int i = 0; i < 8; i++)
			{
				Vector3 val2 = Quaternion.Euler(0f, num2 + (float)i * 45f, 0f) * Vector3.forward;
				if (Physics.Raycast(from, val2, ref val3, 4f, mask, (QueryTriggerInteraction)1) && ((RaycastHit)(ref val3)).distance < num)
				{
					num = ((RaycastHit)(ref val3)).distance;
					val = val2;
				}
			}
			if (val != Vector3.zero && Random.value < 0.7f)
			{
				Vector3 val4 = val + Vector3.up * 0.2f;
				return ((Vector3)(ref val4)).normalized;
			}
			if (!(Random.value < 0.6f))
			{
				return Vector3.down;
			}
			return Vector3.up;
		}

		private void SendRelease(bool evaded = false)
		{
			if (evaded)
			{
				aggression = Mathf.Min(1f, aggression + Plugin.AggressionStep.Value);
				Plugin.Log.LogInfo((object)$"Tentakeln blev undviken. Ilska: {aggression:0.00}.");
			}
			if ((Object)(object)victim != (Object)null)
			{
				Send(155, victim.photonView.ViewID);
			}
			OnRelease();
		}

		private static void Send(byte code, object content, bool reliable = true)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: 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_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			if (SemiFunc.IsMultiplayer())
			{
				PhotonNetwork.RaiseEvent(code, content, new RaiseEventOptions
				{
					Receivers = (ReceiverGroup)0
				}, reliable ? SendOptions.SendReliable : SendOptions.SendUnreliable);
			}
		}

		private static void OnEvent(EventData e)
		{
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: 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)
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			switch (e.Code)
			{
			case 153:
				if (e.CustomData is object[] array4 && array4.Length == 4 && array4[0] is int viewID && array4[1] is float[] flat && array4[2] is float[] flat2 && array4[3] is float anger)
				{
					PlayerAvatar val = FindPlayer(viewID);
					if ((Object)(object)val != (Object)null)
					{
						instance.OnStalk(val, Unflatten(flat), Unflatten(flat2)[0], anger);
					}
				}
				break;
			case 154:
				if (e.CustomData is object[] array5 && array5.Length == 3 && array5[0] is int viewID2 && array5[1] is float[] flat3 && array5[2] is float anger2)
				{
					PlayerAvatar val2 = FindPlayer(viewID2);
					if ((Object)(object)val2 != (Object)null)
					{
						instance.OnGrab(val2, Unflatten(flat3), anger2);
					}
				}
				break;
			case 156:
				if (e.CustomData is float[] array3 && array3.Length == 4)
				{
					instance.tip = new Vector3(array3[0], array3[1], array3[2]);
					instance.visualAggression = array3[3];
				}
				break;
			case 155:
				instance.OnRelease();
				break;
			case 157:
				if (e.CustomData is float[] array && array.Length == 3)
				{
					TentacleSounds.PlayHiss(new Vector3(array[0], array[1], array[2]));
				}
				else if (e.CustomData is float[] array2 && array2.Length == 1)
				{
					instance.hissLit = array2[0] > 0.5f;
				}
				break;
			}
		}

		private static PlayerAvatar FindPlayer(int viewID)
		{
			PhotonView val = PhotonView.Find(viewID);
			if (!((Object)(object)val != (Object)null))
			{
				return null;
			}
			return ((Component)val).GetComponent<PlayerAvatar>();
		}

		private static float[] Flatten(List<Vector3> points)
		{
			//IL_0018: 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_003e: Unknown result type (might be due to invalid IL or missing references)
			float[] array = new float[points.Count * 3];
			for (int i = 0; i < points.Count; i++)
			{
				array[i * 3] = points[i].x;
				array[i * 3 + 1] = points[i].y;
				array[i * 3 + 2] = points[i].z;
			}
			return array;
		}

		private static float[] Flatten(Vector3 point)
		{
			//IL_0008: 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_001a: Unknown result type (might be due to invalid IL or missing references)
			return new float[3] { point.x, point.y, point.z };
		}

		private static List<Vector3> Unflatten(float[] flat)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			List<Vector3> list = new List<Vector3>();
			for (int i = 0; i + 2 < flat.Length; i += 3)
			{
				list.Add(new Vector3(flat[i], flat[i + 1], flat[i + 2]));
			}
			return list;
		}

		private void OnStalk(PlayerAvatar target, List<Vector3> dragRoute, Vector3 start, float anger)
		{
			//IL_0049: 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_0052: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			visualAggression = anger;
			state = State.Stalk;
			stateTime = Time.time;
			victim = target;
			path.Clear();
			path.AddRange(dragRoute);
			trail.Clear();
			trail.Add(start);
			tip = (shownTip = start);
			lunging = false;
			locked = false;
			nextRetarget = Time.time + 1f;
			strikeStart = -10f;
			creepTime = 0f;
			nextStrike = 0f;
			runningTimer = 0f;
			litTimer = 0f;
			lastLit = -10f;
			route = null;
			progressPosition = start;
			progressTime = Time.time;
			lastDistance = Vector3.Distance(start, BodyCenter(target));
		}

		private void OnGrab(PlayerAvatar target, List<Vector3> dragRoute, float anger)
		{
			visualAggression = anger;
			state = State.Grab;
			stateTime = Time.time;
			victim = target;
			path.Clear();
			path.AddRange(dragRoute);
			pathIndex = 0;
			rescueTimer = 0f;
			litTimer = 0f;
			nextJolt = Time.time + 0.6f;
			nextWhip = Time.time + 0.6f + 0.3f;
		}

		private void OnRelease()
		{
			if (state != State.Idle && state != State.Retract)
			{
				retractShape.Clear();
				retractShape.AddRange(shape);
				state = State.Retract;
				stateTime = Time.time;
				victim = null;
			}
		}

		private void ExtendTrail(Vector3 point)
		{
			//IL_0038: 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_0025: Unknown result type (might be due to invalid IL or missing references)
			if (trail.Count == 0 || Vector3.Distance(trail[trail.Count - 1], point) >= 0.4f)
			{
				trail.Add(point);
			}
		}

		private void Draw()
		{
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: 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_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			shape.Clear();
			switch (state)
			{
			case State.Stalk:
			{
				if (!SemiFunc.IsMasterClientOrSingleplayer())
				{
					shownTip = Vector3.Lerp(shownTip, tip, Time.deltaTime * 10f);
					if (trail.Count > 1 && Vector3.Distance(shownTip, trail[0]) < Vector3.Distance(trail[trail.Count - 1], trail[0]) - 0.4f)
					{
						trail.RemoveAt(trail.Count - 1);
					}
					ExtendTrail(shownTip);
				}
				else
				{
					shownTip = tip;
				}
				shape.Add(shownTip);
				for (int num3 = trail.Count - 1; num3 >= 0; num3--)
				{
					shape.Add(trail[num3]);
				}
				break;
			}
			case State.Grab:
				if (!((Object)(object)victim == (Object)null))
				{
					AddCoil(BodyCenter(victim), Mathf.Clamp01((Time.time - stateTime) / 0.6f));
					List<Vector3> list = TentaclePath.Ahead(path, shape[shape.Count - 1], 12f);
					for (int j = 1; j < list.Count; j++)
					{
						shape.Add(list[j]);
					}
				}
				break;
			case State.Retract:
			{
				float num = Mathf.Clamp01((Time.time - stateTime) / 1.5f);
				if (num >= 1f || retractShape.Count < 2)
				{
					state = State.Idle;
					break;
				}
				float num2 = TentaclePath.Length(retractShape);
				for (int i = 0; i <= 16; i++)
				{
					shape.Add(TentaclePath.Sample(retractShape, Mathf.Lerp(num2 * num, num2, (float)i / 16f)));
				}
				break;
			}
			}
			UpdateAudio();
			if (shape.Count < 2)
			{
				line.positionCount = 0;
			}
			else
			{
				Render();
			}
		}

		private void UpdateAudio()
		{
			//IL_0050: 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)
			ambientVoice.Active = state != State.Idle && shape.Count > 0;
			if (shape.Count > 0)
			{
				ambientVoice.Transform.position = shape[shape.Count - 1];
			}
			ambientVoice.Volume = Plugin.AmbientVolume.Value;
			ambientVoice.Pitch = Plugin.AmbientPitch.Value;
			ambientVoice.Update();
			dragVoice.Active = state == State.Grab && (Object)(object)victim != (Object)null;
			if (dragVoice.Active)
			{
				dragVoice.Transform.position = BodyCenter(victim);
			}
			dragVoice.Volume = Plugin.DragVolume.Value;
			dragVoice.Pitch = Plugin.DragPitch.Value * (1f + 0.15f * Mathf.Clamp01(visualAggression));
			dragVoice.Update();
		}

		private void AddCoil(Vector3 center, float amount)
		{
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			float num = 2.25f * amount;
			int num2 = Mathf.Max(2, Mathf.CeilToInt(24f * amount));
			float num3 = Time.time * 0.6f;
			Vector3 val = default(Vector3);
			for (int i = 0; i <= num2; i++)
			{
				float num4 = (float)i / (float)num2;
				float num5 = num3 + num4 * num * MathF.PI * 2f;
				((Vector3)(ref val))..ctor(Mathf.Cos(num5) * 0.42f, 0.45f - num4 * 0.9f, Mathf.Sin(num5) * 0.42f);
				shape.Add(center + val);
			}
		}

		private void Render()
		{
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0269: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: 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_025f: Unknown result type (might be due to invalid IL or missing references)
			float num = TentaclePath.Length(shape);
			float num2 = Mathf.Clamp01(visualAggression);
			int num3 = Mathf.Clamp(Mathf.CeilToInt(num / 0.5f), 48, 256);
			line.positionCount = num3;
			float num4 = ((state == State.Stalk) ? 1.6f : 3.5f) * (1f + 3f * num2);
			float time = Time.time;
			if (num2 > 0f && time >= nextTwitch)
			{
				nextTwitch = time + Random.Range(0.06f, 0.3f) * (1.6f - num2);
				twitchStart = time;
				twitchCenter = Random.value;
				twitchOffset = Random.onUnitSphere * (0.15f + 0.45f * num2);
			}
			float num5 = time - twitchStart;
			float num6 = ((num5 < 0.15f) ? (1f - num5 / 0.15f) : 0f);
			Vector3 val2 = default(Vector3);
			for (int i = 0; i < num3; i++)
			{
				float num7 = (float)i / (float)(num3 - 1);
				Vector3 val = TentaclePath.Sample(shape, num7 * num);
				float num8 = Mathf.Clamp01((num7 * num - 1.5f) / 4f);
				float num9 = time * num4 + num7 * 7f;
				val += new Vector3(Mathf.Sin(num9), Mathf.Sin(num9 * 1.3f + 1f) * 0.6f, Mathf.Cos(num9 * 0.8f)) * (0.03f + 0.35f * num8);
				if (num2 > 0f)
				{
					float num10 = time * (18f + 22f * num2);
					((Vector3)(ref val2))..ctor(Mathf.PerlinNoise(num10, (float)i * 0.37f) - 0.5f, Mathf.PerlinNoise((float)i * 0.53f, num10) - 0.5f, Mathf.PerlinNoise(num10 + 31.7f, (float)i * 0.71f) - 0.5f);
					val += val2 * (0.35f * num2 * (0.25f + num8));
					float num11 = Mathf.Exp(0f - Mathf.Pow((num7 - twitchCenter) / 0.12f, 2f));
					val += twitchOffset * (num6 * num11 * (0.3f + 0.7f * num8));
				}
				line.SetPosition(i, val);
			}
		}
	}
	internal static class TentaclePath
	{
		private static readonly Vector3 BodyHeight = Vector3.up * 0.8f;

		internal static readonly int WallMask = LayerMask.GetMask(new string[1] { "Default" });

		internal static readonly int DoorMask = LayerMask.GetMask(new string[1] { "PhysGrabObjectHinge" });

		internal static readonly int SmashMask = LayerMask.GetMask(new string[2] { "PhysGrabObjectHinge", "PhysGrabObject" });

		internal static List<Vector3> Build(Vector3 from)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			List<LevelPoint> list = (((Object)(object)LevelGenerator.Instance != (Object)null) ? LevelGenerator.Instance.LevelPathPoints : null);
			if (list == null || list.Count == 0)
			{
				return null;
			}
			LevelPoint val = null;
			float num = float.MaxValue;
			foreach (LevelPoint item in list)
			{
				if (!((Object)(object)item == (Object)null))
				{
					float num2 = Vector3.Distance(((Component)item).transform.position, from);
					if (num2 < num)
					{
						num = num2;
						val = item;
					}
				}
			}
			if ((Object)(object)val == (Object)null || val.inStartRoom || val.Truck)
			{
				return null;
			}
			Dictionary<LevelPoint, int> dictionary = new Dictionary<LevelPoint, int> { { val, 0 } };
			Dictionary<LevelPoint, LevelPoint> dictionary2 = new Dictionary<LevelPoint, LevelPoint>();
			Queue<LevelPoint> queue = new Queue<LevelPoint>();
			queue.Enqueue(val);
			int num3 = 0;
			while (queue.Count > 0)
			{
				LevelPoint val2 = queue.Dequeue();
				foreach (LevelPoint connectedPoint in val2.ConnectedPoints)
				{
					if (!((Object)(object)connectedPoint == (Object)null) && !dictionary.ContainsKey(connectedPoint))
					{
						dictionary[connectedPoint] = dictionary[val2] + 1;
						dictionary2[connectedPoint] = val2;
						num3 = Mathf.Max(num3, dictionary[connectedPoint]);
						queue.Enqueue(connectedPoint);
					}
				}
			}
			int num4 = Mathf.Max(3, num3 / 2);
			List<LevelPoint> list2 = new List<LevelPoint>();
			foreach (KeyValuePair<LevelPoint, int> item2 in dictionary)
			{
				if (item2.Value == num4 && !item2.Key.inStartRoom)
				{
					list2.Add(item2.Key);
				}
			}
			if (list2.Count == 0)
			{
				return null;
			}
			List<Vector3> list3 = new List<Vector3>();
			LevelPoint val3 = list2[Random.Range(0, list2.Count)];
			while ((Object)(object)val3 != (Object)null)
			{
				list3.Add(((Component)val3).transform.position + BodyHeight);
				val3 = (dictionary2.TryGetValue(val3, out var value) ? value : null);
			}
			list3.Reverse();
			if (list3.Count < 3)
			{
				return null;
			}
			return list3;
		}

		internal static Vector3? FarPoint(List<Vector3> players, float minDistance)
		{
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			List<LevelPoint> list = (((Object)(object)LevelGenerator.Instance != (Object)null) ? LevelGenerator.Instance.LevelPathPoints : null);
			if (list == null || players.Count == 0)
			{
				return null;
			}
			List<LevelPoint> list2 = new List<LevelPoint>();
			LevelPoint val = null;
			float num = -1f;
			foreach (LevelPoint item in list)
			{
				if ((Object)(object)item == (Object)null || item.inStartRoom || item.Truck)
				{
					continue;
				}
				float num2 = float.MaxValue;
				foreach (Vector3 player in players)
				{
					num2 = Mathf.Min(num2, Vector3.Distance(((Component)item).transform.position, player));
				}
				if (num2 >= minDistance)
				{
					list2.Add(item);
				}
				if (num2 > num)
				{
					num = num2;
					val = item;
				}
			}
			LevelPoint val2 = ((list2.Count > 0) ? list2[Random.Range(0, list2.Count)] : val);
			if (!((Object)(object)val2 != (Object)null))
			{
				return null;
			}
			return ((Component)val2).transform.position + BodyHeight;
		}

		internal static bool Visible(Vector3 a, Vector3 b)
		{
			//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)
			return !Physics.Linecast(a, b, WallMask, (QueryTriggerInteraction)1);
		}

		internal static bool Passable(Vector3 a, Vector3 b, float radius)
		{
			//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_0002: 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_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = b - a;
			float magnitude = ((Vector3)(ref val)).magnitude;
			if (magnitude < 0.001f)
			{
				return true;
			}
			RaycastHit val2 = default(RaycastHit);
			return !Physics.SphereCast(a, radius, val / magnitude, ref val2, magnitude, WallMask, (QueryTriggerInteraction)1);
		}

		internal static List<Vector3> Route(Vector3 from, Vector3 to)
		{
			//IL_0000: 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_000a: 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_0112: 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_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			LevelPoint val = NearestPassable(from) ?? Nearest(from);
			LevelPoint val2 = Nearest(to);
			List<Vector3> list = new List<Vector3>();
			if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null)
			{
				list.Add(to);
				return list;
			}
			Dictionary<LevelPoint, LevelPoint> dictionary = new Dictionary<LevelPoint, LevelPoint> { { val, null } };
			Queue<LevelPoint> queue = new Queue<LevelPoint>();
			queue.Enqueue(val);
			while (queue.Count > 0 && !dictionary.ContainsKey(val2))
			{
				LevelPoint val3 = queue.Dequeue();
				foreach (LevelPoint connectedPoint in val3.ConnectedPoints)
				{
					if ((Object)(object)connectedPoint != (Object)null && !dictionary.ContainsKey(connectedPoint))
					{
						dictionary[connectedPoint] = val3;
						queue.Enqueue(connectedPoint);
					}
				}
			}
			if (dictionary.ContainsKey(val2))
			{
				LevelPoint val4 = val2;
				while ((Object)(object)val4 != (Object)null)
				{
					list.Add(((Component)val4).transform.position + BodyHeight);
					val4 = dictionary[val4];
				}
				list.Reverse();
			}
			list.Add(to);
			return list;
		}

		private static LevelPoint NearestPassable(Vector3 position)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: 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_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)
			List<LevelPoint> list = (((Object)(object)LevelGenerator.Instance != (Object)null) ? LevelGenerator.Instance.LevelPathPoints : null);
			if (list == null)
			{
				return null;
			}
			LevelPoint result = null;
			float num = float.MaxValue;
			foreach (LevelPoint item in list)
			{
				if (!((Object)(object)item == (Object)null))
				{
					float num2 = Vector3.Distance(((Component)item).transform.position, position);
					if (num2 < num && num2 < 20f && Passable(position, ((Component)item).transform.position + BodyHeight, 0.15f))
					{
						num = num2;
						result = item;
					}
				}
			}
			return result;
		}

		private static LevelPoint Nearest(Vector3 position)
		{
			//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)
			List<LevelPoint> list = (((Object)(object)LevelGenerator.Instance != (Object)null) ? LevelGenerator.Instance.LevelPathPoints : null);
			LevelPoint result = null;
			float num = float.MaxValue;
			if (list == null)
			{
				return null;
			}
			foreach (LevelPoint item in list)
			{
				if (!((Object)(object)item == (Object)null))
				{
					float num2 = Vector3.Distance(((Component)item).transform.position, position);
					if (num2 < num)
					{
						num = num2;
						result = item;
					}
				}
			}
			return result;
		}

		internal static List<Vector3> Ahead(List<Vector3> path, Vector3 from, float length)
		{
			//IL_0006: 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_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: 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_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: 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_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: 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_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			List<Vector3> list = new List<Vector3> { from };
			int num = path.Count - 1;
			float num2 = float.MaxValue;
			for (int i = 0; i < path.Count - 1; i++)
			{
				float num3 = DistanceToSegment(from, path[i], path[i + 1]);
				if (num3 < num2)
				{
					num2 = num3;
					num = i + 1;
				}
			}
			float num4 = 0f;
			Vector3 val = from;
			for (int j = num; j < path.Count; j++)
			{
				if (!(num4 < length))
				{
					break;
				}
				float num5 = Vector3.Distance(val, path[j]);
				if (num4 + num5 > length)
				{
					list.Add(Vector3.Lerp(val, path[j], (length - num4) / num5));
					return list;
				}
				num4 += num5;
				list.Add(path[j]);
				val = path[j];
			}
			if (num4 < length)
			{
				Vector3 val2;
				if (list.Count < 2)
				{
					val2 = Vector3.forward;
				}
				else
				{
					Vector3 val3 = list[list.Count - 1] - list[list.Count - 2];
					val2 = ((Vector3)(ref val3)).normalized;
				}
				Vector3 val4 = val2;
				list.Add(val + val4 * (length - num4));
			}
			return list;
		}

		internal static float Length(List<Vector3> points)
		{
			//IL_000f: 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)
			float num = 0f;
			for (int i = 1; i < points.Count; i++)
			{
				num += Vector3.Distance(points[i - 1], points[i]);
			}
			return num;
		}

		internal static Vector3 Sample(List<Vector3> points, float distance)
		{
			//IL_000a: 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_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: 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_0050: Unknown result type (might be due to invalid IL or missing references)
			if (distance <= 0f)
			{
				return points[0];
			}
			for (int i = 1; i < points.Count; i++)
			{
				float num = Vector3.Distance(points[i - 1], points[i]);
				if (distance <= num)
				{
					return Vector3.Lerp(points[i - 1], points[i], (num > 0f) ? (distance / num) : 0f);
				}
				distance -= num;
			}
			return points[points.Count - 1];
		}

		private static float DistanceToSegment(Vector3 p, Vector3 a, Vector3 b)
		{
			//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_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: 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)
			//IL_0024: 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_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = b - a;
			float num = ((((Vector3)(ref val)).sqrMagnitude > 0f) ? Mathf.Clamp01(Vector3.Dot(p - a, val) / ((Vector3)(ref val)).sqrMagnitude) : 0f);
			return Vector3.Distance(p, a + val * num);
		}
	}
	internal static class TentacleSounds
	{
		private static AudioClip synthHiss;

		internal static float HissLength => HissClip().length;

		internal static void PlayHiss(Vector3 position)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_0078: Expected O, but got Unknown
			AudioClip val = HissClip();
			GameObject val2 = new GameObject("FogMod Tentacle Hiss");
			val2.transform.position = position;
			AudioSource val3 = CreateSource(val2, 3f, 35f, (AudioRolloffMode)1);
			val3.clip = val;
			val3.volume = Plugin.SoundVolume.Value;
			val3.pitch = Random.Range(0.92f, 1.05f);
			val3.Play();
			Object.Destroy((Object)val2, val.length / val3.pitch + 0.1f);
		}

		internal static AudioClip HissLoopClip()
		{
			return HissClip();
		}

		private static AudioClip HissClip()
		{
			if (SoundLibrary.Hiss.Count > 0)
			{
				return SoundLibrary.Hiss[0];
			}
			if ((Object)(object)synthHiss == (Object)null)
			{
				float[] array = SoundSynth.Hiss();
				synthHiss = AudioClip.Create("FogMod Hiss", array.Length, 1, 44100, false);
				synthHiss.SetData(array, 0);
			}
			return synthHiss;
		}

		internal static AudioSource CreateSource(GameObject go, float minDistance, float maxDistance, AudioRolloffMode rolloff)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			AudioSource val = go