Decompiled source of EnemyControl v1.0.0

BepInEx/plugins/EnemyControl/EnemyControl.dll

Decompiled 6 days 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 System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Peak;
using Photon.Pun;
using Photon.Realtime;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using Zorro.ControllerSupport;
using Zorro.Settings;

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace EnemyControl
{
	public static class BodyMask
	{
		private sealed class Masked
		{
			public Character Character;

			public readonly List<Renderer> Renderers = new List<Renderer>();

			public readonly List<Light> Lights = new List<Light>();

			public readonly List<Behaviour> Behaviours = new List<Behaviour>();
		}

		private static readonly Dictionary<int, Masked> Active = new Dictionary<int, Masked>();

		private static float _nextRefresh;

		public static void Apply(int viewId, bool hidden)
		{
			if (hidden)
			{
				Hide(viewId);
			}
			else
			{
				Show(viewId);
			}
		}

		private static void Hide(int viewId)
		{
			if (Active.ContainsKey(viewId))
			{
				ShapeState.HiddenBodies.Add(viewId);
				return;
			}
			Character val = FindCharacter(viewId);
			if ((Object)(object)val == (Object)null)
			{
				ShapeState.HiddenBodies.Add(viewId);
				return;
			}
			Masked masked = new Masked
			{
				Character = val
			};
			Active[viewId] = masked;
			ShapeState.HiddenBodies.Add(viewId);
			Collect(masked);
		}

		private static void Show(int viewId)
		{
			ShapeState.HiddenBodies.Remove(viewId);
			if (!Active.TryGetValue(viewId, out var value))
			{
				return;
			}
			Active.Remove(viewId);
			foreach (Renderer renderer in value.Renderers)
			{
				if ((Object)(object)renderer != (Object)null)
				{
					renderer.enabled = true;
				}
			}
			foreach (Light light in value.Lights)
			{
				if ((Object)(object)light != (Object)null)
				{
					((Behaviour)light).enabled = true;
				}
			}
			foreach (Behaviour behaviour in value.Behaviours)
			{
				if ((Object)(object)behaviour != (Object)null)
				{
					behaviour.enabled = true;
				}
			}
		}

		public static void Tick()
		{
			if (ShapeState.HiddenBodies.Count == 0 || Time.unscaledTime < _nextRefresh)
			{
				return;
			}
			_nextRefresh = Time.unscaledTime + 0.25f;
			foreach (int hiddenBody in ShapeState.HiddenBodies)
			{
				if (!Active.TryGetValue(hiddenBody, out var value) || (Object)(object)value.Character == (Object)null)
				{
					Character val = FindCharacter(hiddenBody);
					if ((Object)(object)val == (Object)null)
					{
						continue;
					}
					value = new Masked
					{
						Character = val
					};
					Active[hiddenBody] = value;
				}
				Collect(value);
			}
		}

		private static void Collect(Masked masked)
		{
			GameObject gameObject = ((Component)masked.Character).gameObject;
			Renderer[] componentsInChildren = gameObject.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null) && val.enabled)
				{
					val.enabled = false;
					masked.Renderers.Add(val);
				}
			}
			Light[] componentsInChildren2 = gameObject.GetComponentsInChildren<Light>(true);
			foreach (Light val2 in componentsInChildren2)
			{
				if (!((Object)(object)val2 == (Object)null) && ((Behaviour)val2).enabled)
				{
					((Behaviour)val2).enabled = false;
					masked.Lights.Add(val2);
				}
			}
			AddBehaviour(masked, (Behaviour)(object)gameObject.GetComponentInChildren<IsLookedAt>(true));
			AddBehaviour(masked, (Behaviour)(object)((masked.Character.refs != null) ? masked.Character.refs.interactible : null));
		}

		private static void AddBehaviour(Masked masked, Behaviour behaviour)
		{
			if (!((Object)(object)behaviour == (Object)null) && behaviour.enabled)
			{
				behaviour.enabled = false;
				masked.Behaviours.Add(behaviour);
			}
		}

		private static Character FindCharacter(int viewId)
		{
			PhotonView val = PhotonView.Find(viewId);
			if (!((Object)(object)val != (Object)null))
			{
				return null;
			}
			return ((Component)val).GetComponent<Character>();
		}

		public static void RestoreAll()
		{
			foreach (int item in new List<int>(Active.Keys))
			{
				Show(item);
			}
			Active.Clear();
			ShapeState.HiddenBodies.Clear();
		}
	}
	public static class CondorLoan
	{
		private sealed class Loan
		{
			public Condor Condor;

			public Transform Parent;

			public int SiblingIndex;

			public bool WasActive;

			public Vector3 Home;
		}

		private static readonly Dictionary<int, Loan> Loans = new Dictionary<int, Loan>();

		private static Condor[] _cache;

		public static Condor[] All()
		{
			if (_cache != null)
			{
				Condor[] cache = _cache;
				for (int i = 0; i < cache.Length; i++)
				{
					if ((Object)(object)cache[i] == (Object)null)
					{
						_cache = null;
						break;
					}
				}
			}
			if (_cache == null)
			{
				_cache = Object.FindObjectsByType<Condor>((FindObjectsInactive)1, (FindObjectsSortMode)0);
			}
			return _cache;
		}

		public static void ClearCache()
		{
			_cache = null;
			Loans.Clear();
		}

		public static int IdOf(Condor condor)
		{
			if ((Object)(object)condor == (Object)null || (Object)(object)condor.view == (Object)null)
			{
				return -1;
			}
			if (condor.view.ViewID == 0)
			{
				return condor.view.sceneViewId;
			}
			return condor.view.ViewID;
		}

		public static bool TryFind(int viewId, out Condor found)
		{
			found = null;
			if (viewId <= 0)
			{
				return false;
			}
			Condor[] array = All();
			foreach (Condor val in array)
			{
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val.view == (Object)null) && (val.view.ViewID == viewId || val.view.sceneViewId == viewId))
				{
					found = val;
					return true;
				}
			}
			return false;
		}

		public static Condor Borrow(int viewId)
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			if (Loans.ContainsKey(viewId))
			{
				return Loans[viewId].Condor;
			}
			if (!TryFind(viewId, out var found))
			{
				return null;
			}
			Loan value = new Loan
			{
				Condor = found,
				Parent = ((Component)found).transform.parent,
				SiblingIndex = ((Component)found).transform.GetSiblingIndex(),
				WasActive = ((Component)found).gameObject.activeSelf,
				Home = ((Component)found).transform.position
			};
			((Component)found).transform.SetParent((Transform)null, true);
			((Component)found).gameObject.SetActive(true);
			Loans[viewId] = value;
			return found;
		}

		public static void Return(int viewId)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: 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_0066: Unknown result type (might be due to invalid IL or missing references)
			if (!Loans.TryGetValue(viewId, out var value))
			{
				return;
			}
			Loans.Remove(viewId);
			Condor condor = value.Condor;
			if (!((Object)(object)condor == (Object)null))
			{
				condor._initPos = value.Home;
				condor._state = (CondorState)0;
				((Component)condor).transform.position = value.Home;
				if ((Object)(object)condor.rb != (Object)null)
				{
					condor.rb.position = value.Home;
				}
				if ((Object)(object)value.Parent != (Object)null)
				{
					((Component)condor).transform.SetParent(value.Parent, true);
					((Component)condor).transform.SetSiblingIndex(value.SiblingIndex);
				}
				((Component)condor).gameObject.SetActive(value.WasActive);
			}
		}

		public static bool TryGetHome(int viewId, out Vector3 home)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			home = Vector3.zero;
			if (!Loans.TryGetValue(viewId, out var value))
			{
				return false;
			}
			home = value.Home;
			return true;
		}
	}
	public class DiceManager : MonoBehaviour
	{
		public static DiceManager Instance { get; private set; }

		private void Awake()
		{
			Instance = this;
		}

		private void OnEnable()
		{
			Subscribe();
		}

		private void OnDisable()
		{
			GlobalEvents.OnItemThrown = (Action<Item>)Delegate.Remove(GlobalEvents.OnItemThrown, new Action<Item>(OnItemThrown));
		}

		internal void Subscribe()
		{
			GlobalEvents.OnItemThrown = (Action<Item>)Delegate.Remove(GlobalEvents.OnItemThrown, new Action<Item>(OnItemThrown));
			GlobalEvents.OnItemThrown = (Action<Item>)Delegate.Combine(GlobalEvents.OnItemThrown, new Action<Item>(OnItemThrown));
		}

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

		public void Clear()
		{
		}

		public unsafe void PlaceDie(Vector3 position)
		{
			//IL_0027: 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)
			if (!PhotonNetwork.IsMasterClient)
			{
				Plugin.Log.LogInfo((object)"Wuerfel ablegen geht nur beim Host - Gegenstaende in der Welt gehoeren ihm.");
				return;
			}
			try
			{
				if ((Object)(object)PhotonNetwork.InstantiateItemRoom(Plugin.Cfg.DiceItem.Value, position, Quaternion.Euler(0f, Random.Range(0f, 360f), 0f), true) != (Object)null)
				{
					Plugin.Log.LogInfo((object)("Wuerfel '" + Plugin.Cfg.DiceItem.Value + "' abgelegt bei " + ((object)(*(Vector3*)(&position))/*cast due to .constrained prefix*/).ToString()));
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Wuerfel '" + Plugin.Cfg.DiceItem.Value + "' liess sich nicht ablegen: " + ex.Message));
			}
		}

		public void PlaceDieInFront()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: 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_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			Character localCharacter = Character.localCharacter;
			if (!((Object)(object)localCharacter == (Object)null))
			{
				Vector3 val = (((Object)(object)MainCamera.instance != (Object)null) ? ((Component)MainCamera.instance).transform.forward : ((Component)localCharacter).transform.forward);
				val.y = 0f;
				if (((Vector3)(ref val)).sqrMagnitude < 0.01f)
				{
					val = Vector3.forward;
				}
				PlaceDie(localCharacter.Center + ((Vector3)(ref val)).normalized * 1.5f + Vector3.up * 0.5f);
			}
		}

		private void OnItemThrown(Item item)
		{
			if (Plugin.Cfg.Mode.Value != GameMode.Random || !PhotonNetwork.IsMasterClient || (Object)(object)item == (Object)null || !IsDie(item) || item.lastThrownAmount <= 0.01f)
			{
				return;
			}
			Character lastThrownCharacter = item.lastThrownCharacter;
			if (!((Object)(object)lastThrownCharacter == (Object)null) && !((Object)(object)((MonoBehaviourPun)lastThrownCharacter).photonView == (Object)null) && ((MonoBehaviourPun)lastThrownCharacter).photonView.Owner != null)
			{
				int actor = ((MonoBehaviourPun)lastThrownCharacter).photonView.Owner.ActorNumber;
				DieImpact.Attach(item.rig, delegate
				{
					Burst(item, actor);
				});
			}
		}

		internal static bool IsDie(Item item)
		{
			string value = Plugin.Cfg.DiceItem.Value;
			if (string.IsNullOrEmpty(value))
			{
				return false;
			}
			string text = ((Object)((Component)item).gameObject).name;
			int num = text.IndexOf("(Clone)", StringComparison.OrdinalIgnoreCase);
			if (num >= 0)
			{
				text = text.Substring(0, num);
			}
			return string.Equals(text.Trim(), value.Trim(), StringComparison.OrdinalIgnoreCase);
		}

		private void Burst(Item die, int actor)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: 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)
			Vector3 val = (((Object)(object)die != (Object)null) ? die.transform.position : Vector3.zero);
			EnemyControlNet.BroadcastDiceRoll(actor, val);
			if (actor == PhotonNetwork.LocalPlayer.ActorNumber)
			{
				ShapeController.Instance?.TakeRandom();
			}
			if ((Object)(object)die != (Object)null)
			{
				PhotonView photonView = ((MonoBehaviourPun)die).photonView;
				if ((Object)(object)photonView != (Object)null && photonView.IsMine)
				{
					PhotonNetwork.Destroy(((Component)die).gameObject);
				}
			}
		}
	}
	public class DiceSkinMarker : MonoBehaviour
	{
	}
	public static class DiceSkin
	{
		private static AssetBundle _bundle;

		private static GameObject _prefab;

		private static bool _tried;

		private static bool _iconDone;

		private static bool _logged;

		public static void Apply(Item item)
		{
			//IL_009c: 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_00bc: 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_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: 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)
			//IL_0102: 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)
			if ((Object)(object)item == (Object)null || string.IsNullOrEmpty(Plugin.Cfg.DiceSkinBundle.Value))
			{
				return;
			}
			GameObject val = Prefab();
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			EnsureInventoryIcon(val);
			if (!((Object)(object)((Component)item).GetComponentInChildren<DiceSkinMarker>(true) != (Object)null))
			{
				MeasureMesh(((Component)item).gameObject, visibleOnly: true, out var centre, out var size);
				Renderer[] componentsInChildren = ((Component)item).GetComponentsInChildren<Renderer>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					componentsInChildren[i].enabled = false;
				}
				GameObject val2 = Object.Instantiate<GameObject>(val, item.transform);
				((Object)val2).name = "EnemyControlDiceSkin";
				val2.transform.localRotation = Quaternion.identity;
				val2.transform.localScale = Vector3.one;
				val2.transform.localPosition = centre + Vector3.up * Plugin.Cfg.DiceSkinOffsetY.Value;
				MeasureMesh(val2, visibleOnly: false, out var _, out var size2);
				if (size > 0.0001f && size2 > 0.0001f)
				{
					val2.transform.localScale = Vector3.one * (size / size2 * Plugin.Cfg.DiceSkinScale.Value);
				}
				if (!_logged)
				{
					_logged = true;
					Plugin.Log.LogInfo((object)("Wuerfel-Modell: Original " + size.ToString("0.####") + " um " + ((Vector3)(ref centre)).ToString("0.###") + ", Modell " + size2.ToString("0.####") + ", Skalierung " + val2.transform.localScale.x.ToString("0.###")));
				}
				val2.AddComponent<DiceSkinMarker>();
				Collider[] componentsInChildren2 = val2.GetComponentsInChildren<Collider>(true);
				for (int i = 0; i < componentsInChildren2.Length; i++)
				{
					Object.Destroy((Object)(object)componentsInChildren2[i]);
				}
				Rigidbody[] componentsInChildren3 = val2.GetComponentsInChildren<Rigidbody>(true);
				for (int i = 0; i < componentsInChildren3.Length; i++)
				{
					Object.Destroy((Object)(object)componentsInChildren3[i]);
				}
				if (Plugin.Cfg.DiceSkinFixShaders.Value)
				{
					FixShaders(val2);
				}
				MatchHitbox(item, Plugin.Cfg.DiceSkinScale.Value);
			}
		}

		private static void MeasureMesh(GameObject root, bool visibleOnly, out Vector3 centre, out float size)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: 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_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_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_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: 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_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: 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_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: 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_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: 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_0144: 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_0159: 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_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			centre = Vector3.zero;
			size = 0f;
			Bounds val = default(Bounds);
			bool flag = false;
			Renderer[] componentsInChildren = root.GetComponentsInChildren<Renderer>(!visibleOnly);
			Vector3 val7 = default(Vector3);
			Bounds val8 = default(Bounds);
			foreach (Renderer val2 in componentsInChildren)
			{
				if (visibleOnly && !val2.enabled)
				{
					continue;
				}
				Mesh val3 = null;
				SkinnedMeshRenderer val4 = (SkinnedMeshRenderer)(object)((val2 is SkinnedMeshRenderer) ? val2 : null);
				if (val4 != null)
				{
					val3 = val4.sharedMesh;
				}
				else
				{
					MeshFilter component = ((Component)val2).GetComponent<MeshFilter>();
					if ((Object)(object)component != (Object)null)
					{
						val3 = component.sharedMesh;
					}
				}
				if (!((Object)(object)val3 == (Object)null))
				{
					Matrix4x4 val5 = root.transform.worldToLocalMatrix * ((Component)val2).transform.localToWorldMatrix;
					Bounds bounds = val3.bounds;
					Vector3 val6 = ((Matrix4x4)(ref val5)).MultiplyPoint3x4(((Bounds)(ref bounds)).center);
					bounds = val3.bounds;
					Vector3 extents = ((Bounds)(ref bounds)).extents;
					((Vector3)(ref val7))..ctor(Mathf.Abs(val5.m00) * extents.x + Mathf.Abs(val5.m01) * extents.y + Mathf.Abs(val5.m02) * extents.z, Mathf.Abs(val5.m10) * extents.x + Mathf.Abs(val5.m11) * extents.y + Mathf.Abs(val5.m12) * extents.z, Mathf.Abs(val5.m20) * extents.x + Mathf.Abs(val5.m21) * extents.y + Mathf.Abs(val5.m22) * extents.z);
					((Bounds)(ref val8))..ctor(val6, val7 * 2f);
					if (!flag)
					{
						val = val8;
						flag = true;
					}
					else
					{
						((Bounds)(ref val)).Encapsulate(val8);
					}
				}
			}
			if (flag)
			{
				centre = ((Bounds)(ref val)).center;
				size = Mathf.Max(((Bounds)(ref val)).size.x, Mathf.Max(((Bounds)(ref val)).size.y, ((Bounds)(ref val)).size.z));
			}
		}

		private static void FixShaders(GameObject skin)
		{
			//IL_00b4: 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_00b9: 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)
			Shader val = Shader.Find("Universal Render Pipeline/Lit");
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			Renderer[] componentsInChildren = skin.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val2 in componentsInChildren)
			{
				Material[] materials = val2.materials;
				foreach (Material val3 in materials)
				{
					if (!((Object)(object)val3 == (Object)null) && !((Object)(object)val3.shader == (Object)null) && !((Object)val3.shader).name.StartsWith("Universal Render Pipeline"))
					{
						Texture val4 = (val3.HasProperty("_MainTex") ? val3.GetTexture("_MainTex") : null);
						Color val5 = (val3.HasProperty("_Color") ? val3.GetColor("_Color") : Color.white);
						val3.shader = val;
						if ((Object)(object)val4 != (Object)null && val3.HasProperty("_BaseMap"))
						{
							val3.SetTexture("_BaseMap", val4);
						}
						if (val3.HasProperty("_BaseColor"))
						{
							val3.SetColor("_BaseColor", val5);
						}
					}
				}
				val2.materials = materials;
			}
		}

		private static void EnsureInventoryIcon(GameObject skinPrefab)
		{
			if (_iconDone)
			{
				return;
			}
			_iconDone = true;
			GameObject val = Resources.Load<GameObject>("0_Items/" + Plugin.Cfg.DiceItem.Value);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			Item component = val.GetComponent<Item>();
			if (!((Object)(object)component == (Object)null) && component.UIData != null)
			{
				Texture2D val2 = LoadIcon();
				if ((Object)(object)val2 != (Object)null)
				{
					component.UIData.icon = val2;
					component.UIData.hasAltIcon = false;
					Plugin.Log.LogInfo((object)"Wuerfel-Symbol im Inventar ersetzt.");
				}
				else
				{
					Plugin.Log.LogWarning((object)("Wuerfel-Symbol: '" + Plugin.Cfg.DiceIconFile.Value + "' nicht gefunden - der Guertel zeigt weiter das Original."));
				}
				RenameItem(component);
				component.UIData.hasMainInteract = false;
			}
		}

		private static Texture2D LoadIcon()
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), Plugin.Cfg.DiceIconFile.Value);
			if (File.Exists(text))
			{
				Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
				if (ImageConversion.LoadImage(val, File.ReadAllBytes(text)))
				{
					((Texture)val).wrapMode = (TextureWrapMode)1;
					return val;
				}
				Plugin.Log.LogWarning((object)("Wuerfel-Symbol: " + text + " ist kein lesbares Bild."));
			}
			if (!((Object)(object)_bundle != (Object)null))
			{
				return null;
			}
			return _bundle.LoadAsset<Texture2D>(Plugin.Cfg.DiceSkinIcon.Value);
		}

		private static void RenameItem(Item item)
		{
			string value = Plugin.Cfg.DiceName.Value;
			if (string.IsNullOrEmpty(value))
			{
				return;
			}
			try
			{
				Dictionary<string, List<string>> mainTable = LocalizedText.mainTable;
				if (mainTable == null)
				{
					return;
				}
				int num = 8;
				foreach (KeyValuePair<string, List<string>> item2 in mainTable)
				{
					if (item2.Value != null && item2.Value.Count > 0)
					{
						num = item2.Value.Count;
						break;
					}
				}
				List<string> list = new List<string>();
				for (int i = 0; i < num; i++)
				{
					list.Add(value);
				}
				mainTable["NAME_ENEMYCONTROL_DIE"] = list;
				item.UIData.itemName = "ENEMYCONTROL_DIE";
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Wuerfel-Name liess sich nicht setzen: " + ex.Message));
			}
		}

		private static void MatchHitbox(Item item, float factor)
		{
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.Cfg.DiceMatchHitbox.Value)
			{
				return;
			}
			factor = Mathf.Clamp(factor, 0.5f, 6f);
			if (Mathf.Abs(factor - 1f) < 0.05f)
			{
				return;
			}
			Collider[] componentsInChildren = ((Component)item).GetComponentsInChildren<Collider>(true);
			foreach (Collider val in componentsInChildren)
			{
				SphereCollider val2 = (SphereCollider)(object)((val is SphereCollider) ? val : null);
				if (val2 == null)
				{
					BoxCollider val3 = (BoxCollider)(object)((val is BoxCollider) ? val : null);
					if (val3 == null)
					{
						CapsuleCollider val4 = (CapsuleCollider)(object)((val is CapsuleCollider) ? val : null);
						if (val4 != null)
						{
							val4.radius *= factor;
							val4.height *= factor;
						}
					}
					else
					{
						val3.size *= factor;
					}
				}
				else
				{
					val2.radius *= factor;
				}
			}
		}

		private static GameObject Prefab()
		{
			//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)
			if (_tried)
			{
				return _prefab;
			}
			_tried = true;
			string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), Plugin.Cfg.DiceSkinBundle.Value);
			if (!File.Exists(text))
			{
				Plugin.Log.LogWarning((object)("Wuerfel-Modell: kein Bundle unter " + text + " - der Wuerfel behaelt sein Originalaussehen."));
				return null;
			}
			_bundle = AssetBundle.LoadFromFile(text);
			if ((Object)(object)_bundle == (Object)null)
			{
				Plugin.Log.LogWarning((object)("Wuerfel-Modell: " + text + " liess sich nicht laden. Meist heisst das, das Bundle wurde mit einer neueren Unity-Version gebaut als der von PEAK (6000.3.15f1)."));
				return null;
			}
			string[] allAssetNames = _bundle.GetAllAssetNames();
			Plugin.Log.LogInfo((object)("Wuerfel-Modell: Bundle geladen, enthaelt " + allAssetNames.Length + " Objekte:"));
			string[] array = allAssetNames;
			foreach (string text2 in array)
			{
				Plugin.Log.LogInfo((object)("   " + text2));
			}
			string value = Plugin.Cfg.DiceSkinAsset.Value;
			if (!string.IsNullOrEmpty(value))
			{
				_prefab = _bundle.LoadAsset<GameObject>(value);
			}
			else
			{
				GameObject[] array2 = _bundle.LoadAllAssets<GameObject>();
				_prefab = ((array2.Length != 0) ? array2[0] : null);
			}
			if ((Object)(object)_prefab == (Object)null)
			{
				Plugin.Log.LogWarning((object)("Wuerfel-Modell: '" + value + "' ist im Bundle nicht als Objekt zu finden. Einen der oben aufgelisteten Namen in DiceSkinAsset eintragen, oder das Feld leer lassen fuer das erste Objekt."));
			}
			else
			{
				Plugin.Log.LogInfo((object)("Wuerfel-Modell: '" + ((Object)_prefab).name + "' wird benutzt, Groesse " + _prefab.transform.localScale.x.ToString("0.###")));
			}
			return _prefab;
		}
	}
	public class DieImpact : MonoBehaviour
	{
		private Action _onImpact;

		private float _armedAt;

		private float _deadline;

		private bool _fired;

		public static void Attach(Rigidbody body, Action onImpact)
		{
			if (!((Object)(object)body == (Object)null))
			{
				DieImpact dieImpact = ((Component)body).gameObject.AddComponent<DieImpact>();
				dieImpact._onImpact = onImpact;
				dieImpact._armedAt = Time.time + 0.5f;
				dieImpact._deadline = Time.time + 12f;
			}
		}

		private void OnCollisionEnter(Collision collision)
		{
			if (!_fired && !(Time.time < _armedAt))
			{
				Fire();
			}
		}

		private void Update()
		{
			if (!_fired && Time.time > _deadline)
			{
				Fire();
			}
		}

		private void Fire()
		{
			_fired = true;
			Action onImpact = _onImpact;
			_onImpact = null;
			onImpact?.Invoke();
		}
	}
	public static class EnemyControlNet
	{
		public const byte EvtShape = 191;

		public const byte EvtAttack = 192;

		public const byte EvtDice = 193;

		public const byte EvtPose = 194;

		private static readonly SendOptions Reliable = SendOptions.SendReliable;

		private static readonly SendOptions Unreliable = SendOptions.SendUnreliable;

		public static void BroadcastShape(string mobId, int bodyViewId, int entityViewId)
		{
			//IL_0003: 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_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected O, but got Unknown
			Send(mobId, bodyViewId, entityViewId, new RaiseEventOptions
			{
				Receivers = (ReceiverGroup)0
			});
		}

		public static void SendShapeTo(int targetActor, string mobId, int bodyViewId, int entityViewId)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected O, but got Unknown
			RaiseEventOptions val = new RaiseEventOptions();
			val.TargetActors = new int[1] { targetActor };
			Send(mobId, bodyViewId, entityViewId, val);
		}

		private static void Send(string mobId, int bodyViewId, int entityViewId, RaiseEventOptions options)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			if (PhotonNetwork.InRoom)
			{
				object[] array = new object[4]
				{
					PhotonNetwork.LocalPlayer.ActorNumber,
					mobId ?? string.Empty,
					bodyViewId,
					entityViewId
				};
				PhotonNetwork.RaiseEvent((byte)191, (object)array, options, Reliable);
			}
		}

		public static void BroadcastAttack(int entityViewId, bool attacking)
		{
			//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)
			//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_003b: Expected O, but got Unknown
			if (PhotonNetwork.InRoom)
			{
				PhotonNetwork.RaiseEvent((byte)192, (object)new object[2] { entityViewId, attacking }, new RaiseEventOptions
				{
					Receivers = (ReceiverGroup)0
				}, Reliable);
			}
		}

		public static void BroadcastDiceRoll(int actor, Vector3 where)
		{
			//IL_001e: 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)
			//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_003b: Expected O, but got Unknown
			if (PhotonNetwork.InRoom)
			{
				PhotonNetwork.RaiseEvent((byte)193, (object)new object[2] { actor, where }, new RaiseEventOptions
				{
					Receivers = (ReceiverGroup)0
				}, Reliable);
			}
		}

		public static void BroadcastPose(int entityViewId, Vector3 position, Vector3 forward)
		{
			//IL_001e: 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_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: 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_0044: Expected O, but got Unknown
			if (PhotonNetwork.InRoom)
			{
				PhotonNetwork.RaiseEvent((byte)194, (object)new object[3] { entityViewId, position, forward }, new RaiseEventOptions
				{
					Receivers = (ReceiverGroup)0
				}, Unreliable);
			}
		}

		public static bool TryReadPose(object data, out int entityViewId, out Vector3 position, out Vector3 forward)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: 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_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_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)
			entityViewId = -1;
			position = Vector3.zero;
			forward = Vector3.forward;
			if (!(data is object[] array) || array.Length < 3)
			{
				return false;
			}
			entityViewId = (int)array[0];
			position = (Vector3)array[1];
			forward = (Vector3)array[2];
			return true;
		}

		public static bool TryReadDiceRoll(object data, out int actor, out Vector3 where)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			actor = -1;
			where = Vector3.zero;
			if (!(data is object[] array) || array.Length < 2)
			{
				return false;
			}
			actor = (int)array[0];
			where = (Vector3)array[1];
			return true;
		}

		public static bool TryReadAttack(object data, out int entityViewId, out bool attacking)
		{
			entityViewId = -1;
			attacking = false;
			if (!(data is object[] array) || array.Length < 2)
			{
				return false;
			}
			entityViewId = (int)array[0];
			attacking = (bool)array[1];
			return true;
		}

		public static bool TryRead(object data, out int actor, out string mobId, out int bodyViewId, out int entityViewId)
		{
			actor = -1;
			mobId = null;
			bodyViewId = -1;
			entityViewId = -1;
			if (!(data is object[] array) || array.Length < 4)
			{
				return false;
			}
			actor = (int)array[0];
			mobId = array[1] as string;
			if (string.IsNullOrEmpty(mobId))
			{
				mobId = null;
			}
			bodyViewId = (int)array[2];
			entityViewId = (int)array[3];
			return true;
		}
	}
	public enum Language
	{
		Auto,
		English,
		Deutsch
	}
	public static class Loc
	{
		public static Language Current = Language.English;

		private static readonly Dictionary<string, string> En = new Dictionary<string, string>
		{
			["menu.title"] = "TAKE A SHAPE",
			["menu.sub"] = "Pick a creature. Your body vanishes while you wear it.",
			["menu.sub.active"] = "You are a {0}. Pick another shape, or press [{1}] to come back.",
			["menu.revert"] = "RETURN TO YOUR BODY",
			["menu.close"] = "[Esc] close",
			["menu.missing"] = "not in this level",
			["menu.experimental"] = "experimental",
			["menu.blocked.room"] = "You have to be in a run.",
			["menu.blocked.dead"] = "Dead scouts keep their shape.",
			["menu.blocked.host"] = "Only the host may take a shape.",
			["menu.blocked.dissolving"] = "Wait for your last shape to fade.",
			["hud.active"] = "{0}  -  [{1}] release",
			["hud.inrange"] = "IN RANGE",
			["hud.dissolving"] = "the {0} is fading...",
			["toast.spawnfailed"] = "{0} could not be summoned here.",
			["toast.nocondor"] = "No condor is circling this level.",
			["toast.dicehit"] = "The die bursts. You are a {0}.",
			["toast.diceroll"] = "{0} threw the die.",
			["mode.random.hint"] = "Random mode: no menu. Find a die in the luggage and throw it.",
			["toast.taken"] = "You are a {0}.",
			["toast.released"] = "You are yourself again.",
			["toast.othertook"] = "{0} became a {1}.",
			["toast.otherreleased"] = "{0} is a scout again.",
			["key.move"] = "WASD",
			["key.jump"] = "SPACE",
			["key.sprint"] = "SHIFT",
			["key.crouch"] = "CTRL",
			["key.attack"] = "LMB",
			["key.secondary"] = "RMB",
			["key.release"] = "{0}",
			["ctrl.move"] = "Move",
			["ctrl.steer"] = "Steer",
			["ctrl.hop"] = "Hop",
			["ctrl.fly"] = "Fly",
			["ctrl.soar"] = "Soar",
			["ctrl.drift"] = "Drift",
			["ctrl.jump"] = "Jump",
			["ctrl.up"] = "Rise",
			["ctrl.down"] = "Descend",
			["ctrl.sprint"] = "Sprint",
			["ctrl.faster"] = "Faster",
			["ctrl.throw"] = "Throw whoever you hold",
			["ctrl.attack.scoutmaster"] = "Reach out and grab a scout",
			["ctrl.attack.zombie"] = "Lunge and bite",
			["ctrl.attack.zombiescout"] = "Lunge and bite",
			["ctrl.attack.beetle"] = "Bonk a scout - only right next to one",
			["ctrl.attack.scorpion"] = "Poison a scout - only right next to one",
			["ctrl.attack.frog"] = "Tongue - needs a scout in front of you",
			["ctrl.attack.bees"] = "Sting - poisons whoever you float over",
			["ctrl.attack.ghost"] = "Hold to charge - let go to cancel, hold on and you blow up",
			["ctrl.attack.condor"] = "Hold to snatch the scout below you - let go to drop them",
			["ctrl.attack.tornado"] = "",
			["ctrl.climb"] = "Climb - walk into a wall",
			["ctrl.release"] = "Back to your body",
			["key.wheel"] = "WHEEL",
			["ctrl.zoom"] = "Zoom - all the way in to look out of its eyes",
			["mob.scoutmaster"] = "Scoutmaster",
			["mob.zombie"] = "Mushroom Zombie",
			["mob.zombiescout"] = "Zombified Scout",
			["mob.beetle"] = "Beetle",
			["mob.scorpion"] = "Scorpion",
			["mob.frog"] = "Frog",
			["mob.bees"] = "Bee Swarm",
			["mob.ghost"] = "Gloom Ghost",
			["mob.condor"] = "Condor",
			["mob.tornado"] = "Tornado",
			["mob.scoutmaster.desc"] = "Grabs scouts and throws them off the mountain.",
			["mob.zombie.desc"] = "Lunges and bites. Spores do the rest.",
			["mob.zombiescout.desc"] = "The zombie a fallen scout turns into.",
			["mob.beetle.desc"] = "Small, fast, bonks people over.",
			["mob.scorpion.desc"] = "Small and poisonous.",
			["mob.frog.desc"] = "Hops. The tongue plucks a scout right off the wall.",
			["mob.bees.desc"] = "A swarm. Floats where you point it.",
			["mob.ghost.desc"] = "The ghost of the Gloom. Drifts up to a scout and detonates.",
			["mob.condor.desc"] = "Circles the mountain. Picks a scout up and carries them off.",
			["mob.tornado.desc"] = "Sucks up whatever it drifts over."
		};

		private static readonly Dictionary<string, string> De = new Dictionary<string, string>
		{
			["menu.title"] = "GESTALT ANNEHMEN",
			["menu.sub"] = "Waehle eine Kreatur. Dein Koerper verschwindet, solange du sie traegst.",
			["menu.sub.active"] = "Du bist ein {0}. Waehle eine andere Gestalt, oder druecke [{1}] zum Zurueckkehren.",
			["menu.revert"] = "ZURUECK IN DEN EIGENEN KOERPER",
			["menu.close"] = "[Esc] schliessen",
			["menu.missing"] = "in diesem Level nicht vorhanden",
			["menu.experimental"] = "experimentell",
			["menu.blocked.room"] = "Du musst in einem Lauf sein.",
			["menu.blocked.dead"] = "Tote Scouts behalten ihre Gestalt.",
			["menu.blocked.host"] = "Nur der Host darf eine Gestalt annehmen.",
			["menu.blocked.dissolving"] = "Warte, bis sich die letzte Gestalt aufgeloest hat.",
			["hud.active"] = "{0}  -  [{1}] ablegen",
			["hud.inrange"] = "IN REICHWEITE",
			["hud.dissolving"] = "Der {0} loest sich auf...",
			["toast.spawnfailed"] = "{0} laesst sich hier nicht rufen.",
			["toast.nocondor"] = "In diesem Level kreist kein Kondor.",
			["toast.dicehit"] = "Der Wuerfel platzt. Du bist ein {0}.",
			["toast.diceroll"] = "{0} hat gewuerfelt.",
			["mode.random.hint"] = "Zufallsmodus: kein Menue. Finde im Gepaeck einen Wuerfel und wirf ihn.",
			["toast.taken"] = "Du bist ein {0}.",
			["toast.released"] = "Du bist wieder du selbst.",
			["toast.othertook"] = "{0} ist jetzt ein {1}.",
			["toast.otherreleased"] = "{0} ist wieder ein Scout.",
			["key.move"] = "WASD",
			["key.jump"] = "LEER",
			["key.sprint"] = "SHIFT",
			["key.crouch"] = "STRG",
			["key.attack"] = "LMT",
			["key.secondary"] = "RMT",
			["key.release"] = "{0}",
			["ctrl.move"] = "Laufen",
			["ctrl.steer"] = "Lenken",
			["ctrl.hop"] = "Huepfen",
			["ctrl.fly"] = "Fliegen",
			["ctrl.soar"] = "Segeln",
			["ctrl.drift"] = "Treiben",
			["ctrl.jump"] = "Springen",
			["ctrl.up"] = "Steigen",
			["ctrl.down"] = "Sinken",
			["ctrl.sprint"] = "Sprinten",
			["ctrl.faster"] = "Schneller",
			["ctrl.throw"] = "Gepackten werfen",
			["ctrl.attack.scoutmaster"] = "Nach einem Scout greifen",
			["ctrl.attack.zombie"] = "Anspringen und beissen",
			["ctrl.attack.zombiescout"] = "Anspringen und beissen",
			["ctrl.attack.beetle"] = "Scout umhauen - nur direkt daneben",
			["ctrl.attack.scorpion"] = "Scout vergiften - nur direkt daneben",
			["ctrl.attack.frog"] = "Zunge - braucht einen Scout vor dir",
			["ctrl.attack.bees"] = "Stechen - vergiftet, wen du ueberfliegst",
			["ctrl.attack.ghost"] = "Halten laedt auf - loslassen bricht ab, sonst gehst du hoch",
			["ctrl.attack.condor"] = "Halten packt den Scout unter dir - loslassen laesst ihn fallen",
			["ctrl.attack.tornado"] = "",
			["ctrl.climb"] = "Klettern - gegen die Wand laufen",
			["ctrl.release"] = "Zurueck in den Koerper",
			["key.wheel"] = "MAUSRAD",
			["ctrl.zoom"] = "Zoom - ganz heran fuer die Egoperspektive",
			["mob.scoutmaster"] = "Scoutmaster",
			["mob.zombie"] = "Pilzzombie",
			["mob.zombiescout"] = "Verpilzter Scout",
			["mob.beetle"] = "Kaefer",
			["mob.scorpion"] = "Skorpion",
			["mob.frog"] = "Frosch",
			["mob.bees"] = "Bienenschwarm",
			["mob.ghost"] = "Gloom-Geist",
			["mob.condor"] = "Kondor",
			["mob.tornado"] = "Tornado",
			["mob.scoutmaster.desc"] = "Packt Scouts und wirft sie den Berg hinunter.",
			["mob.zombie.desc"] = "Springt an und beisst. Die Sporen erledigen den Rest.",
			["mob.zombiescout.desc"] = "Der Zombie, zu dem ein gefallener Scout wird.",
			["mob.beetle.desc"] = "Klein, schnell, haut Leute um.",
			["mob.scorpion.desc"] = "Klein und giftig.",
			["mob.frog.desc"] = "Huepft. Die Zunge pflueckt einen Scout von der Wand.",
			["mob.bees.desc"] = "Ein Schwarm. Schwebt dorthin, wo du hinzeigst.",
			["mob.ghost.desc"] = "Der Geist aus dem Gloom. Schwebt an einen Scout heran und geht hoch.",
			["mob.condor.desc"] = "Kreist ueber dem Berg. Hebt einen Scout hoch und traegt ihn fort.",
			["mob.tornado.desc"] = "Saugt alles ein, worueber er treibt."
		};

		public static string T(string key)
		{
			if ((UseGerman() ? De : En).TryGetValue(key, out var value))
			{
				return value;
			}
			if (En.TryGetValue(key, out value))
			{
				return value;
			}
			return key;
		}

		public static string T(string key, params object[] args)
		{
			return string.Format(T(key), args);
		}

		private static bool UseGerman()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Invalid comparison between Unknown and I4
			return Current switch
			{
				Language.Deutsch => true, 
				Language.English => false, 
				_ => (int)Application.systemLanguage == 15, 
			};
		}
	}
	public enum ControlKind
	{
		PeakCharacter,
		GroundMob,
		Hopper,
		Flyer,
		Soarer,
		Drifter
	}
	public sealed class MobDef
	{
		public string Id;

		public string PrefabName;

		public ControlKind Kind;

		public float CamDistance;

		public float CamHeight;

		public float Speed;

		public bool Experimental;

		public bool SceneEntity;

		public string Name => Loc.T("mob." + Id);

		public string AttackLabel => Loc.T("ctrl.attack." + Id);

		public string Description => Loc.T("mob." + Id + ".desc");
	}
	public static class MobCatalog
	{
		public static readonly MobDef[] All = new MobDef[10]
		{
			new MobDef
			{
				Id = "scoutmaster",
				PrefabName = "Character_Scoutmaster",
				Kind = ControlKind.PeakCharacter,
				CamDistance = 7f,
				CamHeight = 0.6f
			},
			new MobDef
			{
				Id = "zombie",
				PrefabName = "MushroomZombie",
				Kind = ControlKind.PeakCharacter,
				CamDistance = 6f,
				CamHeight = 0.6f
			},
			new MobDef
			{
				Id = "zombiescout",
				PrefabName = "MushroomZombie_Player",
				Kind = ControlKind.PeakCharacter,
				CamDistance = 6f,
				CamHeight = 0.6f
			},
			new MobDef
			{
				Id = "beetle",
				PrefabName = "0_Items/Beetle",
				Kind = ControlKind.GroundMob,
				CamDistance = 4f,
				CamHeight = 0.5f
			},
			new MobDef
			{
				Id = "scorpion",
				PrefabName = "0_Items/Scorpion",
				Kind = ControlKind.GroundMob,
				CamDistance = 4f,
				CamHeight = 0.5f
			},
			new MobDef
			{
				Id = "frog",
				PrefabName = "0_Items/Frog",
				Kind = ControlKind.Hopper,
				CamDistance = 5f,
				CamHeight = 0.6f
			},
			new MobDef
			{
				Id = "bees",
				PrefabName = "BeeSwarm",
				Kind = ControlKind.Flyer,
				CamDistance = 4f,
				CamHeight = 0.3f,
				Speed = 9f
			},
			new MobDef
			{
				Id = "ghost",
				PrefabName = "GhostBall",
				Kind = ControlKind.Flyer,
				CamDistance = 30f,
				CamHeight = 3f,
				Speed = 6f
			},
			new MobDef
			{
				Id = "condor",
				PrefabName = "",
				Kind = ControlKind.Soarer,
				CamDistance = 16f,
				CamHeight = 2f,
				Speed = 18f,
				SceneEntity = true
			},
			new MobDef
			{
				Id = "tornado",
				PrefabName = "Tornado",
				Kind = ControlKind.Drifter,
				CamDistance = 26f,
				CamHeight = 9f,
				Speed = 14f
			}
		};

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

		public static MobDef Find(string id)
		{
			MobDef[] all = All;
			foreach (MobDef mobDef in all)
			{
				if (mobDef.Id == id)
				{
					return mobDef;
				}
			}
			return null;
		}

		public static bool IsAvailable(MobDef def)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			if (def == null)
			{
				return false;
			}
			Condor nearest;
			if (def.SceneEntity)
			{
				return FindNearestCondor(Vector3.zero, out nearest);
			}
			if (AvailabilityCache.TryGetValue(def.PrefabName, out var value))
			{
				return value;
			}
			bool flag = (Object)(object)Resources.Load<GameObject>(def.PrefabName) != (Object)null;
			AvailabilityCache[def.PrefabName] = flag;
			return flag;
		}

		public static void ClearCache()
		{
			AvailabilityCache.Clear();
		}

		public static bool FindNearestCondor(Vector3 from, out Condor nearest)
		{
			//IL_005f: 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_0072: 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_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			nearest = null;
			if (RunSettings.IsCustomRun && RunSettings.GetValue((SETTINGTYPE)2750, false) == 0)
			{
				return false;
			}
			float num = float.MaxValue;
			Condor[] array = CondorLoan.All();
			foreach (Condor val in array)
			{
				if ((Object)(object)val == (Object)null || (Object)(object)val.view == (Object)null)
				{
					continue;
				}
				int num2 = CondorLoan.IdOf(val);
				if (num2 > 0 && !ShapeState.ControlledEntities.Contains(num2))
				{
					float num3;
					if (!(from == Vector3.zero))
					{
						Vector3 val2 = ((Component)val).transform.position - from;
						num3 = ((Vector3)(ref val2)).sqrMagnitude;
					}
					else
					{
						num3 = 0f;
					}
					float num4 = num3;
					if (!(num4 > num))
					{
						num = num4;
						nearest = val;
					}
				}
			}
			return (Object)(object)nearest != (Object)null;
		}
	}
	public static class PeakUi
	{
		public static readonly Color Panel = Color32.op_Implicit(new Color32((byte)22, (byte)18, (byte)14, (byte)242));

		public static readonly Color PanelSoft = Color32.op_Implicit(new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, (byte)14));

		public static readonly Color Ink = Color32.op_Implicit(new Color32((byte)233, (byte)224, (byte)205, byte.MaxValue));

		public static readonly Color InkDim = Color32.op_Implicit(new Color32((byte)233, (byte)224, (byte)205, (byte)140));

		public static readonly Color Accent = Color32.op_Implicit(new Color32(byte.MaxValue, (byte)196, (byte)92, byte.MaxValue));

		public static readonly Color Danger = Color32.op_Implicit(new Color32((byte)232, (byte)96, (byte)72, byte.MaxValue));

		private static TMP_FontAsset _cached;

		public static TMP_FontAsset GameFont()
		{
			if ((Object)(object)_cached != (Object)null)
			{
				return _cached;
			}
			GUIManager instance = GUIManager.instance;
			if ((Object)(object)instance != (Object)null)
			{
				if ((Object)(object)instance.interactPromptText != (Object)null && (Object)(object)((TMP_Text)instance.interactPromptText).font != (Object)null)
				{
					_cached = ((TMP_Text)instance.interactPromptText).font;
				}
				else if ((Object)(object)instance.heroText != (Object)null && (Object)(object)((TMP_Text)instance.heroText).font != (Object)null)
				{
					_cached = ((TMP_Text)instance.heroText).font;
				}
			}
			if ((Object)(object)_cached == (Object)null)
			{
				TextMeshProUGUI val = Object.FindAnyObjectByType<TextMeshProUGUI>();
				_cached = (((Object)(object)val != (Object)null && (Object)(object)((TMP_Text)val).font != (Object)null) ? ((TMP_Text)val).font : TMP_Settings.defaultFontAsset);
			}
			return _cached;
		}

		public static void DropFontCache()
		{
			_cached = null;
		}

		public static GameObject MakeCanvas(string name, int sortingOrder, bool interactive)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			((Object)val).hideFlags = (HideFlags)61;
			Object.DontDestroyOnLoad((Object)(object)val);
			Canvas obj = val.AddComponent<Canvas>();
			obj.renderMode = (RenderMode)0;
			obj.sortingOrder = sortingOrder;
			CanvasScaler obj2 = val.AddComponent<CanvasScaler>();
			obj2.uiScaleMode = (ScaleMode)1;
			obj2.referenceResolution = new Vector2(1920f, 1080f);
			obj2.matchWidthOrHeight = 0.5f;
			if (interactive)
			{
				val.AddComponent<GraphicRaycaster>();
			}
			return val;
		}

		public static TextMeshProUGUI MakeLabel(Transform parent, string name, float size, TextAlignmentOptions align, Color color)
		{
			//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_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name, new Type[2]
			{
				typeof(RectTransform),
				typeof(TextMeshProUGUI)
			});
			val.transform.SetParent(parent, false);
			TextMeshProUGUI component = val.GetComponent<TextMeshProUGUI>();
			TMP_FontAsset val2 = GameFont();
			if ((Object)(object)val2 != (Object)null)
			{
				((TMP_Text)component).font = val2;
			}
			((TMP_Text)component).fontSize = size;
			((TMP_Text)component).alignment = align;
			((Graphic)component).color = color;
			((Graphic)component).raycastTarget = false;
			((TMP_Text)component).textWrappingMode = (TextWrappingModes)1;
			return component;
		}

		public static Image MakeImage(Transform parent, string name, Color color)
		{
			//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_0039: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name, new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			val.transform.SetParent(parent, false);
			Image component = val.GetComponent<Image>();
			((Graphic)component).color = color;
			return component;
		}

		public static void PlaceFromTop(RectTransform rt, float top, float height, float sideMargin)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			rt.anchorMin = new Vector2(0f, 1f);
			rt.anchorMax = new Vector2(1f, 1f);
			rt.pivot = new Vector2(0.5f, 1f);
			rt.offsetMin = new Vector2(sideMargin, 0f);
			rt.offsetMax = new Vector2(0f - sideMargin, 0f);
			rt.anchoredPosition = new Vector2(0f, 0f - top);
			rt.sizeDelta = new Vector2(0f, height);
		}

		public static void Stretch(RectTransform rt, float padX = 0f, float padY = 0f)
		{
			//IL_0001: 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_0019: 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)
			rt.anchorMin = Vector2.zero;
			rt.anchorMax = Vector2.one;
			rt.offsetMin = new Vector2(padX, padY);
			rt.offsetMax = new Vector2(0f - padX, 0f - padY);
		}
	}
	public enum GameMode
	{
		Free,
		Random
	}
	public class PluginConfig
	{
		public ConfigEntry<GameMode> Mode;

		public ConfigEntry<string> DiceItem;

		public ConfigEntry<float> DiceChance;

		public ConfigEntry<float> RandomShapeSeconds;

		public ConfigEntry<Key> DebugDiceKey;

		public ConfigEntry<string> DiceSkinBundle;

		public ConfigEntry<string> DiceSkinAsset;

		public ConfigEntry<float> DiceSkinScale;

		public ConfigEntry<float> DiceSkinOffsetY;

		public ConfigEntry<bool> DiceSkinFixShaders;

		public ConfigEntry<string> DiceSkinIcon;

		public ConfigEntry<string> DiceIconFile;

		public ConfigEntry<string> DiceName;

		public ConfigEntry<bool> DiceMatchHitbox;

		public ConfigEntry<Key> MenuKey;

		public ConfigEntry<Key> ReleaseKey;

		public ConfigEntry<bool> HostOnly;

		public ConfigEntry<bool> ReturnToShapePosition;

		public ConfigEntry<float> MobWalkSpeed;

		public ConfigEntry<float> MobSprintSpeed;

		public ConfigEntry<float> MobTurnRate;

		public ConfigEntry<float> FrogTongueCooldown;

		public ConfigEntry<float> FrogTongueAngle;

		public ConfigEntry<bool> FrogTongueHitsCreatures;

		public ConfigEntry<float> FrogHopInterval;

		public ConfigEntry<bool> AutoClimb;

		public ConfigEntry<float> FlyerSpeed;

		public ConfigEntry<float> CondorGrabRange;

		public ConfigEntry<bool> CondorSolid;

		public ConfigEntry<bool> TornadoSucksItems;

		public ConfigEntry<float> TornadoItemSpeed;

		public ConfigEntry<float> TornadoItemHeight;

		public ConfigEntry<float> TornadoItemChaos;

		public ConfigEntry<float> TornadoItemFling;

		public ConfigEntry<bool> TornadoStopsAtWalls;

		public ConfigEntry<float> TornadoMaxClimbAngle;

		public ConfigEntry<float> TornadoProbeDistance;

		public ConfigEntry<float> TornadoMaxDrop;

		public ConfigEntry<float> TornadoWallHeight;

		public ConfigEntry<float> TornadoDuration;

		public ConfigEntry<bool> TornadoFadeOut;

		public ConfigEntry<Language> Language;

		public ConfigEntry<bool> ShowHud;

		public ConfigEntry<float> HudOffsetY;

		public ConfigEntry<float> CameraDistance;

		public ConfigEntry<bool> CameraWheelZoom;

		public ConfigEntry<bool> AnnounceOthers;

		public ConfigEntry<string> Feedback;

		public PluginConfig(ConfigFile file)
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Expected O, but got Unknown
			//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02af: Expected O, but got Unknown
			//IL_0376: Unknown result type (might be due to invalid IL or missing references)
			//IL_0380: Expected O, but got Unknown
			//IL_03af: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b9: Expected O, but got Unknown
			//IL_0460: Unknown result type (might be due to invalid IL or missing references)
			//IL_046a: Expected O, but got Unknown
			//IL_04d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04df: Expected O, but got Unknown
			//IL_050e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0518: Expected O, but got Unknown
			//IL_0547: Unknown result type (might be due to invalid IL or missing references)
			//IL_0551: Expected O, but got Unknown
			//IL_0580: Unknown result type (might be due to invalid IL or missing references)
			//IL_058a: Expected O, but got Unknown
			//IL_05b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c3: Expected O, but got Unknown
			//IL_0646: Unknown result type (might be due to invalid IL or missing references)
			//IL_0650: Expected O, but got Unknown
			//IL_067f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0689: Expected O, but got Unknown
			Mode = file.Bind<GameMode>("0 - Mode", "Mode", GameMode.Random, "Random: no menu. Luggage sometimes holds a die; whoever throws it turns into a random creature for a while. Free: press the menu key and pick a shape yourself. Only the host decides where dice appear - the transformation runs on whoever throws.");
			DiceItem = file.Bind<string>("0 - Mode", "DiceItem", "c_king", "Which item from 0_Items acts as the die. Its own abilities are switched off, so any item works; only the name matters for recognising a thrown die.");
			DiceChance = file.Bind<float>("0 - Mode", "DiceChance", 0.25f, new ConfigDescription("Chance that an opened piece of luggage also holds a die. The normal loot is untouched - the die comes on top of it.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			RandomShapeSeconds = file.Bind<float>("0 - Mode", "RandomShapeSeconds", 60f, new ConfigDescription("How long a rolled shape lasts. You return on your own afterwards; the HUD counts down.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 600f), Array.Empty<object>()));
			DebugDiceKey = file.Bind<Key>("0 - Mode", "DebugDiceKey", (Key)100, "Drops a die at your feet for testing instead of waiting for luggage. Host only, because objects in the world belong to them.");
			DiceIconFile = file.Bind<string>("0 - Mode", "DiceIconFile", "MagicGemIcon.png", "PNG file next to the mod DLL used as the inventory icon. It is read directly, which sidesteps Unity's texture import - the icon from the bundle stayed white.");
			DiceSkinBundle = file.Bind<string>("0 - Mode", "DiceSkinBundle", "gemme", "Asset bundle next to the mod DLL whose model the die wears. Empty means the die looks like the item it replaces. Only the visuals are swapped - picking up, throwing and networking stay the original's.");
			DiceSkinAsset = file.Bind<string>("0 - Mode", "DiceSkinAsset", "MagicGem", "Name of the object inside the bundle. Empty takes the first one; the log lists everything the bundle holds at startup.");
			DiceSkinScale = file.Bind<float>("0 - Mode", "DiceSkinScale", 1f, "Size of the model, relative to the item it replaces. 1 means the same size.");
			DiceSkinOffsetY = file.Bind<float>("0 - Mode", "DiceSkinOffsetY", 0f, "Vertical shift of the model, in case its pivot is not centred.");
			DiceSkinFixShaders = file.Bind<bool>("0 - Mode", "DiceSkinFixShaders", true, "Moves standard shaders onto the URP shader. PEAK renders with the Universal Render Pipeline; a bundle from a plain 3D project would show up magenta.");
			DiceName = file.Bind<string>("0 - Mode", "DiceName", "Magic Gem", "Name the die carries in the belt. The repurposed item brings its own otherwise - PEAK's 'c_king', for instance, is called 'Green King Berry'.");
			DiceMatchHitbox = file.Bind<bool>("0 - Mode", "DiceMatchHitbox", true, "Grows the item's collider with the model. Without it a large gem sinks halfway into the ground and can only be picked up by its middle.");
			MenuKey = file.Bind<Key>("1 - Keys", "MenuKey", (Key)98, "Opens and closes the shape menu. Free mode only.");
			ReleaseKey = file.Bind<Key>("1 - Keys", "ReleaseKey", (Key)99, "Drops the current shape immediately.");
			HostOnly = file.Bind<bool>("2 - Rules", "HostOnly", false, "Only the host may pick a shape. Free mode only, and enforced by each client's own config - this is for rounds with friends, not cheat protection.");
			ReturnToShapePosition = file.Bind<bool>("2 - Rules", "ReturnToShapePosition", true, "You reappear where the creature was standing. Set to false to return to the spot you left, so nobody can ride a beetle up the mountain.");
			MobWalkSpeed = file.Bind<float>("3 - Creatures", "MobWalkSpeed", 5f, "Walking speed of beetle and scorpion (the game's own value is 5).");
			MobSprintSpeed = file.Bind<float>("3 - Creatures", "MobSprintSpeed", 11f, "Their speed while the sprint key is held.");
			MobTurnRate = file.Bind<float>("3 - Creatures", "MobTurnRate", 300f, new ConfigDescription("How fast beetle and scorpion turn while you steer them, in degrees per second. A mob always walks straight ahead - steering it means turning it - and the game gives each creature its own turn rate. The beetle's is low enough that it runs on regardless of the stick. 0 keeps whatever the creature brings.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1080f), Array.Empty<object>()));
			FrogTongueCooldown = file.Bind<float>("3 - Creatures", "FrogTongueCooldown", 2.5f, "Seconds between two tongue shots.");
			FrogTongueAngle = file.Bind<float>("3 - Creatures", "FrogTongueAngle", 30f, "Half-angle of the cone the tongue finds a target in. You aim with the camera, not with the frog's own facing.");
			FrogTongueHitsCreatures = file.Bind<bool>("3 - Creatures", "FrogTongueHitsCreatures", true, "The tongue also grabs the Scoutmaster and zombies, not just scouts. Beetle, scorpion and frog cannot be grabbed - the game does not treat them as characters, and the tongue can only pull characters.");
			FrogHopInterval = file.Bind<float>("3 - Creatures", "FrogHopInterval", 0.6f, "Seconds between two hops. The frog cannot walk - hopping is how PEAK moves it.");
			AutoClimb = file.Bind<bool>("3 - Creatures", "AutoClimb", true, "Scoutmaster and zombies climb when you walk into a wall. That is exactly what their own AI does; without it they cannot get up any ledge.");
			FlyerSpeed = file.Bind<float>("3 - Creatures", "FlyerSpeed", 1f, new ConfigDescription("Speed multiplier for the flying shapes - bee swarm, gloom ghost and condor. Lower it if they feel twitchy, raise it if they crawl.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 3f), Array.Empty<object>()));
			CondorGrabRange = file.Bind<float>("3 - Creatures", "CondorGrabRange", 7f, new ConfigDescription("How close a scout has to be below the condor before it can snatch them. The game's own condor uses five metres and dives at them; a steered one grabs on the attack key instead, so it needs a little more room.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 25f), Array.Empty<object>()));
			CondorSolid = file.Bind<bool>("3 - Creatures", "CondorSolid", true, "The steered condor stops at rock and ground instead of flying through it. PEAK's own condor never touches anything - it circles high above the mountain - so nothing stops it. At a wall it slides along rather than halting dead. Turn this off to fly through the world.");
			TornadoSucksItems = file.Bind<bool>("3 - Creatures", "TornadoSucksItems", true, "The tornado also pulls in loose items, not just players. Applies to every tornado in the run, not only a steered one.");
			TornadoItemSpeed = file.Bind<float>("3 - Creatures", "TornadoItemSpeed", 22f, "Base speed at which items circle inside the vortex. Each item gets its own share of it so they do not fly in lockstep.");
			TornadoItemHeight = file.Bind<float>("3 - Creatures", "TornadoItemHeight", 12f, "Base height above the foot of the tornado that items scatter around.");
			TornadoItemChaos = file.Bind<float>("3 - Creatures", "TornadoItemChaos", 0.7f, new ConfigDescription("How restless the vortex is. 0 gives a clean circle, 1 throws items about and occasionally flings one right out.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			TornadoItemFling = file.Bind<float>("3 - Creatures", "TornadoItemFling", 30f, "Speed at which an item is flung out of the vortex. It is then left alone for five seconds, otherwise the pull drags it straight back.");
			TornadoStopsAtWalls = file.Bind<bool>("3 - Creatures", "TornadoStopsAtWalls", true, "The steered tornado does not pass through cliff walls. Slopes it still climbs, and at a wall it slides along instead of stopping dead.");
			TornadoMaxClimbAngle = file.Bind<float>("3 - Creatures", "TornadoMaxClimbAngle", 55f, new ConfigDescription("Steepest slope in degrees the tornado still drives up. Higher means it takes steeper ground and gets stuck less often.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(20f, 89f), Array.Empty<object>()));
			TornadoProbeDistance = file.Bind<float>("3 - Creatures", "TornadoProbeDistance", 8f, new ConfigDescription("How far ahead the ground is checked. Short reacts late and lets it run into walls; long makes it dodge distant hills.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 25f), Array.Empty<object>()));
			TornadoWallHeight = file.Bind<float>("3 - Creatures", "TornadoWallHeight", 7f, new ConfigDescription("How tall an obstacle has to be to count as a wall. Anything lower - stone pillars, boulders, bushes - the tornado drives straight through.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 40f), Array.Empty<object>()));
			TornadoMaxDrop = file.Bind<float>("3 - Creatures", "TornadoMaxDrop", 20f, new ConfigDescription("How far the tornado may drop at most. It does not fall - PEAK snaps it onto the ground beneath it, at a cliff that means many metres down, player included. 0 removes the limit.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 200f), Array.Empty<object>()));
			TornadoDuration = file.Bind<float>("3 - Creatures", "TornadoDuration", 60f, new ConfigDescription("Seconds a steered tornado holds before it dissolves on its own. 0 means unlimited, so it only ends on a key press.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 180f), Array.Empty<object>()));
			TornadoFadeOut = file.Bind<bool>("3 - Creatures", "TornadoFadeOut", true, "The tornado fades out like a real one when you let go - it shrinks, and only once it is gone does the player appear in its place.");
			Language = file.Bind<Language>("4 - Display", "Language", EnemyControl.Language.English, "Language of the mod's texts. Auto follows the system language.");
			ShowHud = file.Bind<bool>("4 - Display", "ShowHud", true, "Shows which shape you are wearing and how to control it, bottom left.");
			HudOffsetY = file.Bind<float>("4 - Display", "HudOffsetY", 240f, new ConfigDescription("Distance of the key list from the bottom of the screen. High enough that the stamina bar fits underneath, even when extra stamina makes it grow.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(80f, 600f), Array.Empty<object>()));
			CameraDistance = file.Bind<float>("4 - Display", "CameraDistance", 1f, new ConfigDescription("Multiplier for how far the camera sits behind a shape. Raise it if a large creature fills the screen, lower it for a tighter view.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.4f, 3f), Array.Empty<object>()));
			CameraWheelZoom = file.Bind<bool>("4 - Display", "CameraWheelZoom", true, "The mouse wheel pulls the camera in and pushes it out while you wear a shape. All the way in puts you inside the creature - the shape is then hidden for you alone, so you look out of its eyes. Everyone else still sees it.");
			AnnounceOthers = file.Bind<bool>("4 - Display", "AnnounceOthers", true, "Announces when another player takes or drops a shape.");
			Feedback = file.Bind<string>("5 - About", "Feedback", "https://github.com/xBananegame/PEAKModes/issues", "Found a bug or have an idea? Open an issue here. Please attach BepInEx/LogOutput.log when reporting a bug. Changing this value does nothing.");
		}
	}
	[BepInPlugin("com.bananegame.enemycontrol", "EnemyControl", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		public const string Guid = "com.bananegame.enemycontrol";

		public const string Name = "EnemyControl";

		public const string Version = "1.0.0";

		public const string FeedbackUrl = "https://github.com/xBananegame/PEAKModes/issues";

		public static ManualLogSource Log;

		public static PluginConfig Cfg;

		private Harmony _harmony;

		private GameObject _runtime;

		private void Awake()
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			//IL_0115: 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_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			Cfg = new PluginConfig(((BaseUnityPlugin)this).Config);
			Loc.Current = Cfg.Language.Value;
			_harmony = new Harmony("com.bananegame.enemycontrol");
			_harmony.PatchAll();
			_runtime = new GameObject("EnemyControlRuntime");
			((Object)_runtime).hideFlags = (HideFlags)61;
			Object.DontDestroyOnLoad((Object)(object)_runtime);
			_runtime.AddComponent<ShapeNetworkManager>();
			_runtime.AddComponent<ShapeController>();
			_runtime.AddComponent<ShapeMenu>();
			_runtime.AddComponent<ShapeHud>();
			_runtime.AddComponent<DiceManager>();
			SceneManager.sceneLoaded += OnSceneLoaded;
			Log.LogInfo((object)"EnemyControl 1.0.0 geladen. Fehler und Wuensche bitte hier melden: https://github.com/xBananegame/PEAKModes/issues");
			Log.LogInfo((object)("Modus: " + Cfg.Mode.Value.ToString() + ", Menue: " + ((object)Cfg.MenuKey.Value/*cast due to .constrained prefix*/).ToString() + ", Ablegen: " + ((object)Cfg.ReleaseKey.Value/*cast due to .constrained prefix*/).ToString()));
			Log.LogInfo((object)("Tornado: Dauer=" + Cfg.TornadoDuration.Value + "s, Tempo=" + Cfg.TornadoItemSpeed.Value + ", Hoehe=" + Cfg.TornadoItemHeight.Value + ", Unruhe=" + Cfg.TornadoItemChaos.Value + ", Schleudern=" + Cfg.TornadoItemFling.Value + ", Waende=" + Cfg.TornadoStopsAtWalls.Value + ", Steigung=" + Cfg.TornadoMaxClimbAngle.Value + " Grad, Vorausschau=" + Cfg.TornadoProbeDistance.Value + "m"));
		}

		private void OnDestroy()
		{
			SceneManager.sceneLoaded -= OnSceneLoaded;
			if ((Object)(object)_runtime != (Object)null)
			{
				Object.Destroy((Object)(object)_runtime);
			}
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			ShapeController.Instance?.Release(teleportBack: false);
			ShapeController.Instance?.ForceReset();
			DiceManager.Instance?.Clear();
			BodyMask.RestoreAll();
			CondorLoan.ClearCache();
			MobCatalog.ClearCache();
			ShapeState.ClearNetworkState();
			ShapeState.ClearLocal();
			PeakUi.DropFontCache();
			if (((Scene)(ref scene)).name.Contains("Level_") || ((Scene)(ref scene)).name == "WilIsland")
			{
				((MonoBehaviour)this).StartCoroutine(WarmCondorCache());
			}
		}

		private IEnumerator WarmCondorCache()
		{
			yield return (object)new WaitForSeconds(5f);
			Condor[] array = CondorLoan.All();
			Log.LogInfo((object)("Kondore in diesem Level: " + array.Length));
		}

		private void Update()
		{
			//IL_0015: 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_0075: Unknown result type (might be due to invalid IL or missing references)
			Keyboard current = Keyboard.current;
			if (current == null)
			{
				return;
			}
			if (((ButtonControl)current[Cfg.MenuKey.Value]).wasPressedThisFrame)
			{
				if (Cfg.Mode.Value == GameMode.Free)
				{
					ShapeMenu.Instance?.Toggle();
				}
				else
				{
					Toast(Loc.T("mode.random.hint"));
				}
			}
			if (Cfg.Mode.Value == GameMode.Random && ((ButtonControl)current[Cfg.DebugDiceKey.Value]).wasPressedThisFrame)
			{
				DiceManager.Instance?.PlaceDieInFront();
			}
			if (((ButtonControl)current[Cfg.ReleaseKey.Value]).wasPressedThisFrame)
			{
				ShapeController.Instance?.Release();
			}
		}

		public static void Toast(string message)
		{
			Log.LogInfo((object)message);
			ShapeHud.Instance?.Toast(message);
		}
	}
	public class ShapeCamera : MonoBehaviour
	{
		private struct MaskedRenderer
		{
			public Renderer Target;

			public ShadowCastingMode Mode;

			public bool Disabled;
		}

		private CameraOverride _override;

		private MobDef _def;

		private bool _active;

		private float _yaw;

		private float _pitch = 12f;

		private Vector3 _pivot;

		private Vector3 _pivotVelocity;

		private float _zoom = 1f;

		private float _lastWanted = -1f;

		private readonly List<MaskedRenderer> _hidden = new List<MaskedRenderer>();

		private float _boom;

		private MouseSensitivitySetting _mouseSens;

		private ControllerSensitivitySetting _padSens;

		private InvertXSetting _invertX;

		private InvertYSetting _invertY;

		private const float PivotSmoothing = 0.05f;

		private const float CameraRadius = 0.35f;

		private const float BoomExtendSpeed = 20f;

		private const float FirstPersonAt = 1.2f;

		private const float ZoomStep = 0.12f;

		public bool IsActive => _active;

		public Vector3 PlanarForward => Quaternion.Euler(0f, _yaw, 0f) * Vector3.forward;

		public Vector3 PlanarRight => Quaternion.Euler(0f, _yaw, 0f) * Vector3.right;

		public Vector3 LookForward => Quaternion.Euler(_pitch, _yaw, 0f) * Vector3.forward;

		private void Awake()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			GameObject val = new GameObject("EnemyControlCamera");
			((Object)val).hideFlags = (HideFlags)61;
			val.transform.SetParent(((Component)this).transform, false);
			_override = val.AddComponent<CameraOverride>();
			_override.fov = 70f;
		}

		public void Begin(MobDef def)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			_def = def;
			_active = true;
			_pitch = 12f;
			_yaw = (((Object)(object)ShapeState.ActiveObject != (Object)null) ? ShapeState.ActiveObject.transform.eulerAngles.y : 0f);
			_pivot = RawPivot();
			_pivotVelocity = Vector3.zero;
			_lastWanted = -1f;
			_boom = (def?.CamDistance ?? 6f) * Plugin.Cfg.CameraDistance.Value;
			SettingsHandler val = (((Object)(object)GameHandler.Instance != (Object)null) ? GameHandler.Instance.SettingsHandler : null);
			if (val != null)
			{
				_mouseSens = val.GetSetting<MouseSensitivitySetting>();
				_padSens = val.GetSetting<ControllerSensitivitySetting>();
				_invertX = val.GetSetting<InvertXSetting>();
				_invertY = val.GetSetting<InvertYSetting>();
			}
			Place();
			Push();
		}

		public void End()
		{
			_active = false;
			_def = null;
			ShowShape();
			if ((Object)(object)MainCamera.instance != (Object)null && (Object)(object)MainCamera.instance.camOverride == (Object)(object)_override)
			{
				MainCamera.instance.SetCameraOverride((CameraOverride)null);
			}
		}

		private void LateUpdate()
		{
			if (!_active || !ShapeState.IsTransformed)
			{
				if ((Object)(object)MainCamera.instance != (Object)null && (Object)(object)MainCamera.instance.camOverride == (Object)(object)_override)
				{
					MainCamera.instance.SetCameraOverride((CameraOverride)null);
				}
			}
			else
			{
				ReadLook();
				ReadZoom();
				Place();
				Push();
			}
		}

		private void Push()
		{
			if ((Object)(object)MainCamera.instance != (Object)null && (Object)(object)MainCamera.instance.camOverride != (Object)(object)_override)
			{
				MainCamera.instance.SetCameraOverride(_override);
			}
		}

		private void ReadLook()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: 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_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: 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_0069: 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)
			if (ShapeMenu.IsOpen || CharacterInput.action_look == null)
			{
				return;
			}
			Vector2 val = CharacterInput.action_look.ReadValue<Vector2>();
			float num = 0.25f;
			if ((int)InputHandler.GetCurrentUsedInputScheme() == 0)
			{
				if (_mouseSens != null)
				{
					num = ((FloatSetting)_mouseSens).Value;
				}
			}
			else if (_padSens != null)
			{
				num = ((FloatSetting)_padSens).Value;
			}
			if (_invertX != null && (int)((EnumSetting<OffOnMode>)(object)_invertX).Value != 0)
			{
				val.x = 0f - val.x;
			}
			if (_invertY != null && (int)((EnumSetting<OffOnMode>)(object)_invertY).Value != 0)
			{
				val.y = 0f - val.y;
			}
			_yaw += val.x * num;
			_pitch = Mathf.Clamp(_pitch - val.y * num, -70f, 80f);
		}

		private void ReadZoom()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.Cfg.CameraWheelZoom.Value || ShapeMenu.IsOpen)
			{
				return;
			}
			Mouse current = Mouse.current;
			if (current != null)
			{
				float y = ((InputControl<Vector2>)(object)current.scroll).ReadValue().y;
				if (!(Mathf.Abs(y) < 0.01f))
				{
					_zoom = Mathf.Clamp(_zoom - Mathf.Sign(y) * 0.12f, 0f, 2f);
				}
			}
		}

		private void HideShape()
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: 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_006e: 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)
			if (_hidden.Count > 0)
			{
				return;
			}
			GameObject activeObject = ShapeState.ActiveObject;
			if ((Object)(object)activeObject == (Object)null)
			{
				return;
			}
			Renderer[] componentsInChildren = activeObject.GetComponentsInChildren<Renderer>(false);
			foreach (Renderer val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null) && val.enabled)
				{
					ShadowCastingMode shadowCastingMode = val.shadowCastingMode;
					if ((int)shadowCastingMode == 0)
					{
						val.enabled = false;
						_hidden.Add(new MaskedRenderer
						{
							Target = val,
							Mode = shadowCastingMode,
							Disabled = true
						});
					}
					else
					{
						val.shadowCastingMode = (ShadowCastingMode)3;
						_hidden.Add(new MaskedRenderer
						{
							Target = val,
							Mode = shadowCastingMode
						});
					}
				}
			}
		}

		private void ShowShape()
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			foreach (MaskedRenderer item in _hidden)
			{
				if (!((Object)(object)item.Target == (Object)null))
				{
					if (item.Disabled)
					{
						item.Target.enabled = true;
					}
					else
					{
						item.Target.shadowCastingMode = item.Mode;
					}
				}
			}
			_hidden.Clear();
		}

		private Vector3 RawPivot()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			float num = ((_def != null) ? _def.CamHeight : 0.6f);
			return ShapeState.EntityPosition + Vector3.up * num;
		}

		private void Place()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: 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_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_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: 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_0030: 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_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: 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_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: 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_01a6: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = RawPivot();
			Vector3 val2 = val - _pivot;
			if (((Vector3)(ref val2)).sqrMagnitude > 400f)
			{
				_pivot = val;
				_pivotVelocity = Vector3.zero;
			}
			else
			{
				_pivot = Vector3.SmoothDamp(_pivot, val, ref _pivotVelocity, 0.05f, float.PositiveInfinity, Time.deltaTime);
			}
			float num = ((_def != null) ? _def.CamDistance : 6f) * Plugin.Cfg.CameraDistance.Value * _zoom;
			Quaternion val3 = Quaternion.Euler(_pitch, _yaw, 0f);
			Vector3 val4 = val3 * Vector3.back;
			Transform transform = ((Component)_override).transform;
			if (num < 1.2f)
			{
				HideShape();
				transform.position = _pivot;
				transform.rotation = val3;
				_lastWanted = num;
				_boom = 0f;
				return;
			}
			ShowShape();
			float num2 = num;
			RaycastHit val5 = default(RaycastHit);
			if (Physics.SphereCast(_pivot, 0.35f, val4, ref val5, num, LayerMask.op_Implicit(HelperFunctions.terrainMapMask), (QueryTriggerInteraction)1))
			{
				num2 = Mathf.Max(1f, ((RaycastHit)(ref val5)).distance);
			}
			if (!Mathf.Approximately(num, _lastWanted))
			{
				_boom = num2;
				_lastWanted = num;
			}
			else
			{
				_boom = ((num2 < _boom) ? num2 : Mathf.MoveTowards(_boom, num2, 20f * Time.deltaTime));
			}
			Transform transform2 = ((Component)_override).transform;
			transform2.position = _pivot + val4 * _boom;
			transform2.rotation = val3;
		}
	}
	public class ShapeController : MonoBehaviour
	{
		private ShapeCamera _camera;

		private CharacterRagdoll _maskedRagdoll;

		private bool _busy;

		private float _throwCooldown;

		private Transform _driftTarget;

		private RigidbodyInterpolation _flyerInterpolation;

		private RigidbodyConstraints _flyerConstraints;

		private float _flyerDamping;

		private float _flyerAngularDamping;

		private bool _flyerGravity;

		private float _frogCooldown;

		private float _hopCooldown;

		private bool _dissolving;

		private float _mobTurnRate = -1f;

		private Condor _condor;

		private bool _condorCarrying;

		private float _poseCooldown;

		private RigidbodyInterpolation _condorInterpolation;

		private bool _condorKinematic;

		private bool _condorGravity;

		private bool _condorRootMotion;

		private Vector3 _lastFreePos;

		private bool _hasFreePos;

		private Vector3 _startPos;

		private bool _hasStartPos;

		private int _entityViewId = -1;

		private bool _attackBroadcast;

		public static ShapeController Instance { get; private set; }

		public int EntityViewId => _entityViewId;

		private void Awake()
		{
			Instance = this;
			_camera = ((Component)this).gameObject.AddComponent<ShapeCamera>();
		}

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

		public string BlockedReason()
		{
			if (!PhotonNetwork.InRoom)
			{
				return Loc.T("menu.blocked.room");
			}
			Character localCharacter = Character.localCharacter;
			if ((Object)(object)localCharacter == (Object)null)
			{
				return Loc.T("menu.blocked.room");
			}
			if ((Object)(object)localCharacter.data != (Object)null && (localCharacter.data.dead || localCharacter.data.fullyPassedOut))
			{
				return Loc.T("menu.blocked.dead");
			}
			if (_dissolving)
			{
				return Loc.T("menu.blocked.dissolving");
			}
			if (Plugin.Cfg.Mode.Value == GameMode.Free && Plugin.Cfg.HostOnly.Value && !PhotonNetwork.IsMasterClient)
			{
				return Loc.T("menu.blocked.host");
			}
			return null;
		}

		public void TakeRandom()
		{
			List<MobDef> list = new List<MobDef>();
			MobDef[] all = MobCatalog.All;
			foreach (MobDef mobDef in all)
			{
				if (MobCatalog.IsAvailable(mobDef))
				{
					list.Add(mobDef);
				}
			}
			if (list.Count == 0)
			{
				Plugin.Log.LogWarning((object)"Wuerfel geworfen, aber in diesem Level gibt es keine Kreatur.");
				return;
			}
			MobDef mobDef2 = list[Random.Range(0, list.Count)];
			Plugin.Toast(Loc.T("toast.dicehit", mobDef2.Name));
			Take(mobDef2);
		}

		public void Take(MobDef def)
		{
			if (!_busy && !_dissolving && def != null && BlockedReason() == null && MobCatalog.IsAvailable(def))
			{
				((MonoBehaviour)this).StartCoroutine(TakeRoutine(def));
			}
		}

		private IEnumerator TakeRoutine(MobDef def)
		{
			_busy = true;
			if (ShapeState.HasShape)
			{
				Release(teleportBack: false);
			}
			_condor = null;
			_condorCarrying = false;
			_poseCooldown = 0f;
			ShapeState.EntityFacing = Vector3.forward;
			Character me = Character.localCharacter;
			GameObject spawned = null;
			Vector3 forward = (((Object)(object)MainCamera.instance != (Object)null) ? ((Component)MainCamera.instance).transform.forward : ((Component)me).transform.forward);
			forward.y = 0f;
			if (((Vector3)(ref forward)).sqrMagnitude < 0.01f)
			{
				forward = Vector3.forward;
			}
			((Vector3)(ref forward)).Normalize();
			Vector3 val = me.Center + forward * 3f;
			RaycastHit groundPosRaycast = HelperFunctions.GetGroundPosRaycast(val + Vector3.up * 3f, (LayerType)1, 0f);
			if ((Object)(object)((RaycastHit)(ref groundPosRaycast)).transform != (Object)null && Vector3.Distance(((RaycastHit)(ref groundPosRaycast)).point, val) < 30f)
			{
				val = ((RaycastHit)(ref groundPosRaycast)).point + Vector3.up * 0.5f;
			}
			if (def.SceneEntity)
			{
				if (!MobCatalog.FindNearestCondor(me.Center, out var nearest))
				{
					Plugin.Toast(Loc.T("toast.nocondor"));
					_busy = false;
					yield break;
				}
				_condor = CondorLoan.Borrow(CondorLoan.IdOf(nearest));
				if ((Object)(object)_condor == (Object)null || (Object)(object)_condor.view == (Object)null)
				{
					Plugin.Toast(Loc.T("toast.nocondor"));
					_busy = false;
					yield break;
				}
				yield return null;
				if ((Object)(object)_condor == (Object)null)
				{
					_busy = false;
					yield break;
				}
				if (CondorLoan.TryGetHome(_condor.view.ViewID, out var home))
				{
					_condor._initPos = home;
				}
				spawned = ((Component)_condor).gameObject;
				MoveCondorTo(me.Center + Vector3.up * 16f, forward);
			}
			else
			{
				try
				{
					spawned = PhotonNetwork.Instantiate(def.PrefabName, val, Quaternion.LookRotation(forward), (byte)0, (object[])null);
				}
				catch (Exception ex)
				{
					Plugin.Log.LogWarning((object)("Spawn von " + def.PrefabName + " fehlgeschlagen: " + ex.Message));
				}
				if ((Object)(object)spawned == (Object)null)
				{
					Plugin.Toast(Loc.T("toast.spawnfailed", def.Name));
					_busy = false;
					yield break;
				}
				yield return null;
				yield return null;
				if ((Object)(object)spawned == (Object)null)
				{
					_busy = false;
					yield break;
				}
			}
			ShapeState.HasShape = true;
			ShapeState.ActiveDef = def;
			ShapeState.ActiveObject = spawned;
			ShapeState.ActiveCharacter = spawned.GetComponent<Character>();
			ShapeState.ActiveMob = spawned.GetComponent<Mob>();
			ShapeState.ActiveZombie = spawned.GetComponent<MushroomZombie>();
			ShapeState.ActiveRigidbody = spawned.GetComponent<Rigidbody>();
			PhotonView val2 = (((Object)(object)_condor != (Object)null) ? _condor.view : spawned.GetComponent<PhotonView>());
			int num = (_entityViewId = (((Object)(object)val2 != (Object)null) ? val2.ViewID : (-1)));
			if (num > 0)
			{
				ShapeState.ControlledEntities.Add(num);
			}
			_lastFreePos = me.Center;
			_hasFreePos = true;
			_startPos = me.Center;
			_hasStartPos = true;
			PrepareEntity(def);
			MaskLocalBody(masked: true);
			_camera.Begin(def);
			int bodyViewId = (((Object)(object)((MonoBehaviourPun)me).photonView != (Object)null) ? ((MonoBehaviourPun)me).photonView.ViewID : (-1));
			ShapeState.ShapesByActor[PhotonNetwork.LocalPlayer.ActorNumber] = def.Id;
			EnemyControlNet.BroadcastShape(def.Id, bodyViewId, num);
			float num2 = ((def.Kind == ControlKind.Drifter) ? Plugin.Cfg.TornadoDuration.Value : 0f);
			if (Plugin.Cfg.Mode.Value == GameMode.Random)
			{
				float value = Plugin.Cfg.RandomShapeSeconds.Value;
				num2 = ((num2 > 0f) ? Mathf.Min(num2, value) : value);
			}
			ShapeState.ShapeSecondsLeft = num2;
			Plugin.Toast(Loc.T("toast.taken", def.Name));
			Plugin.Log.LogInfo((object)("Gestalt angenommen: " + def.Id + " (" + def.PrefabName + "), ViewID " + num));
			_busy = false;
		}

		private void PrepareEntity(MobDef def)
		{
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: 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_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Expected O, but got Unknown
			//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_039f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b1: Unknown result type (might be due to invalid IL or missing references)
			Mob activeMob = ShapeState.ActiveMob;
			if ((Object)(object)activeMob != (Object)null)
			{
				activeMob.sleeping = false;
				activeMob.UpdateSleeping();
				activeMob._timeLastAttacked = Time.time - 100f;
				if ((Object)(object)activeMob.rig != (Object)null)
				{
					activeMob.rig.interpolation = (RigidbodyInterpolation)1;
				}
				_mobTurnRate = activeMob.turnRate;
				if (Plugin.Cfg.MobTurnRate.Value > 0f)
				{
					activeMob.turnRate = Plugin.Cfg.MobTurnRate.Value;
				}
				Plugin.Log.LogInfo((object)("Mob " + def.Id + " uebernommen: Drehrate vorher " + _mobTurnRate.ToString("0.#") + ", jetzt " + activeMob.turnRate.ToString("0.#")));
			}
			MushroomZombie activeZombie = ShapeState.ActiveZombie;
			if ((Object)(object)activeZombie != (Object)null)
			{
				activeZombie.lifetime = float.MaxValue;
				activeZombie.currentState = (State)3;
			}
			if (def.Kind == ControlKind.Drifter)
			{
				Tornado component = ShapeState.ActiveObject.GetComponent<Tornado>();
				if ((Object)(object)component != (Object)null)
				{
					component.lifeTime = float.MaxValue;
					if ((Object)(object)_driftTarget == (Object)null)
					{
						GameObject val = new GameObject("EnemyControlDriftTarget");
						((Object)val).hideFlags = (HideFlags)61;
						_driftTarget = val.transform;
					}
					_driftTarget.position = ShapeState.ActiveObject.transform.position;
					component.target = _driftTarget;
				}
			}
			if ((Object)(object)_condor != (Object)null && (Object)(object)_condor.rb != (Object)null)
			{
				_condorInterpolation = _condor.rb.interpolation;
				_condorKinematic = _condor.rb.isKinematic;
				_condorGravity = _condor.rb.useGravity;
				_condor.rb.interpolation = (RigidbodyInterpolation)1;
				_condor.rb.isKinematic = true;
				_condor.rb.useGravity = false;
				Plugin.Log.LogInfo((object)("Kondor uebernommen: vorher kinematisch " + _condorKinematic + ", Schwerkraft " + _condorGravity + ", Interpolation " + ((object)Unsafe.As<RigidbodyInterpolation, RigidbodyInterpolation>(ref _condorInterpolation)/*cast due to .constrained prefix*/).ToString()));
			}
			if ((Object)(object)_condor != (Object)null && (Object)(object)_condor.anim != (Object)null)
			{
				_condorRootMotion = _condor.anim.applyRootMotion;
				_condor.anim.applyRootMotion = false;
			}
			if ((Object)(object)_condor != (Object)null && (int)_condor._state != 0 && (Object)(object)_condor._targetChar != (Object)null && (Object)(object)_condor.view != (Object)null)
			{
				_condor.view.RPC("RPCA_CondorAction", (RpcTarget)0, new object[2]
				{
					((MonoBehaviourPun)_condor._targetChar).photonView,
					(object)(CondorActionType)2
				});
			}
			GhostBall component2 = ShapeState.ActiveObject.GetComponent<GhostBall>();
			if ((Object)(object)component2 != (Object)null)
			{
				component2.chaseHeight = float.MinValue;
				component2.lifetime = float.MaxValue;
				component2._readyToExplode = false;
				component2.exploding = false;
				component2.explosionTick = 0f;
			}
			if (def.Kind == ControlKind.Flyer && (Object)(object)ShapeState.ActiveRigidbody != (Object)null)
			{
				Rigidbody activeRigidbody = ShapeState.ActiveRigidbody;
				_flyerInterpolation = activeRigidbody.interpolation;
				_flyerConstraints = activeRigidbody.constraints;
				_flyerDamping = activeRigidbody.linearDamping;
				_flyerAngularDamping = activeRigidbody.angularDamping;
				_flyerGravity = activeRigidbody.useGravity;
				activeRigidbody.useGravity = false;
				activeRigidbody.interpolation = (RigidbodyInterpolation)1;
				activeRigidbody.linearDamping = 0f;
				activeRigidbody.angularDamping = 8f;
				activeRigidbody.constraints = (RigidbodyConstraints)0;
				Plugin.Log.LogInfo((object)("Flieger " + def.Id + ": Masse " + activeRigidbody.mass.ToString("0.##") + ", Daempfung " + _flyerDamping.ToString("0.##") + "/" + _flyerAngularDamping.ToString("0.##") + ", kinematisch " + activeRigidbody.isKinematic + ", Sperren " + ((object)Unsafe.As<RigidbodyConstraints, RigidbodyConstraints>(ref _flyerConstraints)/*cast due to .constrained prefix*/).ToString() + ", Tempo " + (def.Speed * Plugin.Cfg.FlyerSpeed.Value).ToString("0.#")));
			}
		}

		private void MoveCondorTo(Vector3 position, Vector3 forward)
		{
			//IL_001a: 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_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_condor == (Object)null))
			{
				((Component)_condor).transform.position = position;
				if (((Vector3)(ref forward)).sqrMagnitude > 0.0001f)
				{
					((Component)_condor).transform.forward = ((Vector3)(ref forward)).normalized;
				}
				if ((O