Decompiled source of SirenHead v1.0.0

SirenHead.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using Unity.Netcode;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace SirenHead;

internal static class Materials
{
	private class Noise
	{
		private readonly float[] lattice;

		private readonly int cellsU;

		private readonly int cellsV;

		public Noise(int seed, int cellsU, int cellsV)
		{
			this.cellsU = cellsU;
			this.cellsV = cellsV;
			Random random = new Random(seed);
			lattice = new float[4096];
			for (int i = 0; i < lattice.Length; i++)
			{
				lattice[i] = (float)random.NextDouble();
			}
		}

		public float Fbm(float u, float v, int octaves)
		{
			float num = 0f;
			float num2 = 0.5f;
			float num3 = 0f;
			int num4 = 1;
			for (int i = 0; i < octaves; i++)
			{
				num += Value(u, v, cellsU * num4, cellsV * num4) * num2;
				num3 += num2;
				num2 *= 0.5f;
				num4 *= 2;
			}
			return num / num3;
		}

		private float Value(float u, float v, int cu, int cv)
		{
			float num = u * (float)cu;
			float num2 = v * (float)cv;
			int num3 = Mathf.FloorToInt(num);
			int num4 = Mathf.FloorToInt(num2);
			float num5 = num - (float)num3;
			float num6 = num2 - (float)num4;
			num5 = num5 * num5 * (3f - 2f * num5);
			num6 = num6 * num6 * (3f - 2f * num6);
			float num7 = Cell(num3, num4, cu, cv);
			float num8 = Cell(num3 + 1, num4, cu, cv);
			float num9 = Cell(num3, num4 + 1, cu, cv);
			float num10 = Cell(num3 + 1, num4 + 1, cu, cv);
			return Mathf.Lerp(Mathf.Lerp(num7, num8, num5), Mathf.Lerp(num9, num10, num5), num6);
		}

		private float Cell(int x, int y, int cu, int cv)
		{
			x = (x % cu + cu) % cu;
			y = (y % cv + cv) % cv;
			int num = ((x * 73856093) ^ (y * 19349663) ^ (cu * 83492791) ^ (cv * 2654435)) & 0x7FFFFFFF;
			return lattice[num % lattice.Length];
		}
	}

	private static Shader litShader;

	private static Material skin;

	private static Material metal;

	private static Material dark;

	internal static Material Skin()
	{
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)skin == (Object)null)
		{
			skin = Make("SirenHead_Skin", Color.white, SkinTexture(), 0.22f);
		}
		return skin;
	}

	internal static Material Metal()
	{
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)metal == (Object)null)
		{
			metal = Make("SirenHead_Metal", Color.white, MetalTexture(), 0.38f);
		}
		return metal;
	}

	internal static Material Dark()
	{
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)dark == (Object)null)
		{
			dark = Make("SirenHead_Dark", new Color(0.02f, 0.018f, 0.016f), null, 0.1f);
		}
		return dark;
	}

	private static Material Make(string name, Color color, Texture2D texture, float smoothness)
	{
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Expected O, but got Unknown
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Expected O, but got Unknown
		//IL_0061: 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)
		if ((Object)(object)litShader == (Object)null)
		{
			litShader = Shader.Find("HDRP/Lit");
		}
		Material val;
		if ((Object)(object)litShader != (Object)null)
		{
			val = new Material(litShader);
		}
		else
		{
			GameObject val2 = GameObject.CreatePrimitive((PrimitiveType)3);
			val = new Material(val2.GetComponent<Renderer>().sharedMaterial);
			Object.Destroy((Object)(object)val2);
		}
		((Object)val).name = name;
		val.SetColor("_BaseColor", color);
		val.SetColor("_Color", color);
		if ((Object)(object)texture != (Object)null)
		{
			val.SetTexture("_BaseColorMap", (Texture)(object)texture);
			val.SetTexture("_MainTex", (Texture)(object)texture);
		}
		val.SetFloat("_Smoothness", smoothness);
		return val;
	}

	private static Texture2D SkinTexture()
	{
		//IL_00d4: 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_00f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0101: 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_0120: Unknown result type (might be due to invalid IL or missing references)
		//IL_0125: Unknown result type (might be due to invalid IL or missing references)
		//IL_0127: Unknown result type (might be due to invalid IL or missing references)
		//IL_0138: Unknown result type (might be due to invalid IL or missing references)
		//IL_0145: Unknown result type (might be due to invalid IL or missing references)
		//IL_014a: Unknown result type (might be due to invalid IL or missing references)
		//IL_014c: Unknown result type (might be due to invalid IL or missing references)
		//IL_015d: 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_0180: Unknown result type (might be due to invalid IL or missing references)
		//IL_019f: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
		Texture2D val = NewTexture("SirenHeadSkin", 256);
		Color32[] array = (Color32[])(object)new Color32[65536];
		Noise noise = new Noise(17, 28, 3);
		Noise noise2 = new Noise(29, 64, 6);
		Noise noise3 = new Noise(41, 5, 3);
		Noise noise4 = new Noise(53, 10, 2);
		for (int i = 0; i < 256; i++)
		{
			for (int j = 0; j < 256; j++)
			{
				float u = (float)j / 256f;
				float v = (float)i / 256f;
				float num = noise.Fbm(u, v, 3);
				float num2 = noise2.Fbm(u, v, 2);
				float num3 = noise3.Fbm(u, v, 3);
				float num4 = Mathf.Pow(1f - Mathf.Abs(noise4.Fbm(u, v, 2) * 2f - 1f), 10f);
				Color val2 = Color.Lerp(new Color(0.07f, 0.045f, 0.032f), new Color(0.27f, 0.18f, 0.12f), num * num * 1.2f);
				val2 = Color.Lerp(val2, val2 * 0.55f, Mathf.Clamp01((0.5f - num2) * 2.5f));
				val2 = Color.Lerp(val2, new Color(0.34f, 0.24f, 0.17f), num4 * 0.55f);
				val2 = Color.Lerp(val2, new Color(0.26f, 0.09f, 0.06f), Mathf.Clamp01((num3 - 0.6f) * 3f) * 0.6f);
				val2.a = 1f;
				ref Color32 reference = ref array[i * 256 + j];
				reference = Color32.op_Implicit(val2);
			}
		}
		val.SetPixels32(array);
		val.Apply(true);
		return val;
	}

	private static Texture2D MetalTexture()
	{
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: 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_00a2: 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_00ce: 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_00ef: 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)
		Texture2D val = NewTexture("SirenHeadMetal", 128);
		Color32[] array = (Color32[])(object)new Color32[16384];
		Noise noise = new Noise(71, 6, 6);
		Noise noise2 = new Noise(89, 10, 10);
		for (int i = 0; i < 128; i++)
		{
			for (int j = 0; j < 128; j++)
			{
				float u = (float)j / 128f;
				float v = (float)i / 128f;
				Color val2 = Color.Lerp(new Color(0.09f, 0.09f, 0.085f), new Color(0.2f, 0.2f, 0.19f), noise.Fbm(u, v, 4));
				val2 = Color.Lerp(val2, new Color(0.24f, 0.12f, 0.06f), Mathf.Clamp01((noise2.Fbm(u, v, 4) - 0.52f) * 3f) * 0.8f);
				val2.a = 1f;
				ref Color32 reference = ref array[i * 128 + j];
				reference = Color32.op_Implicit(val2);
			}
		}
		val.SetPixels32(array);
		val.Apply(true);
		return val;
	}

	private static Texture2D NewTexture(string name, int size)
	{
		//IL_0004: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Expected O, but got Unknown
		Texture2D val = new Texture2D(size, size, (TextureFormat)4, true);
		((Object)val).name = name;
		((Texture)val).wrapMode = (TextureWrapMode)0;
		((Texture)val).filterMode = (FilterMode)1;
		return val;
	}
}
[HarmonyPatch(typeof(ForestGiantAI))]
internal static class ForestGiantPatches
{
	[HarmonyPatch("Start")]
	[HarmonyPostfix]
	private static void StartPostfix(ForestGiantAI __instance)
	{
		if (!Plugin.Enabled.Value)
		{
			return;
		}
		try
		{
			((Component)__instance).gameObject.AddComponent<SirenHeadController>().Init(__instance);
		}
		catch (Exception ex)
		{
			Plugin.Log.LogError((object)("Couldn't turn a Forest Keeper into Siren Head: " + ex));
		}
	}

	[HarmonyPrefix]
	[HarmonyPatch("Update")]
	private static void UpdatePrefix(ForestGiantAI __instance)
	{
		if (!Plugin.VanillaSight.Value && __instance.playerStealthMeters != null && (Object)(object)Get(__instance) != (Object)null)
		{
			for (int i = 0; i < __instance.playerStealthMeters.Length; i++)
			{
				__instance.playerStealthMeters[i] = 0f;
			}
		}
	}

	[HarmonyPatch("Update")]
	[HarmonyPostfix]
	private static void UpdatePostfix(ForestGiantAI __instance)
	{
		SirenHeadController sirenHeadController = Get(__instance);
		if ((Object)(object)sirenHeadController != (Object)null)
		{
			sirenHeadController.AfterGiantUpdate();
		}
	}

	[HarmonyPatch("DoAIInterval")]
	[HarmonyPostfix]
	private static void DoAIIntervalPostfix(ForestGiantAI __instance)
	{
		SirenHeadController sirenHeadController = Get(__instance);
		if ((Object)(object)sirenHeadController != (Object)null)
		{
			sirenHeadController.AfterAIInterval();
		}
	}

	[HarmonyPatch("BeginEatPlayer")]
	[HarmonyPrefix]
	private static void BeginEatPlayerPrefix(ForestGiantAI __instance, PlayerControllerB playerBeingEaten)
	{
		SirenHeadController sirenHeadController = Get(__instance);
		if ((Object)(object)sirenHeadController != (Object)null && (Object)(object)playerBeingEaten != (Object)null)
		{
			sirenHeadController.OnGrab(playerBeingEaten);
		}
	}

	private static SirenHeadController Get(ForestGiantAI giant)
	{
		return ((Component)giant).GetComponent<SirenHeadController>();
	}
}
[BepInPlugin("axelc.sirenhead", "SirenHead", "1.0.0")]
public class Plugin : BaseUnityPlugin
{
	public const string Guid = "axelc.sirenhead";

	public const string PluginName = "SirenHead";

	public const string Version = "1.0.0";

	internal static ManualLogSource Log;

	internal static ConfigEntry<bool> Enabled;

	internal static ConfigEntry<float> Height;

	internal static ConfigEntry<float> RoamSpeed;

	internal static ConfigEntry<float> ChaseSpeed;

	internal static ConfigEntry<float> ChaseAcceleration;

	internal static ConfigEntry<float> LockOnRadius;

	internal static ConfigEntry<float> CrouchRadiusMultiplier;

	internal static ConfigEntry<bool> RequireLineOfSight;

	internal static ConfigEntry<bool> ShipIsSafe;

	internal static ConfigEntry<float> GiveUpDistance;

	internal static ConfigEntry<float> MaxChaseSeconds;

	internal static ConfigEntry<float> RelockCooldown;

	internal static ConfigEntry<bool> VanillaSight;

	internal static ConfigEntry<float> SirenVolume;

	internal static ConfigEntry<float> AmbientVolume;

	internal static ConfigEntry<float> FootstepVolume;

	internal static ConfigEntry<float> AmbientMinSeconds;

	internal static ConfigEntry<float> AmbientMaxSeconds;

	internal static ConfigEntry<bool> CameraShake;

