Decompiled source of GoodCards v0.1.1

BepInEx/plugins/GoodCards/SlipSkid.GoodCards.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.Mono;
using Game;
using Game.Levels;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Obstacles;
using Obstacles.ObstacleAffixes;
using Player;
using UI;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.Localization;
using UnityEngine.Rendering;
using Utils;
using World;

[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("SlipSkid.GoodCards")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+2e39774f5d9e5435398d48a2670bdf4bb1e3e992")]
[assembly: AssemblyProduct("SlipSkid.GoodCards")]
[assembly: AssemblyTitle("SlipSkid.GoodCards")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace SlipSkid.CustomContent
{
	internal static class ThumbnailLoader
	{
		private static readonly string PluginFolder = Path.GetDirectoryName(typeof(Plugin).Assembly.Location);

		internal static Texture2D Load(string fileName)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Expected O, but got Unknown
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Expected O, but got Unknown
			string path = Path.Combine(PluginFolder, fileName);
			bool flag = default(bool);
			if (!File.Exists(path))
			{
				ManualLogSource log = Plugin.Log;
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(67, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Thumbnail: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(fileName);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" not found next to the plugin, keeping the carrier's art");
				}
				log.LogWarning(val);
				return null;
			}
			Texture2D val2 = new Texture2D(2, 2, (TextureFormat)4, false);
			if (!ImageConversion.LoadImage(val2, File.ReadAllBytes(path)))
			{
				ManualLogSource log2 = Plugin.Log;
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(60, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Thumbnail: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(fileName);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" isn't a valid PNG/JPG, keeping the carrier's art");
				}
				log2.LogWarning(val);
				Object.Destroy((Object)(object)val2);
				return null;
			}
			((Object)val2).name = Path.GetFileNameWithoutExtension(fileName);
			((Object)val2).hideFlags = (HideFlags)32;
			ManualLogSource log3 = Plugin.Log;
			BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(22, 3, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Thumbnail: loaded ");
				((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(fileName);
				((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" (");
				((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(((Texture)val2).width);
				((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("x");
				((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(((Texture)val2).height);
				((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(")");
			}
			log3.LogInfo(val3);
			return val2;
		}
	}
	internal sealed class BurstEffect : MonoBehaviour
	{
		public enum Kind
		{
			Shock,
			Teleport
		}

		public int channel;

		public Kind kind;

		public bool consume;

		private Obstacle _obstacle;

		private bool _used;

		private void Start()
		{
			_obstacle = ((Component)this).GetComponentInParent<Obstacle>();
		}

		internal void Play(Vector3 target)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			if (_used)
			{
				return;
			}
			Vector3 position = ((Component)this).transform.position;
			if (kind == Kind.Shock)
			{
				EffectBurst.Shock(position);
			}
			else
			{
				EffectBurst.Implode(position);
				if (((Vector3)(ref target)).sqrMagnitude > 0.01f)
				{
					EffectBurst.Appear(target);
				}
			}
			if (consume)
			{
				UseUp();
			}
		}

		private void UseUp()
		{
			_used = true;
			if (Object.op_Implicit((Object)(object)_obstacle))
			{
				Renderer[] componentsInChildren = ((Component)_obstacle).GetComponentsInChildren<Renderer>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					componentsInChildren[i].enabled = false;
				}
				Collider[] componentsInChildren2 = ((Component)_obstacle).GetComponentsInChildren<Collider>(true);
				for (int i = 0; i < componentsInChildren2.Length; i++)
				{
					componentsInChildren2[i].enabled = false;
				}
				if (Object.op_Implicit((Object)(object)NetworkManager.Singleton) && NetworkManager.Singleton.IsServer)
				{
					((MonoBehaviour)_obstacle).StartCoroutine(DespawnSoon(_obstacle));
				}
			}
		}

		private static IEnumerator DespawnSoon(Obstacle obstacle)
		{
			yield return (object)new WaitForSeconds(0.2f);
			ObstacleManager.Delete(obstacle);
		}
	}
	internal sealed class EffectBurst : MonoBehaviour
	{
		private sealed class Part
		{
			public Transform transform;

			public Func<float, Vector3> scale;

			public float spin;
		}

		private readonly List<Part> _parts = new List<Part>();

		private readonly List<Transform> _bolts = new List<Transform>();

		private float _born;

		private float _life;

		private float _nextFlicker;

		private Random _rnd;

		internal static void Shock(Vector3 position)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			EffectBurst effectBurst = Create("CustomContent_ShockFx", position, 0.55f);
			Material val = MaterialLibrary.Resolve("glow:#4FD3FF", null);
			Material val2 = MaterialLibrary.Resolve("glow:#E8FBFF", null);
			effectBurst.Add((PrimitiveType)0, val2, Vector3.up * 0.6f, (float t) => Vector3.one * ((t < 0.3f) ? Mathf.Lerp(0.4f, 5f, t / 0.3f) : Mathf.Lerp(5f, 0f, (t - 0.3f) / 0.7f)));
			effectBurst.Add((PrimitiveType)2, val, Vector3.up * 0.15f, (float t) => new Vector3(Mathf.Lerp(1f, 12f, t), Mathf.Lerp(0.15f, 0.01f, t), Mathf.Lerp(1f, 12f, t)));
			effectBurst.Add((PrimitiveType)2, val, Vector3.up * 3f, (float t) => new Vector3(Mathf.Lerp(1.2f, 0f, t), Mathf.Lerp(3f, 6f, t), Mathf.Lerp(1.2f, 0f, t)));
			for (int num = 0; num < 8; num++)
			{
				effectBurst._bolts.Add(effectBurst.Add((PrimitiveType)3, (num % 2 == 0) ? val : val2, Vector3.up * 0.8f, (float t) => new Vector3(0.12f, 0.12f, 3.5f * (1f - t))).transform);
			}
		}

		internal static void Implode(Vector3 position)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: 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_0090: Unknown result type (might be due to invalid IL or missing references)
			EffectBurst effectBurst = Create("CustomContent_TeleportFx", position, 0.6f);
			Material material = MaterialLibrary.Resolve("glow:#A64DFF", null);
			Material material2 = MaterialLibrary.Resolve("glow:#F0B8FF", null);
			effectBurst.Add((PrimitiveType)0, material2, Vector3.up * 0.8f, (float t) => Vector3.one * Mathf.Lerp(3.2f, 0f, t * t));
			for (int num = 0; num < 3; num++)
			{
				float delay = (float)num * 0.12f;
				effectBurst.Add((PrimitiveType)2, material, Vector3.up * (0.4f + (float)num * 0.6f), delegate(float t)
				{
					//IL_0040: Unknown result type (might be due to invalid IL or missing references)
					float num2 = Mathf.Clamp01((t - delay) / (1f - delay));
					return new Vector3(Mathf.Lerp(5f, 0f, num2), 0.04f, Mathf.Lerp(5f, 0f, num2));
				}).spin = 540f * ((num % 2 == 0) ? 1f : (-1f));
			}
		}

		internal static void Appear(Vector3 position)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: 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_006b: Unknown result type (might be due to invalid IL or missing references)
			EffectBurst effectBurst = Create("CustomContent_AppearFx", position, 0.7f);
			Material material = MaterialLibrary.Resolve("glow:#A64DFF", null);
			Material material2 = MaterialLibrary.Resolve("glow:#F0B8FF", null);
			effectBurst.Add((PrimitiveType)2, material, Vector3.up * 4f, (float t) => new Vector3(Mathf.Lerp(2.4f, 0f, t), (t < 0.2f) ? Mathf.Lerp(0f, 4f, t / 0.2f) : 4f, Mathf.Lerp(2.4f, 0f, t)));
			effectBurst.Add((PrimitiveType)0, material2, Vector3.up * 1f, (float t) => Vector3.one * ((t < 0.25f) ? Mathf.Lerp(0f, 3.5f, t / 0.25f) : Mathf.Lerp(3.5f, 0f, (t - 0.25f) / 0.75f)));
		}

		private static EffectBurst Create(string name, Vector3 position, float life)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: 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_003c: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.transform.position = position;
			EffectBurst effectBurst = val.AddComponent<EffectBurst>();
			effectBurst._born = Time.time;
			effectBurst._life = life;
			effectBurst._rnd = new Random(name.GetHashCode() ^ (int)(position.x * 31f + position.z * 17f));
			return effectBurst;
		}

		private Part Add(PrimitiveType type, Material material, Vector3 offset, Func<float, Vector3> scale)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = GameObject.CreatePrimitive(type);
			Object.Destroy((Object)(object)val.GetComponent<Collider>());
			val.transform.SetParent(((Component)this).transform, false);
			val.transform.localPosition = offset;
			if (Object.op_Implicit((Object)(object)material))
			{
				((Renderer)val.GetComponent<MeshRenderer>()).sharedMaterial = material;
			}
			Part part = new Part
			{
				transform = val.transform,
				scale = scale
			};
			_parts.Add(part);
			part.transform.localScale = scale(0f);
			return part;
		}

		private void Update()
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: 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_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_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			float num = (Time.time - _born) / _life;
			if (num >= 1f)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
				return;
			}
			foreach (Part part in _parts)
			{
				part.transform.localScale = part.scale(num);
				if (part.spin != 0f)
				{
					part.transform.Rotate(Vector3.up, part.spin * Time.deltaTime, (Space)1);
				}
			}
			if (_bolts.Count <= 0 || !(Time.time >= _nextFlicker))
			{
				return;
			}
			_nextFlicker = Time.time + 0.045f;
			foreach (Transform bolt in _bolts)
			{
				Vector3 val = new Vector3((float)_rnd.NextDouble() - 0.5f, (float)_rnd.NextDouble() * 0.6f, (float)_rnd.NextDouble() - 0.5f);
				Vector3 normalized = ((Vector3)(ref val)).normalized;
				bolt.localRotation = Quaternion.LookRotation(normalized);
				bolt.localPosition = Vector3.up * 0.8f + normalized * 1.6f * (1f - num);
			}
		}
	}
	internal static class CarLookup
	{
		internal static bool TryGetOwnedCar(Collider other, out PlayerNetworking player, out SphereCarController car)
		{
			player = ((Component)other).GetComponentInParent<PlayerNetworking>();
			car = (Object.op_Implicit((Object)(object)player) ? player.carController : null);
			if (Object.op_Implicit((Object)(object)player) && ((NetworkBehaviour)player).IsOwner && Object.op_Implicit((Object)(object)car))
			{
				return Object.op_Implicit((Object)(object)car.sphereRigidbody);
			}
			return false;
		}

		internal static bool TryGetAnyCar(Collider other, out SphereCarController car)
		{
			PlayerNetworking componentInParent = ((Component)other).GetComponentInParent<PlayerNetworking>();
			car = (Object.op_Implicit((Object)(object)componentInParent) ? componentInParent.carController : null);
			return Object.op_Implicit((Object)(object)car);
		}

		internal static bool IsPlaced(Obstacle obstacle)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Invalid comparison between Unknown and I4
			if (Object.op_Implicit((Object)(object)obstacle))
			{
				return (int)obstacle.state == 3;
			}
			return true;
		}
	}
	internal sealed class Crumble : MonoBehaviour
	{
		private enum State
		{
			Standing,
			Falling,
			Locked
		}

		public int channel;

		public float minSpeed = 8f;

		public float speed = 12f;

		public float stagger;

		public float settleTime = 3f;

		private const float ClientLockTimeout = 4f;

		private Obstacle _obstacle;

		private readonly List<Transform> _pieces = new List<Transform>();

		private readonly List<Vector3> _restPositions = new List<Vector3>();

		private readonly List<Quaternion> _restRotations = new List<Quaternion>();

		private readonly List<Rigidbody> _bodies = new List<Rigidbody>();

		private readonly List<BoxCollider> _debris = new List<BoxCollider>();

		private readonly List<(Collider, Collider)> _ignored = new List<(Collider, Collider)>();

		private Collider[] _solids = (Collider[])(object)new Collider[0];

		private State _state;

		private int _round;

		internal Obstacle Obstacle => _obstacle;

		internal int PieceCount => _pieces.Count;

		private void Start()
		{
			//IL_003e: 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)
			_obstacle = ((Component)this).GetComponentInParent<Obstacle>();
			for (int i = 0; i < ((Component)this).transform.childCount; i++)
			{
				Transform child = ((Component)this).transform.GetChild(i);
				if (Object.op_Implicit((Object)(object)((Component)child).GetComponentInChildren<MeshRenderer>(true)))
				{
					_pieces.Add(child);
					_restPositions.Add(child.localPosition);
					_restRotations.Add(child.localRotation);
				}
			}
			List<Collider> list = new List<Collider>();
			Collider[] componentsInChildren = ((Component)this).GetComponentsInChildren<Collider>(true);
			foreach (Collider val in componentsInChildren)
			{
				if (!val.isTrigger)
				{
					list.Add(val);
					((Component)val).gameObject.AddComponent<CrumbleHit>().owner = this;
				}
			}
			_solids = list.ToArray();
		}

		internal void Knock(Vector3 direction)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			if (_state == State.Standing)
			{
				_state = State.Falling;
				_round = CurrentRound();
				((MonoBehaviour)this).StartCoroutine(Fall((((Vector3)(ref direction)).sqrMagnitude > 0.01f) ? ((Vector3)(ref direction)).normalized : ((Component)this).transform.forward));
			}
		}

		private IEnumerator Fall(Vector3 direction)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			List<Collider> carColliders = new List<Collider>();
			foreach (PlayerData player in GameManager.Players)
			{
				if (Object.op_Implicit((Object)(object)player) && Object.op_Implicit((Object)(object)player.playerNetworking))
				{
					carColliders.AddRange(((Component)player.playerNetworking).GetComponentsInChildren<Collider>(true));
				}
			}
			Vector3 side = Vector3.Cross(Vector3.up, direction);
			for (int i = 0; i < _pieces.Count; i++)
			{
				if (stagger > 0f && i > 0)
				{
					yield return (object)new WaitForSeconds(stagger);
				}
				Transform val = _pieces[i];
				if (!Object.op_Implicit((Object)(object)val))
				{
					continue;
				}
				Random random = new Random(i * 7919 + 17);
				float num = (float)random.NextDouble();
				BoxCollider val2 = ((Component)val).gameObject.AddComponent<BoxCollider>();
				Bounds val3 = LocalBounds(val);
				val2.center = ((Bounds)(ref val3)).center;
				val2.size = ((Bounds)(ref val3)).size;
				_debris.Add(val2);
				foreach (Collider item in carColliders)
				{
					if (Object.op_Implicit((Object)(object)item))
					{
						Physics.IgnoreCollision((Collider)(object)val2, item);
						_ignored.Add(((Collider)(object)val2, item));
					}
				}
				Rigidbody val4 = ((Component)val).gameObject.AddComponent<Rigidbody>();
				val4.velocity = direction * speed * (0.6f + 0.6f * num) + Vector3.up * (2f + 4f * (float)random.NextDouble()) + side * (float)(random.NextDouble() - 0.5) * speed * 0.5f;
				val4.angularVelocity = side * (3f + 4f * num);
				_bodies.Add(val4);
			}
			yield return (object)new WaitForSeconds(settleTime);
			if (IsHost())
			{
				Lock();
				TriggerBus.SendPoses(this, CapturePoses());
				yield break;
			}
			yield return (object)new WaitForSeconds(4f);
			if (_state == State.Falling)
			{
				Lock();
			}
		}

		internal void ApplyPoses(List<(Vector3, Quaternion)> poses)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			if (_state == State.Standing)
			{
				return;
			}
			if (_state == State.Falling)
			{
				((MonoBehaviour)this).StopAllCoroutines();
				Lock();
			}
			for (int i = 0; i < poses.Count && i < _pieces.Count; i++)
			{
				if (Object.op_Implicit((Object)(object)_pieces[i]))
				{
					_pieces[i].localPosition = poses[i].Item1;
					_pieces[i].localRotation = poses[i].Item2;
				}
			}
		}

		internal List<(Vector3, Quaternion)> CapturePoses()
		{
			//IL_0042: 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_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			List<(Vector3, Quaternion)> list = new List<(Vector3, Quaternion)>(_pieces.Count);
			foreach (Transform piece in _pieces)
			{
				list.Add(Object.op_Implicit((Object)(object)piece) ? (piece.localPosition, piece.localRotation) : (Vector3.zero, Quaternion.identity));
			}
			return list;
		}

		private void Lock()
		{
			foreach (Rigidbody body in _bodies)
			{
				if (Object.op_Implicit((Object)(object)body))
				{
					body.isKinematic = true;
					Object.Destroy((Object)(object)body);
				}
			}
			_bodies.Clear();
			foreach (var (val, val2) in _ignored)
			{
				if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val2))
				{
					Physics.IgnoreCollision(val, val2, false);
				}
			}
			_ignored.Clear();
			_state = State.Locked;
		}

		private void LateUpdate()
		{
			if (_state == State.Standing)
			{
				return;
			}
			Collider[] solids = _solids;
			foreach (Collider val in solids)
			{
				if (Object.op_Implicit((Object)(object)val))
				{
					val.enabled = false;
				}
			}
			if (CurrentRound() != _round)
			{
				Restore();
			}
		}

		private void Restore()
		{
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			((MonoBehaviour)this).StopAllCoroutines();
			foreach (Rigidbody body in _bodies)
			{
				if (Object.op_Implicit((Object)(object)body))
				{
					Object.Destroy((Object)(object)body);
				}
			}
			foreach (BoxCollider debri in _debris)
			{
				if (Object.op_Implicit((Object)(object)debri))
				{
					Object.Destroy((Object)(object)debri);
				}
			}
			_bodies.Clear();
			_debris.Clear();
			_ignored.Clear();
			for (int i = 0; i < _pieces.Count; i++)
			{
				if (Object.op_Implicit((Object)(object)_pieces[i]))
				{
					_pieces[i].localPosition = _restPositions[i];
					_pieces[i].localRotation = _restRotations[i];
				}
			}
			Collider[] solids = _solids;
			foreach (Collider val in solids)
			{
				if (Object.op_Implicit((Object)(object)val))
				{
					val.enabled = true;
				}
			}
			_state = State.Standing;
		}

		private static int CurrentRound()
		{
			if (!Object.op_Implicit((Object)(object)GameManager.instance) || !Object.op_Implicit((Object)(object)GameManager.instance.networkVariables))
			{
				return 0;
			}
			return GameManager.instance.networkVariables.roundIndex.Value;
		}

		private static bool IsHost()
		{
			if (Object.op_Implicit((Object)(object)NetworkManager.Singleton))
			{
				return NetworkManager.Singleton.IsServer;
			}
			return true;
		}

		private static Bounds LocalBounds(Transform piece)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: 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_0092: 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_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			bool flag = false;
			Bounds result = default(Bounds);
			((Bounds)(ref result))..ctor(Vector3.zero, Vector3.one * 0.2f);
			MeshFilter[] componentsInChildren = ((Component)piece).GetComponentsInChildren<MeshFilter>(true);
			Vector3 val2 = default(Vector3);
			foreach (MeshFilter val in componentsInChildren)
			{
				if (!Object.op_Implicit((Object)(object)val.sharedMesh))
				{
					continue;
				}
				Bounds bounds = val.sharedMesh.bounds;
				for (int j = 0; j < 8; j++)
				{
					((Vector3)(ref val2))..ctor((j % 2 == 0) ? ((Bounds)(ref bounds)).min.x : ((Bounds)(ref bounds)).max.x, (j / 2 % 2 == 0) ? ((Bounds)(ref bounds)).min.y : ((Bounds)(ref bounds)).max.y, (j / 4 == 0) ? ((Bounds)(ref bounds)).min.z : ((Bounds)(ref bounds)).max.z);
					Vector3 val3 = piece.InverseTransformPoint(((Component)val).transform.TransformPoint(val2));
					if (!flag)
					{
						((Bounds)(ref result))..ctor(val3, Vector3.zero);
						flag = true;
					}
					else
					{
						((Bounds)(ref result)).Encapsulate(val3);
					}
				}
			}
			return result;
		}
	}
	internal sealed class CrumbleHit : MonoBehaviour
	{
		public Crumble owner;

		private void OnCollisionEnter(Collision collision)
		{
			//IL_0045: 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_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)owner) && Object.op_Implicit((Object)(object)owner.Obstacle) && CarLookup.IsPlaced(owner.Obstacle) && CarLookup.TryGetOwnedCar(collision.collider, out var _, out var car))
			{
				Vector3 relativeVelocity = collision.relativeVelocity;
				if (!(((Vector3)(ref relativeVelocity)).magnitude < owner.minSpeed))
				{
					Vector3 direction = Vector3.ProjectOnPlane(((Component)this).transform.position - car.sphereRigidbody.position, Vector3.up);
					TriggerBus.Fire(owner.Obstacle, owner.channel, direction);
				}
			}
		}
	}
	internal sealed class GrowZone : MonoBehaviour
	{
		public float duration = 8f;

		public float scale = 2.2f;

		private Obstacle _obstacle;

		private CarModifier _modifier;

		private void Start()
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Expected O, but got Unknown
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			_obstacle = ((Component)this).GetComponentInParent<Obstacle>();
			_modifier = ScriptableObject.CreateInstance<CarModifier>();
			_modifier.id = "CUSTOMCONTENT_MAGNIFIED";
			_modifier.durationSeconds = duration;
			_modifier.isUniquePerApplier = true;
			float num = 1f / scale;
			AnimationCurve val = new AnimationCurve((Keyframe[])(object)new Keyframe[4]
			{
				new Keyframe(0f, num),
				new Keyframe(0.08f, 1f),
				new Keyframe(0.88f, 1f),
				new Keyframe(1f, num)
			});
			_modifier.scale = new ModifierValue<Vector3>((ModifierValueType)2, val, Vector3.one * scale);
		}

		private void OnTriggerEnter(Collider other)
		{
			if (Object.op_Implicit((Object)(object)_modifier) && CarLookup.IsPlaced(_obstacle) && CarLookup.TryGetAnyCar(other, out var car))
			{
				_modifier.Register(car, (object)this);
			}
		}

		private void OnDestroy()
		{
			if (Object.op_Implicit((Object)(object)_modifier))
			{
				Object.Destroy((Object)(object)_modifier);
			}
		}
	}
	internal sealed class LaunchZone : MonoBehaviour
	{
		public Vector3 localVelocity = new Vector3(0f, 20f, 0f);

		public bool setVelocity = true;

		public float delay;

		public float cooldown = 1f;

		public int channel = -1;

		private Obstacle _obstacle;

		private readonly Dictionary<SphereCarController, float> _lastLaunch = new Dictionary<SphereCarController, float>();

		private void Start()
		{
			_obstacle = ((Component)this).GetComponentInParent<Obstacle>();
		}

		private void OnTriggerEnter(Collider other)
		{
			if (CarLookup.IsPlaced(_obstacle) && CarLookup.TryGetOwnedCar(other, out var _, out var car) && (!_lastLaunch.TryGetValue(car, out var value) || !(Time.time - value < cooldown)))
			{
				_lastLaunch[car] = Time.time;
				if (delay > 0.01f)
				{
					((MonoBehaviour)this).StartCoroutine(LaunchLater(car));
				}
				else
				{
					Launch(car);
				}
			}
		}

		private IEnumerator LaunchLater(SphereCarController car)
		{
			yield return (object)new WaitForSeconds(delay);
			if (Object.op_Implicit((Object)(object)car))
			{
				Launch(car);
			}
		}

		private void Launch(SphereCarController car)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			Rigidbody sphereRigidbody = car.sphereRigidbody;
			Vector3 val = ((Component)this).transform.TransformDirection(localVelocity);
			if (setVelocity)
			{
				sphereRigidbody.velocity = val;
			}
			else
			{
				sphereRigidbody.AddForce(val, (ForceMode)2);
			}
			if (channel >= 0 && Object.op_Implicit((Object)(object)_obstacle))
			{
				TriggerBus.Fire(_obstacle, channel);
			}
		}
	}
	internal sealed class LowGravityShape : GravityShape
	{
		public BoxCollider area;

		public float factor = 0.7f;

		public float planeGravity = 40f;

		private Obstacle _obstacle;

		private void Start()
		{
			_obstacle = ((Component)this).GetComponentInParent<Obstacle>();
		}

		public override Vector3 GetGravityAtPoint(Vector3 position)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: 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_0036: 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_004c: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)area) && CarLookup.IsPlaced(_obstacle))
			{
				Bounds bounds = ((Collider)area).bounds;
				if (((Bounds)(ref bounds)).Contains(position))
				{
					return Vector3.up * planeGravity * factor;
				}
			}
			return Vector3.zero;
		}
	}
	internal sealed class SpawnZone : MonoBehaviour
	{
		public float cooldown = 1.5f;

		public int channel = -1;

		private Obstacle _obstacle;

		private float _last = -100f;

		private void Start()
		{
			_obstacle = ((Component)this).GetComponentInParent<Obstacle>();
		}

		private void OnTriggerEnter(Collider other)
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Expected O, but got Unknown
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			if (CarLookup.IsPlaced(_obstacle) && !(Time.time - _last < cooldown) && CarLookup.TryGetOwnedCar(other, out var _, out var car) && Object.op_Implicit((Object)(object)car.player) && Object.op_Implicit((Object)(object)GameManager.instance))
			{
				_last = Time.time;
				GameManager.instance.PlacePlayerAtSpawn(car.player, false);
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(33, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Teleport: sent ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(car.player.DisplayNameRaw);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" back to the start");
				}
				log.LogInfo(val);
				if (channel >= 0 && Object.op_Implicit((Object)(object)_obstacle))
				{
					TriggerBus.Fire(_obstacle, channel, car.sphereRigidbody.position);
				}
			}
		}
	}
	internal sealed class PushZone : MonoBehaviour
	{
		public float speed = 18f;

		public float up = 5f;

		public float cooldown = 0.4f;

		private Obstacle _obstacle;

		private readonly Dictionary<SphereCarController, float> _last = new Dictionary<SphereCarController, float>();

		private void Start()
		{
			_obstacle = ((Component)this).GetComponentInParent<Obstacle>();
		}

		private void OnCollisionEnter(Collision collision)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: 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_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			if (CarLookup.IsPlaced(_obstacle) && CarLookup.TryGetOwnedCar(collision.collider, out var _, out var car) && (!_last.TryGetValue(car, out var value) || !(Time.time - value < cooldown)))
			{
				_last[car] = Time.time;
				Rigidbody sphereRigidbody = car.sphereRigidbody;
				Vector3 val = Vector3.ProjectOnPlane(sphereRigidbody.position - ((Component)this).transform.position, Vector3.up);
				if (((Vector3)(ref val)).sqrMagnitude < 0.01f)
				{
					val = -Vector3.ProjectOnPlane(sphereRigidbody.velocity, Vector3.up);
				}
				if (((Vector3)(ref val)).sqrMagnitude < 0.01f)
				{
					val = ((Component)this).transform.forward;
				}
				sphereRigidbody.velocity = ((Vector3)(ref val)).normalized * speed + Vector3.up * up;
			}
		}
	}
	internal static class ReverseSurface
	{
		private static int _cachedFrame = -1;

		private static SphereCarController _cachedCar;

		private static bool _cachedResult;

		internal static Surface Instance { get; private set; }

		internal static void Register(SurfaceManager manager)
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			if (!Object.op_Implicit((Object)(object)Instance))
			{
				Instance = Create(manager.defaultSurface);
			}
			if (Object.op_Implicit((Object)(object)Instance) && !manager.surfaces.Contains(Instance))
			{
				manager.surfaces = manager.surfaces.Append(Instance).ToArray();
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(33, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Surfaces: added Reverse at index ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(manager.surfaces.Length - 1);
				}
				log.LogInfo(val);
			}
		}

		private static Surface Create(Surface template)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Expected O, but got Unknown
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)template) || template.effects == null || !Object.op_Implicit((Object)(object)template.effects.material))
			{
				Plugin.Log.LogWarning((object)"Surfaces: no default surface to copy; Reverse surface unavailable");
				return null;
			}
			Surface obj = Object.Instantiate<Surface>(template);
			((Object)obj).name = "CustomContent_Reverse";
			((Object)obj).hideFlags = (HideFlags)32;
			obj.skidMarkColor = new Color32((byte)150, (byte)60, (byte)220, byte.MaxValue);
			Material val = new Material(template.effects.material)
			{
				name = ((Object)template.effects.material).name,
				hideFlags = (HideFlags)32
			};
			val.SetColor("_Color", new Color(0.42f, 0.16f, 0.72f));
			val.SetColor("_ColorSecondary", new Color(0.78f, 0.36f, 1f));
			obj.effects.material = val;
			obj.effects.mainColor = new Color(0.62f, 0.28f, 0.95f);
			obj.effects.lightColor = new Color(0.85f, 0.6f, 1f);
			obj.effects.darkColor = new Color(0.3f, 0.1f, 0.5f);
			return obj;
		}

		internal static bool IsReversed(SphereCarController car)
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)Instance) || !Object.op_Implicit((Object)(object)car) || !Object.op_Implicit((Object)(object)car.player) || !((NetworkBehaviour)car.player).IsOwner)
			{
				return false;
			}
			if (_cachedFrame == Time.frameCount && (Object)(object)_cachedCar == (Object)(object)car)
			{
				return _cachedResult;
			}
			RaycastHit val = default(RaycastHit);
			SurfaceInfo val2 = default(SurfaceInfo);
			bool flag = ((!car.OnGround) ? (Object.op_Implicit((Object)(object)car.sphereRigidbody) && Physics.Raycast(car.sphereRigidbody.position, Vector3.down, ref val, 60f, LayerMask.op_Implicit(car.floorLayerMask), (QueryTriggerInteraction)1) && ((Component)((RaycastHit)(ref val)).collider).TryGetComponent<SurfaceInfo>(ref val2) && (Object)(object)val2.surface == (Object)(object)Instance) : ((Object)(object)car.CurrentSurface == (Object)(object)Instance));
			_cachedFrame = Time.frameCount;
			_cachedCar = car;
			_cachedResult = flag;
			return flag;
		}
	}
	[HarmonyPatch(typeof(SurfaceManager), "Awake")]
	internal static class SurfaceManagerAwakePatch
	{
		private static void Postfix(SurfaceManager __instance)
		{
			if ((Object)(object)SurfaceManager.instance == (Object)(object)__instance)
			{
				ReverseSurface.Register(__instance);
			}
		}
	}
	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	internal static class ReverseSteerPatch
	{
		private static void Postfix(SphereCarController __instance, ref float __result)
		{
			if (ReverseSurface.IsReversed(__instance))
			{
				__result = 0f - __result;
			}
		}
	}
	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	internal static class ReverseAirSteerPatch
	{
		private static void Postfix(SphereCarController __instance, ref float __result)
		{
			if (ReverseSurface.IsReversed(__instance))
			{
				__result = 0f - __result;
			}
		}
	}
	internal sealed class SlingshotZone : MonoBehaviour
	{
		private sealed class Grab
		{
			public SphereCarController car;

			public Collider collider;

			public float sign;

			public float stretch;

			public float maxStretch;
		}

		public Vector3 leftAnchor = new Vector3(-2.2f, 0f, 0f);

		public Vector3 rightAnchor = new Vector3(2.2f, 0f, 0f);

		public float halfWidth = 1.9f;

		public float maxStretch = 7f;

		public float spring = 9f;

		public float damping = 1.5f;

		public float launchBase = 14f;

		public float launchPerMetre = 5f;

		public float launchUp = 4f;

		public float cooldown = 1.2f;

		public Material rubberMaterial;

		public Material pouchMaterial;

		private Obstacle _obstacle;

		private readonly Dictionary<SphereCarController, float> _lastZ = new Dictionary<SphereCarController, float>();

		private readonly Dictionary<SphereCarController, Grab> _grabs = new Dictionary<SphereCarController, Grab>();

		private readonly Dictionary<SphereCarController, float> _cooldownUntil = new Dictionary<SphereCarController, float>();

		private Transform _strandLeft;

		private Transform _strandRight;

		private Transform _pouch;

		private Vector3 _pouchLocal;

		private Vector3 _pouchVelocity;

		private Vector3 Rest => (leftAnchor + rightAnchor) * 0.5f;

		private void Start()
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			_obstacle = ((Component)this).GetComponentInParent<Obstacle>();
			_strandLeft = MakePart("SlingStrandL", rubberMaterial);
			_strandRight = MakePart("SlingStrandR", rubberMaterial);
			_pouch = MakePart("SlingPouch", pouchMaterial);
			_pouch.localScale = new Vector3(1f, 1.1f, 0.45f);
			_pouchLocal = Rest;
			UpdateVisual();
		}

		private Transform MakePart(string partName, Material material)
		{
			GameObject val = GameObject.CreatePrimitive((PrimitiveType)3);
			((Object)val).name = partName;
			Object.Destroy((Object)(object)val.GetComponent<Collider>());
			val.layer = ((Component)this).gameObject.layer;
			val.transform.SetParent(((Component)this).transform, false);
			if (Object.op_Implicit((Object)(object)material))
			{
				((Renderer)val.GetComponent<MeshRenderer>()).sharedMaterial = material;
			}
			return val.transform;
		}

		private void OnTriggerStay(Collider other)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: 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_00be: Unknown result type (might be due to invalid IL or missing references)
			if (CarLookup.IsPlaced(_obstacle) && CarLookup.TryGetAnyCar(other, out var car) && !_grabs.ContainsKey(car))
			{
				Transform transform = ((Component)this).transform;
				Bounds bounds = other.bounds;
				Vector3 val = transform.InverseTransformPoint(((Bounds)(ref bounds)).center);
				float value;
				bool num = _lastZ.TryGetValue(car, out value);
				_lastZ[car] = val.z;
				if (num && !(Mathf.Abs(val.x) > halfWidth) && Mathf.Sign(value) != Mathf.Sign(val.z) && (!_cooldownUntil.TryGetValue(car, out var value2) || !(Time.time < value2)))
				{
					_grabs[car] = new Grab
					{
						car = car,
						collider = other,
						sign = Mathf.Sign(val.z - value)
					};
				}
			}
		}

		private void OnTriggerExit(Collider other)
		{
			if (CarLookup.TryGetAnyCar(other, out var car))
			{
				_lastZ.Remove(car);
				_grabs.Remove(car);
			}
		}

		private void FixedUpdate()
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: 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_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			List<SphereCarController> list = null;
			foreach (Grab value in _grabs.Values)
			{
				if (!Object.op_Implicit((Object)(object)value.car) || !Object.op_Implicit((Object)(object)value.collider))
				{
					(list ?? (list = new List<SphereCarController>())).Add(value.car);
					continue;
				}
				Vector3 val = ((Component)this).transform.forward * value.sign;
				Transform transform = ((Component)this).transform;
				Bounds bounds = value.collider.bounds;
				Vector3 val2 = transform.InverseTransformPoint(((Bounds)(ref bounds)).center);
				bounds = value.collider.bounds;
				value.stretch = Vector3.Dot(((Bounds)(ref bounds)).center - ((Component)this).transform.position, val);
				value.maxStretch = Mathf.Max(value.maxStretch, value.stretch);
				if (Mathf.Abs(val2.x) > halfWidth + 1f || value.stretch < -0.5f)
				{
					(list ?? (list = new List<SphereCarController>())).Add(value.car);
				}
				else if (Object.op_Implicit((Object)(object)value.car.player) && ((NetworkBehaviour)value.car.player).IsOwner && Pull(value, val))
				{
					(list ?? (list = new List<SphereCarController>())).Add(value.car);
				}
			}
			if (list == null)
			{
				return;
			}
			foreach (SphereCarController item in list)
			{
				_grabs.Remove(item);
				if (Object.op_Implicit((Object)(object)item))
				{
					_cooldownUntil[item] = Time.time + cooldown;
				}
			}
		}

		private bool Pull(Grab grab, Vector3 direction)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: 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_00ab: 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_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			Rigidbody sphereRigidbody = grab.car.sphereRigidbody;
			float num = Vector3.Dot(sphereRigidbody.velocity, direction);
			float num2 = Mathf.Max(0f, grab.stretch);
			sphereRigidbody.AddForce(-direction * (spring * num2 + damping * Mathf.Max(0f, num)), (ForceMode)5);
			if (num2 >= maxStretch && num > 0f)
			{
				sphereRigidbody.velocity -= direction * num;
			}
			if (grab.maxStretch > 0.8f && num <= 0.25f)
			{
				sphereRigidbody.velocity = -direction * (launchBase + launchPerMetre * num2) + Vector3.up * launchUp;
				return true;
			}
			return false;
		}

		private void Update()
		{
			UpdateVisual();
		}

		private void UpdateVisual()
		{
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: 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_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: 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_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: 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_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)_pouch))
			{
				return;
			}
			Grab grab = null;
			foreach (Grab value in _grabs.Values)
			{
				if (Object.op_Implicit((Object)(object)value.car) && Object.op_Implicit((Object)(object)value.collider) && (grab == null || value.stretch > grab.stretch))
				{
					grab = value;
				}
			}
			if (grab != null)
			{
				Transform transform = ((Component)this).transform;
				Bounds bounds = grab.collider.bounds;
				Vector3 val = transform.InverseTransformPoint(((Bounds)(ref bounds)).center);
				float num = Mathf.Clamp(grab.stretch, 0f, maxStretch);
				_pouchLocal = new Vector3(Mathf.Clamp(val.x, 0f - halfWidth, halfWidth), Rest.y, grab.sign * num);
				_pouchVelocity = Vector3.zero;
			}
			else
			{
				Vector3 val2 = Rest - _pouchLocal;
				_pouchVelocity += val2 * (220f * Time.deltaTime);
				_pouchVelocity *= Mathf.Exp(-9f * Time.deltaTime);
				_pouchLocal += _pouchVelocity * Time.deltaTime;
			}
			_pouch.localPosition = _pouchLocal;
			Strand(_strandLeft, leftAnchor);
			Strand(_strandRight, rightAnchor);
		}

		private void Strand(Transform strand, Vector3 anchor)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = _pouchLocal - anchor;
			float num = Mathf.Max(0.05f, ((Vector3)(ref val)).magnitude);
			strand.localPosition = anchor + val * 0.5f;
			strand.localRotation = Quaternion.LookRotation(val / num, Vector3.up);
			float num2 = Mathf.Lerp(0.28f, 0.14f, Mathf.Clamp01((num - 2f) / 6f));
			strand.localScale = new Vector3(num2, num2, num);
		}
	}
	internal sealed class TimedActive : MonoBehaviour
	{
		public float speed = 0.2f;

		public float start;

		public float end = 0.5f;

		private Obstacle _obstacle;

		private Collider[] _colliders = (Collider[])(object)new Collider[0];

		private void Start()
		{
			_obstacle = ((Component)this).GetComponentInParent<Obstacle>();
			_colliders = ((Component)this).GetComponentsInChildren<Collider>(true);
		}

		private void LateUpdate()
		{
			double num = TimeUtils.LocalTimeSec * (double)speed * (double)NetworkAnimatedParameter.GlobalSpeedFactor;
			float num2 = (float)(num - Math.Floor(num));
			bool enabled = num2 >= start && num2 < end && CarLookup.IsPlaced(_obstacle);
			Collider[] colliders = _colliders;
			foreach (Collider val in colliders)
			{
				if (Object.op_Implicit((Object)(object)val))
				{
					val.enabled = enabled;
				}
			}
		}
	}
	internal sealed class NetworkAnimatedPosition : NetworkAnimatedTransformation
	{
		public override void UpdateValues()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			base.target.localPosition = new Vector3(base.x.value, base.y.value, base.z.value);
		}

		public override void DoPreview()
		{
		}
	}
	internal sealed class ToiletZone : MonoBehaviour
	{
		public float delay = 0.35f;

		public float exitSpeed = 25f;

		public int channel = -1;

		private Obstacle _obstacle;

		private readonly HashSet<SphereCarController> _flushing = new HashSet<SphereCarController>();

		private void Start()
		{
			_obstacle = ((Component)this).GetComponentInParent<Obstacle>();
		}

		private void OnTriggerEnter(Collider other)
		{
			if (Object.op_Implicit((Object)(object)_obstacle) && CarLookup.IsPlaced(_obstacle) && CarLookup.TryGetOwnedCar(other, out var _, out var car) && _flushing.Add(car))
			{
				((MonoBehaviour)this).StartCoroutine(Flush(car));
			}
		}

		private IEnumerator Flush(SphereCarController car)
		{
			Vector3 direction;
			if (channel >= 0)
			{
				Obstacle obstacle = _obstacle;
				int num = channel;
				direction = default(Vector3);
				TriggerBus.Fire(obstacle, num, direction);
			}
			yield return (object)new WaitForSeconds(delay);
			_flushing.Remove(car);
			if (!Object.op_Implicit((Object)(object)car) || !Object.op_Implicit((Object)(object)car.player))
			{
				yield break;
			}
			Obstacle val = ToiletPairing.FindExit(_obstacle);
			if (Object.op_Implicit((Object)(object)val))
			{
				direction = Vector3.ProjectOnPlane(((Component)val).transform.forward, Vector3.up);
				Vector3 val2 = ((Vector3)(ref direction)).normalized;
				if (((Vector3)(ref val2)).sqrMagnitude < 0.01f)
				{
					val2 = Vector3.forward;
				}
				Vector3 val3 = ((Component)val).transform.position + Vector3.up * 2.5f + val2 * 3.5f;
				car.Teleport(val3, Quaternion.LookRotation(val2), val2, val2 * exitSpeed, Vector3.zero);
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val4 = new BepInExInfoLogInterpolatedStringHandler(20, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("Toilet: flushed ");
					((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(car.player.DisplayNameRaw);
					((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" to ");
					((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(((Object)val).name);
				}
				log.LogInfo(val4);
			}
			else
			{
				FlushToCheckpoint(car);
			}
		}

		private static void FlushToCheckpoint(SphereCarController car)
		{
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			PlayerData player = car.player;
			LevelDefinition val = (Object.op_Implicit((Object)(object)LevelManager.instance) ? LevelManager.instance.levelDefinition : null);
			int num = -1;
			ulong num2 = 0uL;
			if (Object.op_Implicit((Object)(object)val) && player.passedCheckPoints != null)
			{
				for (int i = 0; i < player.passedCheckPoints.Count && i < val.checkpoints.Count; i++)
				{
					if (player.passedCheckPoints[i] > num2)
					{
						num2 = player.passedCheckPoints[i];
						num = i;
					}
				}
			}
			if (num >= 0 && Object.op_Implicit((Object)(object)val.checkpoints[num]))
			{
				Transform transform = ((Component)val.checkpoints[num]).transform;
				car.Teleport(transform.position + Vector3.up * 2f, transform.rotation, transform.forward, Vector3.zero, Vector3.zero);
			}
			else if (Object.op_Implicit((Object)(object)GameManager.instance))
			{
				GameManager.instance.PlacePlayerAtSpawn(player, false);
			}
		}
	}
	internal static class ToiletPairing
	{
		private static readonly FieldRef<GameManager, bool> TimerHandled = AccessTools.FieldRefAccess<GameManager, bool>("_hasHandledObstaclePlacementTimer");

		private static readonly HashSet<PlayerData> AwaitingExit = new HashSet<PlayerData>();

		internal static bool IsToilet(Obstacle obstacle, out CustomObstacle entry)
		{
			entry = null;
			CustomObstacleTag customObstacleTag = (Object.op_Implicit((Object)(object)obstacle) ? ((Component)obstacle).GetComponent<CustomObstacleTag>() : null);
			if (!Object.op_Implicit((Object)(object)customObstacleTag))
			{
				return false;
			}
			entry = CardRegistry.Get(customObstacleTag.Slot);
			if (entry != null)
			{
				return !string.IsNullOrEmpty(entry.PartnerId);
			}
			return false;
		}

		internal static bool IsExit(Obstacle obstacle)
		{
			CustomObstacleTag customObstacleTag = (Object.op_Implicit((Object)(object)obstacle) ? ((Component)obstacle).GetComponent<CustomObstacleTag>() : null);
			if (Object.op_Implicit((Object)(object)customObstacleTag))
			{
				return CardRegistry.Get(customObstacleTag.Slot)?.IsPartnerOnly ?? false;
			}
			return false;
		}

		private static bool CanHandOver()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Invalid comparison between Unknown and I4
			if (Object.op_Implicit((Object)(object)GameManager.instance) && (int)GameManager.instance.networkVariables.state.Value == 8)
			{
				return !TimerHandled.Invoke(GameManager.instance);
			}
			return false;
		}

		internal static void OnPlaced(Obstacle toilet, bool inScene)
		{
			//IL_004a: 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_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_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: 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_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: 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_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Expected O, but got Unknown
			//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_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: 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)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Expected O, but got Unknown
			if (!((NetworkBehaviour)toilet).IsServer || !IsToilet(toilet, out var entry) || Object.op_Implicit((Object)(object)FindExit(toilet)))
			{
				return;
			}
			ObstacleDescription val = CardRegistry.DescriptionOf(entry.PartnerId);
			PlayerData playerInfos = toilet.playerInfos;
			if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)playerInfos))
			{
				return;
			}
			Vector3 val2 = Vector3.ProjectOnPlane(((Component)toilet).transform.forward, Vector3.up);
			Vector3 val3 = ((Vector3)(ref val2)).normalized;
			if (((Vector3)(ref val3)).sqrMagnitude < 0.01f)
			{
				val3 = Vector3.forward;
			}
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val4;
			if (!inScene && CanHandOver())
			{
				val.Spawn(playerInfos, ((Component)toilet).transform.position + Vector3.up * 3f + val3 * 8f, Quaternion.identity, false, -1);
				ManualLogSource log = Plugin.Log;
				val4 = new BepInExInfoLogInterpolatedStringHandler(37, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("Toilet: handed ");
					((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(playerInfos.DisplayNameRaw);
					((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" a Sewer Exit to place");
				}
				log.LogInfo(val4);
				return;
			}
			Vector3 val5 = ((Component)toilet).transform.position + val3 * 18f;
			RaycastHit val6 = default(RaycastHit);
			if (Physics.Raycast(val5 + Vector3.up * 50f, Vector3.down, ref val6, 200f))
			{
				val5 = ((RaycastHit)(ref val6)).point;
			}
			val.Spawn(playerInfos, val5, Quaternion.LookRotation(val3), Vector3.one, true, -1);
			ManualLogSource log2 = Plugin.Log;
			val4 = new BepInExInfoLogInterpolatedStringHandler(40, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("Toilet: dropped a placed Sewer Exit for ");
				((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(playerInfos.DisplayNameRaw);
			}
			log2.LogInfo(val4);
		}

		internal static void OnPlayerPlaced(PlayerData player, Obstacle obstacle, bool inScene)
		{
			if (!inScene && ((NetworkBehaviour)player).IsOwner && IsToilet(obstacle, out var _) && CanHandOver())
			{
				player.placedObstacle.Value = false;
				AwaitingExit.Add(player);
			}
		}

		internal static void OnExitSpawned(Obstacle exit)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Invalid comparison between Unknown and I4
			PlayerData playerInfos = exit.playerInfos;
			if (IsExit(exit) && Object.op_Implicit((Object)(object)playerInfos) && ((NetworkBehaviour)playerInfos).IsOwner && AwaitingExit.Remove(playerInfos) && (int)exit.state == 3)
			{
				playerInfos.placedObstacle.Value = true;
			}
		}

		internal static Obstacle FindExit(Obstacle toilet)
		{
			if (!Object.op_Implicit((Object)(object)toilet) || !Object.op_Implicit((Object)(object)((NetworkBehaviour)toilet).NetworkObject))
			{
				return null;
			}
			ulong networkObjectId = ((NetworkBehaviour)toilet).NetworkObject.NetworkObjectId;
			Obstacle result = null;
			ulong num = ulong.MaxValue;
			foreach (Obstacle allObstacle in ObstacleManager.AllObstacles)
			{
				if (Object.op_Implicit((Object)(object)allObstacle) && Object.op_Implicit((Object)(object)((NetworkBehaviour)allObstacle).NetworkObject) && IsExit(allObstacle))
				{
					ulong networkObjectId2 = ((NetworkBehaviour)allObstacle).NetworkObject.NetworkObjectId;
					if (networkObjectId2 > networkObjectId && networkObjectId2 < num && allObstacle.playerInfosIndex.Value == toilet.playerInfosIndex.Value)
					{
						result = allObstacle;
						num = networkObjectId2;
					}
				}
			}
			return result;
		}
	}
	[HarmonyPatch(typeof(Obstacle), "OnNetworkSpawn")]
	internal static class ExitSpawnedPatch
	{
		private static void Postfix(Obstacle __instance)
		{
			ToiletPairing.OnExitSpawned(__instance);
		}
	}
	[HarmonyPatch(typeof(Obstacle), "OnPlace")]
	internal static class ToiletPlacedPatch
	{
		private static void Postfix(Obstacle __instance, bool inScene)
		{
			ToiletPairing.OnPlaced(__instance, inScene);
		}
	}
	[HarmonyPatch(typeof(PlayerData), "PlaceObstacle")]
	internal static class ToiletPlayerPlacedPatch
	{
		private static void Postfix(PlayerData __instance, Obstacle obstacle, bool inScene)
		{
			ToiletPairing.OnPlayerPlaced(__instance, obstacle, inScene);
		}
	}
	internal static class TriggerBus
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static HandleNamedMessageDelegate <0>__OnMessage;

			public static HandleNamedMessageDelegate <1>__OnPosesMessage;
		}

		private const string MessageName = "SlipSkid.CustomContent.Trigger";

		private const string PosesMessageName = "SlipSkid.CustomContent.Poses";

		private static CustomMessagingManager _registeredWith;

		internal static void Update()
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Expected O, but got Unknown
			NetworkManager singleton = NetworkManager.Singleton;
			CustomMessagingManager val = ((Object.op_Implicit((Object)(object)singleton) && singleton.IsListening) ? singleton.CustomMessagingManager : null);
			if (val != null && val != _registeredWith)
			{
				object obj = <>O.<0>__OnMessage;
				if (obj == null)
				{
					HandleNamedMessageDelegate val2 = OnMessage;
					<>O.<0>__OnMessage = val2;
					obj = (object)val2;
				}
				val.RegisterNamedMessageHandler("SlipSkid.CustomContent.Trigger", (HandleNamedMessageDelegate)obj);
				object obj2 = <>O.<1>__OnPosesMessage;
				if (obj2 == null)
				{
					HandleNamedMessageDelegate val3 = OnPosesMessage;
					<>O.<1>__OnPosesMessage = val3;
					obj2 = (object)val3;
				}
				val.RegisterNamedMessageHandler("SlipSkid.CustomContent.Poses", (HandleNamedMessageDelegate)obj2);
				_registeredWith = val;
			}
		}

		internal static void SendPoses(Crumble crumble, List<(Vector3, Quaternion)> poses)
		{
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: 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_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: 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_0156: 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_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager singleton = NetworkManager.Singleton;
			Obstacle obstacle = crumble.Obstacle;
			if (!Object.op_Implicit((Object)(object)singleton) || !singleton.IsListening || !singleton.IsServer || !Object.op_Implicit((Object)(object)obstacle) || !Object.op_Implicit((Object)(object)((NetworkBehaviour)obstacle).NetworkObject))
			{
				return;
			}
			List<ulong> list = OthersExcept(singleton, singleton.LocalClientId);
			if (list.Count == 0)
			{
				return;
			}
			int num = Array.IndexOf(((Component)obstacle).GetComponentsInChildren<Crumble>(true), crumble);
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(32 + poses.Count * 28, (Allocator)2, -1);
			try
			{
				ulong networkObjectId = ((NetworkBehaviour)obstacle).NetworkObject.NetworkObjectId;
				((FastBufferWriter)(ref val)).WriteValueSafe<ulong>(ref networkObjectId, default(ForPrimitives));
				((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref num, default(ForPrimitives));
				int count = poses.Count;
				((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref count, default(ForPrimitives));
				foreach (var pose in poses)
				{
					var (val2, val3) = pose;
					((FastBufferWriter)(ref val)).WriteValueSafe<float>(ref val2.x, default(ForPrimitives));
					((FastBufferWriter)(ref val)).WriteValueSafe<float>(ref val2.y, default(ForPrimitives));
					((FastBufferWriter)(ref val)).WriteValueSafe<float>(ref val2.z, default(ForPrimitives));
					((FastBufferWriter)(ref val)).WriteValueSafe<float>(ref val3.x, default(ForPrimitives));
					((FastBufferWriter)(ref val)).WriteValueSafe<float>(ref val3.y, default(ForPrimitives));
					((FastBufferWriter)(ref val)).WriteValueSafe<float>(ref val3.z, default(ForPrimitives));
					((FastBufferWriter)(ref val)).WriteValueSafe<float>(ref val3.w, default(ForPrimitives));
				}
				singleton.CustomMessagingManager.SendNamedMessage("SlipSkid.CustomContent.Poses", (IReadOnlyList<ulong>)list, val, (NetworkDelivery)4);
			}
			finally
			{
				((FastBufferWriter)(ref val)).Dispose();
			}
		}

		private static void OnPosesMessage(ulong sender, FastBufferReader reader)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			ulong key = default(ulong);
			((FastBufferReader)(ref reader)).ReadValueSafe<ulong>(ref key, default(ForPrimitives));
			int num = default(int);
			((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref num, default(ForPrimitives));
			int num2 = default(int);
			((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref num2, default(ForPrimitives));
			List<(Vector3, Quaternion)> list = new List<(Vector3, Quaternion)>(num2);
			float num3 = default(float);
			float num4 = default(float);
			float num5 = default(float);
			float num6 = default(float);
			float num7 = default(float);
			float num8 = default(float);
			float num9 = default(float);
			for (int i = 0; i < num2; i++)
			{
				((FastBufferReader)(ref reader)).ReadValueSafe<float>(ref num3, default(ForPrimitives));
				((FastBufferReader)(ref reader)).ReadValueSafe<float>(ref num4, default(ForPrimitives));
				((FastBufferReader)(ref reader)).ReadValueSafe<float>(ref num5, default(ForPrimitives));
				((FastBufferReader)(ref reader)).ReadValueSafe<float>(ref num6, default(ForPrimitives));
				((FastBufferReader)(ref reader)).ReadValueSafe<float>(ref num7, default(ForPrimitives));
				((FastBufferReader)(ref reader)).ReadValueSafe<float>(ref num8, default(ForPrimitives));
				((FastBufferReader)(ref reader)).ReadValueSafe<float>(ref num9, default(ForPrimitives));
				list.Add((new Vector3(num3, num4, num5), new Quaternion(num6, num7, num8, num9)));
			}
			if (NetworkManager.Singleton.SpawnManager.SpawnedObjects.TryGetValue(key, out var value))
			{
				Crumble[] componentsInChildren = ((Component)value).GetComponentsInChildren<Crumble>(true);
				if (num >= 0 && num < componentsInChildren.Length)
				{
					componentsInChildren[num].ApplyPoses(list);
				}
			}
		}

		internal static void Fire(Obstacle obstacle, int channel, Vector3 direction = default(Vector3))
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			Play(obstacle, channel, direction);
			NetworkManager singleton = NetworkManager.Singleton;
			if (Object.op_Implicit((Object)(object)singleton) && singleton.IsListening && Object.op_Implicit((Object)(object)((NetworkBehaviour)obstacle).NetworkObject))
			{
				ulong networkObjectId = ((NetworkBehaviour)obstacle).NetworkObject.NetworkObjectId;
				if (singleton.IsServer)
				{
					Send(networkObjectId, channel, direction, OthersExcept(singleton, singleton.LocalClientId));
					return;
				}
				Send(networkObjectId, channel, direction, new List<ulong> { 0uL });
			}
		}

		private static void OnMessage(ulong sender, FastBufferReader reader)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: 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_0058: 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)
			ulong num = default(ulong);
			((FastBufferReader)(ref reader)).ReadValueSafe<ulong>(ref num, default(ForPrimitives));
			int channel = default(int);
			((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref channel, default(ForPrimitives));
			float num2 = default(float);
			((FastBufferReader)(ref reader)).ReadValueSafe<float>(ref num2, default(ForPrimitives));
			float num3 = default(float);
			((FastBufferReader)(ref reader)).ReadValueSafe<float>(ref num3, default(ForPrimitives));
			float num4 = default(float);
			((FastBufferReader)(ref reader)).ReadValueSafe<float>(ref num4, default(ForPrimitives));
			Vector3 direction = default(Vector3);
			((Vector3)(ref direction))..ctor(num2, num3, num4);
			NetworkManager singleton = NetworkManager.Singleton;
			if (!singleton.SpawnManager.SpawnedObjects.TryGetValue(num, out var value))
			{
				return;
			}
			Obstacle component = ((Component)value).GetComponent<Obstacle>();
			if (Object.op_Implicit((Object)(object)component))
			{
				Play(component, channel, direction);
				if (singleton.IsServer)
				{
					Send(num, channel, direction, OthersExcept(singleton, sender));
				}
			}
		}

		private static void Play(Obstacle obstacle, int channel, Vector3 direction)
		{
			//IL_0046: 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)
			TriggeredMotion[] componentsInChildren = ((Component)obstacle).GetComponentsInChildren<TriggeredMotion>(true);
			foreach (TriggeredMotion triggeredMotion in componentsInChildren)
			{
				if (triggeredMotion.channel == channel)
				{
					triggeredMotion.Trigger();
				}
			}
			Crumble[] componentsInChildren2 = ((Component)obstacle).GetComponentsInChildren<Crumble>(true);
			foreach (Crumble crumble in componentsInChildren2)
			{
				if (crumble.channel == channel)
				{
					crumble.Knock(direction);
				}
			}
			BurstEffect[] componentsInChildren3 = ((Component)obstacle).GetComponentsInChildren<BurstEffect>(true);
			foreach (BurstEffect burstEffect in componentsInChildren3)
			{
				if (burstEffect.channel == channel)
				{
					burstEffect.Play(direction);
				}
			}
		}

		private static List<ulong> OthersExcept(NetworkManager nm, ulong skip)
		{
			List<ulong> list = new List<ulong>();
			foreach (ulong connectedClientsId in nm.ConnectedClientsIds)
			{
				if (connectedClientsId != skip && connectedClientsId != nm.LocalClientId)
				{
					list.Add(connectedClientsId);
				}
			}
			return list;
		}

		private static void Send(ulong id, int channel, Vector3 direction, List<ulong> targets)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: 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_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			if (targets.Count == 0)
			{
				return;
			}
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(32, (Allocator)2, -1);
			try
			{
				((FastBufferWriter)(ref val)).WriteValueSafe<ulong>(ref id, default(ForPrimitives));
				((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref channel, default(ForPrimitives));
				((FastBufferWriter)(ref val)).WriteValueSafe<float>(ref direction.x, default(ForPrimitives));
				((FastBufferWriter)(ref val)).WriteValueSafe<float>(ref direction.y, default(ForPrimitives));
				((FastBufferWriter)(ref val)).WriteValueSafe<float>(ref direction.z, default(ForPrimitives));
				NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("SlipSkid.CustomContent.Trigger", (IReadOnlyList<ulong>)targets, val, (NetworkDelivery)2);
			}
			finally
			{
				((FastBufferWriter)(ref val)).Dispose();
			}
		}
	}
	internal sealed class TriggerPlate : MonoBehaviour
	{
		public int channel;

		public float cooldown = 2f;

		private Obstacle _obstacle;

		private float _last = -100f;

		private void Start()
		{
			_obstacle = ((Component)this).GetComponentInParent<Obstacle>();
		}

		private void OnTriggerEnter(Collider other)
		{
			//IL_0055: 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)
			if (Object.op_Implicit((Object)(object)_obstacle) && CarLookup.IsPlaced(_obstacle) && !(Time.time - _last < cooldown) && CarLookup.TryGetOwnedCar(other, out var _, out var _))
			{
				_last = Time.time;
				TriggerBus.Fire(_obstacle, channel);
			}
		}
	}
	internal sealed class TriggeredMotion : MonoBehaviour
	{
		public enum Kind
		{
			Rotation,
			Position,
			Scale
		}

		public int channel;

		public Kind kind;

		public Vector3 rest;

		public Vector3 active;

		public float startDelay;

		public float inTime = 0.15f;

		public float holdTime = 1f;

		public float outTime = 0.8f;

		public float cooldown = 0.5f;

		public bool arm;

		private Obstacle _obstacle;

		private Collider[] _armed = (Collider[])(object)new Collider[0];

		private float _triggeredAt = -1000f;

		private float Duration => startDelay + inTime + holdTime + outTime;

		private void Start()
		{
			_obstacle = ((Component)this).GetComponentInParent<Obstacle>();
			if (arm)
			{
				_armed = ((Component)this).GetComponentsInChildren<Collider>(true);
			}
			Apply(0f);
		}

		internal void Trigger()
		{
			if (!(Time.time - _triggeredAt < Duration + cooldown))
			{
				_triggeredAt = Time.time;
			}
		}

		private void Update()
		{
			float num = Time.time - _triggeredAt - startDelay;
			float amount = 0f;
			if (num >= 0f)
			{
				if (num < inTime)
				{
					amount = Smooth(num / inTime);
				}
				else if (num < inTime + holdTime)
				{
					amount = 1f;
				}
				else if (num < inTime + holdTime + outTime)
				{
					amount = 1f - Smooth((num - inTime - holdTime) / outTime);
				}
			}
			Apply(amount);
		}

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

		private void LateUpdate()
		{
			if (!arm)
			{
				return;
			}
			float num = Time.time - _triggeredAt - startDelay;
			bool enabled = num >= 0f && num < inTime + holdTime && CarLookup.IsPlaced(_obstacle);
			Collider[] armed = _armed;
			foreach (Collider val in armed)
			{
				if (Object.op_Implicit((Object)(object)val))
				{
					val.enabled = enabled;
				}
			}
		}

		private void Apply(float amount)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: 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)
			Vector3 val = Vector3.LerpUnclamped(rest, active, amount);
			switch (kind)
			{
			case Kind.Rotation:
				((Component)this).transform.localRotation = Quaternion.Euler(val);
				break;
			case Kind.Position:
				((Component)this).transform.localPosition = val;
				break;
			case Kind.Scale:
				((Component)this).transform.localScale = val;
				break;
			}
		}
	}
	internal static class CardConfig
	{
		internal static ConfigEntry<string> ForceCard;

		internal static ConfigEntry<int> ForceAffixIndex;

		internal static ConfigEntry<bool> DebugKeys;

		internal static ConfigEntry<bool> VerboseLog;

		internal static void Bind(ConfigFile config)
		{
			DebugKeys = config.Bind<bool>("Debug", "EnableDebugKeys", false, "F6: spawn a flat test arena above the map and drive onto it. F7 (host): spawn every custom obstacle ahead of you.");
			VerboseLog = config.Bind<bool>("Debug", "VerboseLog", false, "Log the whole vanilla card catalog, materials and zone settings at startup (for modding).");
			ForceCard = config.Bind<string>("Debug", "ForceCard", "", "Host only. A custom card id (e.g. BumperPillar) forces it into draft slot 0. * fills every slot with custom cards; a comma-separated list (e.g. LongRoad,CurvedRoad) fills every slot from just those. Empty = normal rolls.");
			ForceAffixIndex = config.Bind<int>("Debug", "ForceAffixIndex", 0, "Affix for the forced card: 0 = none, otherwise an index into ObstacleAffixManager's list.");
			CardRegistry.BindConfig(config);
		}
	}
	internal sealed class DataObstacle : CustomObstacle
	{
		private static readonly string Folder = Path.Combine(Path.GetDirectoryName(typeof(Plugin).Assembly.Location), "obstacles");

		private readonly string _id;

		private readonly ObstacleData _data;

		public override string Id => _id;

		public override Guid Guid { get; }

		public override string DisplayName => _data?.name ?? _id;

		public override string Description => _data?.description ?? "<color=#E0204A>Missing data file.</color>";

		public override string ThumbnailFile => Path.Combine("obstacles", _id + ".png");

		public override string FullArtFile
		{
			get
			{
				ObstacleData data = _data;
				if (data == null || !data.fullArt)
				{
					return null;
				}
				return Path.Combine("obstacles", _id + "_card.png");
			}
		}

		public override string PartnerId => _data?.partner;

		public override bool IsPartnerOnly => _data?.partnerOnly ?? false;

		public override string DefaultCarrier => _data?.carrier;

		public override bool KeepCarrier => _data?.keepCarrier ?? false;

		protected override CardRarity DefaultRarity
		{
			get
			{
				if (_data == null || !Enum.TryParse<CardRarity>(_data.rarity, ignoreCase: true, out var result))
				{
					return CardRarity.Common;
				}
				return result;
			}
		}

		public DataObstacle(string id, string guid)
		{
			_id = id;
			Guid = new Guid(guid);
			_data = Load(id);
		}

		internal override void Build(Obstacle obstacle, CarrierParts carrier)
		{
			if (_data == null)
			{
				return;
			}
			if (!string.IsNullOrEmpty(_data.scatter))
			{
				ObstacleScatter val = (ObstacleScatter)(object)((obstacle is ObstacleScatter) ? obstacle : null);
				if (val != null)
				{
					ObstacleDescription val2 = CardRegistry.DescriptionOf(_data.scatter);
					if (Object.op_Implicit((Object)(object)val2))
					{
						val.obstacleToScatter = val2;
					}
					val.count = _data.scatterCount;
				}
			}
			if (_data.surface == "reverse")
			{
				ObstacleSurfaceSwap val3 = (ObstacleSurfaceSwap)(object)((obstacle is ObstacleSurfaceSwap) ? obstacle : null);
				if (val3 != null && Object.op_Implicit((Object)(object)ReverseSurface.Instance))
				{
					val3.surfaceToSwapTo = ReverseSurface.Instance;
				}
			}
			if (_data.nodes.Count > 0)
			{
				DataObstacleBuilder.Build(_id, _data, obstacle, carrier);
			}
		}

		private static ObstacleData Load(string id)
		{
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Expected O, but got Unknown
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			string text = Path.Combine(Folder, id + ".json");
			bool flag = default(bool);
			try
			{
				if (!File.Exists(text))
				{
					ManualLogSource log = Plugin.Log;
					BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(24, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("DataObstacle: ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" not found");
					}
					log.LogError(val);
					return null;
				}
				ObstacleData obstacleData = JsonConvert.DeserializeObject<ObstacleData>(File.ReadAllText(text));
				ManualLogSource log2 = Plugin.Log;
				BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(30, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("DataObstacle: loaded ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(id);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" (");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(obstacleData.nodes.Count);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" nodes)");
				}
				log2.LogInfo(val2);
				return obstacleData;
			}
			catch (Exception ex)
			{
				ManualLogSource log3 = Plugin.Log;
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(30, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("DataObstacle: couldn't read ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
				}
				log3.LogError(val);
				return null;
			}
		}
	}
	internal static class DataObstacleBuilder
	{
		internal static void Build(string id, ObstacleData data, Obstacle obstacle, CarrierParts carrier)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Expected O, but got Unknown
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: 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_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0361: Unknown result type (might be due to invalid IL or missing references)
			//IL_0366: Unknown result type (might be due to invalid IL or missing references)
			//IL_036c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0371: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("CustomContent_" + id);
			val.SetActive(false);
			val.layer = carrier.SolidLayer;
			val.transform.SetParent(((Component)obstacle).transform, false);
			val.transform.localScale = VisualSwap.ToLocal(Vector3.one, carrier);
			int num = LayerMask.NameToLayer("Obstacle");
			if (num < 0)
			{
				num = carrier.TriggerLayer;
			}
			Transform[] array = (Transform[])(object)new Transform[data.nodes.Count];
			for (int i = 0; i < data.nodes.Count; i++)
			{
				NodeData nodeData = data.nodes[i];
				GameObject val2 = new GameObject(nodeData.name ?? $"Node{i}");
				val2.layer = carrier.SolidLayer;
				Transform val3 = ((nodeData.parent >= 0 && nodeData.parent < i) ? array[nodeData.parent] : val.transform);
				val2.transform.SetParent(val3, false);
				val2.transform.localPosition = ToVector(nodeData.pos, Vector3.zero);
				val2.transform.localRotation = ToQuaternion(nodeData.rot);
				val2.transform.localScale = ToVector(nodeData.scale, Vector3.one);
				Transform val4 = val2.transform;
				if (nodeData.anim != null)
				{
					val4 = AddAnimator(val2, nodeData.anim);
				}
				if (nodeData.motion != null)
				{
					val4 = AddMotion(((Component)val4).gameObject, nodeData.motion);
				}
				if (nodeData.timed != null)
				{
					TimedActive timedActive = ((Component)val4).gameObject.AddComponent<TimedActive>();
					timedActive.speed = nodeData.timed.speed;
					timedActive.start = nodeData.timed.start;
					timedActive.end = nodeData.timed.end;
				}
				if (nodeData.effect != null)
				{
					BurstEffect burstEffect = ((Component)val4).gameObject.AddComponent<BurstEffect>();
					burstEffect.channel = nodeData.effect.channel;
					burstEffect.kind = ((nodeData.effect.kind == "teleport") ? BurstEffect.Kind.Teleport : BurstEffect.Kind.Shock);
					burstEffect.consume = nodeData.effect.consume;
				}
				if (nodeData.crumble != null)
				{
					Crumble crumble = ((Component)val4).gameObject.AddComponent<Crumble>();
					crumble.channel = nodeData.crumble.channel;
					crumble.minSpeed = nodeData.crumble.minSpeed;
					crumble.speed = nodeData.crumble.speed;
					crumble.stagger = nodeData.crumble.stagger;
					crumble.settleTime = nodeData.crumble.settleTime;
				}
				array[i] = val4;
				if (nodeData.mesh != null)
				{
					AddMesh(((Component)val4).gameObject, nodeData.mesh, carrier.Material);
				}
				if (nodeData.collider != null)
				{
					Collider collider = AddCollider(((Component)val4).gameObject, nodeData.collider);
					((Component)val4).gameObject.layer = (nodeData.collider.trigger ? num : carrier.SolidLayer);
					if (nodeData.zone != null)
					{
						AddZone(((Component)val4).gameObject, collider, nodeData.zone, obstacle);
					}
				}
			}
			float[][] forbiddenPoints = data.forbiddenPoints;
			if (forbiddenPoints != null && forbiddenPoints.L