Decompiled source of Deku Mask v1.0.1

BepInEx/plugins/Omniscye-Empress_DekuMask/EmpressDekuMask.dll

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Empress.REPO.DekuMask
{
	internal sealed class DekuBubbles : MonoBehaviour
	{
		private sealed class ChargeState
		{
			internal int AvatarViewId;

			internal PlayerAvatar Avatar;

			internal GameObject Go;

			internal float StartTime;
		}

		private sealed class BubbleState
		{
			internal int AvatarViewId;

			internal PlayerAvatar Shooter;

			internal GameObject Go;

			internal Vector3 Dir;

			internal float Size;

			internal float Charge;

			internal float Life;
		}

		private const float MaxChargeTime = 1.2f;

		private const float MediumCharge = 0.42f;

		private const float FullCharge = 0.95f;

		private const float MinSize = 0.16f;

		private const float MaxSize = 0.5f;

		private const float FlySpeed = 7.5f;

		private const float MaxFlyTime = 3.5f;

		private readonly List<ChargeState> _charges = new List<ChargeState>();

		private readonly List<BubbleState> _bubbles = new List<BubbleState>();

		private bool _localCharging;

		public static DekuBubbles Instance { get; private set; }

		private void Awake()
		{
			Instance = this;
		}

		private void Update()
		{
			TickLocalInput();
			TickCharges();
			TickBubbles();
		}

		private int LocalViewId()
		{
			PlayerAvatar val = DekuMaskAccess.LocalAvatar();
			if (!((Object)(object)val != (Object)null) || !((Object)(object)val.photonView != (Object)null))
			{
				return -1;
			}
			return val.photonView.ViewID;
		}

		private void Send(byte code, object[] data)
		{
			EmpressDekuMaskPlugin.RaiseToOthers(code, data);
			switch (code)
			{
			case 190:
				ReceiveBlow(data);
				break;
			case 191:
				ReceiveFire(data);
				break;
			case 192:
				ReceivePop(data);
				break;
			case 193:
				ReceiveCancel(data);
				break;
			}
		}

		private void TickLocalInput()
		{
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			PlayerAvatar val = DekuMaskAccess.LocalAvatar();
			DekuMaskRuntime instance = DekuMaskRuntime.Instance;
			bool flag = (Object)(object)val != (Object)null && (Object)(object)instance != (Object)null && instance.IsTransformed(val) && !DekuMaskAccess.IsDisabled(val);
			if (!_localCharging)
			{
				if (flag && DekuMaskAccess.InputAllowed() && !DekuMaskAccess.IsGrabbing(val) && !SemiFunc.InputHold((InputKey)10) && SemiFunc.InputDown((InputKey)11))
				{
					_localCharging = true;
					Send(190, new object[1] { LocalViewId() });
				}
			}
			else if (!flag)
			{
				_localCharging = false;
				Send(193, new object[1] { LocalViewId() });
			}
			else if (SemiFunc.InputHold((InputKey)10) || DekuMaskAccess.IsGrabbing(val))
			{
				_localCharging = false;
				Send(193, new object[1] { LocalViewId() });
			}
			else if (!SemiFunc.InputHold((InputKey)11))
			{
				_localCharging = false;
				ChargeState chargeState = ChargeFor(LocalViewId());
				float num = Mathf.Clamp01(((chargeState != null) ? (Time.time - chargeState.StartTime) : 0f) / 1.2f);
				Vector3 val2 = (((Object)(object)CameraAim.Instance != (Object)null) ? ((Component)CameraAim.Instance).transform.forward : ((Component)val).transform.forward);
				if (((Vector3)(ref val2)).sqrMagnitude < 0.001f)
				{
					val2 = Vector3.forward;
				}
				Vector3 val3 = ((chargeState != null && (Object)(object)chargeState.Go != (Object)null) ? chargeState.Go.transform.position : MouthPosition(val));
				Send(191, new object[4]
				{
					LocalViewId(),
					num,
					val3,
					((Vector3)(ref val2)).normalized
				});
			}
		}

		private static Vector3 MouthPosition(PlayerAvatar avatar)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			float num = EmpressDekuMaskPlugin.Settings.DekuHeight.Value * 0.8f;
			PlayerAvatarVisuals val = DekuMaskAccess.Visuals(avatar);
			Transform val2 = (((Object)(object)val != (Object)null) ? ((Component)val).transform : ((Component)avatar).transform);
			return val2.position + Vector3.up * num + val2.forward * 0.5f;
		}

		private ChargeState ChargeFor(int viewId)
		{
			for (int i = 0; i < _charges.Count; i++)
			{
				if (_charges[i].AvatarViewId == viewId)
				{
					return _charges[i];
				}
			}
			return null;
		}

		private void RemoveCharge(int viewId)
		{
			for (int num = _charges.Count - 1; num >= 0; num--)
			{
				if (_charges[num].AvatarViewId == viewId)
				{
					if ((Object)(object)_charges[num].Go != (Object)null)
					{
						Object.Destroy((Object)(object)_charges[num].Go);
					}
					_charges.RemoveAt(num);
				}
			}
		}

		internal void ReceiveBlow(object[] data)
		{
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			if (data == null || data.Length < 1)
			{
				return;
			}
			int num = Convert.ToInt32(data[0]);
			PlayerAvatar val = DekuMaskAccess.AvatarByViewId(num);
			if ((Object)(object)val == (Object)null || (Object)(object)DekuMaskAssets.BubblePrefab == (Object)null)
			{
				return;
			}
			RemoveCharge(num);
			PlayerAvatarVisuals val2 = DekuMaskAccess.Visuals(val);
			if (!((Object)(object)val2 == (Object)null))
			{
				GameObject val3 = Object.Instantiate<GameObject>(DekuMaskAssets.BubblePrefab, ((Component)val2).transform, false);
				((Object)val3).name = "Empress Deku Bubble Charge";
				Collider[] componentsInChildren = val3.GetComponentsInChildren<Collider>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					Object.Destroy((Object)(object)componentsInChildren[i]);
				}
				val3.transform.localPosition = new Vector3(0f, EmpressDekuMaskPlugin.Settings.DekuHeight.Value * 0.8f, 0.5f);
				val3.transform.localScale = Vector3.one * 0.16f;
				AudioSource val4 = val3.AddComponent<AudioSource>();
				val4.spatialBlend = 1f;
				val4.minDistance = 1f;
				val4.maxDistance = 8f;
				val4.rolloffMode = (AudioRolloffMode)1;
				val4.playOnAwake = false;
				AudioClip val5 = DekuMaskAssets.ClipContaining("blow");
				if ((Object)(object)val5 != (Object)null)
				{
					val4.clip = val5;
					val4.volume = EmpressDekuMaskPlugin.Settings.Volume.Value;
					val4.Play();
				}
				_charges.Add(new ChargeState
				{
					AvatarViewId = num,
					Avatar = val,
					Go = val3,
					StartTime = Time.time
				});
			}
		}

		internal void ReceiveFire(object[] data)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			if (data == null || data.Length < 4)
			{
				return;
			}
			int num = Convert.ToInt32(data[0]);
			float num2 = Convert.ToSingle(data[1]);
			Vector3 position = (Vector3)data[2];
			Vector3 dir = (Vector3)data[3];
			if (((Vector3)(ref dir)).sqrMagnitude < 0.001f)
			{
				dir = Vector3.forward;
			}
			((Vector3)(ref dir)).Normalize();
			RemoveCharge(num);
			if (!((Object)(object)DekuMaskAssets.BubblePrefab == (Object)null))
			{
				GameObject val = Object.Instantiate<GameObject>(DekuMaskAssets.BubblePrefab);
				((Object)val).name = "Empress Deku Bubble";
				Collider[] componentsInChildren = val.GetComponentsInChildren<Collider>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					Object.Destroy((Object)(object)componentsInChildren[i]);
				}
				float num3 = Mathf.Lerp(0.16f, 0.5f, num2);
				val.transform.position = position;
				val.transform.localScale = Vector3.one * num3;
				AudioSource val2 = val.AddComponent<AudioSource>();
				val2.spatialBlend = 1f;
				val2.minDistance = 1f;
				val2.maxDistance = 9f;
				val2.rolloffMode = (AudioRolloffMode)1;
				val2.playOnAwake = false;
				AudioClip val3 = DekuMaskAssets.ClipContaining("fire");
				if ((Object)(object)val3 != (Object)null)
				{
					val2.PlayOneShot(val3, EmpressDekuMaskPlugin.Settings.Volume.Value);
				}
				_bubbles.Add(new BubbleState
				{
					AvatarViewId = num,
					Shooter = DekuMaskAccess.AvatarByViewId(num),
					Go = val,
					Dir = dir,
					Size = num3,
					Charge = num2,
					Life = 0f
				});
			}
		}

		internal void ReceivePop(object[] data)
		{
			//IL_0016: 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_009d: 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_0073: Unknown result type (might be due to invalid IL or missing references)
			if (data == null || data.Length < 3)
			{
				return;
			}
			int num = Convert.ToInt32(data[0]);
			Vector3 pos = (Vector3)data[1];
			bool flag = Convert.ToBoolean(data[2]);
			for (int num2 = _bubbles.Count - 1; num2 >= 0; num2--)
			{
				BubbleState bubbleState = _bubbles[num2];
				if (bubbleState.AvatarViewId == num)
				{
					if ((Object)(object)bubbleState.Go != (Object)null)
					{
						Object.Destroy((Object)(object)bubbleState.Go);
					}
					PopSoundAt(pos);
					if (flag)
					{
						SpawnBlast(pos, bubbleState.Charge, bubbleState.Size);
					}
					_bubbles.RemoveAt(num2);
					return;
				}
			}
			PopSoundAt(pos);
		}

		internal void ReceiveCancel(object[] data)
		{
			if (data != null && data.Length >= 1)
			{
				RemoveCharge(Convert.ToInt32(data[0]));
			}
		}

		private void TickCharges()
		{
			//IL_00b0: 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)
			for (int num = _charges.Count - 1; num >= 0; num--)
			{
				ChargeState chargeState = _charges[num];
				if ((Object)(object)chargeState.Go == (Object)null || (Object)(object)chargeState.Avatar == (Object)null || DekuMaskAccess.IsDisabled(chargeState.Avatar))
				{
					if ((Object)(object)chargeState.Go != (Object)null)
					{
						Object.Destroy((Object)(object)chargeState.Go);
					}
					_charges.RemoveAt(num);
				}
				else
				{
					float num2 = Mathf.Clamp01((Time.time - chargeState.StartTime) / 1.2f);
					float num3 = 1f + Mathf.Sin(Time.time * 9f) * 0.04f;
					chargeState.Go.transform.localScale = Vector3.one * (Mathf.Lerp(0.16f, 0.5f, num2) * num3);
				}
			}
		}

		private void TickBubbles()
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: 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_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			int num = LocalViewId();
			RaycastHit val2 = default(RaycastHit);
			for (int num2 = _bubbles.Count - 1; num2 >= 0; num2--)
			{
				BubbleState bubbleState = _bubbles[num2];
				if ((Object)(object)bubbleState.Go == (Object)null)
				{
					_bubbles.RemoveAt(num2);
					continue;
				}
				bubbleState.Life += Time.deltaTime;
				Vector3 position = bubbleState.Go.transform.position;
				Vector3 val = bubbleState.Dir * (7.5f * Time.deltaTime);
				bool flag = bubbleState.AvatarViewId == num;
				if (flag && ((Vector3)(ref val)).sqrMagnitude > 0f)
				{
					float num3 = bubbleState.Size * 0.45f;
					if (Physics.SphereCast(position, num3, bubbleState.Dir, ref val2, ((Vector3)(ref val)).magnitude, -5, (QueryTriggerInteraction)1))
					{
						PlayerAvatar componentInParent = ((Component)((RaycastHit)(ref val2)).collider).GetComponentInParent<PlayerAvatar>();
						if ((Object)(object)componentInParent == (Object)null || (Object)(object)componentInParent != (Object)(object)bubbleState.Shooter)
						{
							Send(192, new object[3]
							{
								bubbleState.AvatarViewId,
								((RaycastHit)(ref val2)).point + ((RaycastHit)(ref val2)).normal * 0.05f,
								true
							});
							continue;
						}
					}
				}
				bubbleState.Go.transform.position = position + val;
				float num4 = 1f + Mathf.Sin(bubbleState.Life * 11f) * 0.05f;
				float num5 = 1f + Mathf.Cos(bubbleState.Life * 13f) * 0.04f;
				bubbleState.Go.transform.localScale = new Vector3(bubbleState.Size * num4, bubbleState.Size * num5, bubbleState.Size * num4);
				if (flag && bubbleState.Life >= 3.5f)
				{
					Send(192, new object[3]
					{
						bubbleState.AvatarViewId,
						bubbleState.Go.transform.position,
						false
					});
				}
				else if (!flag && bubbleState.Life >= 4.5f)
				{
					Object.Destroy((Object)(object)bubbleState.Go);
					_bubbles.RemoveAt(num2);
				}
			}
		}

		private void PopSoundAt(Vector3 pos)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: 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_007f: Expected O, but got Unknown
			AudioClip val = DekuMaskAssets.ClipContaining("pop");
			if (!((Object)(object)val == (Object)null))
			{
				GameObject val2 = new GameObject("Empress Deku Bubble Pop");
				val2.transform.position = pos;
				AudioSource obj = val2.AddComponent<AudioSource>();
				obj.spatialBlend = 1f;
				obj.minDistance = 1f;
				obj.maxDistance = 12f;
				obj.rolloffMode = (AudioRolloffMode)1;
				obj.playOnAwake = false;
				obj.PlayOneShot(val, EmpressDekuMaskPlugin.Settings.Volume.Value);
				Object.Destroy((Object)val2, 2.5f);
			}
		}

		private void SpawnBlast(Vector3 pos, float charge, float size)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: 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_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Expected O, but got Unknown
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Expected O, but got Unknown
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Expected O, but got Unknown
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Expected O, but got Unknown
			//IL_015c: Expected O, but got Unknown
			int num = ((charge >= 0.95f) ? 25 : ((charge >= 0.42f) ? 11 : 3));
			float num2 = Mathf.Lerp(4f, 14f, charge);
			GameObject val = new GameObject("Empress Deku Bubble Blast");
			val.transform.position = pos;
			SphereCollider obj = val.AddComponent<SphereCollider>();
			((Collider)obj).isTrigger = true;
			obj.radius = size * 0.75f + 0.2f;
			HurtCollider obj2 = val.AddComponent<HurtCollider>();
			obj2.playerLogic = true;
			obj2.playerKill = false;
			obj2.playerDamage = num;
			obj2.playerDamageCooldown = 1f;
			obj2.playerHitForce = num2;
			obj2.playerTumbleForce = num2;
			obj2.playerTumbleTorque = num2 * 0.6f;
			obj2.playerTumbleTime = Mathf.Lerp(1f, 2.6f, charge);
			obj2.playerTumbleTorqueAxis = (TorqueAxis)1;
			obj2.enemyLogic = true;
			obj2.enemyKill = false;
			obj2.enemyStun = charge >= 0.42f;
			obj2.enemyStunType = (EnemyType)4;
			obj2.enemyStunTime = Mathf.Lerp(1f, 2.5f, charge);
			obj2.enemyDamage = num;
			obj2.enemyDamageCooldown = 1f;
			obj2.enemyHitForce = num2;
			obj2.enemyHitTorque = num2 * 0.6f;
			obj2.physLogic = false;
			obj2.onImpactAny = new UnityEvent();
			obj2.onImpactPlayer = new UnityEvent();
			obj2.onImpactEnemy = new UnityEvent();
			obj2.onImpactPhysObject = new UnityEvent();
			Object.Destroy((Object)val, 0.35f);
		}

		private void OnDestroy()
		{
			for (int i = 0; i < _charges.Count; i++)
			{
				if ((Object)(object)_charges[i].Go != (Object)null)
				{
					Object.Destroy((Object)(object)_charges[i].Go);
				}
			}
			_charges.Clear();
			for (int j = 0; j < _bubbles.Count; j++)
			{
				if ((Object)(object)_bubbles[j].Go != (Object)null)
				{
					Object.Destroy((Object)(object)_bubbles[j].Go);
				}
			}
			_bubbles.Clear();
		}
	}
	internal static class DekuMaskAccess
	{
		private static readonly FieldInfo ItemLocalizedNameField = AccessTools.Field(typeof(Item), "itemNameLocalized");

		private static readonly FieldRef<ItemAttributes, string> ItemNameRef = AccessTools.FieldRefAccess<ItemAttributes, string>("itemName");

		private static readonly FieldRef<ItemAttributes, string> InstanceNameRef = AccessTools.FieldRefAccess<ItemAttributes, string>("instanceName");

		private static readonly FieldRef<PlayerController, float> InputDisableTimerRef = AccessTools.FieldRefAccess<PlayerController, float>("InputDisableTimer");

		private static readonly FieldRef<PhysGrabObject, bool> HeldByLocalRef = AccessTools.FieldRefAccess<PhysGrabObject, bool>("heldByLocalPlayer");

		private static readonly FieldRef<PlayerAvatar, bool> IsDisabledRef = AccessTools.FieldRefAccess<PlayerAvatar, bool>("isDisabled");

		private static readonly FieldRef<PlayerAvatar, PlayerAvatarVisuals> AvatarVisualsRef = AccessTools.FieldRefAccess<PlayerAvatar, PlayerAvatarVisuals>("playerAvatarVisuals");

		private static readonly FieldRef<PlayerAvatar, bool> IsMovingRef = AccessTools.FieldRefAccess<PlayerAvatar, bool>("isMoving");

		private static readonly FieldRef<RunManager, bool> LevelIsShopRef = AccessTools.FieldRefAccess<RunManager, bool>("levelIsShop");

		private static readonly FieldRef<PhysGrabber, bool> GrabbedRef = AccessTools.FieldRefAccess<PhysGrabber, bool>("grabbed");

		internal static bool InputAllowed()
		{
			if ((Object)(object)PlayerController.instance != (Object)null)
			{
				return InputDisableTimerRef.Invoke(PlayerController.instance) <= 0f;
			}
			return false;
		}

		internal static bool InShop()
		{
			if (!SemiFunc.RunIsShop() && !SemiFunc.RunIsLobby())
			{
				if ((Object)(object)RunManager.instance != (Object)null)
				{
					return LevelIsShopRef.Invoke(RunManager.instance);
				}
				return false;
			}
			return true;
		}

		internal static bool HeldByLocal(PhysGrabObject grab)
		{
			if ((Object)(object)grab != (Object)null)
			{
				return HeldByLocalRef.Invoke(grab);
			}
			return false;
		}

		internal static bool IsDisabled(PlayerAvatar avatar)
		{
			if ((Object)(object)avatar != (Object)null)
			{
				return IsDisabledRef.Invoke(avatar);
			}
			return false;
		}

		internal static bool IsMoving(PlayerAvatar avatar)
		{
			if ((Object)(object)avatar != (Object)null)
			{
				return IsMovingRef.Invoke(avatar);
			}
			return false;
		}

		internal static bool IsGrabbing(PlayerAvatar avatar)
		{
			if ((Object)(object)avatar != (Object)null && (Object)(object)avatar.physGrabber != (Object)null)
			{
				return GrabbedRef.Invoke(avatar.physGrabber);
			}
			return false;
		}

		internal static PlayerAvatarVisuals Visuals(PlayerAvatar avatar)
		{
			if (!((Object)(object)avatar != (Object)null))
			{
				return null;
			}
			return AvatarVisualsRef.Invoke(avatar);
		}

		internal static PlayerAvatar LocalAvatar()
		{
			if (!((Object)(object)PlayerController.instance != (Object)null))
			{
				return null;
			}
			return PlayerController.instance.playerAvatarScript;
		}

		internal static List<PlayerAvatar> Players()
		{
			if (!((Object)(object)GameDirector.instance != (Object)null) || GameDirector.instance.PlayerList == null)
			{
				return new List<PlayerAvatar>();
			}
			return GameDirector.instance.PlayerList;
		}

		internal static PlayerAvatar AvatarByViewId(int viewId)
		{
			List<PlayerAvatar> list = Players();
			for (int i = 0; i < list.Count; i++)
			{
				if ((Object)(object)list[i] != (Object)null && (Object)(object)list[i].photonView != (Object)null && list[i].photonView.ViewID == viewId)
				{
					return list[i];
				}
			}
			return null;
		}

		internal static void SetItemName(ItemAttributes attributes, string name)
		{
			if (!((Object)(object)attributes == (Object)null))
			{
				ItemNameRef.Invoke(attributes) = name;
				InstanceNameRef.Invoke(attributes) = name;
			}
		}

		internal static string InstanceName(ItemAttributes attributes)
		{
			if (!((Object)(object)attributes != (Object)null))
			{
				return null;
			}
			return InstanceNameRef.Invoke(attributes);
		}

		internal static void ClearLocalizedName(Item item)
		{
			if ((Object)(object)item != (Object)null)
			{
				ItemLocalizedNameField?.SetValue(item, null);
			}
		}
	}
	internal static class DekuMaskAssets
	{
		private const string BundleFile = "empressdekumask.empress";

		private static AssetBundle _bundle;

		private static bool _loaded;

		private static readonly Dictionary<string, AudioClip> Clips = new Dictionary<string, AudioClip>(StringComparer.OrdinalIgnoreCase);

		internal static GameObject MaskPrefab { get; private set; }

		internal static GameObject BodyPrefab { get; private set; }

		internal static GameObject FxPrefab { get; private set; }

		internal static GameObject BubblePrefab { get; private set; }

		internal static AudioClip Clip(string name)
		{
			Clips.TryGetValue(name, out var value);
			return value;
		}

		internal static AudioClip ClipContaining(string token)
		{
			AudioClip val = Clip(token);
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			foreach (KeyValuePair<string, AudioClip> clip in Clips)
			{
				if (clip.Key.IndexOf(token, StringComparison.OrdinalIgnoreCase) >= 0)
				{
					return clip.Value;
				}
			}
			return null;
		}

		internal static AudioClip TransformClip()
		{
			AudioClip val = ClipContaining("transform");
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			foreach (KeyValuePair<string, AudioClip> clip in Clips)
			{
				string text = clip.Key.ToLowerInvariant();
				if (!text.Contains("blow") && !text.Contains("fire") && !text.Contains("pop"))
				{
					return clip.Value;
				}
			}
			return null;
		}

		internal static void Load()
		{
			if (_loaded)
			{
				return;
			}
			_loaded = true;
			string text = Path.Combine(EmpressDekuMaskPlugin.PluginDirectory ?? string.Empty, "bundles", "empressdekumask.empress");
			if (File.Exists(text))
			{
				_bundle = AssetBundle.LoadFromFile(text);
				if ((Object)(object)_bundle != (Object)null)
				{
					MaskPrefab = _bundle.LoadAsset<GameObject>("EmpressDekuMask");
					BodyPrefab = _bundle.LoadAsset<GameObject>("EmpressDekuBody");
					FxPrefab = _bundle.LoadAsset<GameObject>("EmpressDekuFX");
					BubblePrefab = _bundle.LoadAsset<GameObject>("EmpressDekuBubble");
				}
			}
			else
			{
				ManualLogSource log = EmpressDekuMaskPlugin.Log;
				if (log != null)
				{
					log.LogError((object)("Empress Deku Mask bundle missing: " + text));
				}
			}
			ManualLogSource log2 = EmpressDekuMaskPlugin.Log;
			if (log2 != null)
			{
				log2.LogInfo((object)("Empress Deku Mask assets loaded. Mask: " + (((Object)(object)MaskPrefab != (Object)null) ? "OK" : "MISSING") + " Body: " + (((Object)(object)BodyPrefab != (Object)null) ? "OK" : "MISSING")));
			}
		}

		internal static IEnumerator LoadAudio()
		{
			string path = Path.Combine(EmpressDekuMaskPlugin.PluginDirectory ?? string.Empty, "audio");
			if (!Directory.Exists(path))
			{
				yield break;
			}
			string[] files = Directory.GetFiles(path, "*.ogg");
			foreach (string text in files)
			{
				string key = Path.GetFileNameWithoutExtension(text);
				UnityWebRequest request = UnityWebRequestMultimedia.GetAudioClip("file://" + text, (AudioType)14);
				try
				{
					yield return request.SendWebRequest();
					if ((int)request.result == 1)
					{
						AudioClip content = DownloadHandlerAudioClip.GetContent(request);
						if ((Object)(object)content != (Object)null)
						{
							((Object)content).name = key;
							Clips[key] = content;
						}
					}
				}
				finally
				{
					((IDisposable)request)?.Dispose();
				}
			}
			ManualLogSource log = EmpressDekuMaskPlugin.Log;
			if (log != null)
			{
				log.LogInfo((object)("Empress Deku Mask audio loaded: " + Clips.Count + " clips."));
			}
		}
	}
	internal sealed class DekuMaskItem : MonoBehaviour
	{
		private PhysGrabObject _grab;

		private PhotonView _view;

		private bool _used;

		private void Awake()
		{
			_grab = ((Component)this).GetComponent<PhysGrabObject>();
			_view = ((Component)this).GetComponent<PhotonView>();
		}

		private void Update()
		{
			if (_used || (Object)(object)_grab == (Object)null || DekuMaskAccess.InShop() || !DekuMaskAccess.HeldByLocal(_grab) || !DekuMaskAccess.InputAllowed() || !SemiFunc.InputDown((InputKey)2))
			{
				return;
			}
			PlayerAvatar val = DekuMaskAccess.LocalAvatar();
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val.photonView == (Object)null))
			{
				_used = true;
				int viewID = val.photonView.ViewID;
				int num = (((Object)(object)_view != (Object)null) ? _view.ViewID : (-1));
				EmpressDekuMaskPlugin.EnsurePhotonHooked();
				EmpressDekuMaskPlugin.RaiseToAll(189, new object[2] { viewID, num });
				Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<Renderer>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					componentsInChildren[i].enabled = false;
				}
			}
		}
	}
	internal static class DekuMaskItemBuilder
	{
		private static readonly string[] TemplatePaths = new string[4] { "Items/Item Grenade Human", "Items/Item Grenade Explosive", "Items/Item Grenade Stun", "Items/Item Grenade Duct Taped" };

		private static GameObject _prefab;

		private static Item _item;

		private static bool _registered;

		internal static void RegisterItem()
		{
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Expected O, but got Unknown
			//IL_026a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: 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)
			if (_registered)
			{
				return;
			}
			GameObject val = null;
			for (int i = 0; i < TemplatePaths.Length; i++)
			{
				val = Resources.Load<GameObject>(TemplatePaths[i]);
				if ((Object)(object)val != (Object)null)
				{
					break;
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				EmpressDekuMaskPlugin.Log.LogError((object)"Empress Deku Mask could not find a template item.");
				return;
			}
			ItemAttributes component = val.GetComponent<ItemAttributes>();
			if ((Object)(object)component == (Object)null || (Object)(object)component.item == (Object)null)
			{
				EmpressDekuMaskPlugin.Log.LogError((object)"Empress Deku Mask template has no ItemAttributes.");
				return;
			}
			GameObject val2 = new GameObject("Empress Deku Mask Prefabs");
			Object.DontDestroyOnLoad((Object)(object)val2);
			((Object)val2).hideFlags = (HideFlags)61;
			val2.SetActive(false);
			_prefab = Object.Instantiate<GameObject>(val, val2.transform);
			((Object)_prefab).name = "Empress Deku Mask";
			MonoBehaviour[] componentsInChildren = _prefab.GetComponentsInChildren<MonoBehaviour>(true);
			foreach (MonoBehaviour val3 in componentsInChildren)
			{
				if (!((Object)(object)val3 == (Object)null))
				{
					string name = ((object)val3).GetType().Name;
					if (name.StartsWith("ItemGrenade") || name == "ItemToggle" || name == "ItemBattery")
					{
						Object.DestroyImmediate((Object)(object)val3);
					}
				}
			}
			Renderer[] componentsInChildren2 = _prefab.GetComponentsInChildren<Renderer>(true);
			for (int j = 0; j < componentsInChildren2.Length; j++)
			{
				componentsInChildren2[j].enabled = false;
			}
			if ((Object)(object)DekuMaskAssets.MaskPrefab != (Object)null)
			{
				GameObject val4 = Object.Instantiate<GameObject>(DekuMaskAssets.MaskPrefab, _prefab.transform, false);
				((Object)val4).name = "Empress Deku Mask Visual";
				val4.transform.localPosition = new Vector3(0f, 0.05f, 0f);
				val4.transform.localRotation = Quaternion.identity;
				Collider[] componentsInChildren3 = val4.GetComponentsInChildren<Collider>(true);
				for (int j = 0; j < componentsInChildren3.Length; j++)
				{
					Object.DestroyImmediate((Object)(object)componentsInChildren3[j]);
				}
				ScaleToSize(val4, 0.68f);
				componentsInChildren2 = val4.GetComponentsInChildren<Renderer>(true);
				for (int j = 0; j < componentsInChildren2.Length; j++)
				{
					componentsInChildren2[j].enabled = true;
				}
				ReplaceColliders(val4);
			}
			_prefab.AddComponent<DekuMaskItem>();
			Item item = component.item;
			_item = Object.Instantiate<Item>(item);
			((Object)_item).name = "Empress Deku Mask";
			_item.itemName = "Empress Deku Mask";
			DekuMaskAccess.ClearLocalizedName(_item);
			_item.itemSecretShopType = (itemSecretShopType)0;
			_item.maxAmount = 4;
			_item.maxAmountInShop = 2;
			_item.maxPurchase = false;
			_item.maxPurchaseAmount = 4;
			float value = (float)EmpressDekuMaskPlugin.Settings.ShopPrice.Value * 250f;
			Value val5 = (((Object)(object)item.value != (Object)null) ? Object.Instantiate<Value>(item.value) : ScriptableObject.CreateInstance<Value>());
			SetFloatFieldContaining(val5, "min", value);
			SetFloatFieldContaining(val5, "max", value);
			_item.value = val5;
			ItemAttributes component2 = _prefab.GetComponent<ItemAttributes>();
			component2.item = _item;
			DekuMaskAccess.SetItemName(component2, "Empress Deku Mask");
			_registered = Items.RegisterItem(component2) != null;
			EmpressDekuMaskPlugin.Log.LogInfo((object)("Empress Deku Mask item registered: " + _registered));
		}

		private static void ReplaceColliders(GameObject visual)
		{
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: 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_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			List<Collider> list = new List<Collider>();
			Collider[] componentsInChildren = _prefab.GetComponentsInChildren<Collider>(true);
			foreach (Collider val in componentsInChildren)
			{
				if ((Object)(object)val != (Object)null && ((Object)(object)visual == (Object)null || !((Component)val).transform.IsChildOf(visual.transform)))
				{
					list.Add(val);
				}
			}
			if (list.Count == 0)
			{
				return;
			}
			GameObject gameObject = ((Component)list[0]).gameObject;
			PhysicMaterial sharedMaterial = list[0].sharedMaterial;
			for (int num = list.Count - 1; num >= 0; num--)
			{
				if (!((Object)(object)list[num] == (Object)null))
				{
					if ((Object)(object)((Component)list[num]).gameObject == (Object)(object)gameObject)
					{
						Object.DestroyImmediate((Object)(object)list[num]);
					}
					else
					{
						Object.DestroyImmediate((Object)(object)((Component)list[num]).gameObject);
					}
				}
			}
			Bounds val2 = BoundsInSpace(gameObject.transform, visual);
			BoxCollider obj = gameObject.AddComponent<BoxCollider>();
			obj.center = ((Bounds)(ref val2)).center;
			obj.size = Vector3.Max(((Bounds)(ref val2)).size, new Vector3(0.08f, 0.05f, 0.08f));
			((Collider)obj).sharedMaterial = sharedMaterial;
		}

		internal static Bounds BoundsInSpace(Transform space, GameObject target)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: 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_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			Bounds result = default(Bounds);
			((Bounds)(ref result))..ctor(Vector3.zero, Vector3.zero);
			bool flag = false;
			MeshFilter[] componentsInChildren = target.GetComponentsInChildren<MeshFilter>(true);
			foreach (MeshFilter val in componentsInChildren)
			{
				if ((Object)(object)val == (Object)null || (Object)(object)val.sharedMesh == (Object)null)
				{
					continue;
				}
				Bounds bounds = val.sharedMesh.bounds;
				Matrix4x4 val2 = space.worldToLocalMatrix * ((Component)val).transform.localToWorldMatrix;
				for (int j = 0; j < 8; j++)
				{
					Vector3 val3 = ((Bounds)(ref bounds)).center + Vector3.Scale(((Bounds)(ref bounds)).extents, new Vector3(((j & 1) == 0) ? (-1f) : 1f, ((j & 2) == 0) ? (-1f) : 1f, ((j & 4) == 0) ? (-1f) : 1f));
					Vector3 val4 = ((Matrix4x4)(ref val2)).MultiplyPoint3x4(val3);
					if (!flag)
					{
						((Bounds)(ref result))..ctor(val4, Vector3.zero);
						flag = true;
					}
					else
					{
						((Bounds)(ref result)).Encapsulate(val4);
					}
				}
			}
			return result;
		}

		internal static void ScaleToSize(GameObject target, float maxDimension)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: 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_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			Bounds val = BoundsInSpace(target.transform, target);
			float num = Mathf.Max(((Bounds)(ref val)).size.x, Mathf.Max(((Bounds)(ref val)).size.y, ((Bounds)(ref val)).size.z));
			if (!(num <= 0.0001f))
			{
				target.transform.localScale = target.transform.localScale * (maxDimension / num);
			}
		}

		private static void SetFloatFieldContaining(object target, string token, float value)
		{
			if (target == null)
			{
				return;
			}
			FieldInfo[] fields = target.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (FieldInfo fieldInfo in fields)
			{
				if (fieldInfo.FieldType == typeof(float) && fieldInfo.Name.ToLowerInvariant().Contains(token))
				{
					fieldInfo.SetValue(target, value);
				}
			}
		}
	}
	internal sealed class DekuMaskRuntime : MonoBehaviour
	{
		private sealed class Sequence
		{
			internal PlayerAvatar Avatar;

			internal GameObject MaskEffect;

			internal Transform MaskModel;

			internal Light Flash;

			internal AudioSource Audio;

			internal float StartTime;

			internal float EffectLife;

			internal bool Transformed;

			internal bool CameraCaptured;

			internal Vector3 CameraStartPosition;

			internal Vector3 CameraStartAim;
		}

		private sealed class DekuState
		{
			internal PlayerAvatar Avatar;

			internal GameObject Body;

			internal Renderer[] BodyRenderers;

			internal Renderer[] VanillaExtras;

			internal LevelGenerator Level;
		}

		private const float GlideTime = 0.9f;

		private const float FlyInTime = 1.1f;

		private const float AimDropTime = 0.5f;

		private const float ArcStartTime = 1.6f;

		private const float CutsceneTime = 2.6f;

		private const float FaceCamDistance = 2.2f;

		private readonly List<Sequence> _sequences = new List<Sequence>();

		private readonly List<DekuState> _transformed = new List<DekuState>();

		private bool _cameraOverridden;

		public static DekuMaskRuntime Instance { get; private set; }

		public static DekuMaskRuntime EnsureHost()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Instance != (Object)null)
			{
				return Instance;
			}
			GameObject val = new GameObject("Empress Deku Mask Runtime");
			val.transform.parent = null;
			((Object)val).hideFlags = (HideFlags)61;
			Object.DontDestroyOnLoad((Object)val);
			Instance = val.AddComponent<DekuMaskRuntime>();
			val.AddComponent<DekuBubbles>();
			return Instance;
		}

		internal bool IsTransformed(PlayerAvatar avatar)
		{
			if ((Object)(object)avatar != (Object)null)
			{
				return StateFor(avatar) != null;
			}
			return false;
		}

		private void Awake()
		{
			Instance = this;
			((MonoBehaviour)this).StartCoroutine(DekuMaskAssets.LoadAudio());
		}

		private void Update()
		{
			EmpressDekuMaskPlugin.EnsurePhotonHooked();
			TickSequences();
			TickTransformed();
		}

		private void LateUpdate()
		{
			TickLocalCamera();
			TickTransformedVisuals();
		}

		internal void ReceiveDekuUse(object[] data)
		{
			if (data == null || data.Length < 2)
			{
				return;
			}
			int viewId = Convert.ToInt32(data[0]);
			int num = Convert.ToInt32(data[1]);
			if (SemiFunc.IsMasterClientOrSingleplayer() && num > 0)
			{
				PhotonView val = PhotonView.Find(num);
				if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).gameObject != (Object)null)
				{
					string text = DekuMaskAccess.InstanceName(((Component)val).gameObject.GetComponent<ItemAttributes>());
					if ((Object)(object)StatsManager.instance != (Object)null && !string.IsNullOrEmpty(text))
					{
						StatsManager.instance.ItemRemove(text);
					}
					if (PhotonNetwork.InRoom)
					{
						PhotonNetwork.Destroy(((Component)val).gameObject);
					}
					else
					{
						Object.Destroy((Object)(object)((Component)val).gameObject);
					}
				}
			}
			PlayerAvatar val2 = DekuMaskAccess.AvatarByViewId(viewId);
			if (!((Object)(object)val2 == (Object)null) && !IsBusy(val2))
			{
				_sequences.Add(BuildSequence(val2));
			}
		}

		private bool IsBusy(PlayerAvatar avatar)
		{
			for (int i = 0; i < _sequences.Count; i++)
			{
				if ((Object)(object)_sequences[i].Avatar == (Object)(object)avatar)
				{
					return true;
				}
			}
			for (int j = 0; j < _transformed.Count; j++)
			{
				if ((Object)(object)_transformed[j].Avatar == (Object)(object)avatar)
				{
					return true;
				}
			}
			return false;
		}

		private Sequence SequenceFor(PlayerAvatar avatar)
		{
			for (int i = 0; i < _sequences.Count; i++)
			{
				if ((Object)(object)_sequences[i].Avatar == (Object)(object)avatar)
				{
					return _sequences[i];
				}
			}
			return null;
		}

		private DekuState StateFor(PlayerAvatar avatar)
		{
			for (int i = 0; i < _transformed.Count; i++)
			{
				if ((Object)(object)_transformed[i].Avatar == (Object)(object)avatar)
				{
					return _transformed[i];
				}
			}
			return null;
		}

		private Vector3 HeadPosition(PlayerAvatar avatar)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: 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)
			PlayerAvatarVisuals val = DekuMaskAccess.Visuals(avatar);
			if ((Object)(object)val != (Object)null && (Object)(object)val.headLookAtTransform != (Object)null)
			{
				return val.headLookAtTransform.position;
			}
			return ((Component)avatar).transform.position + Vector3.up * 1.2f;
		}

		private Vector3 DekuFocus(PlayerAvatar avatar)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: 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)
			return ((Component)avatar).transform.position + Vector3.up * (EmpressDekuMaskPlugin.Settings.DekuHeight.Value * 0.85f);
		}

		private static Vector3 FlatForward(PlayerAvatar avatar)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: 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)
			Vector3 forward = ((Component)avatar).transform.forward;
			forward.y = 0f;
			if (!(((Vector3)(ref forward)).sqrMagnitude < 0.001f))
			{
				return ((Vector3)(ref forward)).normalized;
			}
			return Vector3.forward;
		}

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

		private Sequence BuildSequence(PlayerAvatar avatar)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Empress Deku Transform");
			Vector3 position = HeadPosition(avatar);
			val.transform.position = position;
			Transform maskModel = null;
			if ((Object)(object)DekuMaskAssets.MaskPrefab != (Object)null)
			{
				GameObject val2 = Object.Instantiate<GameObject>(DekuMaskAssets.MaskPrefab, val.transform, false);
				((Object)val2).name = "Mask";
				Collider[] componentsInChildren = val2.GetComponentsInChildren<Collider>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					Object.Destroy((Object)(object)componentsInChildren[i]);
				}
				DekuMaskItemBuilder.ScaleToSize(val2, 0.42f);
				maskModel = val2.transform;
			}
			Light val3 = val.AddComponent<Light>();
			val3.type = (LightType)2;
			val3.color = new Color(1f, 0.85f, 0.45f);
			val3.range = 6f;
			val3.intensity = 0f;
			val3.shadows = (LightShadows)0;
			float value = EmpressDekuMaskPlugin.Settings.HearingRange.Value;
			AudioSource val4 = val.AddComponent<AudioSource>();
			val4.spatialBlend = 1f;
			val4.minDistance = Mathf.Min(2f, value * 0.15f);
			val4.maxDistance = value;
			val4.rolloffMode = (AudioRolloffMode)1;
			val4.playOnAwake = false;
			AudioClip val5 = DekuMaskAssets.TransformClip();
			if ((Object)(object)val5 != (Object)null)
			{
				val4.clip = val5;
				val4.volume = EmpressDekuMaskPlugin.Settings.Volume.Value;
				val4.Play();
			}
			float num = (((Object)(object)val5 != (Object)null) ? Mathf.Max(3.3999999f, val5.length + 0.3f) : 3.3999999f);
			PlayerAvatarVisuals val6 = DekuMaskAccess.Visuals(avatar);
			if ((Object)(object)DekuMaskAssets.FxPrefab != (Object)null && (Object)(object)val6 != (Object)null)
			{
				GameObject obj = Object.Instantiate<GameObject>(DekuMaskAssets.FxPrefab, ((Component)val6).transform, false);
				((Object)obj).name = "Empress Deku Code";
				obj.transform.localPosition = new Vector3(0f, 0.6f, 0f);
				obj.AddComponent<DekuTimedEffect>().Life = num;
			}
			return new Sequence
			{
				Avatar = avatar,
				MaskEffect = val,
				MaskModel = maskModel,
				Flash = val3,
				Audio = val4,
				StartTime = Time.time,
				EffectLife = num
			};
		}

		private void TickSequences()
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: 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_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: 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_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: 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_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			for (int num = _sequences.Count - 1; num >= 0; num--)
			{
				Sequence sequence = _sequences[num];
				PlayerAvatar avatar = sequence.Avatar;
				if ((Object)(object)avatar == (Object)null || DekuMaskAccess.IsDisabled(avatar))
				{
					AbortSequence(sequence);
					_sequences.RemoveAt(num);
				}
				else
				{
					float num2 = Time.time - sequence.StartTime;
					Vector3 val = HeadPosition(avatar);
					Vector3 forward = ((Component)avatar).transform.forward;
					if ((Object)(object)sequence.MaskEffect != (Object)null)
					{
						float num3 = Mathf.Clamp01(num2 / 1.1f);
						float num4 = num3 * num3 * (3f - 2f * num3);
						Vector3 val2 = val + forward * 0.8f;
						Vector3 val3 = val + forward * 0.06f;
						sequence.MaskEffect.transform.position = Vector3.Lerp(val2, val3, num4);
						if ((Object)(object)sequence.MaskModel != (Object)null)
						{
							sequence.MaskModel.rotation = Quaternion.LookRotation(forward, Vector3.up);
						}
					}
					if (!sequence.Transformed && num2 >= 1.1f)
					{
						sequence.Transformed = true;
						ApplyTransform(sequence, avatar);
					}
					if (sequence.Transformed && (Object)(object)sequence.Flash != (Object)null)
					{
						float num5 = num2 - 1.1f;
						sequence.Flash.intensity = ((num5 < 0.12f) ? Mathf.Lerp(0f, 8f, num5 / 0.12f) : Mathf.Lerp(8f, 0f, Mathf.Clamp01((num5 - 0.12f) / 0.9f)));
					}
					if ((Object)(object)avatar == (Object)(object)DekuMaskAccess.LocalAvatar() && (Object)(object)PlayerController.instance != (Object)null && num2 < 2.6f)
					{
						PlayerController.instance.InputDisable(0.3f);
					}
					if (num2 >= 2.6f)
					{
						if ((Object)(object)avatar == (Object)(object)DekuMaskAccess.LocalAvatar())
						{
							SemiFunc.CameraOverrideStopAim();
						}
						if ((Object)(object)sequence.MaskEffect != (Object)null)
						{
							Object.Destroy((Object)(object)sequence.MaskEffect, Mathf.Max(1.2f, sequence.EffectLife - 2.6f + 0.2f));
						}
						_sequences.RemoveAt(num);
					}
				}
			}
		}

		private void TickLocalCamera()
		{
			PlayerAvatar val = DekuMaskAccess.LocalAvatar();
			CameraPosition instance = CameraPosition.instance;
			CameraAim instance2 = CameraAim.Instance;
			if ((Object)(object)val == (Object)null || (Object)(object)instance == (Object)null || (Object)(object)instance2 == (Object)null)
			{
				return;
			}
			Sequence sequence = SequenceFor(val);
			if (sequence != null && !DekuMaskAccess.IsDisabled(val) && Time.time - sequence.StartTime < 2.6f)
			{
				CutsceneCamera(sequence, val, instance, instance2);
				return;
			}
			DekuState dekuState = StateFor(val);
			if (dekuState != null)
			{
				bool value = EmpressDekuMaskPlugin.Settings.ThirdPerson.Value;
				SetBodyVisible(dekuState, value);
				if (value)
				{
					ThirdPersonCamera(val, instance, instance2);
					return;
				}
			}
			ReleaseCamera(instance);
		}

		private void CutsceneCamera(Sequence sequence, PlayerAvatar avatar, CameraPosition cameraPosition, CameraAim cameraAim)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: 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_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_0016: 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_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: 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_0118: 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_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_016a: 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_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: 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_0184: 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_014d: 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_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_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			if (!sequence.CameraCaptured)
			{
				sequence.CameraCaptured = true;
				sequence.CameraStartPosition = ((Component)cameraPosition).transform.position;
				sequence.CameraStartAim = sequence.CameraStartPosition + ((Component)cameraAim).transform.forward * 3f;
			}
			float num = Time.time - sequence.StartTime;
			Vector3 val = HeadPosition(avatar);
			Vector3 val2 = FlatForward(avatar);
			Vector3 val3 = val + val2 * 2.2f + Vector3.up * 0.15f;
			Vector3 val4 = DekuFocus(avatar);
			Vector3 val6;
			Vector3 val7;
			if (num < 0.9f)
			{
				float num2 = Smooth01(num / 0.9f);
				Vector3 val5 = Vector3.Cross(Vector3.up, val2) * (Mathf.Sin(num2 * MathF.PI) * 0.55f);
				val6 = Vector3.Lerp(sequence.CameraStartPosition, val3, num2) + val5;
				val7 = Vector3.Lerp(sequence.CameraStartAim, val, num2);
			}
			else if (num < 1.6f)
			{
				float num3 = Smooth01((num - 1.1f) / 0.5f);
				val6 = val3;
				val7 = Vector3.Lerp(val, val4, num3);
			}
			else
			{
				float num4 = Smooth01((num - 1.6f) / 0.9999999f);
				if (EmpressDekuMaskPlugin.Settings.ThirdPerson.Value)
				{
					val6 = ArcPosition(val3, val4, val2, num4);
					val7 = val4;
				}
				else
				{
					val6 = Vector3.Lerp(val3, val, num4);
					val7 = Vector3.Lerp(val4, val + val2 * 3f, num4);
				}
			}
			_cameraOverridden = true;
			cameraPosition.OverridePosition(val6, 0.25f);
			cameraAim.AimTargetSet(val7, 0.25f, 8f, ((Component)this).gameObject, 150);
		}

		private Vector3 ArcPosition(Vector3 fromPosition, Vector3 focus, Vector3 forward, float p)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0026: 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_003d: 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_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			DekuMaskSettings settings = EmpressDekuMaskPlugin.Settings;
			Vector3 val = fromPosition - focus;
			Vector3 val2 = default(Vector3);
			((Vector3)(ref val2))..ctor(val.x, 0f, val.z);
			float num = Mathf.Atan2(val2.x, val2.z) * 57.29578f;
			float num2 = Mathf.Atan2(0f - forward.x, 0f - forward.z) * 57.29578f;
			float num3 = Mathf.LerpAngle(num, num2, p) * (MathF.PI / 180f);
			float num4 = Mathf.Lerp(Mathf.Max(((Vector3)(ref val2)).magnitude, 0.5f), settings.ThirdPersonDistance.Value, p);
			float num5 = Mathf.Lerp(val.y, settings.ThirdPersonHeight.Value, p);
			return focus + new Vector3(Mathf.Sin(num3), 0f, Mathf.Cos(num3)) * num4 + Vector3.up * num5;
		}

		private void ThirdPersonCamera(PlayerAvatar avatar, CameraPosition cameraPosition, CameraAim cameraAim)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: 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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			DekuMaskSettings settings = EmpressDekuMaskPlugin.Settings;
			Vector3 val = ((Component)cameraAim).transform.forward;
			val.y = 0f;
			if (((Vector3)(ref val)).sqrMagnitude < 0.001f)
			{
				val = FlatForward(avatar);
			}
			((Vector3)(ref val)).Normalize();
			Vector3 val2 = DekuFocus(avatar) - val * settings.ThirdPersonDistance.Value + Vector3.up * settings.ThirdPersonHeight.Value;
			_cameraOverridden = true;
			cameraPosition.OverridePosition(val2, 0.25f);
		}

		private void ReleaseCamera(CameraPosition cameraPosition)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			if (_cameraOverridden)
			{
				_cameraOverridden = false;
				cameraPosition.OverridePosition(Vector3.zero, 0f);
			}
		}

		private static void SetBodyVisible(DekuState state, bool visible)
		{
			if (state.BodyRenderers == null)
			{
				return;
			}
			for (int i = 0; i < state.BodyRenderers.Length; i++)
			{
				Renderer val = state.BodyRenderers[i];
				if ((Object)(object)val != (Object)null && val.enabled != visible)
				{
					val.enabled = visible;
				}
			}
		}

		private void ApplyTransform(Sequence sequence, PlayerAvatar avatar)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Expected O, but got Unknown
			//IL_00a5: 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_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_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: 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_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			SemiFunc.CameraShakeDistance(((Component)avatar).transform.position, 4f, 0.5f, 1f, 12f);
			if ((Object)(object)sequence.MaskModel != (Object)null)
			{
				((Component)sequence.MaskModel).gameObject.SetActive(false);
			}
			PlayerAvatarVisuals val = DekuMaskAccess.Visuals(avatar);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			if ((Object)(object)val.meshParent != (Object)null)
			{
				val.meshParent.SetActive(false);
			}
			GameObject val2 = null;
			Renderer[] bodyRenderers = null;
			if ((Object)(object)DekuMaskAssets.BodyPrefab != (Object)null)
			{
				val2 = new GameObject("Empress Deku Body");
				val2.transform.SetParent(((Component)val).transform, false);
				val2.transform.localPosition = Vector3.zero;
				val2.transform.localRotation = Quaternion.Euler(0f, EmpressDekuMaskPlugin.Settings.DekuYaw.Value, 0f);
				GameObject val3 = Object.Instantiate<GameObject>(DekuMaskAssets.BodyPrefab, val2.transform, false);
				((Object)val3).name = "Model";
				Collider[] componentsInChildren = val3.GetComponentsInChildren<Collider>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					Object.Destroy((Object)(object)componentsInChildren[i]);
				}
				Bounds val4 = DekuMaskItemBuilder.BoundsInSpace(val2.transform, val3);
				float num = Mathf.Max(((Bounds)(ref val4)).size.y, 0.001f);
				float num2 = EmpressDekuMaskPlugin.Settings.DekuHeight.Value / num;
				val2.transform.localScale = Vector3.one * num2;
				val3.transform.localPosition = new Vector3(0f - ((Bounds)(ref val4)).center.x, 0f - ((Bounds)(ref val4)).min.y, 0f - ((Bounds)(ref val4)).center.z);
				bodyRenderers = val3.GetComponentsInChildren<Renderer>(true);
				val2.AddComponent<DekuWaddle>().Avatar = avatar;
			}
			_transformed.Add(new DekuState
			{
				Avatar = avatar,
				Body = val2,
				BodyRenderers = bodyRenderers,
				VanillaExtras = CollectVanillaExtras(avatar, val),
				Level = LevelGenerator.Instance
			});
		}

		private static Renderer[] CollectVanillaExtras(PlayerAvatar avatar, PlayerAvatarVisuals visuals)
		{
			List<Renderer> list = new List<Renderer>();
			PlayerEyes playerEyes = visuals.playerEyes;
			if ((Object)(object)playerEyes != (Object)null)
			{
				CollectRenderers(playerEyes.eyeLeft, list);
				CollectRenderers(playerEyes.eyeRight, list);
				CollectRenderers(playerEyes.pupilLeft, list);
				CollectRenderers(playerEyes.pupilRight, list);
			}
			FlashlightController flashlightController = avatar.flashlightController;
			if ((Object)(object)flashlightController != (Object)null)
			{
				if ((Object)(object)flashlightController.mesh != (Object)null && !list.Contains((Renderer)(object)flashlightController.mesh))
				{
					list.Add((Renderer)(object)flashlightController.mesh);
				}
				if ((Object)(object)flashlightController.meshShadows != (Object)null && !list.Contains((Renderer)(object)flashlightController.meshShadows))
				{
					list.Add((Renderer)(object)flashlightController.meshShadows);
				}
			}
			return list.ToArray();
		}

		private static void CollectRenderers(Transform root, List<Renderer> extras)
		{
			if ((Object)(object)root == (Object)null)
			{
				return;
			}
			Renderer[] componentsInChildren = ((Component)root).GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				if ((Object)(object)val != (Object)null && !extras.Contains(val))
				{
					extras.Add(val);
				}
			}
		}

		private void TickTransformedVisuals()
		{
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Invalid comparison between Unknown and I4
			for (int i = 0; i < _transformed.Count; i++)
			{
				DekuState dekuState = _transformed[i];
				if (dekuState.VanillaExtras != null)
				{
					for (int j = 0; j < dekuState.VanillaExtras.Length; j++)
					{
						Renderer val = dekuState.VanillaExtras[j];
						if ((Object)(object)val != (Object)null && val.enabled)
						{
							val.enabled = false;
						}
					}
				}
				if (dekuState.BodyRenderers == null)
				{
					continue;
				}
				for (int k = 0; k < dekuState.BodyRenderers.Length; k++)
				{
					Renderer val2 = dekuState.BodyRenderers[k];
					if ((Object)(object)val2 != (Object)null && (int)val2.shadowCastingMode != 1)
					{
						val2.shadowCastingMode = (ShadowCastingMode)1;
					}
				}
			}
		}

		private void AbortSequence(Sequence sequence)
		{
			if ((Object)(object)sequence.MaskEffect != (Object)null)
			{
				Object.Destroy((Object)(object)sequence.MaskEffect);
			}
			if ((Object)(object)sequence.Avatar != (Object)null && (Object)(object)sequence.Avatar == (Object)(object)DekuMaskAccess.LocalAvatar())
			{
				SemiFunc.CameraOverrideStopAim();
			}
		}

		private void TickTransformed()
		{
			for (int num = _transformed.Count - 1; num >= 0; num--)
			{
				DekuState dekuState = _transformed[num];
				if ((Object)(object)dekuState.Avatar == (Object)null || DekuMaskAccess.IsDisabled(dekuState.Avatar) || (Object)(object)LevelGenerator.Instance != (Object)(object)dekuState.Level)
				{
					Restore(dekuState);
					_transformed.RemoveAt(num);
				}
			}
		}

		private void Restore(DekuState state)
		{
			if ((Object)(object)state.Body != (Object)null)
			{
				Object.Destroy((Object)(object)state.Body);
			}
			if (state.VanillaExtras != null)
			{
				for (int i = 0; i < state.VanillaExtras.Length; i++)
				{
					if ((Object)(object)state.VanillaExtras[i] != (Object)null)
					{
						state.VanillaExtras[i].enabled = true;
					}
				}
			}
			if ((Object)(object)state.Avatar != (Object)null)
			{
				PlayerAvatarVisuals val = DekuMaskAccess.Visuals(state.Avatar);
				if ((Object)(object)val != (Object)null && (Object)(object)val.meshParent != (Object)null)
				{
					val.meshParent.SetActive(true);
				}
			}
		}

		private void OnDestroy()
		{
			for (int i = 0; i < _transformed.Count; i++)
			{
				Restore(_transformed[i]);
			}
			_transformed.Clear();
			if ((Object)(object)CameraPosition.instance != (Object)null)
			{
				ReleaseCamera(CameraPosition.instance);
			}
		}
	}
	internal sealed class DekuWaddle : MonoBehaviour
	{
		private const float LegSwing = 34f;

		private const float ArmSwing = 24f;

		private const float ArmFlapMoving = 12f;

		private const float ArmFlapIdle = 3.5f;

		internal PlayerAvatar Avatar;

		private float _phase;

		private float _swing;

		private Transform _legL;

		private Transform _legR;

		private Transform _armL;

		private Transform _armR;

		private bool _pivotsSearched;

		private void FindPivots()
		{
			_pivotsSearched = true;
			Transform[] componentsInChildren = ((Component)this).GetComponentsInChildren<Transform>(true);
			foreach (Transform val in componentsInChildren)
			{
				if (((Object)val).name == "EmpressLegPivotL")
				{
					_legL = val;
				}
				else if (((Object)val).name == "EmpressLegPivotR")
				{
					_legR = val;
				}
				else if (((Object)val).name == "EmpressArmPivotL")
				{
					_armL = val;
				}
				else if (((Object)val).name == "EmpressArmPivotR")
				{
					_armR = val;
				}
			}
		}

		private void Update()
		{
			//IL_00e2: 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_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)Avatar == (Object)null))
			{
				if (!_pivotsSearched)
				{
					FindPivots();
				}
				float num = ((EmpressDekuMaskPlugin.Settings != null) ? EmpressDekuMaskPlugin.Settings.DekuYaw.Value : 0f);
				bool flag = DekuMaskAccess.IsMoving(Avatar);
				_phase += Time.deltaTime * (flag ? 11f : 2.2f);
				_swing = Mathf.MoveTowards(_swing, flag ? 1f : 0f, Time.deltaTime * 5f);
				float num2 = Mathf.Abs(Mathf.Sin(_phase)) * (flag ? 0.07f : 0.015f);
				float num3 = Mathf.Sin(_phase) * (flag ? 6f : 1.2f);
				((Component)this).transform.localPosition = new Vector3(0f, num2, 0f);
				((Component)this).transform.localRotation = Quaternion.Euler(0f, num, num3);
				float num4 = ((EmpressDekuMaskPlugin.Settings != null) ? EmpressDekuMaskPlugin.Settings.ArmDown.Value : 35f);
				float num5 = Mathf.Sin(_phase) * 34f * _swing;
				float num6 = Mathf.Sin(_phase) * 24f * _swing;
				float num7 = Mathf.Sin(_phase) * Mathf.Lerp(3.5f, 12f, _swing);
				if ((Object)(object)_legL != (Object)null)
				{
					_legL.localRotation = Quaternion.Euler(num5, 0f, 0f);
				}
				if ((Object)(object)_legR != (Object)null)
				{
					_legR.localRotation = Quaternion.Euler(0f - num5, 0f, 0f);
				}
				if ((Object)(object)_armL != (Object)null)
				{
					_armL.localRotation = Quaternion.Euler(0f - num6, 0f, num7 - num4);
				}
				if ((Object)(object)_armR != (Object)null)
				{
					_armR.localRotation = Quaternion.Euler(num6, 0f, num4 - num7);
				}
			}
		}
	}
	internal sealed class DekuTimedEffect : MonoBehaviour
	{
		internal float Life;

		private bool _stopped;

		private void Update()
		{
			Life -= Time.deltaTime;
			if (!(Life > 0f) && !_stopped)
			{
				_stopped = true;
				ParticleSystem[] componentsInChildren = ((Component)this).GetComponentsInChildren<ParticleSystem>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					componentsInChildren[i].Stop(true, (ParticleSystemStopBehavior)1);
				}
				Object.Destroy((Object)(object)((Component)this).gameObject, 1.6f);
			}
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("com.empress.repo.dekumask", "Empress Deku Mask", "1.4.0")]
	public sealed class EmpressDekuMaskPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.empress.repo.dekumask";

		public const string PluginName = "Empress Deku Mask";

		public const string PluginVersion = "1.4.0";

		public const string ItemName = "Empress Deku Mask";

		internal const byte DekuUseEventCode = 189;

		internal const byte BubbleBlowEventCode = 190;

		internal const byte BubbleFireEventCode = 191;

		internal const byte BubblePopEventCode = 192;

		internal const byte BubbleCancelEventCode = 193;

		private static bool _photonHooked;

		private static LoadBalancingClient _hookedClient;

		private Harmony _harmony;

		internal static EmpressDekuMaskPlugin Instance { get; private set; }

		internal static ManualLogSource Log { get; private set; }

		internal static DekuMaskSettings Settings { get; private set; }

		internal static string PluginDirectory { get; private set; }

		private void Awake()
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			PluginDirectory = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
			Settings = new DekuMaskSettings(((BaseUnityPlugin)this).Config);
			((Component)this).gameObject.transform.parent = null;
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			DekuMaskAssets.Load();
			DekuMaskItemBuilder.RegisterItem();
			_harmony = new Harmony("com.empress.repo.dekumask");
			_harmony.PatchAll(typeof(EmpressDekuMaskPlugin).Assembly);
			DekuMaskRuntime.EnsureHost();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Empress Deku Mask v1.4.0 loaded.");
		}

		private void OnDestroy()
		{
			RemovePhotonHook();
		}

		internal static void EnsurePhotonHooked()
		{
			LoadBalancingClient networkingClient = PhotonNetwork.NetworkingClient;
			if (networkingClient != null && (!_photonHooked || _hookedClient != networkingClient))
			{
				if (_hookedClient != null)
				{
					_hookedClient.EventReceived -= OnPhotonEvent;
				}
				networkingClient.EventReceived -= OnPhotonEvent;
				networkingClient.EventReceived += OnPhotonEvent;
				_hookedClient = networkingClient;
				_photonHooked = true;
			}
		}

		internal static void RemovePhotonHook()
		{
			if (_hookedClient != null)
			{
				_hookedClient.EventReceived -= OnPhotonEvent;
			}
			_hookedClient = null;
			_photonHooked = false;
		}

		private static void OnPhotonEvent(EventData ev)
		{
			if (ev.CustomData is object[] data)
			{
				Dispatch(ev.Code, data);
			}
		}

		private static void Dispatch(byte code, object[] data)
		{
			switch (code)
			{
			case 189:
				DekuMaskRuntime.Instance?.ReceiveDekuUse(data);
				break;
			case 190:
				DekuBubbles.Instance?.ReceiveBlow(data);
				break;
			case 191:
				DekuBubbles.Instance?.ReceiveFire(data);
				break;
			case 192:
				DekuBubbles.Instance?.ReceivePop(data);
				break;
			case 193:
				DekuBubbles.Instance?.ReceiveCancel(data);
				break;
			}
		}

		internal static void RaiseToAll(byte code, object[] data)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			EnsurePhotonHooked();
			if (!PhotonNetwork.InRoom)
			{
				Dispatch(code, data);
				return;
			}
			RaiseEventOptions val = new RaiseEventOptions
			{
				Receivers = (ReceiverGroup)1
			};
			PhotonNetwork.RaiseEvent(code, (object)data, val, SendOptions.SendReliable);
		}

		internal static void RaiseToOthers(byte code, object[] data)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			EnsurePhotonHooked();
			if (PhotonNetwork.InRoom)
			{
				RaiseEventOptions val = new RaiseEventOptions
				{
					Receivers = (ReceiverGroup)0
				};
				PhotonNetwork.RaiseEvent(code, (object)data, val, SendOptions.SendReliable);
			}
		}
	}
	internal sealed class DekuMaskSettings
	{
		public readonly ConfigEntry<int> ShopPrice;

		public readonly ConfigEntry<float> DekuHeight;

		public readonly ConfigEntry<float> DekuYaw;

		public readonly ConfigEntry<float> ArmDown;

		public readonly ConfigEntry<bool> ThirdPerson;

		public readonly ConfigEntry<float> ThirdPersonDistance;

		public readonly ConfigEntry<float> ThirdPersonHeight;

		public readonly ConfigEntry<float> Volume;

		public readonly ConfigEntry<float> HearingRange;

		public DekuMaskSettings(ConfigFile config)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Expected O, but got Unknown
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Expected O, but got Unknown
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Expected O, but got Unknown
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Expected O, but got Unknown
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Expected O, but got Unknown
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Expected O, but got Unknown
			ShopPrice = config.Bind<int>("Deku", "ShopPrice", 30, new ConfigDescription("In game shop price in thousands. 30 means 30K on the shelf.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 500), Array.Empty<object>()));
			DekuHeight = config.Bind<float>("Deku", "DekuHeight", 1.25f, new ConfigDescription("How tall the Deku body is in meters.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.6f, 2.5f), Array.Empty<object>()));
			DekuYaw = config.Bind<float>("Deku", "DekuYaw", 0f, new ConfigDescription("Yaw in degrees that turns the Deku body to face forward. If he faces the wrong way try 180, 90 or -90.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-180f, 180f), Array.Empty<object>()));
			ArmDown = config.Bind<float>("Deku", "ArmDown", 35f, new ConfigDescription("How many degrees the arms hang down from the sideways pose.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 80f), Array.Empty<object>()));
			ThirdPerson = config.Bind<bool>("Camera", "ThirdPerson", true, "Stay in third person while transformed so you can see your Deku body.");
			ThirdPersonDistance = config.Bind<float>("Camera", "ThirdPersonDistance", 2.1f, new ConfigDescription("Third person camera distance in meters.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 5f), Array.Empty<object>()));
			ThirdPersonHeight = config.Bind<float>("Camera", "ThirdPersonHeight", 0.35f, new ConfigDescription("Third person camera height above the Deku head in meters.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1.5f), Array.Empty<object>()));
			Volume = config.Bind<float>("Audio", "Volume", 0.8f, new ConfigDescription("Transformation sound volume.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			HearingRange = config.Bind<float>("Audio", "HearingRange", 14f, new ConfigDescription("How many meters away players can hear the transformation.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(4f, 40f), Array.Empty<object>()));
		}
	}
}