	private void Awake()
	{
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		Log = ((BaseUnityPlugin)this).Logger;
		BindConfig();
		Sounds.Load();
		new Harmony("axelc.sirenhead").PatchAll();
		Log.LogInfo((object)"SirenHead 1.0.0 loaded. Forest Keepers are now Siren Head.");
	}

	private void BindConfig()
	{
		Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Replace Forest Keepers with Siren Head. Everyone in the lobby should use the same setting.");
		Height = ((BaseUnityPlugin)this).Config.Bind<float>("SirenHead", "Height", 18f, "How tall it stands, in meters, to the top of the sirens. Moon trees are roughly 15-25m.");
		RoamSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("SirenHead", "RoamSpeed", 3.2f, "Walking speed while it wanders. Its strides are long, so this already looks slow and heavy.");
		ChaseSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("SirenHead", "ChaseSpeed", 9f, "Top speed once it has locked on to someone. Sprinting players move at roughly 7-10.");
		ChaseAcceleration = ((BaseUnityPlugin)this).Config.Bind<float>("SirenHead", "ChaseAcceleration", 4f, "How quickly (speed gained per second) it winds up from walking to its top chase speed.");
		LockOnRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Detection", "LockOnRadius", 30f, "Get within this many meters of it and it locks on to you.");
		CrouchRadiusMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Detection", "CrouchRadiusMultiplier", 0.6f, "Crouching players only get noticed within LockOnRadius times this.");
		RequireLineOfSight = ((BaseUnityPlugin)this).Config.Bind<bool>("Detection", "RequireLineOfSight", false, "If true, it only locks on to players it can see from its head (trees and rocks can hide you).");
		ShipIsSafe = ((BaseUnityPlugin)this).Config.Bind<bool>("Detection", "ShipIsSafe", true, "Players inside the ship can't be locked on to, and it gives up the chase if its target gets inside.");
		GiveUpDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Detection", "GiveUpDistance", 140f, "It drops the chase if its target gets this far away.");
		MaxChaseSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Detection", "MaxChaseSeconds", 0f, "It gives up a chase after this many seconds. 0 means it never gives up on its own.");
		RelockCooldown = ((BaseUnityPlugin)this).Config.Bind<float>("Detection", "RelockCooldown", 6f, "Seconds after a chase ends (or a kill) before it can lock on to anyone again.");
		VanillaSight = ((BaseUnityPlugin)this).Config.Bind<bool>("Detection", "VanillaSight", false, "Also keep the Forest Keeper's long-range eyesight (spotting players from far away and staring). Off means only LockOnRadius matters.");
		SirenVolume = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "SirenVolume", 1f, "Volume of the siren it blares while chasing, 0 to 1.");
		AmbientVolume = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "AmbientVolume", 0.85f, "Volume of the static, broken radio and distant wails it lets out while wandering, 0 to 1.");
		FootstepVolume = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "FootstepVolume", 1f, "Volume of its footsteps, 0 to 1.");
		AmbientMinSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "AmbientMinSeconds", 18f, "Shortest gap between its wandering sounds.");
		AmbientMaxSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "AmbientMaxSeconds", 45f, "Longest gap between its wandering sounds.");
		CameraShake = ((BaseUnityPlugin)this).Config.Bind<bool>("Audio", "CameraShake", true, "Its footsteps shake your camera when it walks close by.");
	}
}
internal class SirenHeadController : MonoBehaviour
{
	private const float ScreamAt = 1.9f;

	private const float CrunchAt = 4.7f;

	private static readonly FieldInfo NoticePlayerTimerField = AccessTools.Field(typeof(ForestGiantAI), "noticePlayerTimer");

	private static readonly FieldInfo LostPlayerInChaseField = AccessTools.Field(typeof(ForestGiantAI), "lostPlayerInChase");

	private static readonly FieldInfo InEatingAnimationField = AccessTools.Field(typeof(ForestGiantAI), "inEatingPlayerAnimation");

	private static readonly FieldInfo StopAndLookTimerField = AccessTools.Field(typeof(ForestGiantAI), "stopAndLookTimer");

	private static readonly MethodInfo ChaseClientRpc = AccessTools.Method(typeof(ForestGiantAI), "BeginChasingNewPlayerClientRpc", (Type[])null, (Type[])null);

	private static readonly MethodInfo ChaseServerRpc = AccessTools.Method(typeof(ForestGiantAI), "BeginChasingNewPlayerServerRpc", (Type[])null, (Type[])null);

	private ForestGiantAI ai;

	private SirenHeadModel model;

	private AudioSource sirenSource;

	private AudioSource voiceSource;

	private AudioSource stepSource;

	private float chaseTime;

	private float chaseSpeed;

	private float relockAt;

	private int lastState = -1;

	private float ambientTimer;

	private float eatTime = -1f;

	private bool screamed;

	private bool crunched;

	private float deathTime = -1f;

	public void Init(ForestGiantAI giant)
	{
		ai = giant;
		HideGiant();
		model = SirenHeadModel.Build(((Component)this).transform, Plugin.Height.Value);
		ai.holdPlayerPoint = model.Grip;
		if ((Object)(object)((EnemyAI)ai).creatureAnimator != (Object)null)
		{
			((EnemyAI)ai).creatureAnimator.cullingMode = (AnimatorCullingMode)2;
		}
		sirenSource = CreateAudioSource("SirenHeadSiren", model.Head, 20f, 320f);
		sirenSource.loop = true;
		sirenSource.clip = Sounds.SirenLoop;
		sirenSource.volume = 0f;
		voiceSource = CreateAudioSource("SirenHeadVoice", model.Head, 14f, 200f);
		stepSource = CreateAudioSource("SirenHeadSteps", ((Component)this).transform, 10f, 110f);
		ScanNodeProperties componentInChildren = ((Component)this).GetComponentInChildren<ScanNodeProperties>();
		if ((Object)(object)componentInChildren != (Object)null)
		{
			componentInChildren.headerText = "Siren Head";
			componentInChildren.subText = "Don't let it get close.";
		}
		chaseSpeed = Plugin.RoamSpeed.Value;
		ambientTimer = Random.Range(4f, Plugin.AmbientMaxSeconds.Value);
	}

	private void HideGiant()
	{
		int num = LayerMask.NameToLayer("MapRadar");
		Transform val = (((Object)(object)ai.burningParticlesContainer != (Object)null) ? ai.burningParticlesContainer.transform : null);
		Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<Renderer>(true);
		foreach (Renderer val2 in componentsInChildren)
		{
			if (!(val2 is ParticleSystemRenderer) && ((Component)val2).gameObject.layer != num && (!((Object)(object)val != (Object)null) || !((Component)val2).transform.IsChildOf(val)))
			{
				val2.enabled = false;
			}
		}
	}

	public void AfterAIInterval()
	{
		if (((NetworkBehaviour)ai).IsOwner && !((EnemyAI)ai).isEnemyDead && ((EnemyAI)ai).currentBehaviourStateIndex == 0 && !InEatingAnimation(ai) && !((EnemyAI)ai).inSpecialAnimation && !(Time.time < relockAt))
		{
			PlayerControllerB val = FindLockTarget();
			if ((Object)(object)val != (Object)null)
			{
				BeginChase(val);
			}
		}
	}

	public void AfterGiantUpdate()
	{
		if (!((NetworkBehaviour)ai).IsOwner || ((EnemyAI)ai).isEnemyDead || (Object)(object)((EnemyAI)ai).agent == (Object)null)
		{
			return;
		}
		float deltaTime = Time.deltaTime;
		bool flag = InEatingAnimation(ai);
		bool flag2 = ((EnemyAI)ai).stunNormalizedTimer > 0f;
		if (((EnemyAI)ai).currentBehaviourStateIndex == 1)
		{
			if (!flag)
			{
				chaseTime += deltaTime;
				float value = Plugin.MaxChaseSeconds.Value;
				if (!IsValidLock(ai.chasingPlayer) || (value > 0f && chaseTime > value))
				{
					EndChase();
					return;
				}
				if (NoticePlayerTimerField != null)
				{
					NoticePlayerTimerField.SetValue(ai, 0f);
				}
				if (LostPlayerInChaseField != null)
				{
					LostPlayerInChaseField.SetValue(ai, false);
				}
			}
			if (flag || flag2)
			{
				((EnemyAI)ai).agent.speed = 0f;
				return;
			}
			chaseSpeed = Mathf.Min(Mathf.Max(chaseSpeed, Plugin.RoamSpeed.Value) + Plugin.ChaseAcceleration.Value * deltaTime, Plugin.ChaseSpeed.Value);
			((EnemyAI)ai).agent.speed = chaseSpeed;
		}
		else if (((EnemyAI)ai).currentBehaviourStateIndex == 0)
		{
			chaseTime = 0f;
			chaseSpeed = Plugin.RoamSpeed.Value;
			bool flag3 = StopAndLookTimerField != null && (float)StopAndLookTimerField.GetValue(ai) > 0f;
			if (!flag && !flag2 && !flag3)
			{
				((EnemyAI)ai).agent.speed = Plugin.RoamSpeed.Value;
			}
		}
	}

	private PlayerControllerB FindLockTarget()
	{
		//IL_00a7: 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_00ee: 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)
		StartOfRound instance = StartOfRound.Instance;
		if ((Object)(object)instance == (Object)null || instance.allPlayerScripts == null)
		{
			return null;
		}
		PlayerControllerB result = null;
		float num = float.MaxValue;
		PlayerControllerB[] allPlayerScripts = instance.allPlayerScripts;
		foreach (PlayerControllerB val in allPlayerScripts)
		{
			if (!((Object)(object)val == (Object)null) && val.isPlayerControlled && !val.isPlayerDead && !val.isInsideFactory && (!Plugin.ShipIsSafe.Value || !val.isInHangarShipRoom))
			{
				float num2 = Plugin.LockOnRadius.Value * (val.isCrouching ? Plugin.CrouchRadiusMultiplier.Value : 1f);
				float num3 = Vector3.Distance(((Component)this).transform.position, ((Component)val).transform.position);
				if (!(num3 > num2) && !(num3 >= num) && (!Plugin.RequireLineOfSight.Value || !((Object)(object)val.gameplayCamera != (Object)null) || !Physics.Linecast(model.Head.position, ((Component)val.gameplayCamera).transform.position, instance.collidersAndRoomMaskAndDefault, (QueryTriggerInteraction)1)))
				{
					result = val;
					num = num3;
				}
			}
		}
		return result;
	}

	private bool IsValidLock(PlayerControllerB player)
	{
		//IL_003f: 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)
		if ((Object)(object)player == (Object)null || !player.isPlayerControlled || player.isPlayerDead || player.isInsideFactory)
		{
			return false;
		}
		if (Plugin.ShipIsSafe.Value && player.isInHangarShipRoom)
		{
			return false;
		}
		return Vector3.Distance(((Component)this).transform.position, ((Component)player).transform.position) <= Plugin.GiveUpDistance.Value;
	}

	private void BeginChase(PlayerControllerB player)
	{
		chaseTime = 0f;
		chaseSpeed = Plugin.RoamSpeed.Value;
		ai.FindAndTargetNewPlayerOnLocalClient(player);
		object[] parameters = new object[1] { (int)player.playerClientId };
		if (((NetworkBehaviour)ai).IsServer && ChaseClientRpc != null)
		{
			ChaseClientRpc.Invoke(ai, parameters);
		}
		else if (ChaseServerRpc != null)
		{
			ChaseServerRpc.Invoke(ai, parameters);
		}
	}

	private void EndChase()
	{
		relockAt = Time.time + Plugin.RelockCooldown.Value;
		((EnemyAI)ai).SwitchToBehaviourState(0);
	}

