Decompiled source of Gamba v0.5.3

BepInEx/plugins/Robin-Gamba/RepoGamba.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Realtime;
using TMPro;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Animations;
using UnityEngine.Audio;
using UnityEngine.Playables;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("RepoGamba")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.5.3.0")]
[assembly: AssemblyInformationalVersion("0.5.3")]
[assembly: AssemblyProduct("RepoGamba")]
[assembly: AssemblyTitle("RepoGamba")]
[assembly: AssemblyVersion("0.5.3.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
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 RepoGamba
{
	public enum GambaSound
	{
		Lose,
		Double,
		Upgrade,
		Maximum,
		Idle,
		Denied
	}
	public static class GambaAudioSynth
	{
		public const int SampleRate = 32000;

		public const double Duration = 6.85;

		private const double Tau = Math.PI * 2.0;

		public static float[] Render(GambaSound sound)
		{
			double num;
			switch (sound)
			{
			default:
				throw new ArgumentOutOfRangeException("sound");
			case GambaSound.Lose:
			case GambaSound.Double:
			case GambaSound.Upgrade:
			case GambaSound.Maximum:
				num = 6.85;
				break;
			case GambaSound.Denied:
				num = 0.28;
				break;
			case GambaSound.Idle:
				num = 2.0;
				break;
			}
			float[] array = new float[(int)Math.Round(num * 32000.0)];
			switch (sound)
			{
			case GambaSound.Idle:
			{
				for (int m = 0; m < array.Length; m++)
				{
					double num9 = (double)m / 32000.0;
					array[m] = (float)(0.055 * Math.Sin(Math.PI * 120.0 * num9) + 0.018 * Math.Sin(Math.PI * 240.0 * num9));
				}
				return array;
			}
			case GambaSound.Denied:
				Tone(array, 0.0, 0.12, 220.0, 0.2, 0.08);
				Tone(array, 0.13, 0.13, 164.81, 0.2, 0.08);
				Finish(array);
				return array;
			default:
			{
				Air(array, 0.025, 0.92, 0.13);
				Sweep(array, 0.06, 0.86, 780.0, 1450.0, 0.06);
				Coin(array, 1.0, 0.22, 0.34);
				Knock(array, 1.2, 0.12, 0.3, 1u);
				Sweep(array, 1.24, 0.79, 105.0, 62.0, 0.18);
				for (int i = 0; i < 7; i++)
				{
					Knock(array, 1.3 + (double)i * 0.095, 0.05, 0.14, (uint)(31 + i));
				}
				Air(array, 1.3, 0.6499999999999999, 0.085);
				Knock(array, 1.9849999999999999, 0.14, 0.28, 57u);
				Coin(array, 1.9949999999999999, 0.16, 0.15);
				Knock(array, 2.05, 0.09, 0.26, 59u);
				Sweep(array, 2.15, 0.65, 160.0, 320.0, 0.16);
				Knock(array, 2.8, 0.08, 0.25, 61u);
				Knock(array, 2.9, 0.055, 0.19, 63u);
				for (int j = 92800; j < 182079; j++)
				{
					double num2 = (double)j / 32000.0 - 2.9;
					double num3 = Math.Min(1.0, num2 / 0.12) * Math.Min(1.0, (2.79 - num2) / 0.1);
					double num4 = Math.PI * 2.0 * (87.0 * num2 - 8.0 * num2 * num2);
					array[j] += (float)(num3 * 0.075 * (Math.Sin(num4) + 0.25 * Math.Sin(num4 * 2.0)) * (1.0 + 0.2 * Math.Sin(Math.PI * 26.0 * num2)));
				}
				int num5 = (int)((sound == GambaSound.Maximum) ? GambaSound.Upgrade : sound);
				int num6 = 18 + num5;
				for (int k = 1; k < num6; k++)
				{
					double at = TickAt(num5, k);
					Knock(array, at, 0.04 + 0.022 * (double)k / (double)num6, 0.15 + 0.055 * (double)k / (double)num6, (uint)(k + 7));
					Tone(array, at, 0.047, (new double[3] { 523.25, 659.25, 783.99 })[k % 3], 0.072, 0.035);
				}
				Knock(array, 5.699999999999999, 0.1, 0.29, 81u);
				switch (sound)
				{
				case GambaSound.Lose:
					Sweep(array, 5.759999999999999, 0.47, 310.0, 92.0, 0.23);
					Tone(array, 5.909999999999999, 0.49, 77.78, 0.12, 0.23);
					Knock(array, 6.1899999999999995, 0.17, 0.17, 103u);
					break;
				case GambaSound.Double:
					Melody(array, 5.744999999999999, new double[4] { 523.25, 659.25, 783.99, 1046.5 }, 0.105, 0.19);
					Chord(array, 6.089999999999999, 0.46, new double[3] { 523.25, 659.25, 1046.5 }, 0.105);
					break;
				case GambaSound.Upgrade:
					Sweep(array, 5.725, 0.4, 420.0, 1250.0, 0.085);
					Melody(array, 5.739999999999999, new double[5] { 523.25, 659.25, 783.99, 1046.5, 1318.51 }, 0.087, 0.15);
					Chord(array, 6.129999999999999, 0.48, new double[3] { 659.25, 1046.5, 1318.51 }, 0.115);
					break;
				case GambaSound.Maximum:
					Melody(array, 5.734999999999999, new double[6] { 523.25, 659.25, 783.99, 1046.5, 1318.51, 1567.98 }, 0.068, 0.145);
					Chord(array, 6.129999999999999, 0.49, new double[4] { 523.25, 783.99, 1046.5, 1567.98 }, 0.087);
					break;
				}
				int num7 = sound switch
				{
					GambaSound.Upgrade => 1, 
					GambaSound.Lose => 0, 
					_ => 2, 
				};
				for (int l = 0; l < num7; l++)
				{
					double at2 = 5.699999999999999 + (double)l * 0.14;
					Knock(array, at2, 0.065, 0.15, (uint)(130 + l));
					double num8 = GambaCabinetMotionMath.TrayImpactAt(l);
					Coin(array, num8, 0.24, 0.28);
					Knock(array, num8, 0.065, 0.17, (uint)(140 + l));
					Coin(array, num8 + 0.091, 0.1, 0.1);
				}
				Finish(array);
				return array;
			}
			}
		}

		public static double TickAt(int outcome, int step)
		{
			if (outcome < 0 || outcome > 2 || step < 0 || step > 18 + outcome)
			{
				throw new ArgumentOutOfRangeException();
			}
			return 2.9 + 2.8 * (1.0 - Math.Sqrt(1.0 - (double)step / (double)(18 + outcome)));
		}

		public static int SeekSample(double elapsed, int samples)
		{
			if (double.IsNaN(elapsed) || double.IsInfinity(elapsed) || elapsed < 0.0 || samples <= 0)
			{
				return -1;
			}
			double num = Math.Round(elapsed * 32000.0);
			if (!(num >= (double)samples))
			{
				return (int)num;
			}
			return -1;
		}

		private static void Tone(float[] pcm, double at, double duration, double hz, double gain, double decay)
		{
			Add(pcm, at, duration, (double t) => gain * Math.Min(1.0, t / 0.004) * Math.Exp((0.0 - t) / decay) * (Math.Sin(Math.PI * 2.0 * hz * t) + 0.2 * Math.Sin(Math.PI * 2.0 * hz * 2.0 * t) + 0.065 * Math.Sin(Math.PI * 2.0 * hz * 3.0 * t)));
		}

		private static void Coin(float[] pcm, double at, double duration, double gain)
		{
			Add(pcm, at, duration, (double t) => gain * Math.Min(1.0, t / 0.0015) * Math.Exp((0.0 - t) / 0.048) * (0.58 * Math.Sin(Math.PI * 4280.0 * t) + 0.27 * Math.Sin(Math.PI * 6542.0 * t) + 0.15 * Math.Sin(Math.PI * 9358.0 * t)));
		}

		private static void Air(float[] pcm, double at, double duration, double gain)
		{
			uint seed = 179u;
			double filtered = 0.0;
			Add(pcm, at, duration, delegate(double t)
			{
				seed = seed * 1664525 + 1013904223;
				filtered += 0.19 * ((double)(seed >> 8) / 8388607.5 - 1.0 - filtered);
				return gain * Math.Sin(Math.PI * t / duration) * filtered;
			});
		}

		private static void Knock(float[] pcm, double at, double duration, double gain, uint seed)
		{
			Add(pcm, at, duration, delegate(double t)
			{
				seed = seed * 1664525 + 1013904223;
				double num = (double)(seed >> 8) / 8388607.5 - 1.0;
				return gain * Math.Min(1.0, t / 0.001) * Math.Exp((0.0 - t) / 0.014) * (0.45 * num + 0.55 * Math.Sin(Math.PI * 370.0 * t));
			});
		}

		private static void Sweep(float[] pcm, double at, double duration, double from, double to, double gain)
		{
			Add(pcm, at, duration, delegate(double t)
			{
				double num = Math.PI * 2.0 * (from * t + (to - from) * t * t / (2.0 * duration));
				return gain * Math.Sin(Math.PI * t / duration) * (Math.Sin(num) + 0.14 * Math.Sin(num * 2.0));
			});
		}

		private static void Melody(float[] pcm, double at, double[] notes, double spacing, double gain)
		{
			for (int i = 0; i < notes.Length; i++)
			{
				Tone(pcm, at + (double)i * spacing, 0.22, notes[i], gain, 0.085);
			}
		}

		private static void Chord(float[] pcm, double at, double duration, double[] notes, double gain)
		{
			foreach (double hz in notes)
			{
				Tone(pcm, at, duration, hz, gain, 0.2);
			}
		}

		private static void Add(float[] pcm, double at, double duration, Func<double, double> signal)
		{
			int num = (int)Math.Round(at * 32000.0);
			int num2 = (int)Math.Round(duration * 32000.0);
			for (int i = 0; i < num2 && num + i < pcm.Length; i++)
			{
				if (num + i >= 0)
				{
					double num3 = Math.Min(1.0, (double)(num2 - i - 1) / 256.0);
					pcm[num + i] += (float)(signal((double)i / 32000.0) * num3);
				}
			}
		}

		private static void Finish(float[] pcm)
		{
			for (int i = 0; i < pcm.Length; i++)
			{
				pcm[i] = (float)(0.8 * Math.Tanh(pcm[i]));
			}
			pcm[0] = 0f;
			pcm[^1] = 0f;
		}
	}
	public sealed class GambaCabinetMotion : MonoBehaviour
	{
		private struct Pose
		{
			internal Transform Transform;

			internal Vector3 RestPosition;

			internal Vector3 RestScale;

			internal Quaternion RestRotation;
		}

		private GambaMachine machine;

		private Transform model;

		private Transform tray;

		private AnimationClip? handle;

		private readonly List<Pose> poses = new List<Pose>();

		private readonly GameObject?[,] coins = new GameObject[4, 2];

		private readonly Quaternion[] coinRotation = (Quaternion[])(object)new Quaternion[4];

		private string transaction = "";

		private double elapsed = -1.0;

		private bool failed;

		public void Initialize(GambaMachine owner, AnimationClip clip)
		{
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			machine = owner;
			model = ((Component)this).transform.Find("CabinetModel");
			tray = ((Component)this).transform.Find("PayoutTrayAnchor");
			if (!Object.op_Implicit((Object)(object)model) || !Object.op_Implicit((Object)(object)tray) || !Object.op_Implicit((Object)(object)clip))
			{
				throw new InvalidOperationException("Matching animated cabinet assets are required.");
			}
			handle = Object.Instantiate<AnimationClip>(clip);
			((Object)handle).name = "Gamba owned handle animation";
			handle.events = Array.Empty<AnimationEvent>();
			handle.SampleAnimation(((Component)model).gameObject, 0f);
			Transform[] componentsInChildren = ((Component)model).GetComponentsInChildren<Transform>(true);
			foreach (Transform val in componentsInChildren)
			{
				poses.Add(new Pose
				{
					Transform = val,
					RestPosition = val.localPosition,
					RestRotation = val.localRotation,
					RestScale = val.localScale
				});
			}
			Restore();
		}

		private void LateUpdate()
		{
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			if (failed || !Object.op_Implicit((Object)(object)machine) || !Object.op_Implicit((Object)(object)handle))
			{
				return;
			}
			try
			{
				if (!GambaRuntime.Ready)
				{
					HideCoins();
					Restore();
					return;
				}
				if (transaction != machine.TransactionId)
				{
					transaction = machine.TransactionId;
					elapsed = -1.0;
					HideCoins();
					Restore();
				}
				if (string.IsNullOrEmpty(transaction) || machine.StartedAt < 0.0)
				{
					return;
				}
				elapsed = Math.Max(elapsed, GambaRuntime.Clock - machine.StartedAt);
				bool value = GambaPlugin.ReducedMotion.Value;
				double num = GambaCabinetMotionMath.HandleSample(elapsed, handle.length);
				if (num < 0.0 || value)
				{
					Restore();
				}
				else
				{
					handle.SampleAnimation(((Component)model).gameObject, (float)num);
				}
				GambaPayout gambaPayout = GambaRules.Payout(machine.InputTier, (GambaOutcome)machine.Outcome);
				for (int i = 0; i < gambaPayout.Count; i++)
				{
					double num2 = GambaCabinetMotionMath.CoinProgress(elapsed, i, value);
					if (!(num2 < 0.0))
					{
						GameObject obj = Coin(gambaPayout.Tier, i);
						obj.SetActive(true);
						float num3 = ((gambaPayout.Count != 2) ? 0f : ((i == 0) ? (-0.1f) : 0.1f));
						float num4 = GambaCabinetMotionMath.DropHeight(num2);
						obj.transform.localPosition = new Vector3(num3, num4, (float)(-0.08 * (1.0 - num2)));
						obj.transform.localRotation = Quaternion.AngleAxis((float)(i * 38 - 15), Vector3.up) * Quaternion.AngleAxis((float)(140.0 * (1.0 - num2)), Vector3.right) * coinRotation[gambaPayout.Tier];
					}
				}
			}
			catch (Exception ex)
			{
				failed = true;
				HideCoins();
				Restore();
				GambaPlugin.Log.LogWarning((object)("Gamba handle/payout visual unavailable; wallet unchanged: " + ex.Message));
			}
		}

		private GameObject Coin(int tier, int index)
		{
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Expected O, but got Unknown
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: 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)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0260: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: 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_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: 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)
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_0286: Unknown result type (might be due to invalid IL or missing references)
			//IL_028d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0292: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)coins[tier, index]))
			{
				return coins[tier, index];
			}
			GameObject val = Resources.Load<GameObject>("level/shop/modules/Module - Shop - S - Cosmetic Machine 01");
			CosmeticShopMachineAnimator val2 = (Object.op_Implicit((Object)(object)val) ? val.GetComponentInChildren<CosmeticShopMachineAnimator>(true) : null);
			if (!Object.op_Implicit((Object)(object)val2) || val2.tokenObjectsInserted == null || val2.tokenObjectsInserted.Count <= tier || !Object.op_Implicit((Object)(object)val2.tokenObjectsInserted[tier]))
			{
				throw new InvalidOperationException("Stock payout coin mesh is missing.");
			}
			GameObject val3 = new GameObject("Gamba payout tier " + tier + " (visual only)");
			coins[tier, index] = val3;
			val3.transform.SetParent(tray, false);
			val3.SetActive(false);
			CopyMeshes(val2.tokenObjectsInserted[tier].transform, val3.transform);
			bool flag = true;
			Bounds val4 = default(Bounds);
			MeshFilter[] componentsInChildren = val3.GetComponentsInChildren<MeshFilter>(true);
			foreach (MeshFilter val5 in componentsInChildren)
			{
				Bounds bounds = val5.sharedMesh.bounds;
				for (int j = 0; j < 8; j++)
				{
					Vector3 val6 = ((Bounds)(ref bounds)).center + Vector3.Scale(((Bounds)(ref bounds)).extents, new Vector3((float)(((j & 1) != 0) ? 1 : (-1)), (float)(((j & 2) != 0) ? 1 : (-1)), (float)(((j & 4) != 0) ? 1 : (-1))));
					val6 = val3.transform.InverseTransformPoint(((Component)val5).transform.TransformPoint(val6));
					if (flag)
					{
						((Bounds)(ref val4))..ctor(val6, Vector3.zero);
						flag = false;
					}
					else
					{
						((Bounds)(ref val4)).Encapsulate(val6);
					}
				}
			}
			float num = Mathf.Max(((Bounds)(ref val4)).size.x, Mathf.Max(((Bounds)(ref val4)).size.y, ((Bounds)(ref val4)).size.z));
			if (flag || num < 0.0001f)
			{
				throw new InvalidOperationException("Stock payout coin geometry is empty.");
			}
			Vector3 val7 = ((((Bounds)(ref val4)).size.x <= ((Bounds)(ref val4)).size.y && ((Bounds)(ref val4)).size.x <= ((Bounds)(ref val4)).size.z) ? Vector3.right : ((((Bounds)(ref val4)).size.y <= ((Bounds)(ref val4)).size.z) ? Vector3.up : Vector3.forward));
			coinRotation[tier] = Quaternion.FromToRotation(val7, Vector3.up);
			foreach (Transform item in val3.transform)
			{
				item.localPosition -= ((Bounds)(ref val4)).center;
			}
			val3.transform.localScale = Vector3.one * (0.14f / num);
			return val3;
		}

		private static void CopyMeshes(Transform source, Transform destination)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = new GameObject(((Object)source).name).transform;
			transform.SetParent(destination, false);
			CopyNode(source, transform);
		}

		private static void CopyNode(Transform source, Transform copy)
		{
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Expected O, but got Unknown
			//IL_0080: 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_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			MeshFilter component = ((Component)source).GetComponent<MeshFilter>();
			MeshRenderer component2 = ((Component)source).GetComponent<MeshRenderer>();
			if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component.sharedMesh) && Object.op_Implicit((Object)(object)component2))
			{
				((Component)copy).gameObject.AddComponent<MeshFilter>().sharedMesh = component.sharedMesh;
				MeshRenderer obj = ((Component)copy).gameObject.AddComponent<MeshRenderer>();
				((Renderer)obj).sharedMaterials = ((Renderer)component2).sharedMaterials;
				((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0;
				((Renderer)obj).receiveShadows = false;
			}
			foreach (Transform item in source)
			{
				Transform val = item;
				Transform transform = new GameObject(((Object)val).name).transform;
				transform.SetParent(copy, false);
				transform.localPosition = val.localPosition;
				transform.localRotation = val.localRotation;
				transform.localScale = val.localScale;
				CopyNode(val, transform);
			}
		}

		private void Restore()
		{
			//IL_002a: 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_004c: Unknown result type (might be due to invalid IL or missing references)
			foreach (Pose pose in poses)
			{
				if (Object.op_Implicit((Object)(object)pose.Transform))
				{
					pose.Transform.localPosition = pose.RestPosition;
					pose.Transform.localRotation = pose.RestRotation;
					pose.Transform.localScale = pose.RestScale;
				}
			}
		}

		private void HideCoins()
		{
			GameObject[,] array = coins;
			foreach (GameObject val in array)
			{
				if (Object.op_Implicit((Object)(object)val))
				{
					val.SetActive(false);
				}
			}
		}

		private void OnDisable()
		{
			HideCoins();
			Restore();
		}

		private void OnDestroy()
		{
			if (Object.op_Implicit((Object)(object)handle))
			{
				Object.Destroy((Object)(object)handle);
			}
			GameObject[,] array = coins;
			foreach (GameObject val in array)
			{
				if (Object.op_Implicit((Object)(object)val))
				{
					Object.Destroy((Object)(object)val);
				}
			}
		}
	}
	internal static class GambaCabinetMotionMath
	{
		internal const double NativePullEnd = 2.0 / 3.0;

		internal const double NativeReturnStart = 19.0 / 24.0;

		internal const double CoinStagger = 0.14;

		internal const double DropSeconds = 0.52;

		internal static double TrayImpactAt(int index)
		{
			return 5.699999999999999 + (double)index * 0.14 + 0.338;
		}

		internal static double HandleSample(double elapsed, double clipLength)
		{
			if (double.IsNaN(elapsed) || elapsed < 1.2 || elapsed >= 2.8)
			{
				return -1.0;
			}
			if (elapsed < 2.05)
			{
				return 2.0 / 3.0 * (elapsed - 1.2) / 0.85;
			}
			if (elapsed < 2.15)
			{
				return 2.0 / 3.0 + 0.125 * (elapsed - 2.05) / 0.1;
			}
			return 19.0 / 24.0 + (clipLength - 19.0 / 24.0) * (elapsed - 2.15) / 0.65;
		}

		internal static double CoinProgress(double elapsed, int index, bool reducedMotion)
		{
			if (elapsed < 5.699999999999999)
			{
				return -1.0;
			}
			if (reducedMotion)
			{
				return 1.0;
			}
			double num = elapsed - 5.699999999999999 - (double)index * 0.14;
			if (!(num < 0.0))
			{
				return Math.Min(1.0, num / 0.52);
			}
			return -1.0;
		}

		internal static float DropHeight(double progress)
		{
			double num = Math.Max(0.0, Math.Min(1.0, progress));
			if (num < 0.65)
			{
				return (float)(0.24 * (1.0 - num * num / 0.42250000000000004));
			}
			double num2 = (num - 0.65) / 0.35;
			return (float)(0.026 * Math.Abs(Math.Sin(num2 * Math.PI * 2.0)) * (1.0 - num2));
		}
	}
	public sealed class GambaCoinInsert : MonoBehaviour
	{
		public const double DurationSeconds = 1.95;

		private const string StockResource = "level/shop/modules/Module - Shop - S - Cosmetic Machine 01";

		private const string IntroName = "Cosmetic Shop Machine - Token Intro";

		private const float HandoffSample = 1.75f;

		private readonly GambaCoinInsertTimeline timeline = new GambaCoinInsertTimeline();

		private readonly List<MeshRenderer>[] flying = new List<MeshRenderer>[4]
		{
			new List<MeshRenderer>(),
			new List<MeshRenderer>(),
			new List<MeshRenderer>(),
			new List<MeshRenderer>()
		};

		private readonly List<MeshRenderer>[] inserted = new List<MeshRenderer>[4]
		{
			new List<MeshRenderer>(),
			new List<MeshRenderer>(),
			new List<MeshRenderer>(),
			new List<MeshRenderer>()
		};

		private GambaMachine? machine;

		private PlayerAvatar? bettor;

		private int bettorView = -1;

		private bool resolvedBettor;

		private Transform? slot;

		private Transform? rig;

		private Transform? follow;

		private Transform? target;

		private AnimationClip? intro;

		private PlayableGraph graph;

		private AnimationClipPlayable playable;

		private AnimationCurve? flight;

		private Vector3 dockRigPosition;

		private float sinkDepth;

		private readonly MeshFilter[] flightMeshes = (MeshFilter[])(object)new MeshFilter[4];

		private readonly Quaternion[] dockRotations = (Quaternion[])(object)new Quaternion[4];

		private readonly float[] dockScales = new float[4];

		private bool initialized;

		private bool failed;

		private bool warned;

		public bool Initialize(GambaMachine owner, Transform slotAnchor, float coinScale = 1f, CosmeticShopMachineAnimator? visualSource = null)
		{
			if (initialized)
			{
				if ((Object)(object)machine == (Object)(object)owner)
				{
					return (Object)(object)slot == (Object)(object)slotAnchor;
				}
				return false;
			}
			if (!Object.op_Implicit((Object)(object)owner) || !Object.op_Implicit((Object)(object)slotAnchor) || !Finite(coinScale) || coinScale <= 0f || coinScale > 4f)
			{
				return false;
			}
			try
			{
				machine = owner;
				slot = slotAnchor;
				CosmeticShopMachineAnimator val = (Object.op_Implicit((Object)(object)visualSource) ? visualSource : FindStockVisuals());
				if (!Object.op_Implicit((Object)(object)val))
				{
					throw new InvalidOperationException("Stock cosmetic coin visual source is unavailable.");
				}
				Build(val, slotAnchor, coinScale);
				initialized = true;
				failed = false;
				return true;
			}
			catch (Exception error)
			{
				Fail(error);
				ReleaseOwned();
				return false;
			}
		}

		public bool BeginConfirmed(string transaction, int inputTier, double startedAt, PlayerAvatar? actualBettor)
		{
			if (!Object.op_Implicit((Object)(object)actualBettor) || !Object.op_Implicit((Object)(object)actualBettor.photonView))
			{
				return false;
			}
			return BeginConfirmed(transaction, inputTier, startedAt, actualBettor.photonView.ViewID);
		}

		public bool BeginConfirmed(string transaction, int inputTier, double startedAt, int bettorViewId)
		{
			if (!initialized || failed || !((Behaviour)this).isActiveAndEnabled || !Object.op_Implicit((Object)(object)machine) || bettorViewId < 0 || machine.TransactionId != transaction || machine.InputTier != inputTier || machine.StartedAt != startedAt || machine.BettorViewId != bettorViewId)
			{
				return false;
			}
			try
			{
				if (!timeline.Begin(transaction, inputTier, startedAt, GambaRuntime.Clock))
				{
					return false;
				}
				Hide();
				bettor = null;
				bettorView = bettorViewId;
				resolvedBettor = false;
				Tick();
				return true;
			}
			catch (Exception error)
			{
				Fail(error);
				return false;
			}
		}

		private void LateUpdate()
		{
			if (!initialized || failed)
			{
				return;
			}
			try
			{
				Tick();
			}
			catch (Exception error)
			{
				Fail(error);
			}
		}

		private void Tick()
		{
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: 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_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0263: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0400: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0300: Unknown result type (might be due to invalid IL or missing references)
			//IL_030b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0310: Unknown result type (might be due to invalid IL or missing references)
			//IL_0321: Unknown result type (might be due to invalid IL or missing references)
			//IL_037b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0380: Unknown result type (might be due to invalid IL or missing references)
			//IL_0384: Unknown result type (might be due to invalid IL or missing references)
			//IL_0389: Unknown result type (might be due to invalid IL or missing references)
			//IL_038e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0397: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_033d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0363: Unknown result type (might be due to invalid IL or missing references)
			bool available = Object.op_Implicit((Object)(object)machine) && Object.op_Implicit((Object)(object)slot) && Object.op_Implicit((Object)(object)rig) && Object.op_Implicit((Object)(object)intro) && Object.op_Implicit((Object)(object)follow) && Object.op_Implicit((Object)(object)target) && GambaRuntime.Ready && machine.TransactionId == timeline.Transaction && machine.StartedAt == timeline.StartedAt && machine.InputTier == timeline.Tier && machine.BettorViewId == bettorView;
			if (resolvedBettor && (!Object.op_Implicit((Object)(object)bettor) || !((Component)bettor).gameObject.activeInHierarchy))
			{
				available = false;
			}
			double num = timeline.Sample(GambaRuntime.Clock, GambaPlugin.ReducedMotion?.Value ?? false, available);
			if (num < 0.0)
			{
				Hide();
				return;
			}
			if (!Object.op_Implicit((Object)(object)bettor))
			{
				foreach (PlayerAvatar item in SemiFunc.PlayerGetList())
				{
					if (Object.op_Implicit((Object)(object)item) && Object.op_Implicit((Object)(object)item.photonView) && item.photonView.ViewID == bettorView)
					{
						bettor = item;
						resolvedBettor = true;
						break;
					}
				}
			}
			Transform val = ((Object.op_Implicit((Object)(object)bettor) && ((Component)bettor).gameObject.activeInHierarchy && Object.op_Implicit((Object)(object)bettor.playerAvatarVisuals)) ? bettor.playerAvatarVisuals.headLookAtTransform : null);
			if (!Object.op_Implicit((Object)(object)val))
			{
				Hide();
				return;
			}
			float num2 = GambaCoinMotionMath.ClipSample(num);
			rig.localPosition = dockRigPosition;
			Sample(num2);
			float num3 = flight.Evaluate(num2);
			follow.position = Vector3.LerpUnclamped(val.position, target.position, num3);
			follow.rotation = Quaternion.LerpUnclamped(val.rotation, target.rotation, num3);
			follow.localScale = target.parent.localScale;
			if (num < 1.0)
			{
				float num4 = GambaCoinMotionMath.LandingBlend(num);
				MeshFilter val2 = flightMeshes[timeline.Tier];
				Quaternion val3 = slot.rotation * dockRotations[timeline.Tier] * Quaternion.Inverse(((Component)val2).transform.rotation);
				follow.rotation = Quaternion.Slerp(Quaternion.identity, val3, num4) * follow.rotation;
				float num5 = MaxScale(((Component)val2).transform.lossyScale);
				if (num5 > 0.0001f)
				{
					Transform? obj = follow;
					obj.localScale *= Mathf.Lerp(1f, dockScales[timeline.Tier] / num5, num4);
				}
				Transform transform = ((Component)val2).transform;
				Bounds bounds = val2.sharedMesh.bounds;
				Vector3 val4 = transform.TransformPoint(((Bounds)(ref bounds)).center);
				Transform? obj2 = follow;
				obj2.position += (slot.position - val4) * num4;
			}
			float num6 = GambaCoinMotionMath.SinkProgress(num);
			rig.localPosition = dockRigPosition + Vector3.back * (sinkDepth * num6) + Vector3.down * (0.045f * num6 * num6);
			for (int i = 0; i < 4; i++)
			{
				foreach (MeshRenderer item2 in flying[i])
				{
					((Renderer)item2).enabled = i == timeline.Tier && num < 1.0;
				}
				foreach (MeshRenderer item3 in inserted[i])
				{
					((Renderer)item3).enabled = i == timeline.Tier && num >= 1.0;
				}
			}
		}

		private static CosmeticShopMachineAnimator? FindStockVisuals()
		{
			CosmeticShopMachine instance = CosmeticShopMachine.instance;
			if (Object.op_Implicit((Object)(object)instance) && Object.op_Implicit((Object)(object)instance.animator))
			{
				return instance.animator;
			}
			GameObject val = Resources.Load<GameObject>("level/shop/modules/Module - Shop - S - Cosmetic Machine 01");
			if (!Object.op_Implicit((Object)(object)val))
			{
				return null;
			}
			return val.GetComponentInChildren<CosmeticShopMachineAnimator>(true);
		}

		private void Build(CosmeticShopMachineAnimator source, Transform anchor, float coinScale)
		{
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: 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_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Expected O, but got Unknown
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0403: Unknown result type (might be due to invalid IL or missing references)
			//IL_040f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0415: Unknown result type (might be due to invalid IL or missing references)
			//IL_043c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0441: Unknown result type (might be due to invalid IL or missing references)
			//IL_0445: Unknown result type (might be due to invalid IL or missing references)
			//IL_044a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0459: Unknown result type (might be due to invalid IL or missing references)
			//IL_045b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0460: Unknown result type (might be due to invalid IL or missing references)
			//IL_0465: Unknown result type (might be due to invalid IL or missing references)
			//IL_046d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0472: Unknown result type (might be due to invalid IL or missing references)
			//IL_0479: Unknown result type (might be due to invalid IL or missing references)
			//IL_047e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0483: Unknown result type (might be due to invalid IL or missing references)
			//IL_0485: Unknown result type (might be due to invalid IL or missing references)
			//IL_0493: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0507: Unknown result type (might be due to invalid IL or missing references)
			//IL_050c: Unknown result type (might be due to invalid IL or missing references)
			//IL_050f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0514: Unknown result type (might be due to invalid IL or missing references)
			//IL_0519: Unknown result type (might be due to invalid IL or missing references)
			//IL_052a: Unknown result type (might be due to invalid IL or missing references)
			//IL_052c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0532: Unknown result type (might be due to invalid IL or missing references)
			//IL_0537: Unknown result type (might be due to invalid IL or missing references)
			//IL_053c: Unknown result type (might be due to invalid IL or missing references)
			//IL_054e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0554: Unknown result type (might be due to invalid IL or missing references)
			//IL_0559: Unknown result type (might be due to invalid IL or missing references)
			//IL_056c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0572: Unknown result type (might be due to invalid IL or missing references)
			//IL_0595: Unknown result type (might be due to invalid IL or missing references)
			//IL_059a: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0604: Unknown result type (might be due to invalid IL or missing references)
			//IL_0609: Unknown result type (might be due to invalid IL or missing references)
			//IL_061d: Unknown result type (might be due to invalid IL or missing references)
			//IL_062f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0634: Unknown result type (might be due to invalid IL or missing references)
			//IL_063d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0644: Unknown result type (might be due to invalid IL or missing references)
			//IL_066a: Unknown result type (might be due to invalid IL or missing references)
			//IL_066f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0674: Unknown result type (might be due to invalid IL or missing references)
			//IL_0679: Unknown result type (might be due to invalid IL or missing references)
			//IL_0683: Unknown result type (might be due to invalid IL or missing references)
			//IL_0685: Unknown result type (might be due to invalid IL or missing references)
			//IL_068a: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)source.tokenMeshFollowTransform) || !Object.op_Implicit((Object)(object)source.tokenMeshFollowTransformParent) || !Object.op_Implicit((Object)(object)source.tokenMeshTargetTransform) || source.tokenObjects == null || source.tokenObjects.Count < 4 || source.tokenObjectsInserted == null || source.tokenObjectsInserted.Count < 4 || source.tokenMeshFollowCurve == null || source.tokenMeshFollowCurve.length == 0)
			{
				throw new InvalidOperationException("Stock coin rig is incomplete.");
			}
			Animator component = ((Component)source).GetComponent<Animator>();
			AnimationClip val = null;
			if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component.runtimeAnimatorController))
			{
				AnimationClip[] animationClips = component.runtimeAnimatorController.animationClips;
				foreach (AnimationClip val2 in animationClips)
				{
					if (Object.op_Implicit((Object)(object)val2) && ((Object)val2).name == "Cosmetic Shop Machine - Token Intro")
					{
						val = val2;
						break;
					}
				}
			}
			if (!Object.op_Implicit((Object)(object)val) || !Finite(val.length) || val.length < 1.75f)
			{
				throw new InvalidOperationException("Stock token intro clip was not found.");
			}
			intro = Object.Instantiate<AnimationClip>(val);
			((Object)intro).name = "Gamba owned event-free token intro";
			((Object)intro).hideFlags = (HideFlags)61;
			intro.events = Array.Empty<AnimationEvent>();
			flight = new AnimationCurve(source.tokenMeshFollowCurve.keys)
			{
				preWrapMode = source.tokenMeshFollowCurve.preWrapMode,
				postWrapMode = source.tokenMeshFollowCurve.postWrapMode
			};
			rig = new GameObject("Gamba coin insert (owned render-only rig)").transform;
			rig.SetParent(anchor, false);
			Dictionary<Transform, Transform> mapping = new Dictionary<Transform, Transform> { [((Component)source).transform] = rig };
			follow = CopyPath(source.tokenMeshFollowTransform, ((Component)source).transform, mapping);
			target = CopyPath(source.tokenMeshTargetTransform, ((Component)source).transform, mapping);
			Transform val3 = CopyPath(source.tokenMeshFollowTransformParent, ((Component)source).transform, mapping);
			for (int j = 0; j < 4; j++)
			{
				if (!Object.op_Implicit((Object)(object)source.tokenObjects[j]) || !Object.op_Implicit((Object)(object)source.tokenObjectsInserted[j]))
				{
					throw new InvalidOperationException("Stock coin tier " + j + " is missing.");
				}
				CopyMeshes(source.tokenObjects[j].transform, ((Component)source).transform, mapping, flying[j]);
				CopyMeshes(source.tokenObjectsInserted[j].transform, ((Component)source).transform, mapping, inserted[j]);
				if (flying[j].Count == 0 || inserted[j].Count == 0)
				{
					throw new InvalidOperationException("Stock coin tier " + j + " has no mesh renderer.");
				}
			}
			follow.SetParent(val3, false);
			Transform transform2 = source.tokenObjectsInserted[0].transform;
			if (!Object.op_Implicit((Object)(object)transform2.parent) || !Object.op_Implicit((Object)(object)transform2.parent.parent))
			{
				throw new InvalidOperationException("Stock inserted-coin frame is missing.");
			}
			Transform val4 = CopyPath(transform2.parent.parent, ((Component)source).transform, mapping);
			MeshFilter component2 = ((Component)inserted[0][0]).GetComponent<MeshFilter>();
			if (!Object.op_Implicit((Object)(object)component2) || !Object.op_Implicit((Object)(object)component2.sharedMesh))
			{
				throw new InvalidOperationException("Stock inserted-coin mesh is missing.");
			}
			Animator val5 = ((Component)rig).gameObject.AddComponent<Animator>();
			val5.applyRootMotion = false;
			val5.fireEvents = false;
			val5.cullingMode = (AnimatorCullingMode)0;
			graph = PlayableGraph.Create("Gamba owned coin insert");
			((PlayableGraph)(ref graph)).SetTimeUpdateMode((DirectorUpdateMode)3);
			playable = AnimationClipPlayable.Create(graph, intro);
			((AnimationClipPlayable)(ref playable)).SetApplyFootIK(false);
			((AnimationClipPlayable)(ref playable)).SetApplyPlayableIK(false);
			PlayableExtensions.SetSpeed<AnimationClipPlayable>(playable, 0.0);
			PlayableOutputExtensions.SetSourcePlayable<AnimationPlayableOutput, AnimationClipPlayable>(AnimationPlayableOutput.Create(graph, "Coin transforms only", val5), playable);
			((PlayableGraph)(ref graph)).Play();
			Sample(1.75f);
			Bounds bounds = component2.sharedMesh.bounds;
			Vector3 center = ((Bounds)(ref bounds)).center;
			Vector3 val6 = rig.InverseTransformPoint(((Component)component2).transform.TransformPoint(center));
			Quaternion val7 = Quaternion.Inverse(rig.rotation) * val4.rotation;
			if (!Finite(val6.x) || !Finite(val6.y) || !Finite(val6.z))
			{
				throw new InvalidOperationException("Stock coin landing pose is invalid.");
			}
			rig.localScale = Vector3.one * coinScale;
			rig.localRotation = Quaternion.Euler(0f, 90f, 0f) * Quaternion.Inverse(val7);
			rig.localPosition = -(rig.localRotation * (val6 * coinScale));
			Vector3 val8 = ((Component)component2).transform.TransformPoint(center) - anchor.position;
			if (((Vector3)(ref val8)).sqrMagnitude > 1E-08f || Vector3.Dot(val4.right, -anchor.forward) < 0.999f || Vector3.Dot(val4.up, anchor.up) < 0.999f)
			{
				throw new InvalidOperationException("Stock coin could not be aligned with the cabinet slot.");
			}
			dockRigPosition = rig.localPosition;
			sinkDepth = 0.12f;
			for (int k = 0; k < 4; k++)
			{
				flightMeshes[k] = ((Component)flying[k][0]).GetComponent<MeshFilter>();
				MeshFilter component3 = ((Component)inserted[k][0]).GetComponent<MeshFilter>();
				dockRotations[k] = Quaternion.Inverse(anchor.rotation) * ((Component)component3).transform.rotation;
				dockScales[k] = MaxScale(((Component)component3).transform.lossyScale);
				Bounds bounds2 = component3.sharedMesh.bounds;
				for (int l = 0; l < 8; l++)
				{
					Vector3 val9 = ((Bounds)(ref bounds2)).center + Vector3.Scale(((Bounds)(ref bounds2)).extents, new Vector3((float)(((l & 1) != 0) ? 1 : (-1)), (float)(((l & 2) != 0) ? 1 : (-1)), (float)(((l & 4) != 0) ? 1 : (-1))));
					float z = anchor.InverseTransformPoint(((Component)component3).transform.TransformPoint(val9)).z;
					sinkDepth = Mathf.Max(sinkDepth, z + 0.04f);
				}
			}
			Sample(0f);
			Hide();
		}

		private void Sample(float seconds)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			PlayableExtensions.SetTime<AnimationClipPlayable>(playable, (double)seconds);
			((PlayableGraph)(ref graph)).Evaluate(0f);
		}

		private static Transform CopyPath(Transform original, Transform sourceRoot, Dictionary<Transform, Transform> mapping)
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			if (mapping.TryGetValue(original, out Transform value))
			{
				return value;
			}
			if (!Object.op_Implicit((Object)(object)original) || !original.IsChildOf(sourceRoot) || !Object.op_Implicit((Object)(object)original.parent))
			{
				throw new InvalidOperationException("Stock coin animation path escapes its rig.");
			}
			Transform val = CopyPath(original.parent, sourceRoot, mapping);
			Transform transform = new GameObject(((Object)original).name).transform;
			transform.SetParent(val, false);
			transform.localPosition = original.localPosition;
			transform.localRotation = original.localRotation;
			transform.localScale = original.localScale;
			mapping.Add(original, transform);
			return transform;
		}

		private static void CopyMeshes(Transform original, Transform sourceRoot, Dictionary<Transform, Transform> mapping, List<MeshRenderer> renderers)
		{
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Expected O, but got Unknown
			Transform val = CopyPath(original, sourceRoot, mapping);
			MeshFilter component = ((Component)original).GetComponent<MeshFilter>();
			MeshRenderer component2 = ((Component)original).GetComponent<MeshRenderer>();
			if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component.sharedMesh) && Object.op_Implicit((Object)(object)component2))
			{
				((Component)val).gameObject.AddComponent<MeshFilter>().sharedMesh = component.sharedMesh;
				MeshRenderer val2 = ((Component)val).gameObject.AddComponent<MeshRenderer>();
				((Renderer)val2).enabled = false;
				((Renderer)val2).sharedMaterials = ((Renderer)component2).sharedMaterials;
				((Renderer)val2).shadowCastingMode = (ShadowCastingMode)0;
				((Renderer)val2).receiveShadows = false;
				((Renderer)val2).lightProbeUsage = (LightProbeUsage)1;
				((Renderer)val2).reflectionProbeUsage = (ReflectionProbeUsage)1;
				renderers.Add(val2);
			}
			foreach (Transform item in original)
			{
				CopyMeshes(item, sourceRoot, mapping, renderers);
			}
		}

		private void Hide()
		{
			List<MeshRenderer>[] array = flying;
			for (int i = 0; i < array.Length; i++)
			{
				foreach (MeshRenderer item in array[i])
				{
					if (Object.op_Implicit((Object)(object)item))
					{
						((Renderer)item).enabled = false;
					}
				}
			}
			array = inserted;
			for (int i = 0; i < array.Length; i++)
			{
				foreach (MeshRenderer item2 in array[i])
				{
					if (Object.op_Implicit((Object)(object)item2))
					{
						((Renderer)item2).enabled = false;
					}
				}
			}
		}

		private void Fail(Exception error)
		{
			failed = true;
			timeline.Cancel();
			Hide();
			if (!warned)
			{
				warned = true;
				ManualLogSource log = GambaPlugin.Log;
				if (log != null)
				{
					log.LogWarning((object)("Gamba coin animation unavailable; transaction unchanged: " + error.Message));
				}
			}
		}

		private void OnDisable()
		{
			timeline.Cancel();
			bettor = null;
			bettorView = -1;
			Hide();
		}

		private void OnDestroy()
		{
			timeline.Cancel();
			ReleaseOwned();
		}

		private void ReleaseOwned()
		{
			Hide();
			if (((PlayableGraph)(ref graph)).IsValid())
			{
				((PlayableGraph)(ref graph)).Destroy();
			}
			if (Object.op_Implicit((Object)(object)rig))
			{
				Object.Destroy((Object)(object)((Component)rig).gameObject);
			}
			if (Object.op_Implicit((Object)(object)intro))
			{
				Object.Destroy((Object)(object)intro);
			}
			List<MeshRenderer>[] array = flying;
			for (int i = 0; i < array.Length; i++)
			{
				array[i].Clear();
			}
			array = inserted;
			for (int i = 0; i < array.Length; i++)
			{
				array[i].Clear();
			}
			rig = (follow = (target = null));
			intro = null;
			flight = null;
			initialized = false;
		}

		private static bool Finite(float value)
		{
			if (!float.IsNaN(value))
			{
				return !float.IsInfinity(value);
			}
			return false;
		}

		private static float MaxScale(Vector3 scale)
		{
			//IL_0008: 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_0024: Unknown result type (might be due to invalid IL or missing references)
			return Mathf.Max(new float[3]
			{
				Mathf.Abs(scale.x),
				Mathf.Abs(scale.y),
				Mathf.Abs(scale.z)
			});
		}
	}
	internal sealed class GambaCoinInsertTimeline
	{
		internal const double VisibleSeconds = 1.95;

		private readonly HashSet<string> seen = new HashSet<string>(StringComparer.Ordinal);

		private double newestStart = double.NegativeInfinity;

		private double elapsed = double.NegativeInfinity;

		private bool finished = true;

		internal string Transaction { get; private set; } = "";

		internal int Tier { get; private set; }

		internal double StartedAt { get; private set; } = -1.0;

		internal bool Begin(string transaction, int tier, double start, double now)
		{
			if (transaction == null || transaction.Length != 32 || tier < 0 || tier > 3 || !Finite(start) || !Finite(now) || start < 0.0 || now < 0.0 || start - now > 1.0 || start <= newestStart || seen.Contains(transaction) || seen.Count >= 4096)
			{
				return false;
			}
			seen.Add(transaction);
			double num = (StartedAt = start);
			newestStart = num;
			Transaction = transaction;
			Tier = tier;
			elapsed = double.NegativeInfinity;
			finished = false;
			return true;
		}

		internal double Sample(double now, bool reducedMotion, bool available, double duration = 1.95)
		{
			if (finished)
			{
				return -1.0;
			}
			if (!available || reducedMotion || !Finite(now) || !Finite(duration) || duration <= 0.0)
			{
				Cancel();
				return -1.0;
			}
			elapsed = Math.Max(elapsed, now - StartedAt);
			if (elapsed >= duration)
			{
				Cancel();
				return -1.0;
			}
			if (!(elapsed < 0.0))
			{
				return elapsed;
			}
			return -1.0;
		}

		internal void Cancel()
		{
			finished = true;
		}

		private static bool Finite(double value)
		{
			if (!double.IsNaN(value))
			{
				return !double.IsInfinity(value);
			}
			return false;
		}
	}
	public static class GambaCoinMotionMath
	{
		public const float NativeDockSample = 1.75f;

		public static float ClipSample(double age)
		{
			return (float)(Clamp(age / 1.0) * 1.75);
		}

		public static float LandingBlend(double age)
		{
			return Smooth((age / 1.0 - 0.55) / 0.37);
		}

		public static float SinkProgress(double age)
		{
			return Smooth((age - 1.3) / 0.6499999999999999);
		}

		private static float Smooth(double t)
		{
			t = Clamp(t);
			return (float)(t * t * (3.0 - 2.0 * t));
		}

		private static double Clamp(double t)
		{
			if (!double.IsNaN(t))
			{
				return Math.Max(0.0, Math.Min(1.0, t));
			}
			return 0.0;
		}
	}
	internal static class GambaGlowMath
	{
		internal static float MarqueeMultiplier(double seconds, bool flicker, bool reducedMotion)
		{
			if (!flicker || reducedMotion || double.IsNaN(seconds) || double.IsInfinity(seconds) || seconds < 0.0)
			{
				return 1f;
			}
			double num = Math.Floor(seconds / 6.3);
			double num2 = Math.Sin(num * 12.9898 + 78.233) * 43758.5453;
			num2 -= Math.Floor(num2);
			double num3 = seconds - num * 6.3;
			double num4 = 1.7 + num2 * 2.8;
			double num5 = 0.33 + num2 * 0.15;
			double num6 = Math.Abs(num3 - num4) / num5;
			double num7 = ((num6 < 1.0) ? (0.5 + 0.5 * Math.Cos(num6 * Math.PI)) : 0.0);
			return (float)(1.0 + 0.025 * Math.Sin(seconds * 1.13) - (0.74 + num2 * 0.08) * num7);
		}
	}
	internal static class GambaHudReveal
	{
		private static readonly GambaHudRevealGate Gate = new GambaHudRevealGate();

		internal static bool Holding => Gate.Active;

		internal static void Begin(string transaction, string machine)
		{
			Gate.Hold(transaction, machine, GambaRuntime.Clock);
		}

		internal static void Reveal(string transaction)
		{
			if (Gate.Release(transaction))
			{
				GambaWallet.RefreshUI();
				if (Object.op_Implicit((Object)(object)CosmeticTokenUI.instance))
				{
					((SemiUI)CosmeticTokenUI.instance).Show();
				}
			}
		}

		internal static void Cancel()
		{
			Reveal(Gate.Transaction);
		}

		internal static void Tick()
		{
			if (Holding)
			{
				GambaRuntime instance = GambaRuntime.Instance;
				GambaMachine gambaMachine = (Object.op_Implicit((Object)(object)instance) ? instance.Machine : null);
				if (Gate.NeedsCleanup(GambaRuntime.Clock, GambaRuntime.Ready, Object.op_Implicit((Object)(object)gambaMachine) ? gambaMachine.MachineId : ""))
				{
					Cancel();
				}
			}
		}
	}
	[HarmonyPatch(typeof(CosmeticTokenUI), "Setup")]
	internal static class GambaTokenHudRevealPatch
	{
		private static bool Prefix()
		{
			return !GambaHudReveal.Holding;
		}
	}
	internal sealed class GambaHudRevealGate
	{
		private double deadline;

		internal string Transaction { get; private set; } = "";

		internal string Machine { get; private set; } = "";

		internal bool Active => Transaction.Length > 0;

		internal void Hold(string transaction, string machine, double now)
		{
			if (!Active && !string.IsNullOrEmpty(transaction) && !string.IsNullOrEmpty(machine) && !double.IsNaN(now) && !double.IsInfinity(now))
			{
				Transaction = transaction;
				Machine = machine;
				deadline = now + 30.0;
			}
		}

		internal bool Release(string transaction)
		{
			if (!Active || Transaction != transaction)
			{
				return false;
			}
			string transaction2 = (Machine = "");
			Transaction = transaction2;
			return true;
		}

		internal bool NeedsCleanup(double now, bool ready, string machine)
		{
			if (Active)
			{
				if (ready && !(machine != Machine) && !double.IsNaN(now) && !double.IsInfinity(now))
				{
					return now >= deadline;
				}
				return true;
			}
			return false;
		}
	}
	public sealed class GambaMachine : MonoBehaviour
	{
		private static readonly FieldRef<PlayerAvatar, bool> Disabled = AccessTools.FieldRefAccess<PlayerAvatar, bool>("isDisabled");

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

		private static AssetBundle? bundle;

		private static GameObject? prefab;

		private static Shader? emissiveUIShader;

		private static AnimationClip? handleClip;

		public string MachineId { get; private set; } = "";

		public GambaScreen Screen { get; private set; }

		public GambaPresentation? Presentation { get; private set; }

		public GambaCoinInsert? CoinInsert { get; private set; }

		public Transform ScreenAnchor { get; private set; }

		public int Outcome { get; private set; }

		public int InputTier { get; private set; }

		public int OutputTier { get; private set; }

		public double StartedAt { get; private set; } = -1.0;

		public string TransactionId { get; private set; } = "";

		public int BettorViewId { get; private set; } = -1;

		public bool Busy
		{
			get
			{
				if (StartedAt >= 0.0)
				{
					return GambaRuntime.Clock - StartedAt < 7.299999999999999;
				}
				return false;
			}
		}

		public Vector3 InteractionPoint => ScreenAnchor.position;

		public static GambaMachine Create(string id, Vector3 position, Quaternion rotation)
		{
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)prefab) || !Object.op_Implicit((Object)(object)emissiveUIShader) || !Object.op_Implicit((Object)(object)handleClip))
			{
				string text = Path.Combine(GambaPlugin.DirectoryPath, "gambaassets");
				if (!Object.op_Implicit((Object)(object)bundle))
				{
					bundle = AssetBundle.LoadFromFile(text);
				}
				if (!Object.op_Implicit((Object)(object)bundle))
				{
					throw new FileNotFoundException("Gamba asset bundle could not be loaded", text);
				}
				string[] allAssetNames = bundle.GetAllAssetNames();
				foreach (string text2 in allAssetNames)
				{
					if (text2.EndsWith(".prefab", StringComparison.OrdinalIgnoreCase))
					{
						prefab = bundle.LoadAsset<GameObject>(text2);
						break;
					}
				}
				if (!Object.op_Implicit((Object)(object)prefab))
				{
					throw new InvalidDataException("Gamba asset bundle contains no cabinet prefab.");
				}
				emissiveUIShader = bundle.LoadAsset<Shader>("assets/gamba/generated/gambaemissiveui.shader");
				if (!Object.op_Implicit((Object)(object)emissiveUIShader) || !emissiveUIShader.isSupported)
				{
					throw new InvalidDataException("Gamba needs its matching asset bundle with the emissive screen shader.");
				}
				handleClip = bundle.LoadAsset<AnimationClip>("assets/gamba/generated/gambahandlepull.anim");
				if (!Object.op_Implicit((Object)(object)handleClip))
				{
					throw new InvalidDataException("Gamba 0.4.0 needs its matching animated cabinet bundle.");
				}
			}
			GameObject val = Object.Instantiate<GameObject>(prefab, position, rotation);
			((Object)val).name = "Gamba - Skin Coins";
			val.SetActive(true);
			GambaMachine gambaMachine = val.AddComponent<GambaMachine>();
			gambaMachine.MachineId = id;
			gambaMachine.ScreenAnchor = val.transform.Find("ScreenAnchor");
			if (!Object.op_Implicit((Object)(object)gambaMachine.ScreenAnchor))
			{
				Object.Destroy((Object)(object)val);
				throw new InvalidDataException("Gamba cabinet is missing ScreenAnchor.");
			}
			Vector3 localScale = gambaMachine.ScreenAnchor.localScale;
			gambaMachine.ScreenAnchor.localScale = Vector3.one;
			try
			{
				gambaMachine.Screen = val.AddComponent<GambaScreen>();
				gambaMachine.Screen.Initialize(gambaMachine.ScreenAnchor, localScale.x, localScale.y, emissiveUIShader);
				gambaMachine.Screen.SetEmission(GambaPlugin.ScreenEmission.Value);
				val.AddComponent<GambaMarquee>().Initialize();
				try
				{
					val.AddComponent<GambaCabinetMotion>().Initialize(gambaMachine, handleClip);
				}
				catch (Exception ex)
				{
					GambaCabinetMotion component = val.GetComponent<GambaCabinetMotion>();
					if (Object.op_Implicit((Object)(object)component))
					{
						((Behaviour)component).enabled = false;
						Object.Destroy((Object)(object)component);
					}
					GambaPlugin.Log.LogWarning((object)("Gamba handle/tray presentation unavailable; gameplay remains available: " + ex.Message));
				}
				Transform val2 = val.transform.Find("CoinSlotAnchor");
				if (Object.op_Implicit((Object)(object)val2))
				{
					gambaMachine.CoinInsert = val.AddComponent<GambaCoinInsert>();
					if (!gambaMachine.CoinInsert.Initialize(gambaMachine, val2, 0.3f))
					{
						Object.Destroy((Object)(object)gambaMachine.CoinInsert);
						gambaMachine.CoinInsert = null;
					}
				}
				else
				{
					GambaPlugin.Log.LogWarning((object)"Gamba coin slot anchor is missing; use the matching asset bundle. Gameplay remains available.");
				}
				gambaMachine.Screen.Present(0, 0, 0, topTierDouble: false, -1.0);
				try
				{
					gambaMachine.Presentation = val.AddComponent<GambaPresentation>();
					gambaMachine.Presentation.Initialize(gambaMachine);
				}
				catch (Exception ex2)
				{
					if (Object.op_Implicit((Object)(object)gambaMachine.Presentation))
					{
						((Behaviour)gambaMachine.Presentation).enabled = false;
						Object.Destroy((Object)(object)gambaMachine.Presentation);
					}
					gambaMachine.Presentation = null;
					GambaPlugin.Log.LogWarning((object)("Gamba sound/glow could not initialize; gameplay remains available: " + ex2.Message));
				}
				return gambaMachine;
			}
			catch
			{
				Object.Destroy((Object)(object)val);
				throw;
			}
		}

		public void Begin(string transaction, int tier, int outcome, double start, int bettorViewId = -1)
		{
			if (!(TransactionId == transaction) && tier >= 0 && tier <= 3 && outcome >= 0 && outcome <= 2 && !double.IsNaN(start) && !double.IsInfinity(start))
			{
				Screen.Present(0, tier, tier, topTierDouble: false, -1.0);
				TransactionId = transaction;
				InputTier = tier;
				Outcome = outcome;
				BettorViewId = bettorViewId;
				OutputTier = ((outcome == 2) ? Math.Min(tier + 1, 3) : tier);
				StartedAt = start;
				if (Object.op_Implicit((Object)(object)CoinInsert))
				{
					CoinInsert.BeginConfirmed(transaction, tier, start, BettorViewId);
				}
			}
		}

		private void Update()
		{
			if (!Object.op_Implicit((Object)(object)Screen))
			{
				return;
			}
			Screen.SetEmission(GambaPlugin.ScreenEmission.Value);
			int num = Math.Max(0, GambaWallet.PeekTier);
			double num2 = ((StartedAt < 0.0) ? (-1.0) : (GambaRuntime.Clock - StartedAt));
			if (StartedAt >= 0.0 && num2 < 2.9)
			{
				Screen.Present(0, InputTier, InputTier, topTierDouble: false, -1.0, GambaPlugin.ReducedMotion.Value);
				Screen.SetCaption((num2 < 0.0) ? "READY..." : GambaSequence.Preparation(num2), "1 COIN ACCEPTED - PLEASE WAIT");
				return;
			}
			Screen.Present(Outcome, (StartedAt < 0.0) ? num : InputTier, (StartedAt < 0.0) ? Math.Min(num + 1, 3) : OutputTier, Outcome == 2 && InputTier == 3, (StartedAt < 0.0) ? (-1.0) : (num2 - 2.9), GambaPlugin.ReducedMotion.Value);
			if (num2 >= 5.699999999999999 && Object.op_Implicit((Object)(object)GambaRuntime.Instance))
			{
				string text = GambaRuntime.Instance.LocalReceiptDetail(TransactionId);
				if (text.Length > 0)
				{
					Screen.SetCaption(Screen.CurrentFrame.Status, text);
				}
				GambaHudReveal.Reveal(TransactionId);
			}
		}

		public bool CanReach(PlayerAvatar player, float distance = 3.5f)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: 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_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)player) || !((Component)player).gameObject.activeInHierarchy || Disabled.Invoke(player) || Dead.Invoke(player))
			{
				return false;
			}
			Vector3 val = ((Component)player).transform.position + Vector3.up * 1.2f;
			Vector3 val2 = InteractionPoint - val;
			if (((Vector3)(ref val2)).magnitude > distance || Vector3.Dot(((Component)this).transform.forward, val - ((Component)this).transform.position) < 0.1f)
			{
				return false;
			}
			RaycastHit[] array = Physics.RaycastAll(val, ((Vector3)(ref val2)).normalized, ((Vector3)(ref val2)).magnitude, -1, (QueryTriggerInteraction)1);
			for (int i = 0; i < array.Length; i++)
			{
				RaycastHit val3 = array[i];
				if (Object.op_Implicit((Object)(object)((RaycastHit)(ref val3)).collider) && !((RaycastHit)(ref val3)).transform.IsChildOf(((Component)this).transform) && !Object.op_Implicit((Object)(object)((Component)((RaycastHit)(ref val3)).collider).GetComponentInParent<PlayerAvatar>()) && !Object.op_Implicit((Object)(object)((Component)((RaycastHit)(ref val3)).collider).GetComponentInParent<PlayerController>()) && !Object.op_Implicit((Object)(object)((Component)((RaycastHit)(ref val3)).collider).GetComponentInParent<PlayerTumble>()))
				{
					return false;
				}
			}
			return true;
		}

		public bool IsLookedAt()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: 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_0048: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)Camera.main))
			{
				return false;
			}
			Vector3 val = InteractionPoint - ((Component)Camera.main).transform.position;
			if (((Vector3)(ref val)).sqrMagnitude < 14f)
			{
				return Vector3.Dot(((Component)Camera.main).transform.forward, ((Vector3)(ref val)).normalized) > 0.94f;
			}
			return false;
		}
	}
	public sealed class GambaMarquee : MonoBehaviour
	{
		private readonly Dictionary<Renderer, Material[]> originals = new Dictionary<Renderer, Material[]>();

		private readonly List<Material> owned = new List<Material>();

		private Light spill;

		public float CurrentMultiplier { get; private set; } = 1f;

		public void Initialize()
		{
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Expected O, but got Unknown
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: 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_007b: Expected O, but got Unknown
			MeshRenderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<MeshRenderer>(true);
			foreach (MeshRenderer val in componentsInChildren)
			{
				Material[] sharedMaterials = ((Renderer)val).sharedMaterials;
				Material[] array = (Material[])sharedMaterials.Clone();
				bool flag = false;
				for (int j = 0; j < sharedMaterials.Length; j++)
				{
					if (Object.op_Implicit((Object)(object)sharedMaterials[j]) && sharedMaterials[j].HasProperty("_EmissionMap") && Object.op_Implicit((Object)(object)sharedMaterials[j].GetTexture("_EmissionMap")))
					{
						Material val2 = new Material(sharedMaterials[j])
						{
							name = "Gamba marquee emission (owned)"
						};
						val2.EnableKeyword("_EMISSION");
						array[j] = val2;
						owned.Add(val2);
						flag = true;
					}
				}
				if (flag)
				{
					originals.Add((Renderer)(object)val, sharedMaterials);
					((Renderer)val).sharedMaterials = array;
				}
			}
			GameObject val3 = new GameObject("Gamba marquee warm spill (owned)");
			val3.transform.SetParent(((Component)this).transform, false);
			val3.transform.localPosition = new Vector3(0f, 2.06f, 0.8f);
			spill = val3.AddComponent<Light>();
			spill.type = (LightType)2;
			spill.range = 2.6f;
			spill.renderMode = (LightRenderMode)1;
			spill.shadows = (LightShadows)0;
			spill.color = new Color(1f, 0.72f, 0.06f);
			Tick();
		}

		private void Update()
		{
			Tick();
		}

		private void Tick()
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			CurrentMultiplier = GambaGlowMath.MarqueeMultiplier(Time.realtimeSinceStartupAsDouble, GambaPlugin.MarqueeFlicker.Value, GambaPlugin.ReducedMotion.Value);
			float num = GambaPlugin.MarqueeEmission.Value * CurrentMultiplier;
			foreach (Material item in owned)
			{
				if (Object.op_Implicit((Object)(object)item))
				{
					item.SetColor("_EmissionColor", new Color(num, num * 0.72f, num * 0.06f, 1f));
				}
			}
			if (Object.op_Implicit((Object)(object)spill))
			{
				((Behaviour)spill).enabled = GambaPlugin.ScreenGlow.Value && num > 0f;
				spill.intensity = 0.85f * Mathf.Clamp(GambaPlugin.MarqueeEmission.Value / 3.5f, 0f, 2f) * CurrentMultiplier;
			}
		}

		private void OnDestroy()
		{
			foreach (KeyValuePair<Renderer, Material[]> original in originals)
			{
				if (Object.op_Implicit((Object)(object)original.Key))
				{
					original.Key.sharedMaterials = original.Value;
				}
			}
			foreach (Material item in owned)
			{
				if (Object.op_Implicit((Object)(object)item))
				{
					Object.Destroy((Object)(object)item);
				}
			}
			originals.Clear();
			owned.Clear();
			if (Object.op_Implicit((Object)(object)spill))
			{
				Object.Destroy((Object)(object)((Component)spill).gameObject);
			}
		}
	}
	public static class GambaPlacement
	{
		private static string accessFailure = "";

		public static string LastShopSearch { get; private set; } = "Not searched";

		public static bool TryFindShop(Transform stock, out Vector3 position, out Quaternion rotation)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: 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_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: 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_011f: 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_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: 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_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: 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_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_029a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f0: 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_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: 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_0242: 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)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_0694: Unknown result type (might be due to invalid IL or missing references)
			//IL_0314: Unknown result type (might be due to invalid IL or missing references)
			//IL_0319: Unknown result type (might be due to invalid IL or missing references)
			//IL_031e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0323: Unknown result type (might be due to invalid IL or missing references)
			//IL_0325: Unknown result type (might be due to invalid IL or missing references)
			//IL_0327: Unknown result type (might be due to invalid IL or missing references)
			//IL_0331: Unknown result type (might be due to invalid IL or missing references)
			//IL_0336: Unknown result type (might be due to invalid IL or missing references)
			//IL_033b: 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_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0375: Unknown result type (might be due to invalid IL or missing references)
			//IL_0396: Unknown result type (might be due to invalid IL or missing references)
			//IL_039b: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_03dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0426: Unknown result type (might be due to invalid IL or missing references)
			//IL_0442: Unknown result type (might be due to invalid IL or missing references)
			//IL_0450: Unknown result type (might be due to invalid IL or missing references)
			//IL_046a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0479: Unknown result type (might be due to invalid IL or missing references)
			//IL_047e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0485: Unknown result type (might be due to invalid IL or missing references)
			//IL_0490: Unknown result type (might be due to invalid IL or missing references)
			//IL_0495: Unknown result type (might be due to invalid IL or missing references)
			//IL_049a: Unknown result type (might be due to invalid IL or missing references)
			//IL_049f: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_050c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0517: Unknown result type (might be due to invalid IL or missing references)
			//IL_0521: Unknown result type (might be due to invalid IL or missing references)
			//IL_053c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0541: Unknown result type (might be due to invalid IL or missing references)
			//IL_0548: Unknown result type (might be due to invalid IL or missing references)
			//IL_054d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0566: Unknown result type (might be due to invalid IL or missing references)
			//IL_056d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0585: Unknown result type (might be due to invalid IL or missing references)
			//IL_058a: Unknown result type (might be due to invalid IL or missing references)
			//IL_05bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_05eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ed: Unknown result type (might be due to invalid IL or missing references)
			position = default(Vector3);
			rotation = Quaternion.identity;
			accessFailure = "";
			PlayerAvatar val = SemiFunc.PlayerGetLocal();
			Vector3 val2 = (Object.op_Implicit((Object)(object)val) ? ((Component)val).transform.position : stock.position);
			NavMeshHit val3 = default(NavMeshHit);
			if (!NavMesh.SamplePosition(val2, ref val3, 3f, -1))
			{
				LastShopSearch = $"No walkable entry near player={val2}; stock={stock.position}";
				return false;
			}
			ShopKeycardDoor[] array = Object.FindObjectsOfType<ShopKeycardDoor>();
			Vector3[] slots = GambaShopLayout.Slots;
			Vector3[] array2 = GambaShopLayout.Secrets.Concat(array.Select((ShopKeycardDoor d) => ((Component)d).transform.position)).ToArray();
			List<Vector3> seeds = new List<Vector3>();
			HashSet<Vector2Int> cells = new HashSet<Vector2Int>();
			Seed(((NavMeshHit)(ref val3)).position);
			Vector3[] array3 = array2;
			NavMeshHit val5 = default(NavMeshHit);
			foreach (Vector3 val4 in array3)
			{
				if (NavMesh.SamplePosition(new Vector3(val4.x, stock.position.y, val4.z), ref val5, 2f, -1))
				{
					Seed(((NavMeshHit)(ref val5)).position);
				}
			}
			NavMeshTriangulation val6 = NavMesh.CalculateTriangulation();
			for (int num2 = 0; num2 + 2 < val6.indices.Length; num2 += 3)
			{
				Seed((val6.vertices[val6.indices[num2]] + val6.vertices[val6.indices[num2 + 1]] + val6.vertices[val6.indices[num2 + 2]]) / 3f);
			}
			array3 = val6.vertices;
			for (int num = 0; num < array3.Length; num++)
			{
				Seed(array3[num]);
			}
			for (int num3 = 0; num3 + 2 < val6.indices.Length; num3 += 3)
			{
				if (seeds.Count >= 320)
				{
					break;
				}
				for (int num4 = 0; num4 < 3; num4++)
				{
					Vector3 val7 = val6.vertices[val6.indices[num3 + num4]];
					Vector3 val8 = val6.vertices[val6.indices[num3 + (num4 + 1) % 3]];
					int num5 = Mathf.CeilToInt(Vector3.Distance(val7, val8) / 2f);
					for (int num6 = 1; num6 < num5; num6++)
					{
						Seed(Vector3.Lerp(val7, val8, (float)num6 / (float)num5));
					}
				}
			}
			HashSet<Vector3Int> hashSet = new HashSet<Vector3Int>();
			int num7 = 0;
			int num8 = 0;
			int num9 = 0;
			int num10 = 0;
			int num11 = 0;
			float num12 = float.NegativeInfinity;
			RaycastHit val10 = default(RaycastHit);
			Vector3Int item = default(Vector3Int);
			NavMeshHit val13 = default(NavMeshHit);
			foreach (Vector3 item3 in seeds)
			{
				for (int num13 = 0; num13 < 16; num13++)
				{
					Vector3 val9 = Quaternion.Euler(0f, (float)num13 * 22.5f, 0f) * Vector3.forward;
					if (!Physics.Raycast(item3 + Vector3.up * 1.1f, val9, ref val10, 8f, LayerMask.GetMask(new string[1] { "Default" }), (QueryTriggerInteraction)1) || !StaticWall(((RaycastHit)(ref val10)).collider) || Mathf.Abs(((RaycastHit)(ref val10)).normal.y) > 0.05f)
					{
						continue;
					}
					num7++;
					Vector3 normal = ((RaycastHit)(ref val10)).normal;
					normal.y = 0f;
					((Vector3)(ref normal)).Normalize();
					Vector3 candidate = ((RaycastHit)(ref val10)).point + normal * 0.9f;
					candidate.y = stock.position.y;
					Quaternion val11 = Quaternion.LookRotation(normal);
					((Vector3Int)(ref item))..ctor(Mathf.RoundToInt(candidate.x * 2f), Mathf.RoundToInt(candidate.z * 2f), Mathf.RoundToInt(((Quaternion)(ref val11)).eulerAngles.y / 10f));
					if (!hashSet.Add(item) || !InShopRoom(candidate))
					{
						continue;
					}
					Vector3 val12 = Quaternion.Inverse(Quaternion.Euler(0f, stock.eulerAngles.y, 0f)) * (candidate - stock.position);
					if (!GambaPlacementPolicy.OutsideSkinMachineApproach(val12.x, val12.z) || array.Any((ShopKeycardDoor d) => Flat(candidate, ((Component)d).transform.position) < 3f) || slots.Any((Vector3 v) => Mathf.Abs(candidate.y - v.y) < 2.5f && Flat(candidate, v) < 1.5f))
					{
						continue;
					}
					num8++;
					if (!BackedByWall(candidate, val11))
					{
						continue;
					}
					num9++;
					if (!TryCandidate(candidate, stock.position.y, val11, out var placed))
					{
						continue;
					}
					num10++;
					if (!NavMesh.SamplePosition(placed + normal * 1.3f, ref val13, 0.65f, -1) || !ClearAccess(((NavMeshHit)(ref val3)).position, ((NavMeshHit)(ref val13)).position, array, out var length))
					{
						continue;
					}
					num11++;
					if (ClearAisle(placed, val11))
					{
						float num14 = GambaPlacementPolicy.Score((array2.Length == 0) ? float.PositiveInfinity : array2.Min((Vector3 s) => Flat(s, placed)), length, Flat(stock.position, placed));
						if (!(num14 <= num12))
						{
							num12 = num14;
							position = placed;
							rotation = val11;
						}
					}
				}
			}
			LastShopSearch = $"seeds={seeds.Count} secrets={array2.Length} slots={slots.Length} walls={num7} reserved-clear={num8} backed={num9} floor/footprint={num10} accessible={num11} best={num12} position={position} access={accessFailure}";
			return !float.IsNegativeInfinity(num12);
			void Seed(Vector3 point)
			{
				//IL_0012: 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_0035: 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_0050: Unknown result type (might be due to invalid IL or missing references)
				//IL_0061: Unknown result type (might be due to invalid IL or missing references)
				//IL_007d: Unknown result type (might be due to invalid IL or missing references)
				//IL_008b: Unknown result type (might be due to invalid IL or missing references)
				if (seeds.Count < 320 && !(Mathf.Abs(point.y - stock.position.y) > 0.4f) && !(Flat(point, stock.position) > 55f))
				{
					Vector2Int item2 = default(Vector2Int);
					((Vector2Int)(ref item2))..ctor(Mathf.RoundToInt(point.x / 1.5f), Mathf.RoundToInt(point.z / 1.5f));
					if (cells.Add(item2))
					{
						seeds.Add(point);
					}
				}
			}
		}

		private static bool StaticWall(Collider c)
		{
			if (Object.op_Implicit((Object)(object)c) && !c.isTrigger && !Object.op_Implicit((Object)(object)c.attachedRigidbody) && !Object.op_Implicit((Object)(object)((Component)c).GetComponentInParent<GambaMachine>()) && !Object.op_Implicit((Object)(object)((Component)c).GetComponentInParent<CosmeticShopMachine>()) && !Object.op_Implicit((Object)(object)((Component)c).GetComponentInParent<PhysGrabHinge>()))
			{
				return !Object.op_Implicit((Object)(object)((Component)c).GetComponentInParent<ShopKeycardDoor>());
			}
			return false;
		}

		public static bool InShopRoom(Vector3 position)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			RoomVolume[] array = (from c in Physics.OverlapSphere(position + Vector3.up, 0.1f, LayerMask.GetMask(new string[1] { "RoomVolume" }), (QueryTriggerInteraction)2)
				select ((Component)c).GetComponentInParent<RoomVolume>() into r
				where Object.op_Implicit((Object)(object)r)
				select r).ToArray();
			if (array.Length != 0)
			{
				return array.All((RoomVolume r) => !r.Truck && !r.Extraction);
			}
			return false;
		}

		public static bool BackedByWall(Vector3 position, Quaternion rotation)
		{
			//IL_0042: 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_004c: 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_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			float[] array = new float[3] { -0.65f, 0f, 0.65f };
			RaycastHit val = default(RaycastHit);
			foreach (float num in array)
			{
				float[] array2 = new float[3] { 0.45f, 1.2f, 2.05f };
				foreach (float num2 in array2)
				{
					if (!Physics.Raycast(position + rotation * new Vector3(num, num2, -0.81f), -(rotation * Vector3.forward), ref val, 0.3f, LayerMask.GetMask(new string[1] { "Default" }), (QueryTriggerInteraction)1) || !StaticWall(((RaycastHit)(ref val)).collider) || Vector3.Dot(((RaycastHit)(ref val)).normal, rotation * Vector3.forward) < 0.97f)
					{
						return false;
					}
				}
			}
			return true;
		}

		public static bool ClearAisle(Vector3 position, Quaternion rotation)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			return !Physics.OverlapBox(position + rotation * new Vector3(0f, 1f, 1.55f), new Vector3(0.7f, 0.85f, 0.65f), rotation, -1, (QueryTriggerInteraction)1).Any((Collider c) => Object.op_Implicit((Object)(object)c) && !Object.op_Implicit((Object)(object)((Component)c).GetComponentInParent<GambaMachine>()));
		}

		private static bool ClearAccess(Vector3 from, Vector3 to, ShopKeycardDoor[] doors, out float length)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			//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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: 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_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: 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_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			length = 0f;
			NavMeshPath val = new NavMeshPath();
			if (!NavMesh.CalculatePath(from, to, -1, val) || (int)val.status != 0)
			{
				accessFailure = $"{val.status} from={from} to={to}";
				return false;
			}
			for (int i = 1; i < val.corners.Length; i++)
			{
				Vector3 val2 = val.corners[i] - val.corners[i - 1];
				length += ((Vector3)(ref val2)).magnitude;
				RaycastHit[] array = Physics.SphereCastAll(val.corners[i - 1] + Vector3.up, 0.22f, ((Vector3)(ref val2)).normalized, ((Vector3)(ref val2)).magnitude, LayerMask.GetMask(new string[3] { "Default", "PhysGrabObjectHinge", "StaticGrabObject" }), (QueryTriggerInteraction)1);
				for (int j = 0; j < array.Length; j++)
				{
					RaycastHit hit = array[j];
					if (Object.op_Implicit((Object)(object)((RaycastHit)(ref hit)).collider) && doors.Any((ShopKeycardDoor d) => Object.op_Implicit((Object)(object)d.levelColliderObject) && d.levelColliderObject.activeInHierarchy && (((RaycastHit)(ref hit)).transform.IsChildOf(d.levelColliderObject.transform) || (Object)(object)((Component)((RaycastHit)(ref hit)).collider).GetComponentInParent<ShopKeycardDoor>() == (Object)(object)d)))
					{
						accessFailure = $"Blocked by {((Object)((RaycastHit)(ref hit)).collider).name} at {((RaycastHit)(ref hit)).point}; from={from}";
						return false;
					}
				}
			}
			return true;
		}

		private static float Flat(Vector3 a, Vector3 b)
		{
			//IL_0016: 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)
			a.y = (b.y = 0f);
			return Vector3.Distance(a, b);
		}

		public static bool TryFind(Vector3 near, Vector3 toward, out Vector3 position, out Quaternion rotation)
		{
			//IL_0001: 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_002f: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: 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_009f: Unknown result type (might be due to invalid IL or missing references)
			position = default(Vector3);
			rotation = Quaternion.identity;
			for (int i = 0; i < 5; i++)
			{
				for (int j = 0; j < 16; j++)
				{
					float num = (float)j * MathF.PI / 8f;
					Vector3 val = near + new Vector3(Mathf.Cos(num), 0f, Mathf.Sin(num)) * (2.5f + (float)i * 0.8f);
					Vector3 val2 = toward - val;
					val2.y = 0f;
					if (!(((Vector3)(ref val2)).sqrMagnitude < 0.01f))
					{
						Quaternion val3 = Quaternion.LookRotation(val2);
						if (TryCandidate(val, near.y, val3, out position))
						{
							rotation = val3;
							return true;
						}
					}
				}
			}
			return false;
		}

		private static bool TryCandidate(Vector3 candidate, float floorHeight, Quaternion facing, out Vector3 position)
		{
			//IL_0001: 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_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: 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_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: 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_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing