Decompiled source of BigMonsterEnergy v0.5.1

plugins/AshHenbrey.BigMonsterEnergy.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using Microsoft.CodeAnalysis;
using Peak.Afflictions;
using Photon.Pun;
using Photon.Realtime;
using TMPro;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using Zorro.Core;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("AshHenbrey.BigMonsterEnergy")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.5.1.0")]
[assembly: AssemblyInformationalVersion("0.5.1+78a907c017cf364fcb2e296a47204325d9e997ee")]
[assembly: AssemblyProduct("AshHenbrey.BigMonsterEnergy")]
[assembly: AssemblyTitle("Big Monster Energy")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.5.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	[Embedded]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	[Embedded]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace Microsoft.CodeAnalysis
{
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace BigMonsterEnergy
{
	internal class CarryCue : MonoBehaviour
	{
		private MonsterCanManager? _mgr;

		private Sprite? _fist;

		private bool _fistTried;

		private Image? _reachImg;

		private Sprite? _origSprite;

		private bool _swapped;

		private void Awake()
		{
			_mgr = ((Component)this).GetComponent<MonsterCanManager>();
		}

		private void Update()
		{
			Image val = ReachImage();
			if ((Object)(object)val == (Object)null)
			{
				_swapped = false;
			}
			else if ((Object)(object)_mgr != (Object)null && _mgr.AnyLocalCarry())
			{
				Sprite val2 = Fist();
				if ((Object)(object)val2 != (Object)null && (Object)(object)val.sprite != (Object)(object)val2)
				{
					if (!_swapped)
					{
						_origSprite = val.sprite;
					}
					val.sprite = val2;
					_swapped = true;
				}
			}
			else if (_swapped)
			{
				val.sprite = _origSprite;
				_swapped = false;
			}
		}

		private Image? ReachImage()
		{
			if ((Object)(object)_reachImg != (Object)null)
			{
				return _reachImg;
			}
			GUIManager instance = GUIManager.instance;
			if ((Object)(object)instance == (Object)null || (Object)(object)instance.reticleReach == (Object)null)
			{
				return null;
			}
			_reachImg = instance.reticleReach.GetComponentInChildren<Image>(true);
			_swapped = false;
			return _reachImg;
		}

		private Sprite? Fist()
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_fist != (Object)null || _fistTried)
			{
				return _fist;
			}
			_fistTried = true;
			Texture2D val = EmbeddedAssets.LoadTexture("fist-reticle.png", linear: false);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			((Texture)val).wrapMode = (TextureWrapMode)1;
			_fist = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
			return _fist;
		}

		private void OnDisable()
		{
			Restore();
		}

		private void OnDestroy()
		{
			Restore();
		}

		private void Restore()
		{
			if (_swapped && (Object)(object)_reachImg != (Object)null && (Object)(object)_origSprite != (Object)null)
			{
				_reachImg.sprite = _origSprite;
			}
			_swapped = false;
		}
	}
	internal static class EmbeddedAssets
	{
		private static readonly Assembly Self = typeof(EmbeddedAssets).Assembly;

		public static byte[]? ReadBytes(string endsWith)
		{
			string text = Self.GetManifestResourceNames().FirstOrDefault((string n) => n.EndsWith(endsWith, StringComparison.OrdinalIgnoreCase));
			if (text == null)
			{
				Plugin.Log.LogWarning((object)("Embedded resource ending in '" + endsWith + "' not found. Available: " + string.Join(", ", Self.GetManifestResourceNames())));
				return null;
			}
			using Stream stream = Self.GetManifestResourceStream(text);
			if (stream == null)
			{
				return null;
			}
			using MemoryStream memoryStream = new MemoryStream();
			stream.CopyTo(memoryStream);
			return memoryStream.ToArray();
		}

		public static Texture2D? LoadTexture(string endsWith, bool linear)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			byte[] array = ReadBytes(endsWith);
			if (array == null)
			{
				return null;
			}
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true, linear);
			if (!ImageConversion.LoadImage(val, array))
			{
				Plugin.Log.LogWarning((object)("Failed to decode embedded image '" + endsWith + "'."));
				return null;
			}
			((Texture)val).wrapMode = (TextureWrapMode)0;
			((Texture)val).anisoLevel = 4;
			val.Apply(true);
			return val;
		}

		public static Mesh? LoadMesh(string endsWith)
		{
			byte[] array = ReadBytes(endsWith);
			if (array == null)
			{
				return null;
			}
			try
			{
				string text = Encoding.UTF8.GetString(array);
				return ObjLoader.Parse(text, Path.GetFileNameWithoutExtension(endsWith));
			}
			catch (Exception arg)
			{
				Plugin.Log.LogWarning((object)$"OBJ parse failed for '{endsWith}': {arg}");
				return null;
			}
		}

		public static AudioClip? LoadWavMusicClip()
		{
			byte[] array = ReadBytes(".wav");
			if (array == null)
			{
				return null;
			}
			try
			{
				return WavDecoder.ToAudioClip(array, "MonsterCanMusic");
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("WAV decode failed: " + ex.Message));
			}
			return null;
		}

		public static bool TryGetCompressedAudio(out byte[] bytes, out string extension)
		{
			bytes = Array.Empty<byte>();
			extension = string.Empty;
			string text = Self.GetManifestResourceNames().FirstOrDefault((string n) => n.EndsWith(".ogg", StringComparison.OrdinalIgnoreCase) || n.EndsWith(".mp3", StringComparison.OrdinalIgnoreCase));
			if (text == null)
			{
				return false;
			}
			byte[] array = ReadBytes(text);
			if (array == null)
			{
				return false;
			}
			bytes = array;
			extension = Path.GetExtension(text);
			return true;
		}
	}
	internal static class GameBridge
	{
		private static bool _resolved;

		private static bool _ok;

		private static Type? _characterType;

		private static Type? _airportKioskType;

		private static MemberInfo? _localCharacterMember;

		private const BindingFlags AllInstance = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

		private const BindingFlags AllStatic = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;

		public static bool EnsureResolved()
		{
			if (_resolved)
			{
				return _ok;
			}
			_resolved = true;
			try
			{
				_characterType = FindType("Character");
				_airportKioskType = FindType("AirportCheckInKiosk");
				if (_characterType == null)
				{
					Plugin.Log.LogWarning((object)"GameBridge: 'Character' type not found; game features disabled.");
					return false;
				}
				_localCharacterMember = (MemberInfo?)(((object)_characterType.GetProperty("localCharacter", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)) ?? ((object)_characterType.GetField("localCharacter", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)));
				_ok = _localCharacterMember != null;
				if (!_ok)
				{
					Plugin.Log.LogWarning((object)"GameBridge: could not resolve Character.localCharacter.");
				}
				return _ok;
			}
			catch (Exception arg)
			{
				Plugin.Log.LogWarning((object)$"GameBridge resolve failed: {arg}");
				return false;
			}
		}

		public static Component? GetLocalCharacter()
		{
			if (!EnsureResolved())
			{
				return null;
			}
			object? obj = ReadMember(_localCharacterMember, null);
			return (Component?)((obj is Component) ? obj : null);
		}

		public static bool IsInAirport()
		{
			if (!EnsureResolved() || _airportKioskType == null)
			{
				return false;
			}
			try
			{
				return Object.FindAnyObjectByType(_airportKioskType) != (Object)null;
			}
			catch
			{
				return false;
			}
		}

		public static bool TryGetPlayerPosition(out Vector3 position)
		{
			//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_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			position = Vector3.zero;
			Component localCharacter = GetLocalCharacter();
			if ((Object)(object)localCharacter == (Object)null)
			{
				return false;
			}
			Character val = (Character)(object)((localCharacter is Character) ? localCharacter : null);
			position = ((val != null) ? val.Center : localCharacter.transform.position);
			return true;
		}

		private static Type? FindType(string name)
		{
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				Type type = assembly.GetType(name, throwOnError: false);
				if (type != null)
				{
					return type;
				}
			}
			Assembly[] assemblies2 = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly2 in assemblies2)
			{
				Type[] types;
				try
				{
					types = assembly2.GetTypes();
				}
				catch
				{
					continue;
				}
				Type type2 = types.FirstOrDefault((Type x) => x.Name == name);
				if (type2 != null)
				{
					return type2;
				}
			}
			return null;
		}

		private static object? ReadMember(MemberInfo? m, object? target)
		{
			if (!(m is PropertyInfo propertyInfo))
			{
				if (m is FieldInfo fieldInfo)
				{
					return fieldInfo.GetValue(target);
				}
				return null;
			}
			return propertyInfo.GetValue(target);
		}
	}
	internal class HeroMessage : MonoBehaviour
	{
		public static void Show(string message)
		{
			//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("MonsterCanHeroMessage");
			Object.DontDestroyOnLoad((Object)(object)val);
			val.AddComponent<HeroMessage>().Begin(message);
		}

		private void Begin(string message)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			Canvas val = ((Component)this).gameObject.AddComponent<Canvas>();
			val.renderMode = (RenderMode)0;
			val.sortingOrder = 32000;
			CanvasScaler val2 = ((Component)this).gameObject.AddComponent<CanvasScaler>();
			val2.uiScaleMode = (ScaleMode)1;
			val2.referenceResolution = new Vector2(1920f, 1080f);
			val2.matchWidthOrHeight = 0.5f;
			GameObject val3 = new GameObject("Text");
			val3.transform.SetParent(((Component)this).transform, false);
			TextMeshProUGUI val4 = val3.AddComponent<TextMeshProUGUI>();
			((TMP_Text)val4).text = message;
			((TMP_Text)val4).alignment = (TextAlignmentOptions)514;
			((TMP_Text)val4).textWrappingMode = (TextWrappingModes)1;
			((TMP_Text)val4).fontSize = 60f;
			((TMP_Text)val4).enableAutoSizing = true;
			((TMP_Text)val4).fontSizeMin = 26f;
			((TMP_Text)val4).fontSizeMax = 60f;
			TextMeshProUGUI val5 = (((Object)(object)GUIManager.instance != (Object)null) ? GUIManager.instance.heroText : null);
			if ((Object)(object)val5 != (Object)null)
			{
				if ((Object)(object)((TMP_Text)val5).font != (Object)null)
				{
					((TMP_Text)val4).font = ((TMP_Text)val5).font;
				}
				if ((Object)(object)((TMP_Text)val5).fontSharedMaterial != (Object)null)
				{
					((TMP_Text)val4).fontSharedMaterial = ((TMP_Text)val5).fontSharedMaterial;
				}
				((Graphic)val4).color = ((Graphic)val5).color;
				((TMP_Text)val4).fontStyle = ((TMP_Text)val5).fontStyle;
			}
			else
			{
				((Graphic)val4).color = Color.white;
			}
			RectTransform rectTransform = ((TMP_Text)val4).rectTransform;
			rectTransform.anchorMin = new Vector2(0.1f, 0.35f);
			rectTransform.anchorMax = new Vector2(0.9f, 0.65f);
			rectTransform.offsetMin = Vector2.zero;
			rectTransform.offsetMax = Vector2.zero;
			CanvasGroup val6 = ((Component)this).gameObject.AddComponent<CanvasGroup>();
			val6.alpha = 0f;
			((MonoBehaviour)this).StartCoroutine(Animate(val6));
		}

		private IEnumerator Animate(CanvasGroup group)
		{
			yield return Fade(group, 0f, 1f, 0.3f);
			yield return (object)new WaitForSeconds(2.6f);
			yield return Fade(group, 1f, 0f, 0.8f);
			Object.Destroy((Object)(object)((Component)this).gameObject);
		}

		private static IEnumerator Fade(CanvasGroup g, float from, float to, float dur)
		{
			for (float t = 0f; t < 1f; t += Time.deltaTime / dur)
			{
				g.alpha = Mathf.Lerp(from, to, t);
				yield return null;
			}
			g.alpha = to;
		}
	}
	internal class MonsterCanBehaviour : MonoBehaviour, IInteractibleConstant, IInteractible
	{
		public AudioSource? AudioSource;

		public float BaseOffsetY;

		public Vector3 LocalCenter;

		public int CanId;

		public int TaglineIndex;

		public int UsesLeft;

		public MonsterCanManager? Manager;

		private bool _consumed;

		private Rigidbody? _rb;

		private MonsterCanGrab? _grab;

		public float SpawnTime { get; private set; }

		public bool holdOnFinish => false;

		private void Start()
		{
			SpawnTime = Time.time;
			_rb = ((Component)this).GetComponent<Rigidbody>();
			_grab = ((Component)this).GetComponent<MonsterCanGrab>();
			EnsurePlaying();
		}

		public void EnsurePlaying()
		{
			if ((Object)(object)AudioSource != (Object)null && (Object)(object)AudioSource.clip != (Object)null && !AudioSource.isPlaying)
			{
				AudioSource.Play();
			}
		}

		public void SetUsesLeft(int usesLeft)
		{
			UsesLeft = usesLeft;
		}

		private void Update()
		{
			if (!_consumed && (!((Object)(object)_rb != (Object)null) || _rb.isKinematic) && (!((Object)(object)_grab != (Object)null) || !_grab.IsRemote))
			{
				float value = Plugin.SpinSpeedDegPerSec.Value;
				if (value != 0f)
				{
					((Component)this).transform.Rotate(0f, value * Time.deltaTime, 0f, (Space)0);
				}
			}
		}

		public bool IsInteractible(Character interactor)
		{
			if (!_consumed && UsesLeft > 0)
			{
				if ((Object)(object)_grab != (Object)null)
				{
					return !_grab.IsLocalCarrying;
				}
				return true;
			}
			return false;
		}

		public bool IsConstantlyInteractable(Character interactor)
		{
			return IsInteractible(interactor);
		}

		public float GetInteractTime(Character interactor)
		{
			return Plugin.HoldSeconds.Value;
		}

		public void Interact(Character interactor)
		{
		}

		public void CancelCast(Character interactor)
		{
		}

		public void ReleaseInteract(Character interactor)
		{
		}

		public void Interact_CastFinished(Character interactor)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			//IL_005f: Expected O, but got Unknown
			if (_consumed || UsesLeft <= 0 || (Object)(object)interactor?.refs?.afflictions == (Object)null)
			{
				return;
			}
			float value = Plugin.BuffSeconds.Value;
			Affliction_InfiniteStamina val = new Affliction_InfiniteStamina(value)
			{
				drowsyAffliction = (Affliction)new Affliction_AdjustStatus((STATUSTYPE)6, Plugin.DrowsyAmount.Value, 0f)
			};
			interactor.refs.afflictions.AddAffliction((Affliction)(object)val, false);
			UsesLeft--;
			int num = -1;
			if (UsesLeft <= 0)
			{
				_consumed = true;
				string[] exitMessages = Taglines.ExitMessages;
				num = ((exitMessages.Length != 0) ? Random.Range(0, exitMessages.Length) : (-1));
				if (num >= 0)
				{
					HeroMessage.Show(exitMessages[num]);
				}
			}
			Plugin.Log.LogInfo((object)$"Can #{CanId} drunk: {value}s sugar rush ({UsesLeft} use(s) left).");
			Manager?.NotifyUsed(this, UsesLeft, num);
			if (UsesLeft <= 0)
			{
				PlayDisappear(instant: false);
			}
		}

		public void HoverEnter()
		{
		}

		public void HoverExit()
		{
		}

		public Vector3 Center()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			return ((Component)this).transform.TransformPoint(LocalCenter);
		}

		public Transform GetTransform()
		{
			return ((Component)this).transform;
		}

		public string GetName()
		{
			return Plugin.DisplayName.Value;
		}

		public string GetInteractionText()
		{
			string text = Taglines.Get(TaglineIndex);
			if (UsesLeft <= 1)
			{
				return text;
			}
			return $"{text}  ({UsesLeft} sips)";
		}

		public void PlayDisappear(bool instant)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: 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_009d: Unknown result type (might be due to invalid IL or missing references)
			_consumed = true;
			Collider[] components = ((Component)this).GetComponents<Collider>();
			foreach (Collider val in components)
			{
				val.enabled = false;
			}
			if (!instant)
			{
				Renderer component = ((Component)this).GetComponent<Renderer>();
				Vector3 val2;
				Bounds bounds;
				if (!((Object)(object)component != (Object)null))
				{
					val2 = ((Component)this).transform.position;
				}
				else
				{
					bounds = component.bounds;
					val2 = ((Bounds)(ref bounds)).center;
				}
				Vector3 position = val2;
				float num;
				if (!((Object)(object)component != (Object)null))
				{
					num = 2f;
				}
				else
				{
					bounds = component.bounds;
					float x = ((Bounds)(ref bounds)).extents.x;
					bounds = component.bounds;
					num = Mathf.Max(x, ((Bounds)(ref bounds)).extents.z) * 2f;
				}
				float radius = num;
				SmokeEffect.Puff(position, radius);
			}
			Object.Destroy((Object)(object)((Component)this).gameObject);
		}
	}
	internal class MonsterCanGrab : MonoBehaviour
	{
		private enum Role
		{
			Idle,
			Simulating,
			CoGrabber,
			Remote
		}

		private struct CoInput
		{
			public Vector3 GrabLocal;

			public Vector3 Target;

			public float Time;
		}

		private const float StreamInterval = 0.05f;

		private const float InputExpiry = 0.5f;

		private const float OwnerWatchdog = 2f;

		private const float CarryLinearDamping = 0f;

		private const float CarryAngularDamping = 0.25f;

		private const float SettleLinearDamping = 0.6f;

		private const float SettleAngularDamping = 1.5f;

		private Rigidbody _rb;

		private Collider? _col;

		private MonsterCanBehaviour? _behaviour;

		private Role _role;

		private int _ownerActor = -1;

		private bool _localGrabbing;

		private Vector3 _grabLocalPoint;

		private float _holdDistance;

		private float _settle;

		private readonly Dictionary<int, CoInput> _coInputs = new Dictionary<int, CoInput>();

		private static readonly List<int> _expiredScratch = new List<int>();

		private Vector3 _netPos;

		private Quaternion _netRot = Quaternion.identity;

		private bool _hasNet;

		private float _lastNetTime;

		private float _streamTimer;

		private float _inputTimer;

		public bool IsRemote
		{
			get
			{
				if (_role != Role.Remote)
				{
					return _role == Role.CoGrabber;
				}
				return true;
			}
		}

		public bool IsLocalCarrying => _localGrabbing;

		private int LocalActor
		{
			get
			{
				if (!PhotonNetwork.InRoom)
				{
					return 0;
				}
				return PhotonNetwork.LocalPlayer.ActorNumber;
			}
		}

		private int CanId
		{
			get
			{
				if (!((Object)(object)_behaviour != (Object)null))
				{
					return -1;
				}
				return _behaviour.CanId;
			}
		}

		private MonsterCanManager? Mgr
		{
			get
			{
				if (!((Object)(object)_behaviour != (Object)null))
				{
					return null;
				}
				return _behaviour.Manager;
			}
		}

		private void Awake()
		{
			_rb = ((Component)this).GetComponent<Rigidbody>();
			_col = ((Component)this).GetComponent<Collider>();
			_behaviour = ((Component)this).GetComponent<MonsterCanBehaviour>();
		}

		private void FixedUpdate()
		{
			Character localCharacter = Character.localCharacter;
			switch (_role)
			{
			case Role.Idle:
				IdleUpdate(localCharacter);
				break;
			case Role.Simulating:
				SimulatingUpdate(localCharacter);
				break;
			case Role.CoGrabber:
				CoGrabberUpdate(localCharacter);
				break;
			case Role.Remote:
				RemoteUpdate(localCharacter);
				break;
			}
		}

		private bool ReachingNear(Character? local)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)local != (Object)null && Vector3.Distance(local.Center, ((Component)this).transform.position) <= Plugin.ActivateRange.Value)
			{
				return local.data.isReaching;
			}
			return false;
		}

		private bool Holding(Character? local)
		{
			return ReachingNear(local);
		}

		private void IdleUpdate(Character? local)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			if (ReachingNear(local) && TryGrabPoint(local, out var point))
			{
				BecomeOwner(local, point);
			}
		}

		private void BecomeOwner(Character local, Vector3 grabWorld)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			_role = Role.Simulating;
			_ownerActor = LocalActor;
			_localGrabbing = true;
			_settle = 0f;
			_rb.isKinematic = false;
			Rigidbody rb = _rb;
			rb.linearVelocity *= 0.2f;
			Rigidbody rb2 = _rb;
			rb2.angularVelocity *= 0.2f;
			CaptureGrip(local, grabWorld);
			_streamTimer = 0f;
			Mgr?.NotifyGrab(CanId);
		}

		private void CaptureGrip(Character local, Vector3 grabWorld)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_001c: 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)
			_grabLocalPoint = ((Component)this).transform.InverseTransformPoint(grabWorld);
			Vector3 forward;
			Vector3 val = ViewAnchor(local, out forward);
			_holdDistance = Mathf.Clamp(Vector3.Distance(val, grabWorld), 2f, 6f);
		}

		private void SimulatingUpdate(Character? local)
		{
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			if (_localGrabbing && !Holding(local))
			{
				_localGrabbing = false;
			}
			if (!_localGrabbing && ReachingNear(local) && TryGrabPoint(local, out var point))
			{
				CaptureGrip(local, point);
				_localGrabbing = true;
			}
			PurgeExpiredCoInputs();
			if ((_localGrabbing ? 1 : 0) + _coInputs.Count == 0)
			{
				_rb.linearDamping = 0.6f;
				_rb.angularDamping = 1.5f;
				StreamMaybe();
				_settle += Time.fixedDeltaTime;
				if (_rb.IsSleeping() || _settle > 15f)
				{
					FreezeAndRelease();
				}
				return;
			}
			_rb.linearDamping = 0f;
			_rb.angularDamping = 0.25f;
			_settle = 0f;
			if (_localGrabbing)
			{
				ApplyGrabForce(_grabLocalPoint, OwnTarget(local));
			}
			foreach (CoInput value in _coInputs.Values)
			{
				ApplyGrabForce(value.GrabLocal, value.Target);
			}
			StreamMaybe();
		}

		private Vector3 OwnTarget(Character local)
		{
			//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_0009: 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_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			Vector3 forward;
			Vector3 val = ViewAnchor(local, out forward);
			return val + forward * _holdDistance;
		}

		private void FreezeAndRelease()
		{
			//IL_0011: 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_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			_settle = 0f;
			_rb.linearVelocity = Vector3.zero;
			_rb.angularVelocity = Vector3.zero;
			_rb.isKinematic = true;
			Mgr?.NotifyRelease(CanId, ((Component)this).transform.position, ((Component)this).transform.rotation);
			_role = Role.Idle;
			_ownerActor = -1;
			_coInputs.Clear();
		}

		private void CoGrabberUpdate(Character? local)
		{
			if (!OwnerWentSilent() && _role == Role.CoGrabber)
			{
				if (!Holding(local))
				{
					CoRelease();
					return;
				}
				MirrorFollow();
				StreamInputMaybe(local);
			}
		}

		private void BecomeCoGrabber(Character local, Vector3 grabWorld)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			_role = Role.CoGrabber;
			_localGrabbing = true;
			CaptureGrip(local, grabWorld);
			_inputTimer = 0f;
		}

		private void CoRelease()
		{
			Mgr?.NotifyCoRelease(CanId, LocalActor);
			_role = Role.Remote;
			_localGrabbing = false;
			_lastNetTime = Time.time;
		}

		private void RemoteUpdate(Character? local)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			if (!OwnerWentSilent() && _role == Role.Remote)
			{
				MirrorFollow();
				if (ReachingNear(local) && TryGrabPoint(local, out var point))
				{
					BecomeCoGrabber(local, point);
				}
			}
		}

		private void MirrorFollow()
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: 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_0073: Unknown result type (might be due to invalid IL or missing references)
			if (!_rb.isKinematic)
			{
				_rb.isKinematic = true;
			}
			if (_hasNet)
			{
				float num = 1f - Mathf.Exp(-15f * Time.fixedDeltaTime);
				((Component)this).transform.position = Vector3.Lerp(((Component)this).transform.position, _netPos, num);
				((Component)this).transform.rotation = Quaternion.Slerp(((Component)this).transform.rotation, _netRot, num);
			}
		}

		private bool OwnerWentSilent()
		{
			if (_ownerActor < 0 || Time.time - _lastNetTime <= 2f)
			{
				return false;
			}
			if (_localGrabbing)
			{
				_role = Role.Simulating;
				_ownerActor = LocalActor;
				_hasNet = false;
				_settle = 0f;
				_streamTimer = 0f;
				_rb.isKinematic = false;
				Mgr?.NotifyGrab(CanId);
			}
			else
			{
				_role = Role.Idle;
				_ownerActor = -1;
				_hasNet = false;
				_rb.isKinematic = true;
			}
			return true;
		}

		private void StreamMaybe()
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			_streamTimer -= Time.fixedDeltaTime;
			if (!(_streamTimer > 0f))
			{
				_streamTimer = 0.05f;
				Mgr?.NotifyMove(CanId, ((Component)this).transform.position, ((Component)this).transform.rotation);
			}
		}

		private void StreamInputMaybe(Character local)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			_inputTimer -= Time.fixedDeltaTime;
			if (!(_inputTimer > 0f))
			{
				_inputTimer = 0.05f;
				Mgr?.NotifyGrabInput(CanId, LocalActor, _grabLocalPoint, OwnTarget(local));
			}
		}

		private void ApplyGrabForce(Vector3 grabLocal, Vector3 target)
		{
			//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_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: 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_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_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: 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)
			Vector3 val = ((Component)this).transform.TransformPoint(grabLocal);
			Vector3 val2 = target - val;
			float value = Plugin.CarryStiffness.Value;
			float num = 2f * Mathf.Sqrt(value * _rb.mass);
			Vector3 pointVelocity = _rb.GetPointVelocity(val);
			Vector3 val3 = val2 * value - pointVelocity * num;
			val3 = Vector3.ClampMagnitude(val3, value * 6f);
			_rb.AddForceAtPosition(val3, val, (ForceMode)0);
		}

		public void OnRemoteGrab(int actor)
		{
			if (actor == LocalActor)
			{
				return;
			}
			if (_role == Role.Simulating)
			{
				if (actor < LocalActor)
				{
					_ownerActor = actor;
					_lastNetTime = Time.time;
					_hasNet = false;
					_rb.isKinematic = true;
					_role = (_localGrabbing ? Role.CoGrabber : Role.Remote);
					if (_role == Role.CoGrabber)
					{
						_inputTimer = 0f;
					}
				}
			}
			else
			{
				_ownerActor = actor;
				_lastNetTime = Time.time;
				if (_role == Role.Idle)
				{
					_role = Role.Remote;
					_rb.isKinematic = true;
				}
			}
		}

		public void ApplyRemote(Vector3 pos, Quaternion rot)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: 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)
			if (_role != Role.Simulating)
			{
				if (_role == Role.Idle)
				{
					_role = Role.Remote;
					_rb.isKinematic = true;
				}
				_netPos = pos;
				_netRot = rot;
				_hasNet = true;
				_lastNetTime = Time.time;
			}
		}

		public void EndRemote(Vector3 pos, Quaternion rot)
		{
			//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_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			if (_role != Role.Simulating)
			{
				if (_role == Role.CoGrabber && _localGrabbing)
				{
					((Component)this).transform.position = pos;
					((Component)this).transform.rotation = rot;
					_role = Role.Simulating;
					_ownerActor = LocalActor;
					_hasNet = false;
					_settle = 0f;
					_streamTimer = 0f;
					_rb.isKinematic = false;
					Mgr?.NotifyGrab(CanId);
				}
				else
				{
					((Component)this).transform.position = pos;
					((Component)this).transform.rotation = rot;
					_hasNet = false;
					_ownerActor = -1;
					_localGrabbing = false;
					_role = Role.Idle;
					_rb.isKinematic = true;
				}
			}
		}

		public void OnCoGrabInput(int actor, Vector3 grabLocal, Vector3 target)
		{
			//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_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			if (_role == Role.Simulating && actor != LocalActor)
			{
				_coInputs[actor] = new CoInput
				{
					GrabLocal = grabLocal,
					Target = target,
					Time = Time.time
				};
			}
		}

		public void OnCoRelease(int actor)
		{
			_coInputs.Remove(actor);
		}

		private void PurgeExpiredCoInputs()
		{
			if (_coInputs.Count == 0)
			{
				return;
			}
			float time = Time.time;
			_expiredScratch.Clear();
			foreach (KeyValuePair<int, CoInput> coInput in _coInputs)
			{
				if (time - coInput.Value.Time > 0.5f)
				{
					_expiredScratch.Add(coInput.Key);
				}
			}
			foreach (int item in _expiredScratch)
			{
				_coInputs.Remove(item);
			}
		}

		private static Vector3 ViewAnchor(Character? local, out Vector3 forward)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			Camera main = Camera.main;
			if ((Object)(object)main != (Object)null)
			{
				forward = ((Component)main).transform.forward;
				return ((Component)main).transform.position;
			}
			if ((Object)(object)local != (Object)null)
			{
				forward = ((Component)local).transform.forward;
				return local.Center;
			}
			forward = Vector3.forward;
			return Vector3.zero;
		}

		private bool TryGrabPoint(Character player, out Vector3 point)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: 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_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00af: 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)
			point = ((Component)this).transform.position;
			float num = Plugin.GrabRange.Value;
			bool result = false;
			BodypartType[] array = (BodypartType[])(object)new BodypartType[2]
			{
				(BodypartType)10,
				(BodypartType)7
			};
			foreach (BodypartType val in array)
			{
				Bodypart bodypart = player.GetBodypart(val);
				if (!((Object)(object)bodypart == (Object)null) && !((Object)(object)bodypart.Rig == (Object)null))
				{
					Vector3 val2 = (((Object)(object)_col != (Object)null) ? _col.ClosestPoint(bodypart.Rig.position) : ((Component)this).transform.position);
					float num2 = Vector3.Distance(bodypart.Rig.position, val2);
					if (num2 <= num)
					{
						num = num2;
						point = val2;
						result = true;
					}
				}
			}
			return result;
		}
	}
	internal class MonsterCanManager : MonoBehaviour, IOnEventCallback
	{
		private const byte EV_SPAWN_CAN = 71;

		private const byte EV_CONSUME_CAN = 72;

		private const byte EV_GRAB_CAN = 73;

		private const byte EV_MOVE_CAN = 74;

		private const byte EV_RELEASE_CAN = 75;

		private const byte EV_GRAB_INPUT = 76;

		private const byte EV_CO_RELEASE = 77;

		private const float ClusterRadius = 5f;

		private const int ClusterMaxNeighbours = 4;

		private const float ParkedFarDistance = 300f;

		private const float ParkedSeaLevelY = 8f;

		private readonly List<MonsterCanBehaviour> _cans = new List<MonsterCanBehaviour>();

		private bool _spawning;

		private bool _runSpawnStarted;

		private int _spawnedCount;

		private int _nextCanId;

		private float _checkTimer;

		private bool _showTracker;

		private static Material? _beamMat;

		private static bool IsAuthority
		{
			get
			{
				if (PhotonNetwork.InRoom)
				{
					return PhotonNetwork.IsMasterClient;
				}
				return true;
			}
		}

		private void OnEnable()
		{
			SceneManager.sceneLoaded += OnSceneLoaded;
			PhotonNetwork.AddCallbackTarget((object)this);
		}

		private void OnDisable()
		{
			SceneManager.sceneLoaded -= OnSceneLoaded;
			PhotonNetwork.RemoveCallbackTarget((object)this);
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			DespawnAll();
			_spawnedCount = 0;
			_runSpawnStarted = false;
			if (IsAuthority)
			{
				ClearCaches();
			}
			Plugin.Log.LogInfo((object)$"Scene loaded: '{((Scene)(ref scene)).name}' (inAirport={GameBridge.IsInAirport()}, authority={IsAuthority}).");
		}

		private void Update()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			if (Plugin.EnableTracker.Value && Input.GetKeyDown(Plugin.TrackerKey.Value))
			{
				_showTracker = !_showTracker;
				if (!_showTracker)
				{
					RemoveBeams();
				}
				Plugin.Log.LogInfo((object)("[tracker] " + (_showTracker ? "ON" : "OFF")));
			}
			_checkTimer -= Time.deltaTime;
			if (_checkTimer > 0f)
			{
				return;
			}
			_checkTimer = 1f;
			Prune();
			if (_showTracker)
			{
				EnsureBeams();
			}
			if (!IsAuthority)
			{
				return;
			}
			if (!Plugin.Enabled.Value || GameBridge.IsInAirport() || !GameBridge.TryGetPlayerPosition(out var position))
			{
				if (_cans.Count > 0)
				{
					DespawnAll();
					ClearCaches();
				}
			}
			else if (!_runSpawnStarted && !_spawning)
			{
				_runSpawnStarted = true;
				((MonoBehaviour)this).StartCoroutine(SpawnAtLoad(position));
			}
		}

		private IEnumerator SpawnAtLoad(Vector3 startPos)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			_spawning = true;
			int last = -1;
			int stable = 0;
			for (float t = 0f; t < 15f; t += 1f)
			{
				int num = ((Luggage.ALL_LUGGAGE != null) ? Luggage.ALL_LUGGAGE.Count : 0);
				Plugin.Log.LogInfo((object)$"[spawn] waiting for suitcases to load… count={num} (t={t:F0}s).");
				if (num > 0 && num == last)
				{
					int num2 = stable + 1;
					stable = num2;
					if (num2 >= 2)
					{
						break;
					}
				}
				else
				{
					stable = 0;
				}
				last = num;
				yield return (object)new WaitForSeconds(1f);
			}
			for (float t = 0f; t < 30f; t += 0.5f)
			{
				int total;
				int num3 = CountParkedFar(startPos, out total);
				if (total > 0 && num3 == 0)
				{
					Plugin.Log.LogInfo((object)$"[spawn] suitcases risen (t={t:F1}s, {total} total).");
					break;
				}
				Plugin.Log.LogInfo((object)$"[spawn] waiting for suitcases to rise… {num3} still parked far (t={t:F1}s).");
				yield return (object)new WaitForSeconds(0.5f);
			}
			List<Vector3> list = new List<Vector3>();
			if (Luggage.ALL_LUGGAGE != null)
			{
				foreach (Luggage item in Luggage.ALL_LUGGAGE)
				{
					if ((Object)(object)item != (Object)null && !IsParkedFar(((Component)item).transform.position, startPos))
					{
						list.Add(((Component)item).transform.position);
					}
				}
			}
			List<Vector3> picks = PickAcrossBiomes(list, startPos, Plugin.CansPerRun.Value);
			if (picks == null || picks.Count == 0)
			{
				Plugin.Log.LogInfo((object)"[spawn] biome checkpoints unavailable; falling back to height banding.");
				picks = PickFarSpread(list, Plugin.CansPerRun.Value, startPos);
			}
			if (picks.Count == 0 && GameBridge.TryGetPlayerPosition(out var position))
			{
				for (int i = 0; i < Plugin.CansPerRun.Value; i++)
				{
					Vector3 val = Quaternion.Euler(0f, Random.Range(0f, 360f), 0f) * Vector3.forward;
					picks.Add(position + val * Random.Range(Plugin.ScatterRadiusMin.Value, Plugin.ScatterRadiusMax.Value));
				}
			}
			Plugin.Log.LogInfo((object)$"[spawn] {list.Count} suitcases; placing {picks.Count} can(s).");
			foreach (Vector3 item2 in picks)
			{
				Vector2 insideUnitCircle = Random.insideUnitCircle;
				Vector2 val2 = ((Vector2)(ref insideUnitCircle)).normalized * Random.Range(2.5f, 4.5f);
				Vector3 ground = new Vector3(item2.x + val2.x, item2.y, item2.z + val2.y);
				float t = Random.Range(0f, 360f);
				int tagline = Random.Range(0, Taglines.All.Length);
				int id = _nextCanId++;
				_spawnedCount++;
				Plugin.Log.LogInfo((object)($"Placing can {_spawnedCount}/{picks.Count} at {ground} " + $"({Vector3.Distance(ground, startPos):F0}m from start)."));
				yield return SpawnCanAt(ground, t, tagline, id);
				BroadcastSpawn(ground, t, tagline, id);
			}
			_spawning = false;
		}

		private static List<Vector3>? PickAcrossBiomes(List<Vector3> positions, Vector3 startPos, int count)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ee: Unknown result type (might be due to invalid IL or missing references)
			MountainProgressHandler instance = Singleton<MountainProgressHandler>.Instance;
			if ((Object)(object)instance == (Object)null || instance.progressPoints == null || positions.Count == 0 || count <= 0)
			{
				return null;
			}
			List<Vector3> list = new List<Vector3>();
			List<BiomeType> list2 = new List<BiomeType>();
			ProgressPoint[] progressPoints = instance.progressPoints;
			foreach (ProgressPoint val in progressPoints)
			{
				if (val != null && (Object)(object)val.transform != (Object)null)
				{
					list.Add(val.transform.position);
					list2.Add(val.biome);
				}
			}
			if (list.Count == 0)
			{
				return null;
			}
			List<BiomeType> list3 = new List<BiomeType>();
			foreach (BiomeType item in list2)
			{
				if (!list3.Contains(item))
				{
					list3.Add(item);
				}
			}
			Dictionary<BiomeType, List<Vector3>> byBiome = new Dictionary<BiomeType, List<Vector3>>();
			foreach (Vector3 position in positions)
			{
				int index = 0;
				float num = float.MaxValue;
				for (int j = 0; j < list.Count; j++)
				{
					Vector3 val2 = position - list[j];
					float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude;
					if (sqrMagnitude < num)
					{
						num = sqrMagnitude;
						index = j;
					}
				}
				BiomeType key = list2[index];
				if (!byBiome.TryGetValue(key, out List<Vector3> value))
				{
					value = new List<Vector3>();
					byBiome[key] = value;
				}
				value.Add(position);
			}
			List<Vector3> value2;
			List<BiomeType> list4 = list3.FindAll((BiomeType b) => byBiome.TryGetValue(b, out value2) && value2.Count > 0);
			if (list4.Count > count)
			{
				list4.RemoveAt(0);
			}
			if (list4.Count == 0)
			{
				return null;
			}
			float num2 = Mathf.Clamp(Plugin.InsetIntoBiome.Value, 0f, 0.95f);
			int count2 = list4.Count;
			List<Vector3> list5 = new List<Vector3>();
			for (int num3 = 0; num3 < count; num3++)
			{
				int num4 = num3 * count2 / count;
				int num5 = (num3 + 1) * count2 / count;
				if (num5 <= num4)
				{
					num5 = num4 + 1;
				}
				BiomeType val3 = list4[Random.Range(num4, Mathf.Min(num5, count2))];
				List<Vector3> list6 = byBiome[val3];
				list6.Sort(delegate(Vector3 x, Vector3 y)
				{
					//IL_0000: Unknown result type (might be due to invalid IL or missing references)
					//IL_0002: Unknown result type (might be due to invalid IL or missing references)
					//IL_0007: Unknown result type (might be due to invalid IL or missing references)
					//IL_000c: Unknown result type (might be due to invalid IL or missing references)
					//IL_0017: 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_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)
					Vector3 val4 = x - startPos;
					float sqrMagnitude2 = ((Vector3)(ref val4)).sqrMagnitude;
					val4 = y - startPos;
					return sqrMagnitude2.CompareTo(((Vector3)(ref val4)).sqrMagnitude);
				});
				int num6 = Mathf.Clamp(Mathf.FloorToInt((float)list6.Count * num2), 0, list6.Count - 1);
				List<Vector3> range = list6.GetRange(num6, list6.Count - num6);
				list5.Add(range[Random.Range(0, range.Count)]);
				Plugin.Log.LogInfo((object)($"[spawn] can {num3 + 1}/{count} in biome {val3}: {list6.Count} suitcases, " + $"deep pick (past {num2:P0})."));
			}
			if (list5.Count <= 0)
			{
				return null;
			}
			return list5;
		}

		private static List<Vector3> PickFarSpread(List<Vector3> positions, int count, Vector3 origin)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: 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_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			List<Vector3> list = new List<Vector3>();
			if (positions.Count == 0 || count <= 0)
			{
				return list;
			}
			List<Vector3> list2 = new List<Vector3>();
			float num = 25f;
			for (int i = 0; i < positions.Count; i++)
			{
				int num2 = 0;
				for (int j = 0; j < positions.Count; j++)
				{
					if (i != j)
					{
						Vector3 val = positions[i] - positions[j];
						if (((Vector3)(ref val)).sqrMagnitude < num)
						{
							num2++;
						}
					}
				}
				if (num2 <= 4)
				{
					list2.Add(positions[i]);
				}
			}
			if (list2.Count == 0)
			{
				list2 = positions;
			}
			float num3 = float.MaxValue;
			float num4 = float.MinValue;
			foreach (Vector3 item in list2)
			{
				if (item.y < num3)
				{
					num3 = item.y;
				}
				if (item.y > num4)
				{
					num4 = item.y;
				}
			}
			float num5 = Mathf.Max(0.001f, num4 - num3);
			float num6 = Mathf.Clamp01(Plugin.BandNear.Value);
			float num7 = Mathf.Clamp01(Plugin.BandFar.Value);
			if (num7 <= num6)
			{
				num7 = Mathf.Min(1f, num6 + 0.1f);
			}
			for (int k = 0; k < count; k++)
			{
				float y0 = num3 + num5 * Mathf.Lerp(num6, num7, (float)k / (float)count);
				float y1 = num3 + num5 * Mathf.Lerp(num6, num7, (float)(k + 1) / (float)count);
				List<Vector3> list3 = list2.FindAll((Vector3 p) => p.y >= y0 && p.y <= y1);
				if (list3.Count > 0)
				{
					list.Add(list3[Random.Range(0, list3.Count)]);
					continue;
				}
				float num8 = (y0 + y1) * 0.5f;
				Vector3 val2 = list2[0];
				float num9 = Mathf.Abs(val2.y - num8);
				foreach (Vector3 item2 in list2)
				{
					float num10 = Mathf.Abs(item2.y - num8);
					if (num10 < num9)
					{
						num9 = num10;
						val2 = item2;
					}
				}
				list.Add(val2);
			}
			return list;
		}

		private IEnumerator SpawnCanAt(Vector3 groundPoint, float yaw, int taglineIndex, int canId)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			if (!MonsterCanModel.EnsureLoaded())
			{
				yield break;
			}
			GameObject val = MonsterCanModel.Build();
			if ((Object)(object)val == (Object)null)
			{
				yield break;
			}
			MonsterCanBehaviour behaviour = val.GetComponent<MonsterCanBehaviour>();
			val.transform.position = groundPoint + Vector3.up * (((Object)(object)behaviour != (Object)null) ? behaviour.BaseOffsetY : 0f);
			val.transform.rotation = Quaternion.Euler(0f, yaw, 0f);
			if ((Object)(object)behaviour != (Object)null)
			{
				behaviour.CanId = canId;
				behaviour.TaglineIndex = taglineIndex;
				behaviour.UsesLeft = Mathf.Max(1, Plugin.UsesPerCan.Value);
				behaviour.Manager = this;
				_cans.Add(behaviour);
				if (_showTracker)
				{
					AddBeam(behaviour);
				}
			}
			Plugin.Log.LogInfo((object)$"Can #{canId} placed at {val.transform.position} (alive {_cans.Count}).");
			if (!((Object)(object)behaviour?.AudioSource != (Object)null) || !((Object)(object)behaviour.AudioSource.clip == (Object)null) || !EmbeddedAssets.TryGetCompressedAudio(out byte[] bytes, out string extension))
			{
				yield break;
			}
			yield return TempFileAudioLoader.Load(bytes, extension, delegate(AudioClip? clip)
			{
				if ((Object)(object)behaviour != (Object)null && (Object)(object)behaviour.AudioSource != (Object)null && (Object)(object)clip != (Object)null)
				{
					behaviour.AudioSource.clip = clip;
					behaviour.EnsurePlaying();
				}
			});
		}

		public void NotifyUsed(MonsterCanBehaviour can, int usesLeft, int messageIndex)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			if (usesLeft <= 0)
			{
				_cans.Remove(can);
			}
			if (PhotonNetwork.InRoom)
			{
				RaiseEventOptions val = new RaiseEventOptions
				{
					Receivers = (ReceiverGroup)0,
					CachingOption = (EventCaching)4
				};
				float[] array = new float[3] { can.CanId, usesLeft, messageIndex };
				PhotonNetwork.RaiseEvent((byte)72, (object)array, val, SendOptions.SendReliable);
			}
		}

		public void NotifyGrab(int canId)
		{
			if (PhotonNetwork.InRoom)
			{
				float[] content = new float[2]
				{
					canId,
					PhotonNetwork.LocalPlayer.ActorNumber
				};
				RaiseToOthers(73, content, reliable: true);
			}
		}

		public void NotifyMove(int canId, Vector3 p, Quaternion q)
		{
			//IL_0015: 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_0027: 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_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			if (PhotonNetwork.InRoom)
			{
				float[] content = new float[8] { canId, p.x, p.y, p.z, q.x, q.y, q.z, q.w };
				RaiseToOthers(74, content, reliable: false);
			}
		}

		public void NotifyRelease(int canId, Vector3 p, Quaternion q)
		{
			//IL_0015: 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_0027: 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_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			if (PhotonNetwork.InRoom)
			{
				float[] content = new float[8] { canId, p.x, p.y, p.z, q.x, q.y, q.z, q.w };
				RaiseToOthers(75, content, reliable: true);
			}
		}

		public void NotifyGrabInput(int canId, int actor, Vector3 grabLocal, Vector3 target)
		{
			//IL_001a: 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_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			if (PhotonNetwork.InRoom)
			{
				float[] content = new float[8] { canId, actor, grabLocal.x, grabLocal.y, grabLocal.z, target.x, target.y, target.z };
				RaiseToOthers(76, content, reliable: false);
			}
		}

		public void NotifyCoRelease(int canId, int actor)
		{
			if (PhotonNetwork.InRoom)
			{
				RaiseToOthers(77, new float[2] { canId, actor }, reliable: true);
			}
		}

		private static void RaiseToOthers(byte code, float[] content, bool reliable)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: 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_000d: Expected O, but got Unknown
			//IL_001a: 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)
			RaiseEventOptions val = new RaiseEventOptions
			{
				Receivers = (ReceiverGroup)0
			};
			PhotonNetwork.RaiseEvent(code, (object)content, val, reliable ? SendOptions.SendReliable : SendOptions.SendUnreliable);
		}

		private MonsterCanGrab? FindGrab(int canId)
		{
			MonsterCanBehaviour monsterCanBehaviour = _cans.Find((MonsterCanBehaviour x) => (Object)(object)x != (Object)null && x.CanId == canId);
			if (!((Object)(object)monsterCanBehaviour != (Object)null))
			{
				return null;
			}
			return ((Component)monsterCanBehaviour).GetComponent<MonsterCanGrab>();
		}

		public bool AnyLocalCarry()
		{
			foreach (MonsterCanBehaviour can in _cans)
			{
				if (!((Object)(object)can == (Object)null))
				{
					MonsterCanGrab component = ((Component)can).GetComponent<MonsterCanGrab>();
					if ((Object)(object)component != (Object)null && component.IsLocalCarrying)
					{
						return true;
					}
				}
			}
			return false;
		}

		private static void BroadcastSpawn(Vector3 ground, float yaw, int taglineIndex, int canId)
		{
			//IL_0010: 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_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			if (PhotonNetwork.InRoom)
			{
				float[] array = new float[6] { ground.x, ground.y, ground.z, yaw, taglineIndex, canId };
				RaiseEventOptions val = new RaiseEventOptions
				{
					Receivers = (ReceiverGroup)0,
					CachingOption = (EventCaching)4
				};
				PhotonNetwork.RaiseEvent((byte)71, (object)array, val, SendOptions.SendReliable);
			}
		}

		private static void ClearCaches()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			if (PhotonNetwork.InRoom)
			{
				RaiseEventOptions val = new RaiseEventOptions
				{
					Receivers = (ReceiverGroup)0,
					CachingOption = (EventCaching)6
				};
				PhotonNetwork.RaiseEvent((byte)71, (object)null, val, SendOptions.SendReliable);
				PhotonNetwork.RaiseEvent((byte)72, (object)null, val, SendOptions.SendReliable);
			}
		}

		public void OnEvent(EventData photonEvent)
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: Unknown result type (might be due to invalid IL or missing references)
			switch (photonEvent.Code)
			{
			case 71:
				if (photonEvent.CustomData is float[] array6 && array6.Length >= 6)
				{
					((MonoBehaviour)this).StartCoroutine(SpawnCanAt(new Vector3(array6[0], array6[1], array6[2]), array6[3], (int)array6[4], (int)array6[5]));
				}
				break;
			case 72:
			{
				if (!(photonEvent.CustomData is float[] array7) || array7.Length < 3)
				{
					break;
				}
				int canId = (int)array7[0];
				int num = (int)array7[1];
				int num2 = (int)array7[2];
				MonsterCanBehaviour monsterCanBehaviour = _cans.Find((MonsterCanBehaviour x) => (Object)(object)x != (Object)null && x.CanId == canId);
				if (!((Object)(object)monsterCanBehaviour != (Object)null))
				{
					break;
				}
				monsterCanBehaviour.SetUsesLeft(num);
				if (num <= 0)
				{
					_cans.Remove(monsterCanBehaviour);
					bool flag = Time.time - monsterCanBehaviour.SpawnTime < 1.5f;
					monsterCanBehaviour.PlayDisappear(flag);
					if (!flag && num2 >= 0 && num2 < Taglines.ExitMessages.Length)
					{
						HeroMessage.Show(Taglines.ExitMessages[num2]);
					}
				}
				break;
			}
			case 73:
				if (photonEvent.CustomData is float[] array4 && array4.Length >= 2)
				{
					FindGrab((int)array4[0])?.OnRemoteGrab((int)array4[1]);
				}
				break;
			case 74:
				if (photonEvent.CustomData is float[] array2 && array2.Length >= 8)
				{
					FindGrab((int)array2[0])?.ApplyRemote(new Vector3(array2[1], array2[2], array2[3]), new Quaternion(array2[4], array2[5], array2[6], array2[7]));
				}
				break;
			case 75:
				if (photonEvent.CustomData is float[] array3 && array3.Length >= 8)
				{
					FindGrab((int)array3[0])?.EndRemote(new Vector3(array3[1], array3[2], array3[3]), new Quaternion(array3[4], array3[5], array3[6], array3[7]));
				}
				break;
			case 76:
				if (photonEvent.CustomData is float[] array5 && array5.Length >= 8)
				{
					FindGrab((int)array5[0])?.OnCoGrabInput((int)array5[1], new Vector3(array5[2], array5[3], array5[4]), new Vector3(array5[5], array5[6], array5[7]));
				}
				break;
			case 77:
				if (photonEvent.CustomData is float[] array && array.Length >= 2)
				{
					FindGrab((int)array[0])?.OnCoRelease((int)array[1]);
				}
				break;
			}
		}

		private void EnsureBeams()
		{
			foreach (MonsterCanBehaviour can in _cans)
			{
				if ((Object)(object)can != (Object)null && (Object)(object)((Component)can).transform.Find("TrackerBeam") == (Object)null)
				{
					AddBeam(can);
				}
			}
		}

		private void RemoveBeams()
		{
			foreach (MonsterCanBehaviour can in _cans)
			{
				if (!((Object)(object)can == (Object)null))
				{
					Transform val = ((Component)can).transform.Find("TrackerBeam");
					if ((Object)(object)val != (Object)null)
					{
						Object.Destroy((Object)(object)((Component)val).gameObject);
					}
				}
			}
		}

		private static void AddBeam(MonsterCanBehaviour can)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0023: 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_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("TrackerBeam");
			val.transform.SetParent(((Component)can).transform, false);
			float x = ((Component)can).transform.localScale.x;
			if (x > 0.0001f)
			{
				val.transform.localScale = Vector3.one / x;
			}
			LineRenderer val2 = val.AddComponent<LineRenderer>();
			val2.useWorldSpace = false;
			val2.positionCount = 2;
			val2.SetPosition(0, new Vector3(0f, 2f, 0f));
			val2.SetPosition(1, new Vector3(0f, 600f, 0f));
			val2.startWidth = 4f;
			val2.endWidth = 4f;
			val2.numCapVertices = 3;
			((Renderer)val2).material = GetBeamMaterial();
			val2.startColor = new Color(0.3f, 1f, 0.4f, 0.85f);
			val2.endColor = new Color(0.3f, 1f, 0.4f, 0f);
			((Renderer)val2).shadowCastingMode = (ShadowCastingMode)0;
		}

		private static Material GetBeamMaterial()
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			if ((Object)(object)_beamMat != (Object)null)
			{
				return _beamMat;
			}
			Shader val = Shader.Find("Sprites/Default") ?? Shader.Find("Legacy Shaders/Particles/Alpha Blended");
			_beamMat = new Material(val)
			{
				name = "MonsterCanBeam"
			};
			return _beamMat;
		}

		private void OnGUI()
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: 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_01a1: 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_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Expected O, but got Unknown
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Expected O, but got Unknown
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Unknown result type (might be due to invalid IL or missing references)
			//IL_0264: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: 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_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			if (!_showTracker || !GameBridge.TryGetPlayerPosition(out var position))
			{
				return;
			}
			MonsterCanBehaviour monsterCanBehaviour = null;
			float num = float.MaxValue;
			foreach (MonsterCanBehaviour can in _cans)
			{
				if (!((Object)(object)can == (Object)null))
				{
					float num2 = Vector3.Distance(position, ((Component)can).transform.position);
					if (num2 < num)
					{
						num = num2;
						monsterCanBehaviour = can;
					}
				}
			}
			string text;
			if ((Object)(object)monsterCanBehaviour == (Object)null)
			{
				text = "MONSTER CAN TRACKER — no cans on the map";
			}
			else
			{
				Vector3 val = ((Component)monsterCanBehaviour).transform.position - position;
				Vector3 val2 = val;
				val2.y = 0f;
				string text2;
				if (((Vector3)(ref val2)).sqrMagnitude < 4f)
				{
					text2 = ((val.y > 3f) ? "ABOVE you" : ((val.y < -3f) ? "BELOW you" : "right here"));
				}
				else
				{
					Camera main = Camera.main;
					Vector3 val3 = (((Object)(object)main != (Object)null) ? ((Component)main).transform.forward : Vector3.forward);
					val3.y = 0f;
					float num3 = Vector3.SignedAngle(val3, val2, Vector3.up);
					text2 = ((num3 > 20f) ? "turn RIGHT »" : ((num3 < -20f) ? "« turn LEFT" : "straight AHEAD"));
				}
				text = $"MONSTER CAN TRACKER — nearest {num:F0}m, {Compass(val)}, {text2}   ({_cans.Count} on map)";
			}
			GUIStyle val4 = new GUIStyle(GUI.skin.label)
			{
				alignment = (TextAnchor)4,
				fontSize = 20,
				fontStyle = (FontStyle)1
			};
			val4.normal.textColor = new Color(0.4f, 1f, 0.45f);
			Rect val5 = default(Rect);
			((Rect)(ref val5))..ctor(((float)Screen.width - 900f) / 2f, 12f, 900f, 30f);
			GUIStyle val6 = new GUIStyle(val4);
			val6.normal.textColor = new Color(0f, 0f, 0f, 0.7f);
			GUI.Label(new Rect(((Rect)(ref val5)).x + 2f, ((Rect)(ref val5)).y + 2f, ((Rect)(ref val5)).width, ((Rect)(ref val5)).height), text, val6);
			GUI.Label(val5, text, val4);
		}

		private static bool IsParkedFar(Vector3 p, Vector3 startPos)
		{
			//IL_0000: 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_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = new Vector2(p.x - startPos.x, p.z - startPos.z);
			float magnitude = ((Vector2)(ref val)).magnitude;
			if (magnitude > 300f)
			{
				return p.y < startPos.y + 8f;
			}
			return false;
		}

		private static int CountParkedFar(Vector3 startPos, out int total)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			total = 0;
			int num = 0;
			if (Luggage.ALL_LUGGAGE != null)
			{
				foreach (Luggage item in Luggage.ALL_LUGGAGE)
				{
					if ((Object)(object)item != (Object)null)
					{
						total++;
						if (IsParkedFar(((Component)item).transform.position, startPos))
						{
							num++;
						}
					}
				}
			}
			return num;
		}

		private static string Compass(Vector3 dir)
		{
			//IL_0000: 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)
			float num = Mathf.Atan2(dir.x, dir.z) * 57.29578f;
			string[] array = new string[8] { "N", "NE", "E", "SE", "S", "SW", "W", "NW" };
			int num2 = Mathf.RoundToInt((num % 360f + 360f) % 360f / 45f) % 8;
			return array[num2];
		}

		private void Prune()
		{
			_cans.RemoveAll((MonsterCanBehaviour c) => (Object)(object)c == (Object)null);
		}

		private void DespawnAll()
		{
			foreach (MonsterCanBehaviour can in _cans)
			{
				if ((Object)(object)can != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)can).gameObject);
				}
			}
			_cans.Clear();
		}
	}
	internal static class MonsterCanModel
	{
		private enum ShaderKind
		{
			BuiltIn,
			Urp,
			Hdrp
		}

		private static bool _loaded;

		private static Mesh? _mesh;

		private static Texture2D? _emission;

		private static Texture2D? _normal;

		private static Texture2D? _ao;

		private static Texture2D? _metallic;

		private static AudioClip? _wavClip;

		private static Material? _material;

		public static AudioClip? WavClip => _wavClip;

		public static bool EnsureLoaded()
		{
			if (_loaded)
			{
				return (Object)(object)_mesh != (Object)null;
			}
			_loaded = true;
			_mesh = EmbeddedAssets.LoadMesh(".obj");
			_emission = EmbeddedAssets.LoadTexture("_em.png", linear: false);
			_normal = EmbeddedAssets.LoadTexture("_normal.jpg", linear: true);
			_ao = EmbeddedAssets.LoadTexture("_ao.jpg", linear: true);
			_metallic = EmbeddedAssets.LoadTexture("_metallic.jpg", linear: true);
			_wavClip = EmbeddedAssets.LoadWavMusicClip();
			if ((Object)(object)_mesh == (Object)null)
			{
				Plugin.Log.LogError((object)"MonsterCan: model mesh failed to load; cannot spawn.");
			}
			return (Object)(object)_mesh != (Object)null;
		}

		public static GameObject? Build()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: 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_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Expected O, but got Unknown
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_0276: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Unknown result type (might be due to invalid IL or missing references)
			//IL_027f: Unknown result type (might be due to invalid IL or missing references)
			if (!EnsureLoaded() || (Object)(object)_mesh == (Object)null)
			{
				return null;
			}
			GameObject val = new GameObject("MonsterCan");
			MeshFilter val2 = val.AddComponent<MeshFilter>();
			val2.sharedMesh = _mesh;
			MeshRenderer val3 = val.AddComponent<MeshRenderer>();
			((Renderer)val3).sharedMaterial = _material ?? (_material = BuildMaterial());
			((Renderer)val3).shadowCastingMode = (ShadowCastingMode)1;
			((Renderer)val3).receiveShadows = true;
			Bounds bounds = _mesh.bounds;
			float num = Mathf.Max(0.0001f, ((Bounds)(ref bounds)).size.y);
			float num2 = Plugin.HeightMeters.Value / num;
			val.transform.localScale = Vector3.one * num2;
			val.layer = 0;
			CapsuleCollider val4 = val.AddComponent<CapsuleCollider>();
			bounds = _mesh.bounds;
			val4.center = ((Bounds)(ref bounds)).center;
			bounds = _mesh.bounds;
			val4.height = ((Bounds)(ref bounds)).size.y;
			bounds = _mesh.bounds;
			float x = ((Bounds)(ref bounds)).extents.x;
			bounds = _mesh.bounds;
			val4.radius = Mathf.Max(x, ((Bounds)(ref bounds)).extents.z);
			val4.direction = 1;
			AudioSource val5 = val.AddComponent<AudioSource>();
			val5.clip = _wavClip;
			val5.loop = true;
			val5.playOnAwake = false;
			val5.spatialBlend = 1f;
			val5.minDistance = Plugin.AudioMinDistance.Value;
			val5.maxDistance = Plugin.AudioMaxDistance.Value;
			val5.rolloffMode = (AudioRolloffMode)2;
			val5.SetCustomCurve((AudioSourceCurveType)0, new AnimationCurve((Keyframe[])(object)new Keyframe[5]
			{
				new Keyframe(0f, 0.34f),
				new Keyframe(0.1f, 0.3f),
				new Keyframe(0.4f, 0.18f),
				new Keyframe(0.75f, 0.05f),
				new Keyframe(1f, 0f)
			}));
			val5.volume = Plugin.Volume.Value;
			val5.dopplerLevel = 0f;
			val5.spatialize = false;
			MonsterCanBehaviour monsterCanBehaviour = val.AddComponent<MonsterCanBehaviour>();
			monsterCanBehaviour.AudioSource = val5;
			bounds = _mesh.bounds;
			monsterCanBehaviour.BaseOffsetY = (0f - ((Bounds)(ref bounds)).min.y) * num2;
			bounds = _mesh.bounds;
			monsterCanBehaviour.LocalCenter = ((Bounds)(ref bounds)).center;
			Rigidbody val6 = val.AddComponent<Rigidbody>();
			val6.mass = Plugin.CanMass.Value;
			val6.isKinematic = true;
			val6.interpolation = (RigidbodyInterpolation)1;
			val6.collisionDetectionMode = (CollisionDetectionMode)2;
			val6.angularDamping = 0.25f;
			val.AddComponent<MonsterCanGrab>();
			return val;
		}

		private static Material BuildMaterial()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			(Shader shader, ShaderKind kind) tuple = ResolveShader();
			Shader item = tuple.shader;
			ShaderKind item2 = tuple.kind;
			Material val = new Material(item)
			{
				name = "MonsterCanMaterial"
			};
			Color c = Color.white * Plugin.EmissionIntensity.Value;
			bool flag = Plugin.EmissionIntensity.Value > 0.001f && (Object)(object)_emission != (Object)null;
			switch (item2)
			{
			case ShaderKind.Urp:
				SetTex(val, "_BaseMap", (Texture?)(object)_emission);
				SetColor(val, "_BaseColor", Color.white);
				SetFloat(val, "_Metallic", Plugin.Metallic.Value);
				SetFloat(val, "_Smoothness", Plugin.Smoothness.Value);
				if (Plugin.UseNormalMap.Value)
				{
					SetTex(val, "_BumpMap", (Texture?)(object)_normal);
					Enable(val, "_NORMALMAP", (Object)(object)_normal != (Object)null);
				}
				SetTex(val, "_OcclusionMap", (Texture?)(object)_ao);
				if (flag)
				{
					SetTex(val, "_EmissionMap", (Texture?)(object)_emission);
					SetColor(val, "_EmissionColor", c);
					Enable(val, "_EMISSION", on: true);
				}
				break;
			case ShaderKind.Hdrp:
				SetTex(val, "_BaseColorMap", (Texture?)(object)_emission);
				SetColor(val, "_BaseColor", Color.white);
				SetFloat(val, "_Metallic", Plugin.Metallic.Value);
				SetFloat(val, "_Smoothness", Plugin.Smoothness.Value);
				if (Plugin.UseNormalMap.Value)
				{
					SetTex(val, "_NormalMap", (Texture?)(object)_normal);
					Enable(val, "_NORMALMAP", (Object)(object)_normal != (Object)null);
				}
				if (flag)
				{
					SetTex(val, "_EmissiveColorMap", (Texture?)(object)_emission);
					SetColor(val, "_EmissiveColor", c);
					Enable(val, "_EMISSION", on: true);
				}
				break;
			default:
				SetTex(val, "_MainTex", (Texture?)(object)_emission);
				SetColor(val, "_Color", Color.white);
				SetFloat(val, "_Metallic", Plugin.Metallic.Value);
				SetFloat(val, "_Glossiness", Plugin.Smoothness.Value);
				if (Plugin.UseNormalMap.Value)
				{
					SetTex(val, "_BumpMap", (Texture?)(object)_normal);
					Enable(val, "_NORMALMAP", (Object)(object)_normal != (Object)null);
				}
				SetTex(val, "_OcclusionMap", (Texture?)(object)_ao);
				if (flag)
				{
					SetTex(val, "_EmissionMap", (Texture?)(object)_emission);
					SetColor(val, "_EmissionColor", c);
					Enable(val, "_EMISSION", on: true);
					val.globalIlluminationFlags = (MaterialGlobalIlluminationFlags)1;
				}
				break;
			}
			Plugin.Log.LogInfo((object)$"MonsterCan material: shader '{((Object)item).name}' ({item2}).");
			return val;
		}

		private static (Shader shader, ShaderKind kind) ResolveShader()
		{
			RenderPipelineAsset currentRenderPipeline = GraphicsSettings.currentRenderPipeline;
			if ((Object)(object)currentRenderPipeline != (Object)null)
			{
				string name = ((object)currentRenderPipeline).GetType().Name;
				if (name.Contains("Universal"))
				{
					Shader val = Shader.Find("Universal Render Pipeline/Lit");
					if ((Object)(object)val != (Object)null)
					{
						return (shader: val, kind: ShaderKind.Urp);
					}
				}
				else if (name.Contains("HDRenderPipeline") || name.Contains("HDRP"))
				{
					Shader val2 = Shader.Find("HDRP/Lit");
					if ((Object)(object)val2 != (Object)null)
					{
						return (shader: val2, kind: ShaderKind.Hdrp);
					}
				}
			}
			Shader val3 = Shader.Find("Standard");
			if ((Object)(object)val3 != (Object)null)
			{
				return (shader: val3, kind: ShaderKind.BuiltIn);
			}
			Shader val4 = Shader.Find("Universal Render Pipeline/Lit");
			if ((Object)(object)val4 != (Object)null)
			{
				return (shader: val4, kind: ShaderKind.Urp);
			}
			Shader item = Shader.Find("Legacy Shaders/Diffuse") ?? Shader.Find("Sprites/Default");
			Plugin.Log.LogWarning((object)"MonsterCan: no PBR shader found; using legacy fallback.");
			return (shader: item, kind: ShaderKind.BuiltIn);
		}

		private static void SetTex(Material m, string prop, Texture? t)
		{
			if ((Object)(object)t != (Object)null && m.HasProperty(prop))
			{
				m.SetTexture(prop, t);
			}
		}

		private static void SetColor(Material m, string prop, Color c)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			if (m.HasProperty(prop))
			{
				m.SetColor(prop, c);
			}
		}

		private static void SetFloat(Material m, string prop, float v)
		{
			if (m.HasProperty(prop))
			{
				m.SetFloat(prop, v);
			}
		}

		private static void Enable(Material m, string kw, bool on)
		{
			if (on)
			{
				m.EnableKeyword(kw);
			}
			else
			{
				m.DisableKeyword(kw);
			}
		}
	}
	internal static class ObjLoader
	{
		public static Mesh Parse(string text, string meshName)
		{
			//IL_02ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fc: Expected O, but got Unknown
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: 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_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: Unknown result type (might be due to invalid IL or missing references)
			List<Vector3> list = new List<Vector3>();
			List<Vector2> list2 = new List<Vector2>();
			List<Vector3> list3 = new List<Vector3>();
			List<Vector3> list4 = new List<Vector3>();
			List<Vector2> list5 = new List<Vector2>();
			List<Vector3> list6 = new List<Vector3>();
			List<int> list7 = new List<int>();
			Dictionary<string, int> dictionary = new Dictionary<string, int>();
			bool flag = false;
			bool flag2 = false;
			CultureInfo invariantCulture = CultureInfo.InvariantCulture;
			string[] array = text.Split('\n');
			string[] array2 = array;
			foreach (string text2 in array2)
			{
				string text3 = text2.Trim();
				if (text3.Length == 0 || text3[0] == '#')
				{
					continue;
				}
				if (text3[0] == 'v')
				{
					string[] array3 = text3.Split((char[]?)null, StringSplitOptions.RemoveEmptyEntries);
					if (array3[0] == "v" && array3.Length >= 4)
					{
						list.Add(new Vector3(float.Parse(array3[1], invariantCulture), float.Parse(array3[2], invariantCulture), float.Parse(array3[3], invariantCulture)));
					}
					else if (array3[0] == "vt" && array3.Length >= 3)
					{
						list2.Add(new Vector2(float.Parse(array3[1], invariantCulture), float.Parse(array3[2], invariantCulture)));
					}
					else if (array3[0] == "vn" && array3.Length >= 4)
					{
						list3.Add(new Vector3(float.Parse(array3[1], invariantCulture), float.Parse(array3[2], invariantCulture), float.Parse(array3[3], invariantCulture)));
					}
				}
				else
				{
					if (text3[0] != 'f')
					{
						continue;
					}
					string[] array4 = text3.Split((char[]?)null, StringSplitOptions.RemoveEmptyEntries);
					List<int> list8 = new List<int>(array4.Length - 1);
					for (int j = 1; j < array4.Length; j++)
					{
						string text4 = array4[j];
						if (!dictionary.TryGetValue(text4, out var value))
						{
							ParseFaceVertex(text4, list.Count, list2.Count, list3.Count, out var vi, out var ti, out var ni);
							Vector3 val = list[vi];
							val.x = 0f - val.x;
							list4.Add(val);
							if (ti >= 0 && ti < list2.Count)
							{
								list5.Add(list2[ti]);
								flag = true;
							}
							else
							{
								list5.Add(Vector2.zero);
							}
							if (ni >= 0 && ni < list3.Count)
							{
								Vector3 val2 = list3[ni];
								val2.x = 0f - val2.x;
								list6.Add(val2);
								flag2 = true;
							}
							else
							{
								list6.Add(Vector3.zero);
							}
							value = (dictionary[text4] = list4.Count - 1);
						}
						list8.Add(value);
					}
					for (int k = 2; k < list8.Count; k++)
					{
						list7.Add(list8[0]);
						list7.Add(list8[k]);
						list7.Add(list8[k - 1]);
					}
				}
			}
			Mesh val3 = new Mesh
			{
				name = meshName
			};
			val3.indexFormat = (IndexFormat)(list4.Count > 65000);
			val3.SetVertices(list4);
			if (flag)
			{
				val3.SetUVs(0, list5);
			}
			val3.SetTriangles(list7, 0);
			if (flag2)
			{
				val3.SetNormals(list6);
			}
			else
			{
				val3.RecalculateNormals();
			}
			val3.RecalculateTangents();
			val3.RecalculateBounds();
			Plugin.Log.LogInfo((object)$"OBJ '{meshName}': {list4.Count} verts, {list7.Count / 3} tris.");
			return val3;
		}

		private static void ParseFaceVertex(string token, int vCount, int tCount, int nCount, out int vi, out int ti, out int ni)
		{
			vi = (ti = (ni = -1));
			string[] array = token.Split('/');
			vi = Resolve(array[0], vCount);
			if (array.Length > 1 && array[1].Length > 0)
			{
				ti = Resolve(array[1], tCount);
			}
			if (array.Length > 2 && array[2].Length > 0)
			{
				ni = Resolve(array[2], nCount);
			}
		}

		private static int Resolve(string s, int count)
		{
			int num = int.Parse(s, CultureInfo.InvariantCulture);
			if (num <= 0)
			{
				return count + num;
			}
			return num - 1;
		}
	}
	[BepInPlugin("AshHenbrey.BigMonsterEnergy", "Big Monster Energy", "0.5.1")]
	public class Plugin : BaseUnityPlugin
	{
		internal static ConfigEntry<bool> Enabled;

		internal static ConfigEntry<float> HeightMeters;

		internal static ConfigEntry<float> EmissionIntensity;

		internal static ConfigEntry<bool> UseNormalMap;

		internal static ConfigEntry<float> Metallic;

		internal static ConfigEntry<float> Smoothness;

		internal static ConfigEntry<float> SpinSpeedDegPerSec;

		internal static ConfigEntry<int> CansPerRun;

		internal static ConfigEntry<float> InsetIntoBiome;

		internal static ConfigEntry<float> BandNear;

		internal static ConfigEntry<float> BandFar;

		internal static ConfigEntry<float> ScatterRadiusMin;

		internal static ConfigEntry<float> ScatterRadiusMax;

		internal static ConfigEntry<float> Volume;

		internal static ConfigEntry<float> AudioMinDistance;

		internal static ConfigEntry<float> AudioMaxDistance;

		internal static ConfigEntry<string> DisplayName;

		internal static ConfigEntry<int> UsesPerCan;

		internal static ConfigEntry<float> HoldSeconds;

		internal static ConfigEntry<float> BuffSeconds;

		internal static ConfigEntry<float> DrowsyAmount;

		internal static ConfigEntry<float> CanMass;

		internal static ConfigEntry<float> CarryStiffness;

		internal static ConfigEntry<float> GrabRange;

		internal static ConfigEntry<float> ActivateRange;

		internal static ConfigEntry<bool> EnableTracker;

		internal static ConfigEntry<KeyCode> TrackerKey;

		public const string Id = "AshHenbrey.BigMonsterEnergy";

		internal static ManualLogSource Log { get; private set; }

		internal static Plugin Instance { get; private set; }

		public static string Name => "Big Monster Energy";

		public static string Version => "0.5.1";

		private void Awake()
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Expected O, but got Unknown
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Expected O, but got Unknown
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Expected O, but got Unknown
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Expected O, but got Unknown
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Expected O, but got Unknown
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Expected O, but got Unknown
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Expected O, but got Unknown
			//IL_02c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d2: Expected O, but got Unknown
			//IL_0366: Unknown result type (might be due to invalid IL or missing references)
			//IL_0370: Expected O, but got Unknown
			//IL_03a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ad: Expected O, but got Unknown
			//IL_03e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ea: Expected O, but got Unknown
			//IL_041d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0427: Expected O, but got Unknown
			//IL_045a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0464: Expected O, but got Unknown
			//IL_0497: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a1: Expected O, but got Unknown
			//IL_04d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04de: Expected O, but got Unknown
			//IL_0511: Unknown result type (might be due to invalid IL or missing references)
			//IL_051b: Expected O, but got Unknown
			//IL_0569: Unknown result type (might be due to invalid IL or missing references)
			//IL_056f: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Master switch for spawning cans.");
			HeightMeters = ((BaseUnityPlugin)this).Config.Bind<float>("Appearance", "HeightMeters", 6f, new ConfigDescription("How tall a can stands in the world, in metres (~3x a player).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 200f), Array.Empty<object>()));
			EmissionIntensity = ((BaseUnityPlugin)this).Config.Bind<float>("Appearance", "EmissionIntensity", 0.35f, new ConfigDescription("Glow strength of the can's artwork (0 = no glow).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 4f), Array.Empty<object>()));
			UseNormalMap = ((BaseUnityPlugin)this).Config.Bind<bool>("Appearance", "UseNormalMap", true, "Apply the model's normal map. Disable if the surface looks wrong on your setup.");
			Metallic = ((BaseUnityPlugin)this).Config.Bind<float>("Appearance", "Metallic", 1f, new ConfigDescription("Metalness of the can body.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			Smoothness = ((BaseUnityPlugin)this).Config.Bind<float>("Appearance", "Smoothness", 0.6f, new ConfigDescription("Surface smoothness / shininess.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			SpinSpeedDegPerSec = ((BaseUnityPlugin)this).Config.Bind<float>("Appearance", "SpinSpeedDegPerSec", 6f, "Slow idle rotation speed in degrees/second (0 = no spin).");
			CansPerRun = ((BaseUnityPlugin)this).Config.Bind<int>("Spawn", "CansPerRun", 2, new ConfigDescription("How many cans exist per map/run. They're spread across the run's biomes (the spawn biome is skipped when possible) and placed deep in each — see InsetIntoBiome.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 20), Array.Empty<object>()));
			InsetIntoBiome = ((BaseUnityPlugin)this).Config.Bind<float>("Spawn", "InsetIntoBiome", 0.75f, new ConfigDescription("How deep into its biome each can sits, 0 = biome entrance, 1 = biome exit. 0.75 puts it in the far quarter of the biome (well past the entrance). Raise it to push cans even further in.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.95f), Array.Empty<object>()));
			BandNear = ((BaseUnityPlugin)this).Config.Bind<float>("Spawn", "BandNear", 0.05f, new ConfigDescription("Fallback height banding only (used when biome data is unavailable). Lowest a can may appear, as a fraction of the climb's height (0 = spawn, 1 = summit).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			BandFar = ((BaseUnityPlugin)this)