	public void OnGrab(PlayerControllerB player)
	{
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		eatTime = 0f;
		screamed = false;
		crunched = false;
		model.BeginGrab(((Component)player).transform.position);
	}

	private void LateUpdate()
	{
		if ((Object)(object)ai == (Object)null || model == null)
		{
			return;
		}
		float deltaTime = Time.deltaTime;
		int currentBehaviourStateIndex = ((EnemyAI)ai).currentBehaviourStateIndex;
		bool isEnemyDead = ((EnemyAI)ai).isEnemyDead;
		bool eating = InEatingAnimation(ai);
		bool flag = currentBehaviourStateIndex == 1 && !isEnemyDead;
		if (currentBehaviourStateIndex != lastState)
		{
			if (currentBehaviourStateIndex == 1 && lastState != -1)
			{
				OnChaseStarted();
			}
			lastState = currentBehaviourStateIndex;
		}
		if (isEnemyDead && deathTime < 0f)
		{
			deathTime = 0f;
			sirenSource.Stop();
			voiceSource.Stop();
			voiceSource.PlayOneShot(Sounds.Death, Plugin.SirenVolume.Value);
		}
		if (deathTime >= 0f)
		{
			deathTime += deltaTime;
		}
		UpdateSiren(deltaTime, flag);
		UpdateAmbient(deltaTime, currentBehaviourStateIndex, isEnemyDead);
		UpdateGrab(deltaTime, eating);
		Transform lookTarget = null;
		if (eatTime >= 0f)
		{
			lookTarget = model.Grip;
		}
		else if (flag && (Object)(object)ai.chasingPlayer != (Object)null)
		{
			lookTarget = (((Object)(object)ai.chasingPlayer.gameplayCamera != (Object)null) ? ((Component)ai.chasingPlayer.gameplayCamera).transform : ((Component)ai.chasingPlayer).transform);
		}
		SirenHeadModel.Events events = model.Animate(deltaTime, flag, eating, eatTime, deathTime, ((EnemyAI)ai).stunNormalizedTimer > 0f, lookTarget);
		if (events.Footfalls > 0)
		{
			Footstep(flag ? 1f : 0.75f);
		}
		if (events.Landed)
		{
			stepSource.PlayOneShot(Sounds.Pick(Sounds.Steps), Plugin.FootstepVolume.Value);
			stepSource.PlayOneShot(Sounds.Pick(Sounds.Steps), Plugin.FootstepVolume.Value);
			ShakeIfClose(60f, (ScreenShakeType)1);
		}
	}

	private void OnChaseStarted()
	{
		voiceSource.PlayOneShot(Sounds.Scream, Plugin.SirenVolume.Value * 0.9f);
		PlayerControllerB val = LocalPlayer();
		if ((Object)(object)val != (Object)null && (Object)(object)ai.chasingPlayer == (Object)(object)val)
		{
			val.JumpToFearLevel(1f, true);
		}
	}

	private void UpdateSiren(float dt, bool chasing)
	{
		float num = (chasing ? Plugin.SirenVolume.Value : 0f);
		float num2 = ((num > sirenSource.volume) ? 1.2f : 0.3f);
		sirenSource.volume = Mathf.MoveTowards(sirenSource.volume, num, num2 * dt);
		if (num > 0f && !sirenSource.isPlaying && (Object)(object)sirenSource.clip != (Object)null)
		{
			sirenSource.time = Random.Range(0f, sirenSource.clip.length * 0.5f);
			sirenSource.Play();
		}
		else if (num <= 0f && sirenSource.volume <= 0.001f && sirenSource.isPlaying)
		{
			sirenSource.Stop();
		}
	}

	private void UpdateAmbient(float dt, int state, bool dead)
	{
		if (state == 0 && !dead && !(eatTime >= 0f))
		{
			ambientTimer -= dt;
			if (!(ambientTimer > 0f))
			{
				float num = Mathf.Max(1f, Plugin.AmbientMinSeconds.Value);
				ambientTimer = Random.Range(num, Mathf.Max(num, Plugin.AmbientMaxSeconds.Value));
				AudioClip val = ((Random.value < 0.4f) ? Sounds.Pick(Sounds.Wails) : Sounds.Pick(Sounds.Radio));
				voiceSource.PlayOneShot(val, Plugin.AmbientVolume.Value);
			}
		}
	}

	private void UpdateGrab(float dt, bool eating)
	{
		if (eatTime < 0f)
		{
			return;
		}
		eatTime += dt;
		if (!screamed && eatTime >= 1.9f)
		{
			screamed = true;
			voiceSource.PlayOneShot(Sounds.Scream, Plugin.SirenVolume.Value);
			PlayerControllerB val = LocalPlayer();
			if ((Object)(object)val != (Object)null && (Object)(object)val.inAnimationWithEnemy == (Object)(object)ai)
			{
				val.JumpToFearLevel(1f, true);
			}
		}
		if (!crunched && eatTime >= 4.7f)
		{
			crunched = true;
			voiceSource.PlayOneShot(Sounds.Crunch, 1f);
		}
		if (!eating && eatTime > 0.5f)
		{
			eatTime = -1f;
		}
	}

	private void Footstep(float loudness)
	{
		stepSource.pitch = Random.Range(0.92f, 1.06f);
		stepSource.PlayOneShot(Sounds.Pick(Sounds.Steps), Plugin.FootstepVolume.Value * loudness);
		ShakeIfClose(22f * model.Scale, (ScreenShakeType)0);
	}

	private void ShakeIfClose(float distance, ScreenShakeType type)
	{
		//IL_003f: 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_005c: Unknown result type (might be due to invalid IL or missing references)
		PlayerControllerB val = LocalPlayer();
		if (Plugin.CameraShake.Value && !((Object)(object)val == (Object)null) && !val.isPlayerDead && !val.isInsideFactory && !((Object)(object)HUDManager.Instance == (Object)null) && Vector3.Distance(((Component)val).transform.position, ((Component)this).transform.position) < distance)
		{
			HUDManager.Instance.ShakeCamera(type);
		}
	}

	private AudioSource CreateAudioSource(string name, Transform parent, float minDistance, float maxDistance)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Expected O, but got Unknown
		GameObject val = new GameObject(name);
		val.transform.SetParent(parent, false);
		AudioSource val2 = val.AddComponent<AudioSource>();
		val2.playOnAwake = false;
		val2.spatialBlend = 1f;
		val2.rolloffMode = (AudioRolloffMode)0;
		val2.minDistance = minDistance;
		val2.maxDistance = maxDistance;
		val2.dopplerLevel = 0f;
		val2.spread = 40f;
		if ((Object)(object)((EnemyAI)ai).creatureSFX != (Object)null && (Object)(object)((EnemyAI)ai).creatureSFX.outputAudioMixerGroup != (Object)null)
		{
			val2.outputAudioMixerGroup = ((EnemyAI)ai).creatureSFX.outputAudioMixerGroup;
		}
		else
		{
			PlayerControllerB val3 = LocalPlayer();
			if ((Object)(object)val3 != (Object)null && (Object)(object)val3.movementAudio != (Object)null)
			{
				val2.outputAudioMixerGroup = val3.movementAudio.outputAudioMixerGroup;
			}
		}
		return val2;
	}

	private static bool InEatingAnimation(ForestGiantAI giant)
	{
		if (InEatingAnimationField != null)
		{
			return (bool)InEatingAnimationField.GetValue(giant);
		}
		return false;
	}

	private static PlayerControllerB LocalPlayer()
	{
		if (!((Object)(object)GameNetworkManager.Instance != (Object)null))
		{
			return null;
		}
		return GameNetworkManager.Instance.localPlayerController;
	}
}
internal class SirenHeadModel
{
	internal struct Events
	{
		public int Footfalls;

		public bool Landed;
	}

	private static class Meshes
	{
		private static readonly Dictionary<string, Mesh> cache = new Dictionary<string, Mesh>();

		public static Mesh Get(string key, Func<Mesh> build)
		{
			if (!cache.TryGetValue(key, out var value) || (Object)(object)value == (Object)null)
			{
				value = build();
				((Object)value).name = "SirenHead_" + key;
				cache[key] = value;
			}
			return value;
		}
	}

	private const int EnemyLayer = 19;

	internal const float DesignHeight = 18f;

	private const float Thigh = 4.9f;

	private const float Shin = 5.1f;

	private const float FootDrop = 0.42f;

	private const float StandHip = 10.42f;

	private const float HipHalfWidth = 0.5f;

	private const float TorsoLength = 3.7f;

	private const float ShoulderHalfWidth = 1.05f;

	private const float ShoulderHeight = 3.45f;

	private const float UpperArm = 3.9f;

	private const float Forearm = 4f;

	private const float PalmCenter = 0.55f;

	private const float NeckLength = 3f;

	private const float StepLength = 5.6f;

	public Transform Root;

	public Transform Head;

	public Transform Grip;

	public float Scale;

	private Transform hips;

	private Transform spine;

	private Transform neck;

	private readonly Transform[] hip = (Transform[])(object)new Transform[2];

	private readonly Transform[] knee = (Transform[])(object)new Transform[2];

	private readonly Transform[] ankle = (Transform[])(object)new Transform[2];

	private readonly Transform[] shoulder = (Transform[])(object)new Transform[2];

	private readonly Transform[] elbow = (Transform[])(object)new Transform[2];

	private readonly Transform[] wrist = (Transform[])(object)new Transform[2];

	private static readonly float[] Sides = new float[2] { -1f, 1f };

	private float phase;

	private float speed;

	private Vector3 lastPosition;

	private bool hasLastPosition;

	private float moveBlend;

	private float chaseBlend;

	private float eatBlend;

	private float crouch;

	private readonly float[] lastSwingCos = new float[2];

	private float time;

	private float twitchTimer = 4f;

	private float twitchHold;

	private Quaternion twitchTarget = Quaternion.identity;

	private Quaternion twitchCurrent = Quaternion.identity;

	private Vector3 grabStart;

	private Vector3 holdOffsetSeed;

	private bool landed;

	public static SirenHeadModel Build(Transform enemyRoot, float height)
	{
		//IL_0024: 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_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: 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_00a5: Unknown result type (might be due to invalid IL or missing references)
		SirenHeadModel sirenHeadModel = new SirenHeadModel();
		sirenHeadModel.Scale = Mathf.Max(0.2f, height / 18f);
		sirenHeadModel.Root = Pivot(enemyRoot, "SirenHeadModel", Vector3.zero);
		sirenHeadModel.Root.localScale = Vector3.one * sirenHeadModel.Scale;
		sirenHeadModel.BuildBody();
		sirenHeadModel.Grip = Pivot(sirenHeadModel.Root, "SirenHeadGrip", new Vector3(0f, 8f, 3f));
		sirenHeadModel.holdOffsetSeed = new Vector3(Random.value * 100f, Random.value * 100f, Random.value * 100f);
		sirenHeadModel.phase = Random.value * (float)Math.PI * 2f;
		return sirenHeadModel;
	}

