Decompiled source of CloudAndBounceFungusPrediction v0.9.3

plugins/CloudFungusPrediction.dll

Decompiled 4 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Peak;
using Photon.Pun;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace CloudFungusPrediction
{
	[HarmonyPatch(typeof(CharacterItems), "Update")]
	public static class BounceFungusPreviewPatch
	{
		private static float _lastChargeForce = -1f;

		public static void Postfix(CharacterItems __instance, Character ___character)
		{
			//IL_00d6: 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)
			if (Plugin.EnableBounceFungusPreview == null || !Plugin.EnableBounceFungusPreview.Value || (Object)(object)__instance == (Object)null || (Object)(object)___character == (Object)null || !___character.IsLocal)
			{
				return;
			}
			Item val = (((Object)(object)___character.data != (Object)null) ? ___character.data.currentItem : null);
			if ((Object)(object)val == (Object)null)
			{
				CloudPreviewRenderer.ClearBounceFungus();
				return;
			}
			ShelfShroom component = ((Component)val).GetComponent<ShelfShroom>();
			if ((Object)(object)component == (Object)null || !component.breakOnCollision || (Object)(object)component.instantiateOnBreak == (Object)null)
			{
				CloudPreviewRenderer.ClearBounceFungus();
				return;
			}
			if (!((Object)(object)___character.input != (Object)null) || !___character.input.dropIsPressed || !(__instance.throwChargeLevel > 0.05f))
			{
				CloudPreviewRenderer.ClearBounceFungus();
				return;
			}
			CaptureChargeForce(__instance);
			if (!ComputeImpact(val, ___character, component, out var impactPoint, out var impactNormal))
			{
				CloudPreviewRenderer.ClearBounceFungus();
			}
			else
			{
				CloudPreviewRenderer.ShowBounceFungus(component, impactPoint, impactNormal);
			}
		}

		public static void Dispose()
		{
			_lastChargeForce = -1f;
			CloudPreviewRenderer.ClearBounceFungus();
		}

		public static bool ComputeImpact(Item item, Character owner, ShelfShroom shelfShroom, out Vector3 impactPoint, out Vector3 impactNormal)
		{
			//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_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_001d: 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_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: 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_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_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: 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_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: 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_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			impactPoint = Vector3.zero;
			impactNormal = Vector3.up;
			Vector3 position = item.transform.position;
			Vector3 val = PreviewMath.LookDirection(owner.data.lookValues) * _lastChargeForce * 0.5f * item.throwForceMultiplier;
			if ((Object)(object)item.rig != (Object)null)
			{
				val += item.rig.linearVelocity;
			}
			if (((Vector3)(ref val)).sqrMagnitude < 0.0001f)
			{
				return false;
			}
			LayerMask predictionMask = PreviewMath.PredictionMask;
			Vector3 val2 = position;
			float fixedDeltaTime = Time.fixedDeltaTime;
			float deltaTime = Time.deltaTime;
			Vector3 val3 = val;
			Vector3 gravity = Physics.gravity;
			float num = (((Object)(object)item.rig != (Object)null) ? item.rig.linearDamping : 0f);
			float num2 = 0f;
			float num3 = 0f;
			float minBreakVelocity = shelfShroom.minBreakVelocity;
			Vector3 val4 = val2;
			int num4 = 0;
			RaycastHit val6 = default(RaycastHit);
			for (int i = 0; i < 300; i++)
			{
				num2 += deltaTime;
				for (num3 += deltaTime; num3 >= fixedDeltaTime; num3 -= fixedDeltaTime)
				{
					val3 += gravity * fixedDeltaTime;
					val3 *= 1f / (1f + num * fixedDeltaTime);
					val2 += val3 * fixedDeltaTime;
				}
				if (++num4 < 3)
				{
					if (val2.y < position.y - 200f)
					{
						return false;
					}
					continue;
				}
				num4 = 0;
				Vector3 val5 = val2 - val4;
				if (((Vector3)(ref val5)).sqrMagnitude > 1E-08f && Physics.Raycast(val4, ((Vector3)(ref val5)).normalized, ref val6, ((Vector3)(ref val5)).magnitude + 0.05f, LayerMask.op_Implicit(predictionMask)) && ((Vector3)(ref val3)).magnitude >= minBreakVelocity)
				{
					impactPoint = ((RaycastHit)(ref val6)).point;
					impactNormal = ((RaycastHit)(ref val6)).normal;
					return true;
				}
				val4 = val2;
				if (val2.y < position.y - 200f)
				{
					return false;
				}
			}
			return false;
		}

		private static void CaptureChargeForce(CharacterItems ci)
		{
			if (!((Object)(object)ci == (Object)null))
			{
				_lastChargeForce = ci.minThrowForce + (ci.maxThrowForce - ci.minThrowForce) * ci.throwChargeLevel;
			}
		}
	}
	public class CloudFungusGroundPreviewFollower : MonoBehaviour
	{
		private Item _item;

		private CloudFungus _fungus;

		private GameObject _preview;

		private Character _thrower;

		private void Awake()
		{
			_item = ((Component)this).GetComponent<Item>();
			_fungus = ((Component)this).GetComponent<CloudFungus>();
		}

		internal void SetThrower(Character thrower)
		{
			_thrower = thrower;
		}

		private void Update()
		{
			//IL_003c: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_item == (Object)null || (Object)(object)_fungus == (Object)null || Plugin.EnableGroundPreview == null || !Plugin.EnableGroundPreview.Value)
			{
				Clear();
				return;
			}
			if ((int)_item.itemState != 0 || (Object)(object)_thrower == (Object)null || !_thrower.IsLocal)
			{
				Clear();
				return;
			}
			if ((Object)(object)_preview == (Object)null)
			{
				_preview = CloudPreviewRenderer.CreateGroundPreview(_fungus);
				if ((Object)(object)_preview == (Object)null)
				{
					return;
				}
			}
			_preview.transform.SetPositionAndRotation(((Component)this).transform.position, Quaternion.identity);
		}

		private void Clear()
		{
			if ((Object)(object)_preview != (Object)null)
			{
				Object.Destroy((Object)(object)_preview);
				_preview = null;
			}
		}

		private void OnDestroy()
		{
			Clear();
		}
	}
	[HarmonyPatch(typeof(Item), "RPC_SetThrownData")]
	public static class ItemThrownPatch
	{
		private static readonly FieldInfo _lastThrownCharacterField = typeof(Item).GetField("lastThrownCharacter", BindingFlags.Instance | BindingFlags.NonPublic);

		public static void Postfix(Item __instance)
		{
			if ((Object)(object)__instance == (Object)null)
			{
				return;
			}
			object? obj = _lastThrownCharacterField?.GetValue(__instance);
			Character val = (Character)((obj is Character) ? obj : null);
			if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)__instance).GetComponent<CloudFungus>() == (Object)null))
			{
				CloudFungusGroundPreviewFollower cloudFungusGroundPreviewFollower = ((Component)__instance).GetComponent<CloudFungusGroundPreviewFollower>();
				if ((Object)(object)cloudFungusGroundPreviewFollower == (Object)null)
				{
					cloudFungusGroundPreviewFollower = ((Component)__instance).gameObject.AddComponent<CloudFungusGroundPreviewFollower>();
				}
				cloudFungusGroundPreviewFollower.SetThrower(val);
			}
		}
	}
	[HarmonyPatch(typeof(CharacterItems), "DoDropping")]
	public static class CloudFungusPredictionPatch
	{
		private static float _currentChargeForce = -1f;

		public static float CurrentChargeForce => _currentChargeForce;

		public static Vector3 CurrentLookDir { get; private set; } = Vector3.forward;

		public static void Postfix(CharacterItems __instance, Character ___character)
		{
			//IL_0022: 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_00ed: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance == (Object)null || (Object)(object)___character == (Object)null || !___character.IsLocal)
			{
				return;
			}
			CaptureChargeForce(__instance);
			CurrentLookDir = LookDirectionOf(___character);
			if (Plugin.EnablePrediction != null && Plugin.EnablePrediction.Value)
			{
				Item val = (((Object)(object)___character.data != (Object)null) ? ___character.data.currentItem : null);
				CloudFungus val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<CloudFungus>() : null);
				Vector3 impactPoint;
				if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null)
				{
					CloudPreviewRenderer.ClearPrediction();
				}
				else if (!((Object)(object)___character.input != (Object)null) || !___character.input.dropIsPressed || !(__instance.throwChargeLevel > 0.01f) || Plugin.EnableInstantPrediction == null || !Plugin.EnableInstantPrediction.Value)
				{
					CloudPreviewRenderer.ClearPrediction();
				}
				else if (PhysicsGhostPreview.IsSuppressingInstant)
				{
					CloudPreviewRenderer.ClearPrediction();
				}
				else if (ComputeImpact(val, ___character, val2, CurrentLookDir, out impactPoint))
				{
					CloudPreviewRenderer.ShowPrediction(impactPoint, val2);
				}
			}
		}

		public static void Dispose()
		{
			_currentChargeForce = -1f;
			CloudPreviewRenderer.ClearPrediction();
			CloudPreviewRenderer.ClearGhostPrediction();
		}

		internal static Vector3 LookDirectionOf(Character character)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)character == (Object)null || (Object)(object)character.data == (Object)null)
			{
				return Vector3.forward;
			}
			return PreviewMath.LookDirection(character.data.lookValues);
		}

		public static bool ComputeImpact(Item item, Character owner, CloudFungus fungus, Vector3 lookDir, out Vector3 impactPoint)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: 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_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: 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_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: 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_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: 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_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0369: Unknown result type (might be due to invalid IL or missing references)
			//IL_036b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0387: Unknown result type (might be due to invalid IL or missing references)
			//IL_038e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0372: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_037e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0380: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_0295: Unknown result type (might be due to invalid IL or missing references)
			//IL_029a: Unknown result type (might be due to invalid IL or missing references)
			//IL_029f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0301: Unknown result type (might be due to invalid IL or missing references)
			//IL_0303: Unknown result type (might be due to invalid IL or missing references)
			//IL_0308: Unknown result type (might be due to invalid IL or missing references)
			//IL_030d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0311: Unknown result type (might be due to invalid IL or missing references)
			//IL_0318: Unknown result type (might be due to invalid IL or missing references)
			//IL_0325: Unknown result type (might be due to invalid IL or missing references)
			//IL_032a: Unknown result type (might be due to invalid IL or missing references)
			//IL_032f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_035d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0362: Unknown result type (might be due to invalid IL or missing references)
			//IL_034b: Unknown result type (might be due to invalid IL or missing references)
			//IL_034d: Unknown result type (might be due to invalid IL or missing references)
			impactPoint = Vector3.zero;
			float num = (((Object)(object)fungus != (Object)null) ? fungus.timeAliveNeeded : 0.5f);
			float num2 = (((Object)(object)fungus != (Object)null) ? fungus.yVelocityNeeded : (-1f));
			Vector3 position = item.transform.position;
			Vector3 val = lookDir * _currentChargeForce * 0.5f * item.throwForceMultiplier;
			if ((Object)(object)item.rig != (Object)null)
			{
				val += item.rig.linearVelocity;
			}
			if (((Vector3)(ref val)).sqrMagnitude < 0.0001f)
			{
				return false;
			}
			LayerMask predictionMask = PreviewMath.PredictionMask;
			Vector3 val2 = position;
			float fixedDeltaTime = Time.fixedDeltaTime;
			float deltaTime = Time.deltaTime;
			Vector3 val3 = val;
			Vector3 gravity = Physics.gravity;
			float num3 = (((Object)(object)item.rig != (Object)null) ? item.rig.linearDamping : 0f);
			float num4 = 0f;
			float num5 = 0f;
			float itemRadius = GetItemRadius(item);
			float itemBounciness = GetItemBounciness(item);
			float itemFriction = GetItemFriction(item);
			Vector3 val4 = val2;
			int num6 = 0;
			int num7 = 0;
			RaycastHit val6 = default(RaycastHit);
			for (int i = 0; i < 300; i++)
			{
				num4 += deltaTime;
				for (num5 += deltaTime; num5 >= fixedDeltaTime; num5 -= fixedDeltaTime)
				{
					val3 += gravity * fixedDeltaTime;
					val3 *= 1f / (1f + num3 * fixedDeltaTime);
					val2 += val3 * fixedDeltaTime;
				}
				if (++num6 < 3)
				{
					if (num4 > num && val3.y < num2)
					{
						impactPoint = val2;
						return true;
					}
					if (val2.y < position.y - 200f)
					{
						return false;
					}
					continue;
				}
				num6 = 0;
				Vector3 val5 = val2 - val4;
				if (((Vector3)(ref val5)).sqrMagnitude > 1E-08f && Physics.SphereCast(val4, itemRadius, ((Vector3)(ref val5)).normalized, ref val6, ((Vector3)(ref val5)).magnitude + 0.05f, LayerMask.op_Implicit(predictionMask), (QueryTriggerInteraction)1) && !IsSelfCollider(((RaycastHit)(ref val6)).collider, item, owner))
				{
					bool flag = ((RaycastHit)(ref val6)).normal.y > 0.5f;
					if (num4 > num && val3.y < num2)
					{
						impactPoint = ((RaycastHit)(ref val6)).point;
						return true;
					}
					float num8 = (itemBounciness + GetHitBounciness(((RaycastHit)(ref val6)).collider)) * 0.5f;
					float num9 = (itemFriction + GetHitFriction(((RaycastHit)(ref val6)).collider)) * 0.5f;
					float num10 = Vector3.Dot(val3, ((RaycastHit)(ref val6)).normal);
					if (Mathf.Abs(num10) < Physics.bounceThreshold)
					{
						num8 = 0f;
					}
					Vector3 val7 = num10 * ((RaycastHit)(ref val6)).normal;
					Vector3 val8 = val3 - val7;
					float magnitude = ((Vector3)(ref val8)).magnitude;
					if (magnitude > 0.0001f)
					{
						float num11 = (1f + num8) * Mathf.Max(0f, 0f - num10);
						float num12 = Mathf.Min(num9 * num11, magnitude);
						val8 -= val8 / magnitude * num12;
					}
					val3 = val8 - num8 * val7;
					val2 = ((RaycastHit)(ref val6)).point + ((RaycastHit)(ref val6)).normal * (itemRadius + 0.02f);
					num7++;
					if (flag && ((Vector3)(ref val3)).sqrMagnitude < 0.25f)
					{
						impactPoint = val2;
						return true;
					}
					if (num7 >= 8)
					{
						impactPoint = ((RaycastHit)(ref val6)).point;
						return true;
					}
				}
				val4 = val2;
				if (num4 > num && val3.y < num2)
				{
					impactPoint = val2;
					return true;
				}
				if (val2.y < position.y - 200f)
				{
					return false;
				}
			}
			return false;
		}

		internal static float GetItemBounciness(Item item)
		{
			return GetItemMaterialValue(item, bounciness: true);
		}

		internal static float GetItemFriction(Item item)
		{
			return GetItemMaterialValue(item, bounciness: false);
		}

		private static float GetItemMaterialValue(Item item, bool bounciness)
		{
			float result = (bounciness ? 0f : 0.6f);
			if ((Object)(object)item == (Object)null || item.colliders == null)
			{
				return result;
			}
			bool flag = false;
			float num = 0f;
			for (int i = 0; i < item.colliders.Length; i++)
			{
				Collider val = item.colliders[i];
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val.sharedMaterial == (Object)null))
				{
					float num2 = (bounciness ? val.sharedMaterial.bounciness : val.sharedMaterial.dynamicFriction);
					if (!flag || num2 > num)
					{
						num = num2;
					}
					flag = true;
				}
			}
			if (!flag)
			{
				return result;
			}
			if (!bounciness)
			{
				return Mathf.Clamp(num, 0f, 2f);
			}
			return Mathf.Clamp01(num);
		}

		internal static float GetHitBounciness(Collider col)
		{
			if ((Object)(object)col != (Object)null && (Object)(object)col.sharedMaterial != (Object)null)
			{
				return Mathf.Clamp01(col.sharedMaterial.bounciness);
			}
			return 0f;
		}

		internal static float GetHitFriction(Collider col)
		{
			if ((Object)(object)col != (Object)null && (Object)(object)col.sharedMaterial != (Object)null)
			{
				return Mathf.Clamp(col.sharedMaterial.dynamicFriction, 0f, 2f);
			}
			return 0.6f;
		}

		internal static float GetItemRadius(Item item)
		{
			//IL_0055: 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_005b: 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_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: 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_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			float num = 0f;
			if ((Object)(object)item != (Object)null && item.colliders != null)
			{
				for (int i = 0; i < item.colliders.Length; i++)
				{
					Collider val = item.colliders[i];
					if ((Object)(object)val == (Object)null || val.isTrigger || !val.enabled)
					{
						continue;
					}
					Vector3 lossyScale = ((Component)val).transform.lossyScale;
					float num2 = Mathf.Max(Mathf.Abs(lossyScale.x), Mathf.Max(Mathf.Abs(lossyScale.y), Mathf.Abs(lossyScale.z)));
					SphereCollider val2 = (SphereCollider)(object)((val is SphereCollider) ? val : null);
					float num3;
					if (val2 != null)
					{
						num3 = val2.radius * num2;
					}
					else
					{
						CapsuleCollider val3 = (CapsuleCollider)(object)((val is CapsuleCollider) ? val : null);
						if (val3 != null)
						{
							num3 = val3.radius * num2;
						}
						else
						{
							BoxCollider val4 = (BoxCollider)(object)((val is BoxCollider) ? val : null);
							if (val4 != null)
							{
								num3 = Mathf.Min(val4.size.x, Mathf.Min(val4.size.y, val4.size.z)) * 0.5f * num2;
							}
							else
							{
								Bounds bounds = val.bounds;
								Vector3 extents = ((Bounds)(ref bounds)).extents;
								num3 = Mathf.Min(extents.x, Mathf.Min(extents.y, extents.z));
							}
						}
					}
					if (num3 > num)
					{
						num = num3;
					}
				}
			}
			if (num < 0.02f)
			{
				num = 0.12f;
			}
			return Mathf.Clamp(num, 0.05f, 0.3f);
		}

		private static bool IsSelfCollider(Collider collider, Item item, Character owner)
		{
			if ((Object)(object)collider == (Object)null)
			{
				return true;
			}
			Transform transform = ((Component)collider).transform;
			if ((Object)(object)item != (Object)null && ((Object)(object)transform == (Object)(object)item.transform || transform.IsChildOf(item.transform)))
			{
				return true;
			}
			if ((Object)(object)owner != (Object)null && ((Object)(object)transform == (Object)(object)((Component)owner).transform || transform.IsChildOf(((Component)owner).transform)))
			{
				return true;
			}
			return false;
		}

		private static void CaptureChargeForce(CharacterItems ci)
		{
			if (!((Object)(object)ci == (Object)null))
			{
				_currentChargeForce = ci.minThrowForce + (ci.maxThrowForce - ci.minThrowForce) * ci.throwChargeLevel;
			}
		}
	}
	public static class CloudPreviewRenderer
	{
		private static GameObject _predictionPreview;

		private static GameObject _ghostPredictionPreview;

		private static GameObject _bounceFungusPreview;

		private static float _randomYRotation;

		private static readonly Random _rng = new Random();

		private static float GhostTransparency
		{
			get
			{
				if (!((Object)(object)Plugin.Instance != (Object)null) || Plugin.GhostTransparency == null)
				{
					return 0.85f;
				}
				return Plugin.GhostTransparency.Value;
			}
		}

		public static GameObject CreateGroundPreview(CloudFungus fungus)
		{
			if ((Object)(object)fungus == (Object)null || (Object)(object)fungus.instantiateOnBreak == (Object)null)
			{
				return null;
			}
			GameObject val = CreateCloudPreview(fungus.instantiateOnBreak);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			((Object)val).name = "CloudFungusGroundPreview";
			ApplyTransparency(val);
			return val;
		}

		public static void ShowPrediction(Vector3 position, CloudFungus fungus)
		{
			//IL_0057: 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)
			if ((Object)(object)fungus == (Object)null || (Object)(object)fungus.instantiateOnBreak == (Object)null)
			{
				return;
			}
			if ((Object)(object)_predictionPreview == (Object)null)
			{
				_predictionPreview = CreateCloudPreview(fungus.instantiateOnBreak);
				if ((Object)(object)_predictionPreview == (Object)null)
				{
					return;
				}
				ApplyTransparency(_predictionPreview);
			}
			_predictionPreview.transform.SetPositionAndRotation(position, Quaternion.identity);
		}

		public static void ClearPrediction()
		{
			if ((Object)(object)_predictionPreview != (Object)null)
			{
				Object.Destroy((Object)(object)_predictionPreview);
				_predictionPreview = null;
			}
		}

		public static void ShowGhostPrediction(Vector3 position, CloudFungus fungus)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)fungus == (Object)null))
			{
				ShowGhostPrediction(position, fungus.instantiateOnBreak);
			}
		}

		public static void ShowGhostPrediction(Vector3 position, GameObject breakPrefab)
		{
			//IL_0058: 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)
			if ((Object)(object)breakPrefab == (Object)null)
			{
				return;
			}
			if ((Object)(object)_ghostPredictionPreview == (Object)null)
			{
				_ghostPredictionPreview = CreateCloudPreview(breakPrefab);
				if ((Object)(object)_ghostPredictionPreview == (Object)null)
				{
					return;
				}
				((Object)_ghostPredictionPreview).name = "CloudFungusGhostPrediction";
				ApplyTransparency(_ghostPredictionPreview, GhostTransparency);
			}
			_ghostPredictionPreview.transform.SetPositionAndRotation(position, Quaternion.identity);
		}

		public static void ClearGhostPrediction()
		{
			if ((Object)(object)_ghostPredictionPreview != (Object)null)
			{
				Object.Destroy((Object)(object)_ghostPredictionPreview);
				_ghostPredictionPreview = null;
			}
		}

		public static void ShowBounceFungus(ShelfShroom shelfShroom, Vector3 position, Vector3 normal)
		{
			//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_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_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: 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)
			if ((Object)(object)shelfShroom == (Object)null || (Object)(object)shelfShroom.instantiateOnBreak == (Object)null)
			{
				return;
			}
			if ((Object)(object)_bounceFungusPreview == (Object)null)
			{
				_randomYRotation = (float)(_rng.NextDouble() * 360.0);
				_bounceFungusPreview = CreateBounceFungusPreview(shelfShroom);
				if ((Object)(object)_bounceFungusPreview == (Object)null)
				{
					return;
				}
				ApplyTransparency(_bounceFungusPreview);
			}
			Quaternion val = ((!shelfShroom.stickToNormal) ? Quaternion.Euler(0f, _randomYRotation, 0f) : Quaternion.LookRotation(Vector3.forward, normal));
			_bounceFungusPreview.transform.SetPositionAndRotation(position, val);
		}

		public static void ClearBounceFungus()
		{
			if ((Object)(object)_bounceFungusPreview != (Object)null)
			{
				Object.Destroy((Object)(object)_bounceFungusPreview);
				_bounceFungusPreview = null;
			}
		}

		public static void Dispose()
		{
			ClearPrediction();
			ClearGhostPrediction();
			ClearBounceFungus();
		}

		private static GameObject CreateCloudPreview(GameObject breakPrefab)
		{
			if ((Object)(object)breakPrefab == (Object)null)
			{
				return null;
			}
			GameObject obj = Object.Instantiate<GameObject>(breakPrefab, CloudPreviewRoot.Root);
			((Object)obj).name = "CloudFungusPrediction";
			Cleanup(obj);
			return obj;
		}

		private static GameObject CreateBounceFungusPreview(ShelfShroom shelfShroom)
		{
			if ((Object)(object)shelfShroom.instantiateOnBreak == (Object)null)
			{
				return null;
			}
			GameObject obj = Object.Instantiate<GameObject>(shelfShroom.instantiateOnBreak, CloudPreviewRoot.Root);
			((Object)obj).name = "BounceFungusPreview";
			Cleanup(obj);
			return obj;
		}

		private static void Cleanup(GameObject preview)
		{
			PhotonCleanupHelper component = preview.GetComponent<PhotonCleanupHelper>();
			if ((Object)(object)component != (Object)null)
			{
				Object.Destroy((Object)(object)component);
			}
			Collider[] componentsInChildren = preview.GetComponentsInChildren<Collider>();
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Object.Destroy((Object)(object)componentsInChildren[i]);
			}
			Component[] componentsInChildren2 = preview.GetComponentsInChildren<Component>();
			foreach (Component val in componentsInChildren2)
			{
				if (((object)val).GetType().Name == "AudioSource")
				{
					Behaviour val2 = (Behaviour)(object)((val is Behaviour) ? val : null);
					if (val2 != null)
					{
						val2.enabled = false;
					}
				}
			}
			Rigidbody[] componentsInChildren3 = preview.GetComponentsInChildren<Rigidbody>();
			for (int i = 0; i < componentsInChildren3.Length; i++)
			{
				componentsInChildren3[i].isKinematic = true;
			}
		}

		internal static void ApplyTransparency(GameObject preview)
		{
			float transparency = (((Object)(object)Plugin.Instance != (Object)null && Plugin.PreviewTransparency != null) ? Plugin.PreviewTransparency.Value : 0.6f);
			ApplyTransparency(preview, transparency);
		}

		internal static void ApplyTransparency(GameObject preview, float transparency)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			if (transparency >= 0.99f)
			{
				return;
			}
			Renderer[] componentsInChildren = preview.GetComponentsInChildren<Renderer>();
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Material material = componentsInChildren[i].material;
				if (material.HasProperty("_Color"))
				{
					Color color = material.color;
					color.a = transparency;
					material.color = color;
				}
			}
		}
	}
	public static class CloudPreviewRoot
	{
		private static GameObject _root;

		public static Transform Root
		{
			get
			{
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: Expected O, but got Unknown
				if ((Object)(object)_root == (Object)null)
				{
					_root = new GameObject("CloudFungusPrediction.PreviewRoot");
					Object.DontDestroyOnLoad((Object)(object)_root);
				}
				return _root.transform;
			}
		}

		public static void Dispose()
		{
			if ((Object)(object)_root != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)_root);
				_root = null;
			}
		}
	}
	public static class ColoredLogging
	{
		private static readonly MethodInfo SetConsoleColorMethod;

		private static readonly TextWriter ConsoleStream;

		static ColoredLogging()
		{
			Type type = typeof(BaseUnityPlugin).Assembly.GetType("BepInEx.ConsoleManager");
			if (type != null)
			{
				SetConsoleColorMethod = type.GetMethod("SetConsoleColor", BindingFlags.Static | BindingFlags.Public);
				ConsoleStream = type.GetProperty("ConsoleStream", BindingFlags.Static | BindingFlags.Public)?.GetValue(null) as TextWriter;
			}
		}

		private static void SetColor(ConsoleColor color)
		{
			SetConsoleColorMethod?.Invoke(null, new object[1] { color });
		}

		private static void WriteColored(string message, ConsoleColor color, bool newline = true)
		{
			if (ConsoleStream != null)
			{
				SetColor(color);
				if (newline)
				{
					ConsoleStream.WriteLine(message);
				}
				else
				{
					ConsoleStream.Write(message);
				}
				SetColor(ConsoleColor.Gray);
			}
		}

		public static void LogColor(this ManualLogSource log, string message, ConsoleColor color = ConsoleColor.Gray)
		{
			WriteColored(message, color);
		}

		public static void LogColorW(this ManualLogSource log, string message, ConsoleColor color = ConsoleColor.Yellow)
		{
			WriteColored(message, color);
		}

		public static void LogColorE(this ManualLogSource log, string message, ConsoleColor color = ConsoleColor.Red)
		{
			WriteColored(message, color);
		}

		public static void LogColorS(this ManualLogSource log, string message, ConsoleColor color = ConsoleColor.Green)
		{
			WriteColored(message, color);
		}

		public static void LogColorM(this ManualLogSource log, string message, ConsoleColor color = ConsoleColor.Magenta)
		{
			WriteColored(message, color);
		}

		public static void LogColorC(this ManualLogSource log, string message, ConsoleColor color = ConsoleColor.Cyan)
		{
			WriteColored(message, color);
		}
	}
	public class GhostPreviewBinder : MonoBehaviour
	{
		private bool _wasDown;

		private void Update()
		{
			if ((Object)(object)Plugin.Instance == (Object)null || Plugin.EnablePhysicsGhost == null || !Plugin.EnablePhysicsGhost.Value)
			{
				if (PhysicsGhostPreview.IsActive)
				{
					PhysicsGhostPreview.StopGhost("物理幽灵功能已关闭");
				}
				if (WarpGhostPreview.IsActive)
				{
					WarpGhostPreview.StopGhost("物理幽灵功能已关闭");
				}
				_wasDown = false;
			}
			else
			{
				bool flag = IsPreviewKeyHeld();
				if (flag && !_wasDown)
				{
					StartGhost();
				}
				_wasDown = flag;
				PhysicsGhostPreview.Tick(flag);
				WarpGhostPreview.Tick(flag);
			}
		}

		private static bool IsPreviewKeyHeld()
		{
			//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_0016: 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_0034: Unknown result type (might be due to invalid IL or missing references)
			if (Plugin.PreviewKey == null)
			{
				return false;
			}
			KeyboardShortcut value = Plugin.PreviewKey.Value;
			if ((int)((KeyboardShortcut)(ref value)).MainKey == 0)
			{
				return false;
			}
			IEnumerable<KeyCode> modifiers = ((KeyboardShortcut)(ref value)).Modifiers;
			if (modifiers != null)
			{
				foreach (KeyCode item in modifiers)
				{
					if (!IsKeyHeld(item))
					{
						return false;
					}
				}
			}
			return IsKeyHeld(((KeyboardShortcut)(ref value)).MainKey);
		}

		private static bool IsKeyHeld(KeyCode key)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			if ((int)key == 0)
			{
				return false;
			}
			try
			{
				IInputSystem current = UnityInput.Current;
				return current != null && current.GetKey(key);
			}
			catch
			{
				return false;
			}
		}

		private static void StartGhost()
		{
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			Character val = LocalCharacter();
			if ((Object)(object)val == (Object)null || (Object)(object)val.data == (Object)null)
			{
				return;
			}
			Item val2 = HeldItem(val);
			if ((Object)(object)val2 == (Object)null)
			{
				return;
			}
			WarpOnThrow component = ((Component)val2).GetComponent<WarpOnThrow>();
			if ((Object)(object)component != (Object)null)
			{
				if (Plugin.EnableWarpFungusPreview != null && Plugin.EnableWarpFungusPreview.Value)
				{
					PhysicsGhostPreview.StopGhost("切换到曲迁菇");
					WarpGhostPreview.StartGhost(val2, component, CloudFungusPredictionPatch.CurrentLookDir, CloudFungusPredictionPatch.CurrentChargeForce);
				}
				return;
			}
			CloudFungus component2 = ((Component)val2).GetComponent<CloudFungus>();
			if ((Object)(object)component2 != (Object)null)
			{
				WarpGhostPreview.StopGhost("切换到云雾菇");
				PhysicsGhostPreview.StartGhost(val2, component2, CloudFungusPredictionPatch.CurrentLookDir, CloudFungusPredictionPatch.CurrentChargeForce);
			}
		}

		private static Item HeldItem(Character character)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Invalid comparison between Unknown and I4
			if ((Object)(object)character == (Object)null || (Object)(object)character.data == (Object)null)
			{
				return null;
			}
			Item currentItem = character.data.currentItem;
			if ((Object)(object)currentItem != (Object)null)
			{
				return currentItem;
			}
			List<Item> aLL_ITEMS = Item.ALL_ITEMS;
			if (aLL_ITEMS == null)
			{
				return null;
			}
			for (int i = 0; i < aLL_ITEMS.Count; i++)
			{
				Item val = aLL_ITEMS[i];
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val.holderCharacter != (Object)(object)character) && (int)val.itemState == 1)
				{
					return val;
				}
			}
			return null;
		}

		private static Character LocalCharacter()
		{
			Character localCharacter = Character.localCharacter;
			if ((Object)(object)localCharacter != (Object)null)
			{
				return localCharacter;
			}
			Player localPlayer = Player.localPlayer;
			if (!((Object)(object)localPlayer != (Object)null))
			{
				return null;
			}
			return localPlayer.character;
		}

		private void OnDestroy()
		{
			PhysicsGhostPreview.StopGhost("组件销毁");
			WarpGhostPreview.StopGhost("组件销毁");
		}
	}
	internal static class PhysicsGhostPreview
	{
		private const float MaxFlightTime = 8f;

		private const float RestSpeed = 0.6f;

		private const float RestHoldTime = 0.3f;

		private const int MaxTrailPoints = 512;

		private static readonly Color TrailColor = new Color(0.35f, 0.9f, 1f, 0.9f);

		private static readonly FieldInfo _timeAliveNeededField = typeof(CloudFungus).GetField("timeAliveNeeded", BindingFlags.Instance | BindingFlags.Public);

		private static readonly FieldInfo _yVelocityNeededField = typeof(CloudFungus).GetField("yVelocityNeeded", BindingFlags.Instance | BindingFlags.Public);

		private static GameObject _ghost;

		private static Rigidbody _rig;

		private static Item _sourceItem;

		private static CloudFungus _sourceFungus;

		private static GameObject _breakPrefab;

		private static float _breakTime = 0.5f;

		private static float _breakYVel = -1f;

		private static float _launchOriginY;

		private static float _flightTime;

		private static float _restTime;

		private static bool _finished;

		private static bool _unavailable;

		private static float _releaseTime = -1f;

		private static LineRenderer _trail;

		private static int _trailPoints;

		public static bool IsActive => (Object)(object)_ghost != (Object)null;

		public static bool IsSuppressingInstant
		{
			get
			{
				if ((Object)(object)_ghost == (Object)null)
				{
					return false;
				}
				if (Plugin.HideInstantWhilePreviewing == null || !Plugin.HideInstantWhilePreviewing.Value)
				{
					return false;
				}
				if (_releaseTime < 0f)
				{
					return true;
				}
				return Time.time - _releaseTime < RestoreInstantDelayValue;
			}
		}

		private static float RemoveGhostDelayValue
		{
			get
			{
				if (Plugin.RemoveGhostDelay == null)
				{
					return 0f;
				}
				return Mathf.Max(0f, Plugin.RemoveGhostDelay.Value);
			}
		}

		private static float RestoreInstantDelayValue
		{
			get
			{
				if (Plugin.RestoreInstantDelay == null)
				{
					return 0f;
				}
				return Mathf.Max(0f, Plugin.RestoreInstantDelay.Value);
			}
		}

		public static bool StartGhost(Item item, CloudFungus fungus, Vector3 lookDir, float chargeForce)
		{
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			if (_unavailable)
			{
				return false;
			}
			if ((Object)(object)item == (Object)null || (Object)(object)fungus == (Object)null)
			{
				return false;
			}
			if (!EnsureGhost(item, fungus))
			{
				return false;
			}
			if ((Object)(object)_ghost == (Object)null || (Object)(object)_rig == (Object)null)
			{
				return false;
			}
			_breakPrefab = fungus.instantiateOnBreak;
			_breakTime = (float)(_timeAliveNeededField?.GetValue(fungus) ?? ((object)0.5f));
			_breakYVel = (float)(_yVelocityNeededField?.GetValue(fungus) ?? ((object)(-1f)));
			((Vector3)(ref lookDir)).Normalize();
			Launch(item, lookDir, chargeForce);
			return true;
		}

		public static void Tick(bool keyHeld)
		{
			//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_0088: 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_008e: 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_00a7: 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_00c8: 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_0106: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_ghost == (Object)null || (Object)(object)_rig == (Object)null)
			{
				return;
			}
			if (!keyHeld)
			{
				if (_releaseTime < 0f)
				{
					_releaseTime = Time.time;
				}
				if (Time.time - _releaseTime >= RemoveGhostDelayValue)
				{
					StopGhost("松开预览键");
				}
				return;
			}
			_releaseTime = -1f;
			if (_finished)
			{
				return;
			}
			_flightTime += Time.deltaTime;
			Vector3 position = _ghost.transform.position;
			Vector3 linearVelocity = _rig.linearVelocity;
			AppendTrail(position);
			if (position.y < _launchOriginY - 1500f)
			{
				Finish(position, showPreview: false);
				return;
			}
			if (_flightTime > _breakTime && linearVelocity.y < _breakYVel)
			{
				Finish(position, showPreview: true);
				return;
			}
			if (((Vector3)(ref linearVelocity)).sqrMagnitude < 0.36f)
			{
				_restTime += Time.deltaTime;
				if (_flightTime > _breakTime && _restTime >= 0.3f)
				{
					Finish(position, showPreview: true);
					return;
				}
			}
			else
			{
				_restTime = 0f;
			}
			if (_flightTime > 8f)
			{
				Finish(position, showPreview: false);
			}
		}

		public static void StopGhost(string reason = null)
		{
			Clear();
			CloudPreviewRenderer.ClearGhostPrediction();
		}

		public static void Dispose()
		{
			StopGhost("插件卸载");
			if ((Object)(object)_trail != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)_trail).gameObject);
				_trail = null;
			}
			_unavailable = false;
		}

		private static void Clear()
		{
			EndTrail();
			if ((Object)(object)_ghost != (Object)null)
			{
				Object.Destroy((Object)(object)_ghost);
			}
			_ghost = null;
			_rig = null;
			_sourceItem = null;
			_sourceFungus = null;
			_breakPrefab = null;
			_breakTime = 0.5f;
			_breakYVel = -1f;
			_launchOriginY = 0f;
			_flightTime = 0f;
			_restTime = 0f;
			_finished = false;
			_releaseTime = -1f;
		}

		private static bool EnsureGhost(Item item, CloudFungus fungus)
		{
			if ((Object)(object)_ghost != (Object)null && (Object)(object)_sourceItem == (Object)(object)item && (Object)(object)_sourceFungus == (Object)(object)fungus)
			{
				return true;
			}
			Clear();
			if (!CreateGhost(item, fungus))
			{
				return false;
			}
			_sourceItem = item;
			_sourceFungus = fungus;
			return true;
		}

		private static bool CreateGhost(Item item, CloudFungus fungus)
		{
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = FindPrefab(item);
			if ((Object)(object)val == (Object)null)
			{
				return Unavailable("找不到物品 prefab(Resources.Load(\"0_Items/" + PrefabNameOf(item) + "\") 失败)");
			}
			GameObject val2 = Object.Instantiate<GameObject>(val, CloudPreviewRoot.Root);
			if ((Object)(object)val2 == (Object)null)
			{
				return Unavailable("克隆 prefab 失败");
			}
			((Object)val2).name = "CloudFungusPhysicsGhost";
			PhotonView[] componentsInChildren = val2.GetComponentsInChildren<PhotonView>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren[i]);
			}
			PhotonCleanupHelper[] componentsInChildren2 = val2.GetComponentsInChildren<PhotonCleanupHelper>(true);
			for (int i = 0; i < componentsInChildren2.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren2[i]);
			}
			MonoBehaviour[] componentsInChildren3 = val2.GetComponentsInChildren<MonoBehaviour>(true);
			foreach (MonoBehaviour val3 in componentsInChildren3)
			{
				if ((Object)(object)val3 != (Object)null)
				{
					((Behaviour)val3).enabled = false;
				}
			}
			Collider[] componentsInChildren4 = val2.GetComponentsInChildren<Collider>(true);
			foreach (Collider obj in componentsInChildren4)
			{
				obj.enabled = true;
				obj.isTrigger = false;
			}
			Renderer[] componentsInChildren5 = val2.GetComponentsInChildren<Renderer>(true);
			for (int i = 0; i < componentsInChildren5.Length; i++)
			{
				componentsInChildren5[i].enabled = true;
			}
			Rigidbody val4 = val2.GetComponent<Rigidbody>();
			if ((Object)(object)val4 == (Object)null)
			{
				val4 = val2.AddComponent<Rigidbody>();
			}
			val4.mass = item.mass;
			val4.useGravity = true;
			val4.isKinematic = true;
			val4.interpolation = (RigidbodyInterpolation)1;
			val4.collisionDetectionMode = (CollisionDetectionMode)2;
			if ((Object)(object)item.rig != (Object)null)
			{
				val4.linearDamping = item.rig.linearDamping;
				val4.angularDamping = item.rig.angularDamping;
				val4.maxAngularVelocity = item.rig.maxAngularVelocity;
				val4.centerOfMass = item.rig.centerOfMass;
			}
			int mask = LayerMask.GetMask(new string[3] { "Terrain", "Map", "Default" });
			val4.excludeLayers = LayerMask.op_Implicit(~mask);
			val2.transform.localScale = item.transform.localScale;
			val2.SetActive(false);
			CloudPreviewRenderer.ApplyTransparency(val2, (Plugin.GhostTransparency != null) ? Plugin.GhostTransparency.Value : 0.85f);
			_ghost = val2;
			_rig = val4;
			return true;
		}

		private static void Launch(Item item, Vector3 lookDir, float chargeForce)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0033: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: 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_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: 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_00ca: 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_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_ghost == (Object)null) && !((Object)(object)_rig == (Object)null))
			{
				Vector3 position = item.transform.position;
				Quaternion rotation = item.transform.rotation;
				_launchOriginY = position.y;
				_ghost.transform.SetPositionAndRotation(position, rotation);
				_ghost.SetActive(true);
				_rig.isKinematic = false;
				_rig.detectCollisions = true;
				_rig.WakeUp();
				_rig.linearVelocity = lookDir * chargeForce * 0.5f * item.throwForceMultiplier + (((Object)(object)item.rig != (Object)null) ? item.rig.linearVelocity : Vector3.zero);
				_rig.angularVelocity = Vector3.Cross(lookDir, Vector3.up) * chargeForce * 0.5f;
				_flightTime = 0f;
				_restTime = 0f;
				_finished = false;
				BeginTrail(position);
				CloudPreviewRenderer.ClearGhostPrediction();
			}
		}

		private static void Finish(Vector3 pos, bool showPreview)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: 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_0067: Unknown result type (might be due to invalid IL or missing references)
			_finished = true;
			AppendTrail(pos);
			if ((Object)(object)_rig != (Object)null)
			{
				_rig.linearVelocity = Vector3.zero;
				_rig.angularVelocity = Vector3.zero;
				_rig.isKinematic = true;
				_rig.detectCollisions = false;
			}
			if (showPreview)
			{
				if ((Object)(object)_ghost != (Object)null)
				{
					_ghost.transform.position = pos;
				}
				CloudPreviewRenderer.ShowGhostPrediction(pos, _breakPrefab);
			}
			else if ((Object)(object)_ghost != (Object)null)
			{
				_ghost.SetActive(false);
			}
		}

		private static void BeginTrail(Vector3 origin)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			EnsureTrail();
			if (!((Object)(object)_trail == (Object)null))
			{
				((Component)_trail).gameObject.SetActive(true);
				_trail.positionCount = 1;
				_trail.SetPosition(0, origin);
				_trailPoints = 1;
			}
		}

		private static void AppendTrail(Vector3 pos)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_trail == (Object)null) && ((Component)_trail).gameObject.activeSelf && _trailPoints < 512)
			{
				_trail.positionCount = _trailPoints + 1;
				_trail.SetPosition(_trailPoints, pos);
				_trailPoints++;
			}
		}

		private static void EndTrail()
		{
			if (!((Object)(object)_trail == (Object)null))
			{
				((Component)_trail).gameObject.SetActive(false);
				_trail.positionCount = 0;
				_trailPoints = 0;
			}
		}

		private static void EnsureTrail()
		{
			//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_0029: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_trail != (Object)null))
			{
				GameObject val = new GameObject("CloudFungusGhostTrail");
				val.transform.SetParent(CloudPreviewRoot.Root, false);
				LineRenderer val2 = val.AddComponent<LineRenderer>();
				val2.useWorldSpace = true;
				val2.positionCount = 0;
				val2.startWidth = 0.08f;
				val2.endWidth = 0.08f;
				val2.numCapVertices = 2;
				val2.numCornerVertices = 2;
				((Renderer)val2).shadowCastingMode = (ShadowCastingMode)0;
				((Renderer)val2).receiveShadows = false;
				val2.startColor = TrailColor;
				val2.endColor = TrailColor;
				val2.alignment = (LineAlignment)0;
				Material val3 = CreateTrailMaterial();
				if ((Object)(object)val3 != (Object)null)
				{
					((Renderer)val2).material = val3;
				}
				val.SetActive(false);
				_trail = val2;
				_trailPoints = 0;
			}
		}

		private static Material CreateTrailMaterial()
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			//IL_005a: 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)
			string[] array = new string[5] { "Sprites/Default", "UI/Default", "Universal Render Pipeline/Unlit", "Unlit/Color", "Legacy Shaders/Particles/Alpha Blended Premultiply" };
			for (int i = 0; i < array.Length; i++)
			{
				Shader val = Shader.Find(array[i]);
				if (!((Object)(object)val == (Object)null))
				{
					Material val2 = new Material(val);
					if (val2.HasProperty("_Color"))
					{
						val2.color = TrailColor;
					}
					if (val2.HasProperty("_BaseColor"))
					{
						val2.SetColor("_BaseColor", TrailColor);
					}
					return val2;
				}
			}
			return null;
		}

		private static GameObject FindPrefab(Item item)
		{
			string text = PrefabNameOf(item);
			GameObject val = Resources.Load<GameObject>("0_Items/" + text);
			if ((Object)(object)val != (Object)null && (Object)(object)val.GetComponent<CloudFungus>() != (Object)null)
			{
				return val;
			}
			val = Resources.Load<GameObject>(text);
			if ((Object)(object)val != (Object)null && (Object)(object)val.GetComponent<CloudFungus>() != (Object)null)
			{
				return val;
			}
			return null;
		}

		private static string PrefabNameOf(Item item)
		{
			if ((Object)(object)item == (Object)null)
			{
				return null;
			}
			string text = ((Object)((Component)item).gameObject).name;
			if (text.EndsWith("(Clone)"))
			{
				text = text.Substring(0, text.Length - "(Clone)".Length);
			}
			return text;
		}

		private static bool Unavailable(string reason)
		{
			_unavailable = true;
			return false;
		}
	}
	public static class PluginInfo
	{
		public const string Guid = "CloudFungusPrediction";

		public const string Name = "CloudFungusPrediction";

		public const string Version = "0.9.3";
	}
	[BepInPlugin("CloudFungusPrediction", "CloudFungusPrediction", "0.9.3")]
	public class Plugin : BaseUnityPlugin
	{
		public static ConfigEntry<bool> EnablePrediction;

		public static ConfigEntry<bool> EnableInstantPrediction;

		public static ConfigEntry<bool> EnablePhysicsGhost;

		public static ConfigEntry<KeyboardShortcut> PreviewKey;

		public static ConfigEntry<bool> EnableGroundPreview;

		public static ConfigEntry<bool> EnableBounceFungusPreview;

		public static ConfigEntry<float> PreviewTransparency;

		public static ConfigEntry<float> GhostTransparency;

		public static ConfigEntry<bool> HideInstantWhilePreviewing;

		public static ConfigEntry<float> RestoreInstantDelay;

		public static ConfigEntry<float> RemoveGhostDelay;

		public static ConfigEntry<bool> EnableWarpFungusPreview;

		public static ConfigEntry<Color> WarpPreviewColor;

		internal static ManualLogSource Log { get; private set; }

		public static Plugin Instance { get; private set; }

		private void Awake()
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			Instance = this;
			Log.LogColorM("          云朵蘑菇预测 v0.9.3 加载完成");
			BindConfig();
			new Harmony("CloudFungusPrediction").PatchAll(Assembly.GetExecutingAssembly());
			GameObject val = new GameObject("[CloudFungusPrediction]GhostBinder");
			Object.DontDestroyOnLoad((Object)val);
			val.AddComponent<GhostPreviewBinder>();
			Log.LogColorC("          云朵蘑菇预测 v0.9.3 已就绪");
		}

		private void BindConfig()
		{
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Expected O, but got Unknown
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Expected O, but got Unknown
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			EnablePrediction = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enable Prediction", true, "蓄力时预测云朵蘑菇落地后云团的位置");
			EnableInstantPrediction = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enable Instant Prediction", true, "即时解析预览:蓄力时每帧用解析模拟算落点,瞬时出结果、跟随蓄力实时更新,但在地形复杂处(岩石、墙角)可能有数米偏差。关掉则只保留按住预览键的物理幽灵(更准但要等它飞完)");
			EnableGroundPreview = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enable Ground Preview", true, "云朵蘑菇落地后显示云团预览");
			EnablePhysicsGhost = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enable Physics Ghost", true, "按住预览键时用真实物理幽灵预测落点:克隆手中的蘑菇成为真实刚体在场景里跑物理,拐角、斜面、滚动、弹跳都与游戏一致(需要约 1 秒真实时间让它飞完)。松开预览键立即取消预览。云雾菇用来看落点,曲迁菇用来看滚动后的传送落点");
			PreviewKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "Preview Key", new KeyboardShortcut((KeyCode)324, Array.Empty<KeyCode>()), "按住此键(手持云雾菇或曲迁菇时)用物理幽灵真实模拟落点,松开立即取消预览");
			EnableBounceFungusPreview = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enable Bounce Fungus Preview", true, "蓄力时预测弹力蘑菇(BounceFungus)的落地位置和朝向");
			PreviewTransparency = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Preview Transparency", 0.6f, "预览透明度(0=完全透明,1=完全可见)");
			GhostTransparency = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Ghost Transparency", 0.85f, "物理幽灵的透明度(0=完全透明,1=完全可见)。独立于 Preview Transparency,因为幽灵要在飞行中被看清,若沿用很低的预览透明度会看不见");
			HideInstantWhilePreviewing = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Hide Instant While Previewing", true, "按住预览键(物理幽灵)期间隐藏即时解析预览,只显示物理幽灵;松开按键后恢复。关掉则两种预览同时显示");
			RestoreInstantDelay = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Restore Instant Delay", 0f, new ConfigDescription("松开预览键后多少秒恢复即时解析预览(0=立即恢复)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>()));
			RemoveGhostDelay = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Remove Ghost Delay", 0f, new ConfigDescription("松开预览键后多少秒移除物理幽灵(0=立即移除)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>()));
			EnableWarpFungusPreview = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enable Warp Fungus Preview", true, "预测曲迁菇(Warp Fungus)的飞行轨迹与传送落点:蓄力时显示解析轨迹,按住预览键时改用物理幽灵模拟真实滚动与后续碰撞(曲迁菇撞地后会滚动,可能滚一段距离才触发传送,解析模拟算不出这一段)");
			WarpPreviewColor = ((BaseUnityPlugin)this).Config.Bind<Color>("General", "Warp Preview Color", new Color(0.62f, 0.38f, 1f), "曲迁菇预览的轨迹线与落点标记颜色");
		}

		private void OnDestroy()
		{
			CloudPreviewRenderer.Dispose();
			CloudPreviewRoot.Dispose();
			CloudFungusPredictionPatch.Dispose();
			BounceFungusPreviewPatch.Dispose();
			PhysicsGhostPreview.Dispose();
			WarpFungusPreviewPatch.Dispose();
			WarpGhostPreview.Dispose();
			WarpFungusPreviewRenderer.Dispose();
		}
	}
	internal static class PreviewMath
	{
		private static bool _predictionMaskResolved;

		private static LayerMask _predictionMask;

		internal static LayerMask PredictionMask
		{
			get
			{
				//IL_003a: 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_002f: Unknown result type (might be due to invalid IL or missing references)
				if (!_predictionMaskResolved)
				{
					_predictionMask = LayerMask.op_Implicit(LayerMask.GetMask(new string[3] { "Terrain", "Map", "Default" }));
					_predictionMaskResolved = true;
				}
				return _predictionMask;
			}
		}

		internal static Vector3 LookDirection(Vector2 lookValues)
		{
			//IL_0000: 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_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: 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_003d: 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)
			Vector3 result = Quaternion.Euler(0f - lookValues.y, lookValues.x, 0f) * Vector3.forward;
			if (((Vector3)(ref result)).sqrMagnitude < 1E-06f)
			{
				return Vector3.forward;
			}
			((Vector3)(ref result)).Normalize();
			return result;
		}
	}
	[HarmonyPatch(typeof(CharacterItems), "Update")]
	public static class WarpFungusPreviewPatch
	{
		private static float _lastChargeForce = -1f;

		private static bool _hasCache;

		private static float _cacheForce = -1f;

		private static Vector3 _cacheDir = Vector3.forward;

		private static Vector3 _cachePos;

		private static readonly List<Vector3> _pathBuffer = new List<Vector3>(128);

		public static void Postfix(CharacterItems __instance, Character ___character)
		{
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: 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_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: 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_011f: 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_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			if (Plugin.EnableWarpFungusPreview == null || !Plugin.EnableWarpFungusPreview.Value || WarpGhostPreview.IsActive || (Object)(object)__instance == (Object)null || (Object)(object)___character == (Object)null || !___character.IsLocal)
			{
				return;
			}
			Item val = (((Object)(object)___character.data != (Object)null) ? ___character.data.currentItem : null);
			if ((Object)(object)val == (Object)null)
			{
				WarpFungusPreviewRenderer.Clear();
				return;
			}
			WarpOnThrow component = ((Component)val).GetComponent<WarpOnThrow>();
			if ((Object)(object)component == (Object)null)
			{
				WarpFungusPreviewRenderer.Clear();
				return;
			}
			if (!((Object)(object)___character.input != (Object)null) || !___character.input.dropIsPressed || !(__instance.throwChargeLevel > 0.05f))
			{
				InvalidateCache();
				WarpFungusPreviewRenderer.Clear();
				return;
			}
			_lastChargeForce = __instance.minThrowForce + (__instance.maxThrowForce - __instance.minThrowForce) * __instance.throwChargeLevel;
			Vector3 val2 = PreviewMath.LookDirection(___character.data.lookValues);
			Vector3 position = val.transform.position;
			if (_hasCache && Mathf.Abs(_cacheForce - _lastChargeForce) < 0.0001f && Vector3.Dot(_cacheDir, val2) > 0.9999f)
			{
				Vector3 val3 = position - _cachePos;
				if (((Vector3)(ref val3)).sqrMagnitude < 0.0016f)
				{
					return;
				}
			}
			if (!ComputeTrajectory(val, ___character, component, out var points, out var warpPoint, out var canWarp))
			{
				InvalidateCache();
				WarpFungusPreviewRenderer.Clear();
				return;
			}
			_cacheForce = _lastChargeForce;
			_cacheDir = val2;
			_cachePos = position;
			_hasCache = true;
			WarpFungusPreviewRenderer.Show(points, warpPoint, canWarp);
		}

		public static void Dispose()
		{
			_lastChargeForce = -1f;
			InvalidateCache();
			WarpFungusPreviewRenderer.Clear();
		}

		private static void InvalidateCache()
		{
			_hasCache = false;
		}

		public static bool ComputeTrajectory(Item item, Character owner, WarpOnThrow warp, out List<Vector3> points, out Vector3 warpPoint, out bool canWarp)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: 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_0088: 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_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: 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_00c7: 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_0126: 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_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_028c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0293: Unknown result type (might be due to invalid IL or missing references)
			//IL_029e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0319: Unknown result type (might be due to invalid IL or missing references)
			//IL_031d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0342: Unknown result type (might be due to invalid IL or missing references)
			//IL_0347: Unknown result type (might be due to invalid IL or missing references)
			//IL_034c: Unknown result type (might be due to invalid IL or missing references)
			//IL_034e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0350: Unknown result type (might be due to invalid IL or missing references)
			//IL_0352: Unknown result type (might be due to invalid IL or missing references)
			//IL_0357: Unknown result type (might be due to invalid IL or missing references)
			//IL_03aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_03be: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03de: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0391: Unknown result type (might be due to invalid IL or missing references)
			//IL_0393: Unknown result type (might be due to invalid IL or missing references)
			//IL_0397: Unknown result type (might be due to invalid IL or missing references)
			//IL_039e: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a8: Unknown result type (might be due to invalid IL or missing references)
			points = null;
			warpPoint = Vector3.zero;
			canWarp = false;
			if ((Object)(object)item == (Object)null || (Object)(object)owner == (Object)null || (Object)(object)owner.data == (Object)null || (Object)(object)warp == (Object)null)
			{
				return false;
			}
			Vector3 position = item.transform.position;
			Vector3 val = PreviewMath.LookDirection(owner.data.lookValues) * _lastChargeForce * 0.5f * item.throwForceMultiplier;
			if ((Object)(object)item.rig != (Object)null)
			{
				val += item.rig.linearVelocity;
			}
			if (((Vector3)(ref val)).sqrMagnitude < 0.0001f)
			{
				return false;
			}
			List<Vector3> pathBuffer = _pathBuffer;
			pathBuffer.Clear();
			pathBuffer.Add(position);
			LayerMask predictionMask = PreviewMath.PredictionMask;
			Vector3 val2 = position;
			Vector3 val3 = val;
			float fixedDeltaTime = Time.fixedDeltaTime;
			float deltaTime = Time.deltaTime;
			Vector3 gravity = Physics.gravity;
			float num = (((Object)(object)item.rig != (Object)null) ? item.rig.linearDamping : 0f);
			float num2 = 0f;
			float num3 = 0f;
			float itemRadius = CloudFungusPredictionPatch.GetItemRadius(item);
			float itemBounciness = CloudFungusPredictionPatch.GetItemBounciness(item);
			float itemFriction = CloudFungusPredictionPatch.GetItemFriction(item);
			Vector3 val4 = val2;
			int num4 = 0;
			int num5 = 0;
			RaycastHit val6 = default(RaycastHit);
			for (int i = 0; i < 300; i++)
			{
				num2 += deltaTime;
				for (num3 += deltaTime; num3 >= fixedDeltaTime; num3 -= fixedDeltaTime)
				{
					val3 += gravity * fixedDeltaTime;
					val3 *= 1f / (1f + num * fixedDeltaTime);
					val2 += val3 * fixedDeltaTime;
				}
				if (num2 >= warp.maxTime)
				{
					if (pathBuffer.Count < 2)
					{
						return false;
					}
					points = pathBuffer;
					return true;
				}
				if (++num4 < 3)
				{
					if (val2.y < position.y - 200f)
					{
						return false;
					}
					continue;
				}
				num4 = 0;
				pathBuffer.Add(val2);
				Vector3 val5 = val2 - val4;
				if (((Vector3)(ref val5)).sqrMagnitude > 1E-08f && Physics.Raycast(val4, ((Vector3)(ref val5)).normalized, ref val6, ((Vector3)(ref val5)).magnitude + 0.05f, LayerMask.op_Implicit(predictionMask)))
				{
					bool num6 = (Object)(object)((RaycastHit)(ref val6)).collider != (Object)null && (LayerMask.op_Implicit(HelperFunctions.terrainMapMask) & (1 << ((Component)((RaycastHit)(ref val6)).collider).gameObject.layer)) != 0;
					bool flag = ((Vector3)(ref val3)).magnitude > warp.minVelocity;
					bool flag2 = num2 > warp.minTime && num2 < warp.maxTime;
					if (num6 && flag && flag2)
					{
						warpPoint = ((RaycastHit)(ref val6)).point + ((RaycastHit)(ref val6)).normal * warp.moveAwayFromWallDistance;
						canWarp = true;
						pathBuffer.Add(warpPoint);
						points = pathBuffer;
						return true;
					}
					pathBuffer.Add(((RaycastHit)(ref val6)).point);
					num5++;
					if (num5 >= 6)
					{
						if (pathBuffer.Count < 2)
						{
							return false;
						}
						points = pathBuffer;
						return true;
					}
					float num7 = (itemBounciness + CloudFungusPredictionPatch.GetHitBounciness(((RaycastHit)(ref val6)).collider)) * 0.5f;
					float num8 = (itemFriction + CloudFungusPredictionPatch.GetHitFriction(((RaycastHit)(ref val6)).collider)) * 0.5f;
					float num9 = Vector3.Dot(val3, ((RaycastHit)(ref val6)).normal);
					if (Mathf.Abs(num9) < Physics.bounceThreshold)
					{
						num7 = 0f;
					}
					Vector3 val7 = num9 * ((RaycastHit)(ref val6)).normal;
					Vector3 val8 = val3 - val7;
					float magnitude = ((Vector3)(ref val8)).magnitude;
					if (magnitude > 0.0001f)
					{
						float num10 = (1f + num7) * Mathf.Max(0f, 0f - num9);
						float num11 = Mathf.Min(num8 * num10, magnitude);
						val8 -= val8 / magnitude * num11;
					}
					val3 = val8 - num7 * val7;
					val2 = ((RaycastHit)(ref val6)).point + ((RaycastHit)(ref val6)).normal * (itemRadius + 0.02f);
					val4 = val2;
				}
				else
				{
					val4 = val2;
					if (val2.y < position.y - 200f)
					{
						return false;
					}
				}
			}
			if (pathBuffer.Count < 2)
			{
				return false;
			}
			points = pathBuffer;
			return true;
		}
	}
	public static class WarpFungusPreviewRenderer
	{
		private static LineRenderer _line;

		private static GameObject _marker;

		private static Material _material;

		private static Color PreviewColor
		{
			get
			{
				//IL_0023: 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_002f: 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)
				Color result = (Color)(((Object)(object)Plugin.Instance != (Object)null && Plugin.WarpPreviewColor != null) ? Plugin.WarpPreviewColor.Value : new Color(0.62f, 0.38f, 1f));
				result.a = Mathf.Clamp(((Object)(object)Plugin.Instance != (Object)null && Plugin.PreviewTransparency != null) ? Plugin.PreviewTransparency.Value : 0.6f, 0.2f, 1f);
				return result;
			}
		}

		private static Material PreviewMaterial
		{
			get
			{
				//IL_0051: Unknown result type (might be due to invalid IL or missing references)
				//IL_005b: Expected O, but got Unknown
				//IL_0071: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)_material != (Object)null)
				{
					return _material;
				}
				string[] array = new string[4] { "Sprites/Default", "UI/Default", "Unlit/Color", "Legacy Shaders/Particles/Alpha Blended Premultiply" };
				for (int i = 0; i < array.Length; i++)
				{
					Shader val = Shader.Find(array[i]);
					if (!((Object)(object)val == (Object)null))
					{
						_material = new Material(val);
						if (_material.HasProperty("_Color"))
						{
							_material.color = PreviewColor;
						}
						break;
					}
				}
				return _material;
			}
		}

		public static void Show(List<Vector3> points, Vector3 warpPoint, bool canWarp)
		{
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			if (points == null || points.Count < 2)
			{
				Clear();
				return;
			}
			EnsureLine();
			if ((Object)(object)_line != (Object)null)
			{
				((Component)_line).gameObject.SetActive(true);
				_line.positionCount = points.Count;
				for (int i = 0; i < points.Count; i++)
				{
					_line.SetPosition(i, points[i]);
				}
			}
			if (canWarp)
			{
				EnsureMarker();
				if ((Object)(object)_marker != (Object)null)
				{
					_marker.SetActive(true);
					_marker.transform.position = warpPoint;
				}
			}
			else if ((Object)(object)_marker != (Object)null)
			{
				_marker.SetActive(false);
			}
		}

		public static void Clear()
		{
			if ((Object)(object)_line != (Object)null)
			{
				((Component)_line).gameObject.SetActive(false);
				_line.positionCount = 0;
			}
			if ((Object)(object)_marker != (Object)null)
			{
				_marker.SetActive(false);
			}
		}

		public static void Dispose()
		{
			Clear();
			if ((Object)(object)_line != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)_line).gameObject);
				_line = null;
			}
			if ((Object)(object)_marker != (Object)null)
			{
				Object.Destroy((Object)(object)_marker);
				_marker = null;
			}
			if ((Object)(object)_material != (Object)null)
			{
				Object.Destroy((Object)(object)_material);
				_material = null;
			}
		}

		private static void EnsureLine()
		{
			//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_0029: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_line != (Object)null))
			{
				GameObject val = new GameObject("WarpFungusPreviewLine");
				val.transform.SetParent(CloudPreviewRoot.Root, false);
				LineRenderer val2 = val.AddComponent<LineRenderer>();
				val2.useWorldSpace = true;
				val2.positionCount = 0;
				val2.startWidth = 0.08f;
				val2.endWidth = 0.08f;
				val2.numCapVertices = 2;
				val2.numCornerVertices = 2;
				((Renderer)val2).shadowCastingMode = (ShadowCastingMode)0;
				((Renderer)val2).receiveShadows = false;
				val2.startColor = PreviewColor;
				val2.endColor = PreviewColor;
				val2.alignment = (LineAlignment)0;
				Material previewMaterial = PreviewMaterial;
				if ((Object)(object)previewMaterial != (Object)null)
				{
					((Renderer)val2).material = previewMaterial;
				}
				val.SetActive(false);
				_line = val2;
			}
		}

		private static void EnsureMarker()
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_marker != (Object)null)
			{
				return;
			}
			_marker = GameObject.CreatePrimitive((PrimitiveType)0);
			((Object)_marker).name = "WarpFungusPreviewMarker";
			_marker.transform.SetParent(CloudPreviewRoot.Root, false);
			_marker.transform.localScale = Vector3.one * 0.5f;
			Collider component = _marker.GetComponent<Collider>();
			if ((Object)(object)component != (Object)null)
			{
				Object.Destroy((Object)(object)component);
			}
			Renderer component2 = _marker.GetComponent<Renderer>();
			if ((Object)(object)component2 != (Object)null)
			{
				component2.shadowCastingMode = (ShadowCastingMode)0;
				component2.receiveShadows = false;
				Material previewMaterial = PreviewMaterial;
				if ((Object)(object)previewMaterial != (Object)null)
				{
					component2.material = previewMaterial;
				}
			}
			_marker.SetActive(false);
		}
	}
	public class WarpGhostProbe : MonoBehaviour
	{
		public struct Hit
		{
			public int Layer;

			public Vector3 Point;

			public Vector3 Normal;

			public float Speed;

			public float Time;
		}

		public static readonly List<Hit> Hits = new List<Hit>(8);

		private void OnCollisionEnter(Collision collision)
		{
			//IL_005b: 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_006e: 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_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)
			if (collision != null)
			{
				ContactPoint[] contacts = collision.contacts;
				if (contacts != null && contacts.Length != 0 && Hits.Count < 64)
				{
					List<Hit> hits = Hits;
					Hit item = new Hit
					{
						Layer = (((Object)(object)collision.gameObject != (Object)null) ? collision.gameObject.layer : (-1)),
						Point = ((ContactPoint)(ref contacts[0])).point,
						Normal = ((ContactPoint)(ref contacts[0])).normal
					};
					Vector3 relativeVelocity = collision.relativeVelocity;
					item.Speed = ((Vector3)(ref relativeVelocity)).magnitude;
					item.Time = Time.time;
					hits.Add(item);
				}
			}
		}

		private void OnDisable()
		{
			Hits.Clear();
		}
	}
	internal static class WarpGhostPreview
	{
		private const float MaxFlightTime = 8f;

		private const float RestSpeed = 0.6f;

		private const float RestHoldTime = 0.3f;

		private const int MaxPathPoints = 512;

		private static GameObject _ghost;

		private static Rigidbody _rig;

		private static Item _sourceItem;

		private static WarpOnThrow _sourceWarp;

		private static float _minVelocity;

		private static float _minTime;

		private static float _maxTime;

		private static float _moveAway;

		private static float _launchOriginY;

		private static float _launchTime;

		private static float _flightTime;

		private static float _restTime;

		private static bool _finished;

		private static bool _windowClosed;

		private static bool _unavailable;

		private static float _releaseTime = -1f;

		private static Vector3 _warpPoint;

		private static readonly List<Vector3> _path = new List<Vector3>(512);

		public static bool IsActive => (Object)(object)_ghost != (Object)null;

		private static float RemoveGhostDelayValue
		{
			get
			{
				if (Plugin.RemoveGhostDelay == null)
				{
					return 0f;
				}
				return Mathf.Max(0f, Plugin.RemoveGhostDelay.Value);
			}
		}

		public static bool StartGhost(Item item, WarpOnThrow warp, Vector3 lookDir, float chargeForce)
		{
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			if (_unavailable)
			{
				return false;
			}
			if ((Object)(object)item == (Object)null || (Object)(object)warp == (Object)null)
			{
				return false;
			}
			if (!EnsureGhost(item, warp))
			{
				return false;
			}
			if ((Object)(object)_ghost == (Object)null || (Object)(object)_rig == (Object)null)
			{
				return false;
			}
			_minVelocity = warp.minVelocity;
			_minTime = warp.minTime;
			_maxTime = warp.maxTime;
			_moveAway = warp.moveAwayFromWallDistance;
			((Vector3)(ref lookDir)).Normalize();
			Launch(item, lookDir, chargeForce);
			return true;
		}

		public static void Tick(bool keyHeld)
		{
			//IL_007d: 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_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_ghost == (Object)null || (Object)(object)_rig == (Object)null)
			{
				return;
			}
			if (!keyHeld)
			{
				if (_releaseTime < 0f)
				{
					_releaseTime = Time.time;
				}
				if (Time.time - _releaseTime >= RemoveGhostDelayValue)
				{
					StopGhost("松开预览键");
				}
				return;
			}
			_releaseTime = -1f;
			if (_finished)
			{
				return;
			}
			_flightTime += Time.deltaTime;
			Vector3 position = _ghost.transform.position;
			Vector3 linearVelocity = _rig.linearVelocity;
			AppendPath(position);
			if (position.y < _launchOriginY - 1500f)
			{
				Finish(warped: false);
				return;
			}
			if (!_windowClosed)
			{
				if (TryConsumeWarp(out var destination))
				{
					_warpPoint = destination;
					Finish(warped: true);
					return;
				}
				if (_flightTime >= _maxTime)
				{
					_windowClosed = true;
				}
			}
			if (((Vector3)(ref linearVelocity)).sqrMagnitude < 0.36f)
			{
				_restTime += Time.deltaTime;
				if (_restTime >= 0.3f)
				{
					Finish(warped: false);
					return;
				}
			}
			else
			{
				_restTime = 0f;
			}
			if (_flightTime > 8f)
			{
				Finish(warped: false);
			}
		}

		public static void StopGhost(string reason = null)
		{
			Clear();
			WarpFungusPreviewRenderer.Clear();
		}

		public static void Dispose()
		{
			StopGhost("插件卸载");
			_unavailable = false;
		}

		private static bool TryConsumeWarp(out Vector3 destination)
		{
			//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_001b: 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_0076: 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_008a: Unknown result type (might be due to invalid IL or missing references)
			destination = Vector3.zero;
			List<WarpGhostProbe.Hit> hits = WarpGhostProbe.Hits;
			if (hits.Count == 0)
			{
				return false;
			}
			int num = LayerMask.op_Implicit(HelperFunctions.terrainMapMask);
			for (int i = 0; i < hits.Count; i++)
			{
				WarpGhostProbe.Hit hit = hits[i];
				if ((num & (1 << hit.Layer)) != 0 && !(hit.Speed <= _minVelocity))
				{
					float num2 = hit.Time - _launchTime;
					if (!(num2 <= _minTime) && !(num2 >= _maxTime))
					{
						destination = hit.Point + hit.Normal * _moveAway;
						hits.Clear();
						return true;
					}
				}
			}
			hits.Clear();
			return false;
		}

		private static void Clear()
		{
			//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)
			WarpGhostProbe.Hits.Clear();
			if ((Object)(object)_ghost != (Object)null)
			{
				Object.Destroy((Object)(object)_ghost);
			}
			_ghost = null;
			_rig = null;
			_sourceItem = null;
			_sourceWarp = null;
			_launchOriginY = 0f;
			_launchTime = 0f;
			_flightTime = 0f;
			_restTime = 0f;
			_finished = false;
			_windowClosed = false;
			_warpPoint = Vector3.zero;
			_path.Clear();
			_releaseTime = -1f;
		}

		private static bool EnsureGhost(Item item, WarpOnThrow warp)
		{
			if ((Object)(object)_ghost != (Object)null && (Object)(object)_sourceItem == (Object)(object)item && (Object)(object)_sourceWarp == (Object)(object)warp)
			{
				return true;
			}
			Clear();
			if (!CreateGhost(item, warp))
			{
				return false;
			}
			_sourceItem = item;
			_sourceWarp = warp;
			return true;
		}

		private static bool CreateGhost(Item item, WarpOnThrow warp)
		{
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = FindPrefab(item);
			if ((Object)(object)val == (Object)null)
			{
				return Unavailable("找不到物品 prefab(Resources.Load(\"0_Items/" + PrefabNameOf(item) + "\") 失败)");
			}
			GameObject val2 = Object.Instantiate<GameObject>(val, CloudPreviewRoot.Root);
			if ((Object)(object)val2 == (Object)null)
			{
				return Unavailable("克隆 prefab 失败");
			}
			((Object)val2).name = "WarpFungusPhysicsGhost";
			PhotonView[] componentsInChildren = val2.GetComponentsInChildren<PhotonView>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren[i]);
			}
			PhotonCleanupHelper[] componentsInChildren2 = val2.GetComponentsInChildren<PhotonCleanupHelper>(true);
			for (int i = 0; i < componentsInChildren2.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren2[i]);
			}
			MonoBehaviour[] componentsInChildren3 = val2.GetComponentsInChildren<MonoBehaviour>(true);
			foreach (MonoBehaviour val3 in componentsInChildren3)
			{
				if ((Object)(object)val3 != (Object)null)
				{
					((Behaviour)val3).enabled = false;
				}
			}
			val2.AddComponent<WarpGhostProbe>();
			Collider[] componentsInChildren4 = val2.GetComponentsInChildren<Collider>(true);
			foreach (Collider obj in componentsInChildren4)
			{
				obj.enabled = true;
				obj.isTrigger = false;
			}
			Renderer[] componentsInChildren5 = val2.GetComponentsInChildren<Renderer>(true);
			for (int i = 0; i < componentsInChildren5.Length; i++)
			{
				componentsInChildren5[i].enabled = true;
			}
			Rigidbody val4 = val2.GetComponent<Rigidbody>();
			if ((Object)(object)val4 == (Object)null)
			{
				val4 = val2.AddComponent<Rigidbody>();
			}
			val4.mass = item.mass;
			val4.useGravity = true;
			val4.isKinematic = tru