	private void BuildBody()
	{
		//IL_002d: 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_0297: Unknown result type (might be due to invalid IL or missing references)
		//IL_0156: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_04db: Unknown result type (might be due to invalid IL or missing references)
		//IL_0757: Unknown result type (might be due to invalid IL or missing references)
		//IL_0547: Unknown result type (might be due to invalid IL or missing references)
		//IL_05b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_060c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0828: Unknown result type (might be due to invalid IL or missing references)
		//IL_08d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_08dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_08e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_08e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0916: Unknown result type (might be due to invalid IL or missing references)
		//IL_0924: Unknown result type (might be due to invalid IL or missing references)
		//IL_0929: Unknown result type (might be due to invalid IL or missing references)
		//IL_092b: Unknown result type (might be due to invalid IL or missing references)
		Material mat = Materials.Skin();
		Material mat2 = Materials.Metal();
		Material mat3 = Materials.Dark();
		hips = Pivot(Root, "Hips", new Vector3(0f, 10.42f, 0f));
		Part(hips, "Pelvis", Meshes.Get("Pelvis", () => Tube((Vector3[])(object)new Vector3[5]
		{
			new Vector3(-0.62f, -0.05f, 0f),
			new Vector3(-0.3f, 0.05f, 0.02f),
			new Vector3(0f, 0.02f, 0.04f),
			new Vector3(0.3f, 0.05f, 0.02f),
			new Vector3(0.62f, -0.05f, 0f)
		}, new float[5] { 0.26f, 0.34f, 0.36f, 0.34f, 0.26f }, 10)), mat);
		Part(hips, "Groin", Meshes.Get("Groin", () => Tube((Vector3[])(object)new Vector3[3]
		{
			new Vector3(0f, 0.05f, 0.05f),
			new Vector3(0f, -0.35f, 0.08f),
			new Vector3(0f, -0.6f, 0.02f)
		}, new float[3] { 0.3f, 0.2f, 0.08f }, 8)), mat);
		for (int num = 0; num < 2; num++)
		{
			float num2 = Sides[num];
			hip[num] = Pivot(hips, "Hip" + num, new Vector3(num2 * 0.5f, -0.08f, 0f));
			Part(hip[num], "Thigh", Meshes.Get("Thigh", () => Tube((Vector3[])(object)new Vector3[6]
			{
				new Vector3(0f, 0.15f, 0f),
				new Vector3(0f, -1.2f, 0.06f),
				new Vector3(0f, -2.5f, 0.08f),
				new Vector3(0f, -3.8f, 0.04f),
				new Vector3(0f, -4.65f, 0.02f),
				new Vector3(0f, -4.9f, 0f)
			}, new float[6] { 0.36f, 0.31f, 0.26f, 0.21f, 0.25f, 0.27f }, 10)), mat);
			knee[num] = Pivot(hip[num], "Knee", new Vector3(0f, -4.9f, 0f));
			Part(knee[num], "Shin", Meshes.Get("Shin", () => Tube((Vector3[])(object)new Vector3[5]
			{
				new Vector3(0f, 0.1f, 0.02f),
				new Vector3(0f, -1.3f, 0.1f),
				new Vector3(0f, -2.6f, 0.1f),
				new Vector3(0f, -3.9f, 0.05f),
				new Vector3(0f, -5.1f, 0f)
			}, new float[5] { 0.25f, 0.2f, 0.17f, 0.14f, 0.15f }, 9)), mat);
			ankle[num] = Pivot(knee[num], "Ankle", new Vector3(0f, -5.1f, 0f));
			Part(ankle[num], "Foot", Meshes.Get("Foot", () => Tube((Vector3[])(object)new Vector3[4]
			{
				new Vector3(0f, 0.05f, -0.25f),
				new Vector3(0f, -0.22f, 0.15f),
				new Vector3(0f, -0.33f, 0.6f),
				new Vector3(0f, -0.36f, 0.95f)
			}, new float[4] { 0.15f, 0.16f, 0.11f, 0.07f }, 8)), mat);
			for (int num3 = 0; num3 < 3; num3++)
			{
				float spread = (float)(num3 - 1) * 0.12f;
				Part(ankle[num], "Toe" + num3, Meshes.Get("Toe" + num3, () => Tube((Vector3[])(object)new Vector3[3]
				{
					new Vector3(spread * 0.5f, -0.33f, 0.85f),
					new Vector3(spread, -0.37f, 1.2f),
					new Vector3(spread * 1.4f, -0.41f, 1.45f)
				}, new float[3] { 0.06f, 0.045f, 0.02f }, 6)), mat);
			}
		}
		spine = Pivot(hips, "Spine", new Vector3(0f, 0.1f, 0f));
		Transform val = Part(spine, "Torso", Meshes.Get("Torso", () => Profile(new float[8] { 0f, 0.5f, 1f, 1.6f, 2.2f, 2.8f, 3.3f, 3.7f }, new float[8] { 0.42f, 0.36f, 0.4f, 0.62f, 0.8f, 0.8f, 0.66f, 0.38f }, 14)), mat);
		val.localScale = new Vector3(1f, 1f, 0.6f);
		for (int num4 = 0; num4 < 6; num4++)
		{
			int ribIndex = num4;
			Part(spine, "Rib" + num4, Meshes.Get("Rib" + num4, () => Rib(ribIndex)), mat);
		}
		for (int num5 = 0; num5 < 7; num5++)
		{
			float y = 0.5f + (float)num5 * 0.45f;
			float back = (0f - ChestRadius(y)) * 0.6f;
			Part(spine, "Vertebra" + num5, Meshes.Get("Vertebra" + num5, () => Tube((Vector3[])(object)new Vector3[3]
			{
				new Vector3(0f, y - 0.1f, back + 0.04f),
				new Vector3(0f, y, back - 0.03f),
				new Vector3(0f, y + 0.1f, back + 0.04f)
			}, new float[3] { 0.06f, 0.11f, 0.06f }, 6)), mat);
		}
		Part(spine, "Collarbones", Meshes.Get("Collarbones", () => Tube((Vector3[])(object)new Vector3[5]
		{
			new Vector3(-1.15f, 3.4f, 0f),
			new Vector3(-0.5f, 3.57f, 0.05f),
			new Vector3(0f, 3.63f, 0.06f),
			new Vector3(0.5f, 3.57f, 0.05f),
			new Vector3(1.15f, 3.4f, 0f)
		}, new float[5] { 0.24f, 0.2f, 0.26f, 0.2f, 0.24f }, 8)), mat);
		for (int num6 = 0; num6 < 2; num6++)
		{
			float side = Sides[num6];
			Part(spine, "Tendon" + num6, Meshes.Get("Tendon" + num6, () => Tube((Vector3[])(object)new Vector3[3]
			{
				new Vector3(side * 0.85f, 3.55f, -0.05f),
				new Vector3(side * 0.45f, 4.05f, -0.06f),
				new Vector3(side * 0.16f, 4.85f, -0.03f)
			}, new float[3] { 0.11f, 0.07f, 0.04f }, 6)), mat);
		}
		for (int num7 = 0; num7 < 2; num7++)
		{
			float side2 = Sides[num7];
			shoulder[num7] = Pivot(spine, "Shoulder" + num7, new Vector3(side2 * 1.05f, 3.45f, 0f));
			Part(shoulder[num7], "UpperArm", Meshes.Get("UpperArm", () => Tube((Vector3[])(object)new Vector3[5]
			{
				new Vector3(0f, 0.2f, 0f),
				new Vector3(0f, -1f, 0.03f),
				new Vector3(0f, -2.2f, 0.04f),
				new Vector3(0f, -3.4f, 0.02f),
				new Vector3(0f, -3.9f, 0f)
			}, new float[5] { 0.25f, 0.2f, 0.16f, 0.13f, 0.16f }, 9)), mat);
			elbow[num7] = Pivot(shoulder[num7], "Elbow", new Vector3(0f, -3.9f, 0f));
			Part(elbow[num7], "Forearm", Meshes.Get("Forearm", () => Tube((Vector3[])(object)new Vector3[5]
			{
				new Vector3(0f, 0.08f, 0f),
				new Vector3(0f, -1.2f, 0.04f),
				new Vector3(0f, -2.5f, 0.05f),
				new Vector3(0f, -3.6f, 0.02f),
				new Vector3(0f, -4f, 0f)
			}, new float[5] { 0.16f, 0.14f, 0.12f, 0.09f, 0.1f }, 8)), mat);
			wrist[num7] = Pivot(elbow[num7], "Wrist", new Vector3(0f, -4f, 0f));
			Transform val2 = Part(wrist[num7], "Palm", Meshes.Get("Palm", () => Tube((Vector3[])(object)new Vector3[3]
			{
				new Vector3(0f, 0.02f, 0f),
				new Vector3(0f, -0.4f, 0f),
				new Vector3(0f, -0.8f, 0f)
			}, new float[3] { 0.1f, 0.16f, 0.13f }, 8)), mat);
			val2.localScale = new Vector3(0.6f, 1f, 1f);
			for (int num8 = 0; num8 < 4; num8++)
			{
				float z = ((float)num8 - 1.5f) * 0.085f;
				float length = ((num8 == 0 || num8 == 3) ? 0.85f : 1f);
				string key = "Finger" + num8 + ((side2 < 0f) ? "L" : "R");
				float inward = 0f - side2;
				Part(wrist[num7], "Finger" + num8, Meshes.Get(key, () => Tube((Vector3[])(object)new Vector3[5]
				{
					new Vector3(0f, -0.72f, z),
					new Vector3(inward * 0.03f, -0.72f - 0.4f * length, z * 1.15f),
					new Vector3(inward * 0.1f, -0.72f - 0.75f * length, z * 1.25f),
					new Vector3(inward * 0.24f, -0.72f - 1f * length, z * 1.3f),
					new Vector3(inward * 0.38f, -0.72f - 1.1f * length, z * 1.3f)
				}, new float[5] { 0.05f, 0.042f, 0.036f, 0.026f, 0.012f }, 6)), mat);
			}
			string key2 = "Thumb" + ((side2 < 0f) ? "L" : "R");
			Part(wrist[num7], "Thumb", Meshes.Get(key2, () => Tube((Vector3[])(object)new Vector3[3]
			{
				new Vector3((0f - side2) * 0.04f, -0.3f, 0.12f),
				new Vector3((0f - side2) * 0.12f, -0.6f, 0.22f),
				new Vector3((0f - side2) * 0.22f, -0.85f, 0.22f)
			}, new float[3] { 0.05f, 0.04f, 0.015f }, 6)), mat);
		}
		neck = Pivot(spine, "Neck", new Vector3(0f, 3.65f, 0f));
		Part(neck, "NeckPole", Meshes.Get("NeckPole", () => Tube((Vector3[])(object)new Vector3[5]
		{
			new Vector3(0f, -0.1f, 0f),
			new Vector3(0.04f, 0.8f, 0.03f),
			new Vector3(-0.03f, 1.6f, 0.05f),
			new Vector3(0.02f, 2.4f, 0.01f),
			new Vector3(0f, 3f, 0f)
		}, new float[5] { 0.21f, 0.15f, 0.13f, 0.12f, 0.11f }, 8)), mat);
		for (int num9 = 0; num9 < 6; num9++)
		{
			float y2 = 0.3f + (float)num9 * 0.42f;
			Part(neck, "NeckKnob" + num9, Meshes.Get("NeckKnob" + num9, () => Tube((Vector3[])(object)new Vector3[3]
			{
				new Vector3(0f, y2 - 0.07f, 0f),
				new Vector3(0f, y2, -0.02f),
				new Vector3(0f, y2 + 0.07f, 0f)
			}, new float[3] { 0.12f, 0.17f, 0.12f }, 7)), mat);
		}
		Head = Pivot(neck, "Head", new Vector3(0f, 3f, 0f));
		Part(Head, "Post", Meshes.Get("Post", () => Tube((Vector3[])(object)new Vector3[3]
		{
			new Vector3(0f, -0.1f, 0f),
			new Vector3(0f, 0.5f, 0f),
			new Vector3(0.02f, 1f, 0f)
		}, new float[3] { 0.11f, 0.08f, 0.05f }, 7)), mat);
		Part(Head, "Bracket", Meshes.Get("Bracket", () => Tube((Vector3[])(object)new Vector3[3]
		{
			new Vector3(-0.42f, 0.28f, 0f),
			new Vector3(0f, 0.3f, 0f),
			new Vector3(0.42f, 0.28f, 0f)
		}, new float[3] { 0.07f, 0.09f, 0.07f }, 6)), mat2);
		for (int num10 = 0; num10 < 2; num10++)
		{
			float side3 = Sides[num10];
			Vector3 val3 = new Vector3(side3, 0.18f, 0.22f);
			Vector3 normalized = ((Vector3)(ref val3)).normalized;
			Transform val4 = Pivot(Head, "Horn" + num10, new Vector3(side3 * 0.32f, 0.28f, 0f));
			val4.localRotation = Quaternion.FromToRotation(Vector3.up, normalized);
			Part(val4, "Driver", Meshes.Get("Driver", () => Tube((Vector3[])(object)new Vector3[4]
			{
				new Vector3(0f, -0.3f, 0f),
				new Vector3(0f, -0.25f, 0f),
				new Vector3(0f, 0.1f, 0f),
				new Vector3(0f, 0.18f, 0f)
			}, new float[4] { 0.16f, 0.22f, 0.22f, 0.13f }, 12)), mat2);
			Part(val4, "Bell", Meshes.Get("Bell", () => Bell(inside: false)), mat2);
			Part(val4, "BellInside", Meshes.Get("BellInside", () => Bell(inside: true)), mat3);
			Part(val4, "Throat", Meshes.Get("Throat", () => Disc(0.6f, 0.16f, 12)), mat3);
			Part(val4, "Rim", Meshes.Get("Rim", () => Ring(1.55f, 0.66f, 0.045f, 24)), mat2);
			Part(Head, "Cable" + num10, Meshes.Get("Cable" + num10, () => Tube((Vector3[])(object)new Vector3[5]
			{
				new Vector3(side3 * 0.42f, 0.18f, -0.12f),
				new Vector3(side3 * 0.52f, -0.45f, -0.24f),
				new Vector3(side3 * 0.36f, -1.1f, -0.22f),
				new Vector3(side3 * 0.16f, -1.6f, -0.12f),
				new Vector3(side3 * 0.1f, -1.9f, -0.08f)
			}, new float[5] { 0.035f, 0.035f, 0.035f, 0.035f, 0.03f }, 5)), mat3);
		}
	}

	public void BeginGrab(Vector3 playerPosition)
	{
		//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_000d: Unknown result type (might be due to invalid IL or missing references)
		grabStart = playerPosition;
		Grip.position = playerPosition;
	}

	public Events Animate(float dt, bool chasing, bool eating, float eatTime, float deathTime, bool stunned, Transform lookTarget)
	{
		//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_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: 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_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_030d: Unknown result type (might be due to invalid IL or missing references)
		//IL_032f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0421: Unknown result type (might be due to invalid IL or missing references)
		//IL_0466: Unknown result type (might be due to invalid IL or missing references)
		//IL_0507: Unknown result type (might be due to invalid IL or missing references)
		//IL_0542: Unknown result type (might be due to invalid IL or missing references)
		//IL_05e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_062b: Unknown result type (might be due to invalid IL or missing references)
		//IL_064d: Unknown result type (might be due to invalid IL or missing references)
		//IL_06e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_06f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0705: Unknown result type (might be due to invalid IL or missing references)
		//IL_070a: Unknown result type (might be due to invalid IL or missing references)
		//IL_070f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0717: Unknown result type (might be due to invalid IL or missing references)
		//IL_0719: Unknown result type (might be due to invalid IL or missing references)
		//IL_0723: Unknown result type (might be due to invalid IL or missing references)
		//IL_0728: Unknown result type (might be due to invalid IL or missing references)
		//IL_0738: Unknown result type (might be due to invalid IL or missing references)
		//IL_0743: Unknown result type (might be due to invalid IL or missing references)
		//IL_0748: Unknown result type (might be due to invalid IL or missing references)
		//IL_074d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0771: Unknown result type (might be due to invalid IL or missing references)
		//IL_0776: Unknown result type (might be due to invalid IL or missing references)
		//IL_077b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0669: Unknown result type (might be due to invalid IL or missing references)
		//IL_06a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_06ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_07b3: Unknown result type (might be due to invalid IL or missing references)
		Events result = default(Events);
		time += dt;
		Vector3 position = Root.parent.position;
		if (hasLastPosition && dt > 0f)
		{
			Vector3 val = position - lastPosition;
			val.y = 0f;
			float num = Mathf.Min(((Vector3)(ref val)).magnitude / dt, 15f);
			speed = Mathf.Lerp(speed, num, 1f - Mathf.Exp((0f - dt) * 4f));
		}
		lastPosition = position;
		hasLastPosition = true;
		bool flag = deathTime >= 0f;
		bool flag2 = eatTime >= 0f;
		float num2 = ((flag || eating) ? 0f : Mathf.Clamp01(speed / (1.2f * Scale)));
		moveBlend = Mathf.MoveTowards(moveBlend, num2, dt * 1.5f);
		chaseBlend = Mathf.MoveTowards(chaseBlend, (chasing && !flag) ? 1f : 0f, dt * 1.2f);
		eatBlend = Mathf.MoveTowards(eatBlend, (flag2 && eatTime < 4.8f && !flag) ? 1f : 0f, dt * ((flag2 && eatTime < 4.8f) ? 6f : 1f));
		float num3 = ((flag2 && eatTime < 0.45f) ? 1f : 0f);
		crouch = Mathf.MoveTowards(crouch, num3, dt * ((num3 > crouch) ? 4f : 0.9f));
		float num4 = Smooth(crouch);
		phase += speed / (11.2f * Scale) * (float)Math.PI * 2f * dt;
		if (phase > (float)Math.PI * 2f)
		{
			phase -= (float)Math.PI * 2f;
		}
		float num5 = Mathf.Lerp(20f, 30f, chaseBlend) * moveBlend;
		float num6 = Mathf.Lerp(38f, 62f, chaseBlend) * moveBlend;
		float num7 = 0f;
		float[] array = new float[2];
		for (int i = 0; i < 2; i++)
		{
			float num8 = phase + (float)i * (float)Math.PI;
			float num9 = Mathf.Cos(num8);
			float num10 = num5 * Mathf.Sin(num8);
			float num11 = num6 * Mathf.Pow(Mathf.Max(0f, num9), 1.3f) + 4f;
			num10 = Mathf.Lerp(num10, 45f, num4);
			num11 = Mathf.Lerp(num11, 92f, num4);
			array[i] = num10;
			if (!flag)
			{
				hip[i].localRotation = Quaternion.Euler(0f - num10, 0f, Sides[i] * 2f);
				knee[i].localRotation = Quaternion.Euler(num11, 0f, 0f);
				ankle[i].localRotation = Quaternion.Euler(num10 - num11, 0f, 0f);
			}
			float num12 = 4.9f * Mathf.Cos(num10 * ((float)Math.PI / 180f)) + 5.1f * Mathf.Cos((num10 - num11) * ((float)Math.PI / 180f));
			num7 = Mathf.Max(num7, num12 + 0.42f);
			if (lastSwingCos[i] > 0f && num9 <= 0f && moveBlend > 0.3f)
			{
				result.Footfalls++;
			}
			lastSwingCos[i] = num9;
		}
		float num13 = 1f - moveBlend;
		if (!flag)
		{
			float num14 = Mathf.Cos(phase) * 0.22f * moveBlend;
			float num15 = Mathf.Sin(time * 0.8f) * 0.05f * num13;
			hips.localPosition = new Vector3(num14, num7 + num15, 0f);
			hips.localRotation = Quaternion.Euler(0f, Mathf.Sin(phase) * 4f * moveBlend, Mathf.Cos(phase) * 2.5f * moveBlend);
		}
		float num16 = Mathf.Lerp(7f, 20f, chaseBlend) + 48f * num4;
		if (!flag)
		{
			spine.localRotation = Quaternion.Euler(num16 + Mathf.Sin(time * 0.7f) * 1.5f * num13, (0f - Mathf.Sin(phase)) * 5f * moveBlend, (0f - Mathf.Cos(phase)) * 2f * moveBlend + Mathf.Sin(time * 0.45f) * 2f * num13);
			neck.localRotation = Quaternion.Euler((0f - num16) * 0.65f + 5f, 0f, Mathf.Sin(time * 0.31f) * 3f);
		}
		AnimateHead(dt, chasing, flag2, stunned, flag, lookTarget);
		for (int j = 0; j < 2; j++)
		{
			float num17 = Sides[j];
			float num18 = (0f - array[j]) * 0.8f + chaseBlend * 14f;
			float num19 = num17 * (5f + chaseBlend * 7f + Mathf.Sin(time * 0.9f + (float)j * 1.7f) * 1.5f * num13);
			if (!flag)
			{
				shoulder[j].localRotation = Quaternion.Euler(0f - num18 + num16 * 0.85f, 0f, num19);
				elbow[j].localRotation = Quaternion.Euler(0f - (10f + 22f * chaseBlend + Mathf.Max(0f, num18) * 0.6f), 0f, 0f);
				wrist[j].localRotation = Quaternion.Euler(-8f, 0f, 0f);
			}
			if (stunned && !flag)
			{
				Transform obj = shoulder[j];
				obj.localRotation *= Quaternion.Euler(Mathf.Sin(time * 37f + (float)j) * 6f, 0f, Mathf.Sin(time * 29f + (float)j) * 5f);
			}
		}
		if (eatBlend > 0f && !flag)
		{
			ReachForGrab(eatTime);
		}
		Vector3 val2 = wrist[1].position - wrist[1].up * (0.55f * Scale);
		Grip.position = val2 - Vector3.up * 1f;
		Vector3 val3 = Head.position - Grip.position;
		val3.y = 0f;
		if (((Vector3)(ref val3)).sqrMagnitude > 0.01f)
		{
			Grip.rotation = Quaternion.LookRotation(((Vector3)(ref val3)).normalized, Vector3.up);
		}
		if (flag)
		{
			float num20 = Mathf.Clamp01(deathTime / 2.6f);
			Root.localRotation = Quaternion.Euler(86f * num20 * num20, 0f, 0f);
			if (num20 >= 1f && !landed)
			{
				landed = true;
				result.Landed = true;
			}
		}
		return result;
	}

	private void AnimateHead(float dt, bool chasing, bool holding, bool stunned, bool dead, Transform lookTarget)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_020b: 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_0229: 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_023a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0104: Unknown result type (might be due to invalid IL or missing references)
		//IL_0109: Unknown result type (might be due to invalid IL or missing references)
		//IL_010e: Unknown result type (might be due to invalid IL or missing references)
		//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)
		//IL_0120: 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_0127: 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_014f: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
		if (dead)
		{
			return;
		}
		Quaternion identity = Quaternion.identity;
		if (stunned)
		{
			Head.localRotation = Quaternion.Euler(Mathf.Sin(time * 41f) * 7f, Mathf.Sin(time * 33f) * 10f, Mathf.Sin(time * 27f) * 6f);
			return;
		}
		if ((chasing || holding) && (Object)(object)lookTarget != (Object)null)
		{
			Vector3 val = lookTarget.position - Head.position;
			Vector3 val2 = default(Vector3);
			((Vector3)(ref val2))..ctor(val.x, 0f, val.z);
			if (((Vector3)(ref val2)).sqrMagnitude > 0.01f)
			{
				float num = (0f - Mathf.Atan2(val.y, ((Vector3)(ref val2)).magnitude)) * 57.29578f;
				Quaternion val3 = Quaternion.LookRotation(((Vector3)(ref val2)).normalized, Vector3.up) * Quaternion.Euler(Mathf.Clamp(num, -30f, 50f), 0f, 0f);
				Quaternion val4 = Quaternion.Inverse(neck.rotation) * val3;
				Head.localRotation = Quaternion.Slerp(Head.localRotation, val4, 1f - Mathf.Exp((0f - dt) * 5f));
				return;
			}
		}
		twitchTimer -= dt;
		if (twitchTimer <= 0f)
		{
			if (twitchHold <= 0f)
			{
				twitchTarget = Quaternion.Euler(Random.Range(-12f, 18f), Random.Range(-40f, 40f), Random.Range(-22f, 22f));
				twitchHold = Random.Range(1f, 3.5f);
			}
			twitchHold -= dt;
			if (twitchHold <= 0f)
			{
				twitchTarget = identity;
				twitchTimer = Random.Range(3f, 9f);
			}
		}
		twitchCurrent = Quaternion.Slerp(twitchCurrent, twitchTarget, 1f - Mathf.Exp((0f - dt) * 14f));
		Head.localRotation = twitchCurrent;
	}

	private void ReachForGrab(float eatTime)
	{
		//IL_0006: 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_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: 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_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: 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_0110: Unknown result type (might be due to invalid IL or missing references)
		//IL_0120: Unknown result type (might be due to invalid IL or missing references)
		//IL_0125: Unknown result type (might be due to invalid IL or missing references)
		//IL_012a: Unknown result type (might be due to invalid IL or missing references)
		//IL_007f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_0136: Unknown result type (might be due to invalid IL or missing references)
		//IL_013b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0148: Unknown result type (might be due to invalid IL or missing references)
		//IL_014d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0157: Unknown result type (might be due to invalid IL or missing references)
		//IL_015c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0163: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0177: Unknown result type (might be due to invalid IL or missing references)
		//IL_017c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0181: 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_0186: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val = Head.position + Root.parent.forward * (2.1f * Scale) - Vector3.up * (0.4f * Scale);
		Vector3 val2 = grabStart + Vector3.up * 1f;
		Vector3 target;
		if (eatTime < 0.45f)
		{
			target = val2;
		}
		else if (eatTime < 2.1f)
		{
			target = Vector3.Lerp(val2, val, Smooth((eatTime - 0.45f) / 1.65f));
		}
		else
		{
			float num = Mathf.Clamp01((eatTime - 2.1f) / 0.4f);
			Vector3 val3 = default(Vector3);
			((Vector3)(ref val3))..ctor(Mathf.PerlinNoise(holdOffsetSeed.x, eatTime * 6f) - 0.5f, Mathf.PerlinNoise(holdOffsetSeed.y, eatTime * 6f) - 0.5f, Mathf.PerlinNoise(holdOffsetSeed.z, eatTime * 6f) - 0.5f);
			target = val + val3 * (0.5f * Scale * num);
		}
		Vector3 right = Root.parent.right;
		Vector3 pole = -Root.parent.forward * 0.4f + right * 0.8f - Vector3.up * 0.4f;
		SolveArm(1, target, pole, eatBlend);
	}

	private void SolveArm(int i, Vector3 target, Vector3 pole, float weight)
	{
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: 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_00a5: 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_00d6: 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)
		//IL_00e1: 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_00ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f8: 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_00fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0102: Unknown result type (might be due to invalid IL or missing references)
		//IL_0107: 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_011f: 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_0122: Unknown result type (might be due to invalid IL or missing references)
		//IL_0127: Unknown result type (might be due to invalid IL or missing references)
		//IL_012e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0148: Unknown result type (might be due to invalid IL or missing references)
		//IL_014e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0150: Unknown result type (might be due to invalid IL or missing references)
		//IL_0152: Unknown result type (might be due to invalid IL or missing references)
		//IL_0157: Unknown result type (might be due to invalid IL or missing references)
		//IL_015e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0178: Unknown result type (might be due to invalid IL or missing references)
		//IL_017d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0184: 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_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		float num = 3.9f * Scale;
		float num2 = 4.55f * Scale;
		Vector3 position = shoulder[i].position;
		Vector3 val = target - position;
		float num3 = Mathf.Clamp(((Vector3)(ref val)).magnitude, 0.01f, num + num2 - 0.001f);
		Vector3 normalized = ((Vector3)(ref val)).normalized;
		float num4 = Mathf.Clamp((num * num + num3 * num3 - num2 * num2) / (2f * num * num3), -1f, 1f);
		float num5 = Mathf.Sqrt(1f - num4 * num4);
		Vector3 val2 = pole - Vector3.Dot(pole, normalized) * normalized;
		if (((Vector3)(ref val2)).sqrMagnitude < 0.0001f)
		{
			val2 = Vector3.Cross(normalized, Root.parent.right);
		}
		((Vector3)(ref val2)).Normalize();
		Vector3 val3 = position + normalized * (num * num4) + val2 * (num * num5);
		Vector3 val4 = position + normalized * num3;
		shoulder[i].rotation = Quaternion.Slerp(shoulder[i].rotation, AimDown(val3 - position), weight);
		elbow[i].rotation = Quaternion.Slerp(elbow[i].rotation, AimDown(val4 - val3), weight);
		wrist[i].localRotation = Quaternion.Slerp(wrist[i].localRotation, Quaternion.identity, weight);
	}

	private Quaternion AimDown(Vector3 dir)
	{
		//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_0013: 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_0030: 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_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: 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)
		Vector3 val = Root.parent.forward;
		if (Mathf.Abs(Vector3.Dot(((Vector3)(ref dir)).normalized, val)) > 0.95f)
		{
			val = Vector3.up;
		}
		return Quaternion.LookRotation(dir, val) * Quaternion.Euler(-90f, 0f, 0f);
	}

	private static float Smooth(float t)
	{
		t = Mathf.Clamp01(t);
		return t * t * (3f - 2f * t);
	}

	private static float ChestRadius(float y)
	{
		float[] array = new float[8] { 0f, 0.5f, 1f, 1.6f, 2.2f, 2.8f, 3.3f, 3.7f };
		float[] array2 = new float[8] { 0.42f, 0.36f, 0.4f, 0.62f, 0.8f, 0.8f, 0.66f, 0.38f };
		for (int i = 0; i < array.Length - 1; i++)
		{
			if (y <= array[i + 1])
			{
				return Mathf.Lerp(array2[i], array2[i + 1], (y - array[i]) / (array[i + 1] - array[i]));
			}
		}
		return array2[^1];
	}

	private static Mesh Rib(int index)
	{
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		float num = 1.55f + (float)index * 0.26f;
		float num2 = ChestRadius(num) + 0.02f;
		Vector3[] array = (Vector3[])(object)new Vector3[9];
		float[] array2 = new float[9];
		for (int i = 0; i < 9; i++)
		{
			float num3 = (float)i / 8f;
			float num4 = Mathf.Lerp(15f, 165f, num3) * ((float)Math.PI / 180f);
			float num5 = Mathf.Sin(num4) * 0.22f;
			ref Vector3 reference = ref array[i];
			reference = new Vector3(Mathf.Cos(num4) * num2, num - num5, Mathf.Sin(num4) * num2 * 0.6f);
			array2[i] = 0.055f * (1f - Mathf.Abs(num3 - 0.5f) * 0.6f);
		}
		return Tube(array, array2, 5);
	}

	private static Mesh Profile(float[] heights, float[] radii, int sides)
	{
		//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)
		Vector3[] array = (Vector3[])(object)new Vector3[heights.Length];
		for (int i = 0; i < heights.Length; i++)
		{
			ref Vector3 reference = ref array[i];
			reference = new Vector3(0f, heights[i], 0f);
		}
		return Tube(array, radii, sides);
	}

	private static Mesh Bell(bool inside)
	{
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		Vector3[] array = (Vector3[])(object)new Vector3[9];
		float[] array2 = new float[9];
		for (int i = 0; i < 9; i++)
		{
			float num = (float)i / 8f;
			ref Vector3 reference = ref array[i];
			reference = new Vector3(0f, Mathf.Lerp(0.12f, 1.55f, num), 0f);
			float num2 = 0.12f + 0.52f * Mathf.Pow(num, 2.2f);
			array2[i] = (inside ? (num2 - 0.02f) : num2);
		}
		return Tube(array, array2, 16, capStart: false, capEnd: false, inside);
	}

	private static Mesh Disc(float y, float radius, int sides)
	{
		//IL_0024: 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_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
		List<Vector3> list = new List<Vector3>();
		List<Vector3> list2 = new List<Vector3>();
		List<Vector2> list3 = new List<Vector2>();
		List<int> list4 = new List<int>();
		list.Add(new Vector3(0f, y, 0f));
		list2.Add(Vector3.up);
		list3.Add(new Vector2(0.5f, 0.5f));
		for (int i = 0; i <= sides; i++)
		{
			float num = (float)i * (float)Math.PI * 2f / (float)sides;
			list.Add(new Vector3(Mathf.Cos(num) * radius, y, Mathf.Sin(num) * radius));
			list2.Add(Vector3.up);
			list3.Add(new Vector2(0.5f + Mathf.Cos(num) * 0.5f, 0.5f + Mathf.Sin(num) * 0.5f));
		}
		for (int j = 0; j < sides; j++)
		{
			list4.Add(0);
			list4.Add(j + 2);
			list4.Add(j + 1);
		}
		return BuildMesh(list, list2, list3, list4);
	}

	private static Mesh Ring(float y, float radius, float thickness, int segments)
	{
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		Vector3[] array = (Vector3[])(object)new Vector3[segments + 1];
		float[] array2 = new float[segments + 1];
		for (int i = 0; i <= segments; i++)
		{
			float num = (float)i * (float)Math.PI * 2f / (float)segments;
			ref Vector3 reference = ref array[i];
			reference = new Vector3(Mathf.Cos(num) * radius, y, Mathf.Sin(num) * radius);
			array2[i] = thickness;
		}
		return Tube(array, array2, 6, capStart: false, capEnd: false);
	}

	private static Mesh Tube(Vector3[] points, float[] radii, int sides, bool capStart = true, bool capEnd = true, bool inside = false)
	{
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00eb: 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_0105: 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_0109: Unknown result type (might be due to invalid IL or missing references)
		//IL_010b: Unknown result type (might be due to invalid IL or missing references)
		//IL_010d: 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_009c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a1: 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_00a5: 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_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0288: Unknown result type (might be due to invalid IL or missing references)
		//IL_028d: Unknown result type (might be due to invalid IL or missing references)
		//IL_028f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0130: 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_013e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0147: Unknown result type (might be due to invalid IL or missing references)
		//IL_014c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0151: Unknown result type (might be due to invalid IL or missing references)
		//IL_015c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0161: Unknown result type (might be due to invalid IL or missing references)
		//IL_0167: Unknown result type (might be due to invalid IL or missing references)
		//IL_016c: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b9: 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_0181: 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_019a: Unknown result type (might be due to invalid IL or missing references)
		List<Vector3> list = new List<Vector3>();
		List<Vector3> list2 = new List<Vector3>();
		List<Vector2> list3 = new List<Vector2>();
		List<int> list4 = new List<int>();
		int num = points.Length;
		Vector3 val = Vector3.zero;
		Vector3 val2 = Vector3.up;
		Vector3 normal = Vector3.up;
		float num2 = 0f;
		for (int i = 0; i < num; i++)
		{
			Vector3 val3 = points[Mathf.Min(i + 1, num - 1)] - points[Mathf.Max(i - 1, 0)];
			Vector3 normalized = ((Vector3)(ref val3)).normalized;
			if (i == 0)
			{
				Vector3 val4 = ((Mathf.Abs(normalized.y) < 0.9f) ? Vector3.up : Vector3.right);
				Vector3 val5 = Vector3.Cross(normalized, val4);
				val = ((Vector3)(ref val5)).normalized;
				val2 = normalized;
			}
			else
			{
				Vector3 val6 = val - Vector3.Dot(val, normalized) * normalized;
				val = ((Vector3)(ref val6)).normalized;
				num2 += Vector3.Distance(points[i - 1], points[i]);
			}
			normal = normalized;
			Vector3 val7 = Vector3.Cross(normalized, val);
			for (int j = 0; j <= sides; j++)
			{
				float num3 = (float)j * (float)Math.PI * 2f / (float)sides;
				Vector3 val8 = val * Mathf.Cos(num3) + val7 * Mathf.Sin(num3);
				list.Add(points[i] + val8 * radii[i]);
				list2.Add(inside ? (-val8) : val8);
				list3.Add(new Vector2((float)j / (float)sides, num2 * 0.35f));
			}
		}
		int num4 = sides + 1;
		for (int k = 0; k < num - 1; k++)
		{
			for (int l = 0; l < sides; l++)
			{
				int num5 = k * num4 + l;
				int item = num5 + 1;
				int num6 = num5 + num4;
				int item2 = num6 + 1;
				if (inside)
				{
					list4.Add(num5);
					list4.Add(num6);
					list4.Add(item);
					list4.Add(item);
					list4.Add(num6);
					list4.Add(item2);
				}
				else
				{
					list4.Add(num5);
					list4.Add(item);
					list4.Add(num6);
					list4.Add(item);
					list4.Add(item2);
					list4.Add(num6);
				}
			}
		}
		if (capStart)
		{
			AddCap(list, list2, list3, list4, 0, sides, points[0], -val2, isStart: true);
		}
		if (capEnd)
		{
			AddCap(list, list2, list3, list4, (num - 1) * num4, sides, points[num - 1], normal, isStart: false);
		}
		return BuildMesh(list, list2, list3, list4);
	}

	private static void AddCap(List<Vector3> verts, List<Vector3> normals, List<Vector2> uvs, List<int> tris, int ringStart, int sides, Vector3 center, Vector3 normal, bool isStart)
	{
		//IL_0008: 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_001b: 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_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		int count = verts.Count;
		verts.Add(center);
		normals.Add(normal);
		uvs.Add(uvs[ringStart]);
		for (int i = 0; i <= sides; i++)
		{
			verts.Add(verts[ringStart + i]);
			normals.Add(normal);
			uvs.Add(uvs[ringStart + i]);
		}
		for (int j = 0; j < sides; j++)
		{
			tris.Add(count);
			tris.Add(isStart ? (count + 2 + j) : (count + 1 + j));
			tris.Add(isStart ? (count + 1 + j) : (count + 2 + j));
		}
	}

	private static Mesh BuildMesh(List<Vector3> verts, List<Vector3> normals, List<Vector2> uvs, List<int> tris)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Expected O, but got Unknown
		Mesh val = new Mesh();
		((Object)val).name = "SirenHeadMesh";
		val.SetVertices(verts);
		val.SetNormals(normals);
		val.SetUVs(0, uvs);
		val.SetTriangles(tris, 0);
		val.RecalculateBounds();
		val.RecalculateTangents();
		return val;
	}

	private static Transform Pivot(Transform parent, string name, Vector3 localPosition)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Expected O, but got Unknown
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject(name);
		val.layer = 19;
		val.transform.SetParent(parent, false);
		val.transform.localPosition = localPosition;
		return val.transform;
	}

	private static Transform Part(Transform parent, string name, Mesh mesh, Material mat)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		Transform val = Pivot(parent, name, Vector3.zero);
		((Component)val).gameObject.AddComponent<MeshFilter>().sharedMesh = mesh;
		((Renderer)((Component)val).gameObject.AddComponent<MeshRenderer>()).sharedMaterial = mat;
		return val;
	}
}
internal static class Sounds
{
	internal const int SirenSeed = 1201;

	internal const int ScreamSeed = 3307;

	internal const int DeathSeed = 5519;

	internal const int StepSeed = 7741;

	internal const int RadioSeed = 9109;

	internal const int WailSeed = 2213;

	internal const int CrunchSeed = 6607;

	internal static AudioClip SirenLoop;

	internal static AudioClip Scream;

	internal static AudioClip Death;

	internal static AudioClip Crunch;

	internal static AudioClip[] Steps;

	internal static AudioClip[] Radio;

	internal static AudioClip[] Wails;

	internal static void Load()
	{
		SirenLoop = Make("SirenHead_Siren", 1201, Synth.SirenLoopSamples);
		Scream = Make("SirenHead_Scream", 3307, Synth.ScreamSamples);
		Death = Make("SirenHead_Death", 5519, Synth.DeathSamples);
		Crunch = Make("SirenHead_Crunch", 6607, Synth.CrunchSamples);
		Steps = MakeSet("SirenHead_Step", 5, 7741, Synth.StepSamples);
		Radio = MakeSet("SirenHead_Radio", 4, 9109, Synth.RadioSamples);
		Wails = MakeSet("SirenHead_Wail", 3, 2213, Synth.WailSamples);
	}

	internal static AudioClip Pick(AudioClip[] clips)
	{
		if (clips != null && clips.Length != 0)
		{
			return clips[Random.Range(0, clips.Length)];
		}
		return null;
	}

	private static AudioClip[] MakeSet(string name, int count, int seed, Func<int, float[]> generate)
	{
		AudioClip[] array = (AudioClip[])(object)new AudioClip[count];
		for (int i = 0; i < count; i++)
		{
			array[i] = Make(name + i, seed * (i + 1), generate);
		}
		return array;
	}

	private static AudioClip Make(string name, int seed, Func<int, float[]> generate)
	{
		float[] array = generate(seed);
		AudioClip val = AudioClip.Create(name, array.Length, 1, 44100, false);
		val.SetData(array, 0);
		return val;
	}
}
internal static class Synth
{
	private class Echo
	{
		private readonly float[] buffer;

		private int index;

		public Echo(float seconds)
		{
			buffer = new float[Math.Max(1, (int)(seconds * 44100f))];
		}

		public float Process(float input, float feedback)
		{
			float num = buffer[index];
			buffer[index] = input + num * feedback;
			index = (index + 1) % buffer.Length;
			return num;
		}
	}

	private class Biquad
	{
		private double b0;

		private double b1;

		private double b2;

		private double a1;

		private double a2;

		private double x1;

		private double x2;

		private double y1;

		private double y2;

		public void SetBandpass(double hz, double q)
		{
			double num = Math.PI * 2.0 * hz / 44100.0;
			double num2 = Math.Sin(num) / (2.0 * q);
			double num3 = 1.0 + num2;
			b0 = num2 / num3;
			b1 = 0.0;
			b2 = (0.0 - num2) / num3;
			a1 = -2.0 * Math.Cos(num) / num3;
			a2 = (1.0 - num2) / num3;
		}

		public double Process(double x)
		{
			double result = b0 * x + b1 * x1 + b2 * x2 - a1 * y1 - a2 * y2;
			x2 = x1;
			x1 = x;
			y2 = y1;
			y1 = result;
			return result;
		}
	}

	internal const int SampleRate = 44100;

	private const double TwoPi = Math.PI * 2.0;

	internal static float[] SirenLoopSamples(int seed)
	{
		Random rng = new Random(seed);
		Echo echoA = new Echo(0.38f);
		Echo echoB = new Echo(0.71f);
		double p1 = 0.0;
		double p2 = 0.0;
		double p3 = 0.0;
		float smooth = 0f;
		float wind = 0f;
		float crackle = 0f;
		Func<float, float> render = delegate(float t)
		{
			float num = (t % 12f + 12f) % 12f / 12f;
			float num2 = ((num < 0.24f) ? SmoothStep(num / 0.24f) : ((num < 0.5f) ? (1f - 0.06f * (num - 0.24f) / 0.26f) : ((!(num < 0.78f)) ? 0f : Lerp(0.94f, 0f, SmoothStep((num - 0.5f) / 0.28f)))));
			double num3 = (double)Lerp(165f, 530f, num2) * (1.0 + 0.012 * Math.Sin(33.3008821280518 * (double)t));
			p1 += num3 / 44100.0;
			p2 += num3 * 1.19 / 44100.0;
			p3 += num3 * 1.004 / 44100.0;
			float num4 = Rotor(p1) * 0.5f + Rotor(p2) * 0.35f + Rotor(p3) * 0.3f;
			smooth += (num4 - smooth) * 0.45f;
			float num5 = (float)(rng.NextDouble() * 2.0 - 1.0);
			wind += (num5 - wind) * 0.08f;
			if (rng.NextDouble() < 0.00015873015873015873)
			{
				crackle = 1f;
			}
			crackle *= 0.9985f;
			float num6 = smooth * (0.55f + 0.45f * num2) + wind * 0.25f * num2 + num5 * crackle * 0.35f;
			num6 = (float)Math.Tanh(num6 * 2.4f);
			return num6 + echoA.Process(num6, 0.35f) * 0.35f + echoB.Process(num6, 0.2f) * 0.22f;
		};
		float[] array = RenderLoop(render, 12f, 1.5f, 3f);
		Normalize(array, 0.9f);
		return array;
	}

	internal static float[] ScreamSamples(int seed)
	{
		Random random = new Random(seed);
		int num = 114659;
		float[] array = new float[num];
		Echo echo = new Echo(0.33f);
		double num2 = 0.0;
		double num3 = 0.0;
		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);
			num5 += (num7 - num5) * 0.3f;
			float num8 = num7 - num5;
			float num14;
			if (num6 < 2.15f)
			{
				float num9 = SmoothStep(Math.Min(1f, num6 / 0.28f));
				double num10 = (double)Lerp(260f, 780f, num9) * (1.0 + 0.035 * Math.Sin(38.955748904513435 * (double)num6) * (double)num9);
				num2 += num10 / 44100.0;
				num3 += num10 * 1.5 / 44100.0;
				float num11 = Rotor(num2) * 0.6f + Saw(num3) * 0.25f;
				num4 += (num11 - num4) * 0.6f;
				float num12 = Math.Min(1f, num6 / 0.04f);
				float num13 = ((num6 > 1.95f) ? (1f - (num6 - 1.95f) / 0.2f) : 1f);
				num14 = (float)Math.Tanh((num4 + num8 * 0.18f) * 4f) * num12 * num13;
			}
			else
			{
				float num15 = num6 - 2.15f;
				float num16 = ((random.NextDouble() < 0.5) ? 1f : 0.2f);
				num14 = num8 * num16 * (float)Math.Exp((0f - num15) * 7f) * 0.6f;
			}
			array[i] = num14 + echo.Process(num14, 0.3f) * 0.3f;
		}
		Normalize(array, 0.95f);
		return array;
	}

	internal static float[] DeathSamples(int seed)
	{
		Random random = new Random(seed);
		int num = 220500;
		float[] array = new float[num];
		Echo echo = new Echo(0.45f);
		double num2 = 0.0;
		float num3 = 0f;
		float num4 = 1f;
		int num5 = 0;
		for (int i = 0; i < num; i++)
		{
			float num6 = (float)i / 44100f;
			float num7 = num6 / 5f;
			double num8 = 34.0 + 500.0 * Math.Exp((double)(0f - num6) * 1.1);
			num2 += num8 / 44100.0;
			float num9 = (float)(random.NextDouble() * 2.0 - 1.0);
			if (--num5 <= 0)
			{
				num5 = (int)(Range(random, 0.02f, 0.09f) * 44100f);
				num4 = ((random.NextDouble() < 0.25 + (double)num7 * 0.6) ? 0.1f : 1f);
			}
			float num10 = Rotor(num2) * 0.7f + num9 * 0.1f;
			num3 += (num10 - num3) * 0.35f;
			float num11 = Math.Min(1f, num6 / 0.05f) * (float)Math.Pow(1f - num7, 1.5);
			float num12 = (float)Math.Tanh(num3 * 3f) * num11 * num4;
			array[i] = num12 + echo.Process(num12, 0.35f) * 0.35f;
		}
		Normalize(array, 0.9f);
		return array;
	}

	internal static float[] StepSamples(int seed)
	{
		Random random = new Random(seed);
		int num = 57329;
		float[] array = new float[num];
		float num2 = Range(random, 38f, 52f);
		float num3 = Range(random, 170f, 290f);
		float num4 = Range(random, 0.05f, 0.14f);
		double num5 = 0.0;
		double num6 = 0.0;
		float num7 = 0f;
		float num8 = 0f;
		float num9 = 0f;
		float num10 = 0f;
		for (int i = 0; i < num; i++)
		{
			float num11 = (float)i / 44100f;
			float num12 = (float)(random.NextDouble() * 2.0 - 1.0);
			num5 += (double)num2 * (0.7 + 0.5 * Math.Exp((0f - num11) * 12f)) / 44100.0;
			float num13 = (float)Math.Sin(Math.PI * 2.0 * num5) * (float)Math.Exp((double)(0f - num11) * 6.5) * Math.Min(1f, num11 / 0.006f);
			num7 += (num12 - num7) * 0.18f;
			float num14 = num7 * (float)Math.Exp((0f - num11) * 16f) * 0.9f;
			num8 += (num12 - num8) * 0.015f;
			float num15 = num8 * (float)Math.Exp((double)(0f - num11) * 2.5) * 3f;
			float num16 = 0f;
			if (num11 > num4 && num11 < num4 + 0.32f)
			{
				float num17 = num11 - num4;
				if (num17 >= num10)
				{
					num9 = 1f;
					num10 = num17 + Range(random, 0.008f, 0.025f);
				}
				num9 *= 0.996f;
				num6 += (double)num3 * (1.0 - (double)num17 * 0.6) / 44100.0;
				num16 = Saw(num6) * num9 * (float)Math.Sin(Math.PI * (double)num17 / 0.3199999928474426) * 0.22f;
			}
			array[i] = (float)Math.Tanh((num13 * 1.3f + num14 + num15 + num16) * 1.4f);
		}
		Normalize(array, 0.95f);
		return array;
	}

	internal static float[] RadioSamples(int seed)
	{
		Random random = new Random(seed);
		float num = Range(random, 4f, 6f);
		int num2 = (int)(num * 44100f);
		float[] array = new float[num2];
		Biquad biquad = new Biquad();
		Biquad biquad2 = new Biquad();
		Biquad biquad3 = new Biquad();
		Biquad biquad4 = new Biquad();
		biquad.SetBandpass(Range(random, 2200f, 3600f), 0.7);
		biquad4.SetBandpass(1200.0, 0.6);
		Echo echo = new Echo(0.29f);
		float num3 = Range(random, 0.6f, 1.4f);
		float num4 = num - Range(random, 0.8f, 1.6f);
		float num5 = Range(random, 0.2f, num - 1f);
		double num6 = 0.0;
		double num7 = 0.0;
		float num8 = Range(random, 95f, 135f);
		int num9 = 0;
		float num10 = 0f;
		float num11 = 0f;
		float num12 = 0f;
		for (int i = 0; i < num2; i++)
		{
			float num13 = (float)i / 44100f;
			float num14 = (float)(random.NextDouble() * 2.0 - 1.0);
			if (random.NextDouble() < 6.802721088435374E-05)
			{
				num12 = 1f;
			}
			num12 *= 0.99995f;
			float num15 = ((random.NextDouble() < 0.002) ? (num14 * 3f) : 0f);
			float num16 = (float)biquad.Process(num14) * (0.25f + 0.75f * num12) + num15 * 0.3f;
			float num17 = 0f;
			if (num13 > num3 && num13 < num4)
			{
				if (--num9 <= 0)
				{
					num9 = (int)(Range(random, 0.07f, 0.17f) * 44100f);
					biquad2.SetBandpass(Range(random, 280f, 820f), 5.0);
					biquad3.SetBandpass(Range(random, 900f, 2300f), 7.0);
					num10 = ((random.NextDouble() < 0.2) ? 0f : Range(random, 0.5f, 1f));
					num8 *= Range(random, 0.93f, 1.07f);
					num8 = Math.Max(80f, Math.Min(160f, num8));
				}
				num11 += (num10 - num11) * 0.002f;
				num6 += (double)(num8 / 44100f);
				float num18 = Saw(num6) + num14 * 0.15f;
				num17 = (float)(biquad2.Process(num18) * 1.2 + biquad3.Process(num18) * 0.8) * num11;
				num17 = (float)biquad4.Process(Math.Tanh(num17 * 3f)) * 1.5f;
			}
			float num19 = 0f;
			if (num13 > num5 && num13 < num5 + 0.9f)
			{
				float num20 = (num13 - num5) / 0.9f;
				num7 += (double)(Lerp(900f, 2300f, (float)Math.Sin(Math.PI * (double)num20)) / 44100f);
				num19 = (float)Math.Sin(Math.PI * 2.0 * num7) * (float)Math.Sin(Math.PI * (double)num20) * 0.12f;
			}
			float num21 = Math.Min(1f, num13 / 0.15f) * Math.Min(1f, (num - num13) / 0.4f);
			float num22 = (float)Math.Tanh((num16 * 0.6f + num17 + num19) * 1.6f) * num21;
			array[i] = num22 + echo.Process(num22, 0.3f) * 0.3f;
		}
		Normalize(array, 0.8f);
		return array;
	}

	internal static float[] WailSamples(int seed)
	{
		Random rng = new Random(seed);
		float num = Range(rng, 6.5f, 8f);
		int num2 = (int)(num * 44100f);
		float[] array = new float[num2];
		float num3 = Range(rng, 95f, 125f);
		float b = num3 * Range(rng, 2.6f, 3.2f);
		float num4 = Range(rng, 2f, 2.8f);
		float num5 = num4 + Range(rng, 1f, 1.8f);
		Echo echo = new Echo(0.29f);
		Echo echo2 = new Echo(0.53f);
		Echo echo3 = new Echo(0.97f);
		double num6 = 0.0;
		double num7 = 0.0;
		float num8 = 0f;
		for (int i = 0; i < num2; i++)
		{
			float num9 = (float)i / 44100f;
			float val = ((num9 < num4) ? SmoothStep(num9 / num4) : ((num9 < num5) ? 1f : (1f - SmoothStep((num9 - num5) / (num - num5 - 0.3f)))));
			double num10 = (double)Lerp(num3, b, Math.Max(0f, val)) * (1.0 + 0.01 * Math.Sin(25.7610597594363 * (double)num9));
			num6 += num10 / 44100.0;
			num7 += num10 * 1.19 / 44100.0;
			float num11 = Rotor(num6) * 0.6f + Rotor(num7) * 0.4f;
			num8 += (num11 - num8) * 0.12f;
			float num12 = Math.Max(0f, val) * Math.Min(1f, num9 / 0.3f);
			float num13 = num8 * num12;
			array[i] = num13 + echo.Process(num13, 0.4f) * 0.4f + echo2.Process(num13, 0.35f) * 0.3f + echo3.Process(num13, 0.3f) * 0.25f;
		}
		Normalize(array, 0.75f);
		return array;
	}

	internal static float[] CrunchSamples(int seed)
	{
		Random random = new Random(seed);
		int num = 48510;
		float[] array = new float[num];
		float[] array2 = new float[11];
		float[] array3 = new float[11];
		float num2 = 0f;
		for (int i = 0; i < 11; i++)
		{
			array2[i] = num2;
			array3[i] = Range(random, 1400f, 3200f);
			num2 += Range(random, 0.015f, 0.06f);
		}
		float num3 = 0f;
		float num4 = 0f;
		for (int j = 0; j < num; j++)
		{
			float num5 = (float)j / 44100f;
			float num6 = (float)(random.NextDouble() * 2.0 - 1.0);
			num3 += (num6 - num3) * 0.3f;
			float num7 = num6 - num3;
			num4 += (num6 - num4) * 0.06f;
			float num8 = (float)Math.Sin(Math.PI * 140.0 * (double)num5 * (1.0 - (double)num5 * 0.5)) * (float)Math.Exp((0f - num5) * 9f) * 0.8f;
			num8 += num4 * (float)Math.Exp((0f - num5) * 5f) * 2.2f * (0.6f + 0.4f * (float)Math.Sin(Math.PI * 26.0 * (double)num5));
			for (int k = 0; k < 11 && !(num5 < array2[k]); k++)
			{
				float num9 = num5 - array2[k];
				if (!(num9 > 0.08f))
				{
					num8 += ((float)Math.Sin(Math.PI * 2.0 * (double)array3[k] * (double)num9) * 0.5f * (float)Math.Exp((0f - num9) * 450f) + num7 * (float)Math.Exp((0f - num9) * 600f)) * 0.8f;
				}
			}
			array[j] = (float)Math.Tanh(num8 * 1.5f);
		}
		Normalize(array, 0.9f);
		return array;
	}

	private static float Rotor(double phase)
	{
		return (float)Math.Tanh(3.0 * Math.Sin(Math.PI * 2.0 * phase)) * 0.7f + Saw(phase) * 0.3f;
	}

	private static float[] RenderLoop(Func<float, float> render, float period, float crossfade, float warmup)
	{
		int num = (int)(warmup * 44100f);
		int num2 = (int)(period * 44100f);
		int num3 = (int)(crossfade * 44100f);
		float[] array = new float[num2 + num3];
		for (int i = -num; i < num2 + num3; i++)
		{
			float num4 = render((float)i / 44100f);
			if (i >= 0)
			{
				array[i] = num4;
			}
		}
		float[] array2 = new float[num2];
		for (int j = 0; j < num2; j++)
		{
			if (j < num3)
			{
				double num5 = (double)j / (double)num3;
				array2[j] = (float)((double)array[num2 + j] * Math.Cos(num5 * Math.PI / 2.0) + (double)array[j] * Math.Sin(num5 * Math.PI / 2.0));
			}
			else
			{
				array2[j] = array[j];
			}
		}
		return array2;
	}

	private static float Saw(double phase)
	{
		return (float)(2.0 * (phase - Math.Floor(phase)) - 1.0);
	}

	private static float Range(Random rng, float min, float max)
	{
		return min + (float)rng.NextDouble() * (max - min);
	}

	private static float Lerp(float a, float b, float t)
	{
		return a + (b - a) * t;
	}

	private static float SmoothStep(float t)
	{
		t = Math.Max(0f, Math.Min(1f, t));
		return t * t * (3f - 2f * t);
	}

	private static void Normalize(float[] samples, float peak)
	{
		float num = 0f;
		foreach (float value in samples)
		{
			num = Math.Max(num, Math.Abs(value));
		}
		if (!(num <= 0f))
		{
			float num2 = peak / num;
			for (int j = 0; j < samples.Length; j++)
			{
				samples[j] *= num2;
			}
		}
	}
}