Decompiled source of ScalerCore v0.6.1

ScalerCore.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Realtime;
using ScalerCore.AprilFools;
using ScalerCore.Handlers;
using ScalerCore.Handlers.EnemyVisuals;
using ScalerCore.Utilities;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Audio;
using UnityEngine.Rendering.PostProcessing;
using UnityEngine.UI;

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

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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 ScalerCore
{
	internal static class BuildInfo
	{
		public const string Version = "0.6.1";
	}
	[HarmonyPatch(typeof(PhysGrabObject), "Start")]
	internal static class AttachToValuablePatch
	{
		private static void Postfix(PhysGrabObject __instance)
		{
			if (!((Object)(object)((Component)__instance).GetComponent<ScaleController>() != (Object)null))
			{
				bool num = (Object)(object)((Component)__instance).GetComponent<ValuableObject>() != (Object)null;
				bool flag = (Object)(object)((Component)__instance).GetComponent<ItemAttributes>() != (Object)null;
				bool flag2 = (Object)(object)((Component)__instance).GetComponent<CosmeticWorldObject>() != (Object)null;
				if (num || flag || flag2)
				{
					((Component)__instance).gameObject.AddComponent<ScaleController>();
				}
			}
		}
	}
	[HarmonyPatch(typeof(EnemyRigidbody), "Awake")]
	internal static class AttachToEnemyPatch
	{
		private static void Postfix(EnemyRigidbody __instance)
		{
			if (!((Object)(object)((Component)__instance).GetComponent<ScaleController>() != (Object)null))
			{
				((Component)__instance).gameObject.AddComponent<ScaleController>();
			}
		}
	}
	[HarmonyPatch(typeof(PlayerAvatar), "Start")]
	internal static class AttachToPlayerPatch
	{
		private static void Postfix(PlayerAvatar __instance)
		{
			if (!((Object)(object)((Component)__instance).GetComponent<ScaleController>() != (Object)null))
			{
				((Component)__instance).gameObject.AddComponent<ScaleController>();
				PhotonView component = ((Component)__instance).GetComponent<PhotonView>();
				if (component != null)
				{
					component.RefreshRpcMonoBehaviourCache();
				}
			}
		}
	}
	[HarmonyPatch(typeof(PhysGrabHinge), "Awake")]
	internal static class AttachToDoorPatch
	{
		private static void Postfix(PhysGrabHinge __instance)
		{
			if (!((Object)(object)((Component)__instance).GetComponent<ScaleController>() != (Object)null))
			{
				((Component)__instance).gameObject.AddComponent<ScaleController>();
			}
		}
	}
	[HarmonyPatch(typeof(RunManager), "ChangeLevel")]
	internal static class LevelChangePatch
	{
		private static void Postfix()
		{
			ScaleManager.CleanupAll();
			MapCollapse.OnLevelChange();
		}
	}
	[HarmonyPatch(typeof(RunManagerPUN), "UpdateLevelRPC")]
	internal static class LevelChangeNonHostPatch
	{
		private static void Postfix()
		{
			if (!SemiFunc.IsMasterClientOrSingleplayer())
			{
				ScaleManager.CleanupAll();
				MapCollapse.OnLevelChange();
			}
		}
	}
	[HarmonyPatch(typeof(PlayerTumble), "SetupDone")]
	internal static class PlayerTumbleLinkPatch
	{
		private static void Postfix(PlayerTumble __instance)
		{
			PlayerAvatar playerAvatar = __instance.playerAvatar;
			ScaleController scaleController = ((playerAvatar != null) ? ((Component)playerAvatar).GetComponent<ScaleController>() : null);
			if (!((Object)(object)scaleController == (Object)null))
			{
				AttachLink(((Component)__instance).gameObject, scaleController);
				Collider[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<Collider>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					AttachLink(((Component)componentsInChildren[i]).gameObject, scaleController);
				}
				Plugin.Log.LogDebug((object)("[SC] PlayerShrinkLink (tumble) attached → " + ((Object)((Component)__instance).gameObject).name + "  avatar=" + ((Object)((Component)scaleController).gameObject).name));
			}
		}

		private static void AttachLink(GameObject go, ScaleController ctrl)
		{
			(go.GetComponent<PlayerShrinkLink>() ?? go.AddComponent<PlayerShrinkLink>()).Controller = ctrl;
		}
	}
	[HarmonyPatch(typeof(PlayerAvatar), "PlayerDeathRPC")]
	internal static class PlayerDeathExpandPatch
	{
		private static void Postfix(PlayerAvatar __instance)
		{
			if (SemiFunc.IsMasterClientOrSingleplayer())
			{
				ScaleController component = ((Component)__instance).GetComponent<ScaleController>();
				if (!((Object)(object)component == (Object)null) && component.IsScaled && !component._invertedActive)
				{
					component.DispatchExpand();
				}
			}
		}
	}
	[HarmonyPatch(typeof(PlayerHealth), "Hurt")]
	internal static class PlayerBonkPatch
	{
		private static void Prefix(PlayerHealth __instance, out int __state)
		{
			__state = __instance.health;
		}

		private static void Postfix(PlayerHealth __instance, int __state)
		{
			if (__instance.health >= __state)
			{
				return;
			}
			ScaleController scaleController = ((Component)__instance).GetComponentInParent<ScaleController>() ?? ((Component)__instance).GetComponentInChildren<ScaleController>();
			if ((Object)(object)scaleController == (Object)null)
			{
				return;
			}
			if (scaleController.IsScaled)
			{
				if (!scaleController._invertedActive)
				{
					scaleController.RequestBonkExpand();
				}
			}
			else if (scaleController._invertedActive)
			{
				scaleController.RequestInvertedReshrink();
			}
		}
	}
	[HarmonyPatch(typeof(ItemEquippable), "RequestEquip")]
	internal static class ShrunkEquipBlockPatch
	{
		private static bool Prefix(ItemEquippable __instance)
		{
			ScaleController component = ((Component)__instance).GetComponent<ScaleController>();
			if ((Object)(object)component == (Object)null)
			{
				return true;
			}
			bool flag = false;
			if (component.HandlerState is CartHandler.State state)
			{
				flag = state.AddedEquippable;
			}
			else if (component.HandlerState is ItemHandler.State state2)
			{
				flag = state2.AddedEquippable;
			}
			else if (component.HandlerState is VehicleHandler.State state3)
			{
				flag = state3.AddedEquippable;
			}
			if (!flag)
			{
				return true;
			}
			PlayerAvatar instance = PlayerAvatar.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return true;
			}
			ScaleController component2 = ((Component)instance).GetComponent<ScaleController>();
			if ((Object)(object)component2 != (Object)null && component2.IsScaled)
			{
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(PlayerCollisionGrounded), "Update")]
	internal static class GroundedWallJumpFix
	{
		private static void Postfix(PlayerCollisionGrounded __instance)
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			if (!__instance.Grounded)
			{
				return;
			}
			PlayerAvatar instance = PlayerAvatar.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			ScaleController component = ((Component)instance).GetComponent<ScaleController>();
			if (!((Object)(object)component == (Object)null) && component.IsScaled)
			{
				float num = __instance.Collider.radius * 1.5f;
				if (!Physics.Raycast(((Component)__instance).transform.position, Vector3.down, num, LayerMask.op_Implicit(__instance.LayerMask), (QueryTriggerInteraction)1))
				{
					__instance.Grounded = false;
					__instance.GroundedTimer = 0f;
					__instance.CollisionController.Grounded = false;
				}
			}
		}
	}
	[HarmonyPatch(typeof(PhysGrabber), "OverrideGrabDistance")]
	internal static class GrabDistanceScalePatch
	{
		private static void Prefix(ref float dist)
		{
			if (!((Object)(object)PhysGrabber.instance?.playerAvatar == (Object)null))
			{
				ScaleController component = ((Component)PhysGrabber.instance.playerAvatar).GetComponent<ScaleController>();
				if (!((Object)(object)component == (Object)null) && component.IsScaled)
				{
					dist *= 0.7f;
				}
			}
		}
	}
	[HarmonyPatch(typeof(PhysGrabObject), "OverrideGrabVerticalPosition")]
	internal static class GrabVerticalPositionScalePatch
	{
		private static void Prefix(ref float pos)
		{
			PhysGrabber instance = PhysGrabber.instance;
			object obj;
			if (instance == null)
			{
				obj = null;
			}
			else
			{
				PlayerAvatar playerAvatar = instance.playerAvatar;
				obj = ((playerAvatar != null) ? ((Component)playerAvatar).GetComponent<ScaleController>() : null);
			}
			ScaleController scaleController = (ScaleController)obj;
			if (!((Object)(object)scaleController == (Object)null) && scaleController.IsScaled)
			{
				pos = 0f;
			}
		}
	}
	[HarmonyPatch(typeof(PhysGrabber), "StartGrabbingPhysObject")]
	internal static class ForceGrabPointVerticalScalePatch
	{
		private static void Postfix(PhysGrabber __instance, PhysGrabObject ___grabbedPhysGrabObject)
		{
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			PlayerAvatar playerAvatar = __instance.playerAvatar;
			if ((Object)(object)playerAvatar == (Object)null)
			{
				return;
			}
			ScaleController component = ((Component)playerAvatar).GetComponent<ScaleController>();
			if ((Object)(object)component == (Object)null || !component.IsScaled || (Object)(object)___grabbedPhysGrabObject == (Object)null)
			{
				return;
			}
			Transform forceGrabPoint = ___grabbedPhysGrabObject.forceGrabPoint;
			if (!((Object)(object)forceGrabPoint == (Object)null) && ((Component)forceGrabPoint).gameObject.activeSelf)
			{
				PlayerLocalCamera localCamera = playerAvatar.localCamera;
				Transform val = ((localCamera != null) ? localCamera.GetOverrideTransform() : null);
				if (!((Object)(object)val == (Object)null))
				{
					float num = 0.3f * (1f - component._options.Factor);
					Vector3 val2 = val.up * num;
					Transform physGrabPointPuller = __instance.physGrabPointPuller;
					physGrabPointPuller.position += val2;
					Transform physGrabPointPlane = __instance.physGrabPointPlane;
					physGrabPointPlane.position += val2;
				}
			}
		}
	}
	[HarmonyPatch(typeof(PhysGrabCart), "CartSteer")]
	internal static class CartHandledDistancePatch
	{
		[CompilerGenerated]
		private sealed class <Transpiler>d__1 : IEnumerable<CodeInstruction>, IEnumerable, IEnumerator<CodeInstruction>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private CodeInstruction <>2__current;

			private int <>l__initialThreadId;

			private MethodBase originalMethod;

			public MethodBase <>3__originalMethod;

			private IEnumerable<CodeInstruction> instructions;

			public IEnumerable<CodeInstruction> <>3__instructions;

			private MethodInfo <lerpMethod>5__2;

			private MethodInfo <scaleMethod>5__3;

			private int <grabberIndex>5__4;

			private IEnumerator<CodeInstruction> <>7__wrap4;

			private CodeInstruction <code>5__6;

			CodeInstruction IEnumerator<CodeInstruction>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <Transpiler>d__1(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				switch (<>1__state)
				{
				case -3:
				case 1:
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
					break;
				case -4:
				case 2:
				case 3:
				case 4:
				case 5:
					try
					{
					}
					finally
					{
						<>m__Finally2();
					}
					break;
				}
				<lerpMethod>5__2 = null;
				<scaleMethod>5__3 = null;
				<>7__wrap4 = null;
				<code>5__6 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0242: Unknown result type (might be due to invalid IL or missing references)
				//IL_024c: Expected O, but got Unknown
				//IL_026b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0275: Expected O, but got Unknown
				//IL_0211: Unknown result type (might be due to invalid IL or missing references)
				//IL_021b: Expected O, but got Unknown
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
					{
						<>1__state = -1;
						<lerpMethod>5__2 = AccessTools.Method(typeof(Mathf), "Lerp", new Type[3]
						{
							typeof(float),
							typeof(float),
							typeof(float)
						}, (Type[])null);
						<scaleMethod>5__3 = AccessTools.Method(typeof(CartHandledDistancePatch), "ScalePullDist", (Type[])null, (Type[])null);
						IList<LocalVariableInfo> localVariables = originalMethod.GetMethodBody().LocalVariables;
						<grabberIndex>5__4 = -1;
						int num = 0;
						foreach (LocalVariableInfo item in localVariables)
						{
							if (item.LocalType == typeof(PhysGrabber))
							{
								num++;
								if (num == 2)
								{
									<grabberIndex>5__4 = item.LocalIndex;
									break;
								}
							}
						}
						if (<grabberIndex>5__4 == -1)
						{
							Plugin.Log.LogWarning((object)"[SC] CartSteer transpiler: Physgrabber local not found");
							<>7__wrap4 = instructions.GetEnumerator();
							<>1__state = -3;
							goto IL_0161;
						}
						<>7__wrap4 = instructions.GetEnumerator();
						<>1__state = -4;
						break;
					}
					case 1:
						<>1__state = -3;
						goto IL_0161;
					case 2:
						<>1__state = -4;
						if (<code>5__6.opcode == OpCodes.Call && (MethodInfo)<code>5__6.operand == <lerpMethod>5__2)
						{
							<>2__current = new CodeInstruction(OpCodes.Ldarg_0, (object)null);
							<>1__state = 3;
							return true;
						}
						goto IL_0288;
					case 3:
						<>1__state = -4;
						<>2__current = new CodeInstruction(OpCodes.Ldloc, (object)<grabberIndex>5__4);
						<>1__state = 4;
						return true;
					case 4:
						<>1__state = -4;
						<>2__current = new CodeInstruction(OpCodes.Call, (object)<scaleMethod>5__3);
						<>1__state = 5;
						return true;
					case 5:
						{
							<>1__state = -4;
							goto IL_0288;
						}
						IL_0161:
						if (<>7__wrap4.MoveNext())
						{
							CodeInstruction current = <>7__wrap4.Current;
							<>2__current = current;
							<>1__state = 1;
							return true;
						}
						<>m__Finally1();
						<>7__wrap4 = null;
						return false;
						IL_0288:
						<code>5__6 = null;
						break;
					}
					if (<>7__wrap4.MoveNext())
					{
						<code>5__6 = <>7__wrap4.Current;
						<>2__current = <code>5__6;
						<>1__state = 2;
						return true;
					}
					<>m__Finally2();
					<>7__wrap4 = null;
					return false;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<>7__wrap4 != null)
				{
					<>7__wrap4.Dispose();
				}
			}

			private void <>m__Finally2()
			{
				<>1__state = -1;
				if (<>7__wrap4 != null)
				{
					<>7__wrap4.Dispose();
				}
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<CodeInstruction> IEnumerable<CodeInstruction>.GetEnumerator()
			{
				<Transpiler>d__1 <Transpiler>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<Transpiler>d__ = this;
				}
				else
				{
					<Transpiler>d__ = new <Transpiler>d__1(0);
				}
				<Transpiler>d__.instructions = <>3__instructions;
				<Transpiler>d__.originalMethod = <>3__originalMethod;
				return <Transpiler>d__;
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<CodeInstruction>)this).GetEnumerator();
			}
		}

		private static float ScalePullDist(float d, PhysGrabCart cart, PhysGrabber grabber)
		{
			ScaleController component = ((Component)cart).GetComponent<ScaleController>();
			if ((Object)(object)component != (Object)null && component.IsScaled)
			{
				return d * Mathf.Lerp(component._options.Factor, 1f, 0.15f);
			}
			if ((Object)(object)grabber == (Object)null)
			{
				return d;
			}
			ScaleController component2 = ((Component)grabber.playerAvatar).GetComponent<ScaleController>();
			if ((Object)(object)component2 != (Object)null && component2.IsScaled)
			{
				return d * Mathf.Lerp(1f, component2._options.Factor, 0.15f);
			}
			return d;
		}

		[IteratorStateMachine(typeof(<Transpiler>d__1))]
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, MethodBase originalMethod)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <Transpiler>d__1(-2)
			{
				<>3__instructions = instructions,
				<>3__originalMethod = originalMethod
			};
		}
	}
	[HarmonyPatch(typeof(CameraGlitch), "Update")]
	internal static class CameraGlitchScalePatch
	{
		private static void Postfix(CameraGlitch __instance)
		{
			//IL_002a: 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_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			PlayerAvatar instance = PlayerAvatar.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			ScaleController component = ((Component)instance).GetComponent<ScaleController>();
			if (!((Object)(object)component == (Object)null) && component.IsScaled)
			{
				float num = ((component.OriginalScale.x > 0f) ? (component._t.localScale.x / component.OriginalScale.x) : 1f);
				if (!(num >= 1f) && !(num <= 0f))
				{
					Transform transform = ((Component)__instance).transform;
					transform.localScale /= num;
				}
			}
		}
	}
	[HarmonyPatch(typeof(PlayerAvatar), "Footstep")]
	internal static class FootstepPitchPatch
	{
		private static void Prefix(PlayerAvatar __instance)
		{
			ScaleController component = ((Component)__instance).GetComponent<ScaleController>();
			if ((Object)(object)component != (Object)null && component.IsScaled)
			{
				ScaleController.FootstepPitchMult = component._options.FootstepPitchMultiplier;
			}
		}

		private static void Postfix()
		{
			ScaleController.FootstepPitchMult = 1f;
		}
	}
	[HarmonyPatch(typeof(Sound), "Play", new Type[]
	{
		typeof(Vector3),
		typeof(float),
		typeof(float),
		typeof(float),
		typeof(float)
	})]
	internal static class SoundPlayPitchPatch
	{
		private static void Postfix(AudioSource __result)
		{
			if (ScaleController.FootstepPitchMult != 1f && (Object)(object)__result != (Object)null)
			{
				__result.pitch *= ScaleController.FootstepPitchMult;
			}
		}
	}
	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	internal static class DriverFullyMountedScalePatch
	{
		private static void Postfix(ItemVehicle __instance, ref bool __result)
		{
			if (!__result && __instance.seats != null && __instance.seats.Length != 0 && !((Object)(object)__instance.seats[0].seatedPlayer == (Object)null))
			{
				ScaleController component = ((Component)__instance).GetComponent<ScaleController>();
				if ((Object)(object)component != (Object)null && component.IsScaled)
				{
					__result = true;
				}
			}
		}
	}
	public class PlayerShrinkLink : MonoBehaviour
	{
		public ScaleController Controller;
	}
	[BepInPlugin("Vippy.ScalerCore", "ScalerCore", "0.6.1")]
	public class Plugin : BaseUnityPlugin
	{
		private static Harmony? _harmony;

		internal static ManualLogSource Log;

		private void Awake()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			_harmony = new Harmony("Vippy.ScalerCore");
			_harmony.PatchAll();
			((Component)this).gameObject.AddComponent<MapCollapse>();
		}
	}
	public class ScaleController : MonoBehaviourPunCallbacks
	{
		[CompilerGenerated]
		private sealed class <ChallengeModeDeferred>d__62 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public ScaleController <>4__this;

			private PlayerHandler.State <playerState>5__2;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <ChallengeModeDeferred>d__62(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<playerState>5__2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				int num = <>1__state;
				ScaleController scaleController = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					goto IL_0042;
				case 1:
					<>1__state = -1;
					goto IL_0042;
				case 2:
					{
						<>1__state = -1;
						goto IL_008c;
					}
					IL_0042:
					if ((Object)(object)LevelGenerator.Instance == (Object)null || !LevelGenerator.Instance.Generated)
					{
						<>2__current = null;
						<>1__state = 1;
						return true;
					}
					if (!SemiFunc.IsMultiplayer())
					{
						break;
					}
					<playerState>5__2 = scaleController.HandlerState as PlayerHandler.State;
					goto IL_008c;
					IL_008c:
					if ((Object)(object)<playerState>5__2?.PlayerAvatar.voiceChat == (Object)null)
					{
						<>2__current = null;
						<>1__state = 2;
						return true;
					}
					<playerState>5__2 = null;
					break;
				}
				if (!scaleController.IsScaled && SemiFunc.IsMasterClientOrSingleplayer())
				{
					ScaleOptions @default = ScaleOptions.Default;
					@default.InvertedMode = true;
					@default.Duration = 0f;
					scaleController.DispatchShrink(@default);
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <LobbyPitchDeferred>d__63 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			private int <i>5__2;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <LobbyPitchDeferred>d__63(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<i>5__2 = 0;
					break;
				case 1:
					<>1__state = -1;
					<i>5__2++;
					break;
				}
				if (<i>5__2 < 10)
				{
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				PlayerVoiceChat[] array = Object.FindObjectsOfType<PlayerVoiceChat>();
				foreach (PlayerVoiceChat val in array)
				{
					if (ChallengeMode)
					{
						val.OverridePitch(1.3f, 0.2f, 0.5f, 9999f, 0f, 0f);
					}
					else
					{
						val.OverridePitchCancel();
					}
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <PlayerBounceAnim>d__61 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public ScaleController <>4__this;

			public Vector3 from;

			public Vector3 to;

			private float <duration>5__2;

			private float <elapsed>5__3;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <PlayerBounceAnim>d__61(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0067: Unknown result type (might be due to invalid IL or missing references)
				//IL_006d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0073: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
				int num = <>1__state;
				ScaleController scaleController = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<duration>5__2 = 0.4f;
					<elapsed>5__3 = 0f;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (<elapsed>5__3 < <duration>5__2)
				{
					<elapsed>5__3 += Time.deltaTime;
					float num2 = BackOutEase(Mathf.Clamp01(<elapsed>5__3 / <duration>5__2));
					scaleController._t.localScale = Vector3.LerpUnclamped(from, to, num2);
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				scaleController._t.localScale = to;
				scaleController._transitioning = false;
				scaleController._playerBounceAnim = null;
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public static readonly HashSet<ScaleController> Scaled = new HashSet<ScaleController>();

		internal static float FootstepPitchMult = 1f;

		public static bool AllowManualScale = true;

		public Transform? ScaleTarget;

		internal IScaleHandler? Handler;

		internal object? HandlerState;

		internal bool HandlerOwnsScale;

		internal PhysGrabObject? _physGrabObject;

		internal Transform _t;

		internal Rigidbody? _rb;

		internal float _originalMass;

		private RoomVolumeCheck? _roomVolumeCheck;

		private Vector3 _originalRoomVolumeSize;

		private bool _isItem;

		internal ItemEquippable? _itemEquippable;

		internal List<ItemHandler.ScaledField>? _scaledItemFields;

		internal bool _invertedActive;

		internal Vector3 _target;

		internal Vector3 _animScale;

		internal bool _transitioning;

		internal float _currentAnimSpeed = ScaleOptions.Default.Speed;

		private Coroutine? _playerBounceAnim;

		private float _shrinkTimer;

		internal ScaleOptions _options;

		internal float _bonkImmuneTimer;

		internal string _displayName = "";

		internal PhotonView? _networkPV;

		internal AudioPitchHelper _audioPitch = new AudioPitchHelper();

		public static bool ChallengeMode { get; set; }

		public Vector3 OriginalScale { get; internal set; }

		public bool IsScaled { get; private set; }

		public ScaleOptions CurrentOptions => _options;

		public ScaleTargets TargetType
		{
			get
			{
				if (!(Handler is PlayerHandler))
				{
					if (!(Handler is EnemyHandler))
					{
						if (!(Handler is ItemHandler))
						{
							if (!(Handler is VehicleHandler))
							{
								return ScaleTargets.Valuables;
							}
							return ScaleTargets.Items;
						}
						return ScaleTargets.Items;
					}
					return ScaleTargets.Enemies;
				}
				return ScaleTargets.Players;
			}
		}

		private void Awake()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			_t = ((Component)this).transform;
			OriginalScale = ((Component)this).transform.localScale;
			_target = OriginalScale;
			_animScale = OriginalScale;
		}

		private void Start()
		{
			//IL_0044: 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_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			Handler = ScaleHandlerRegistry.Resolve(((Component)this).gameObject);
			Handler?.Setup(this);
			if ((Object)(object)ScaleTarget != (Object)null)
			{
				_t = ScaleTarget;
				OriginalScale = _t.localScale;
				_target = OriginalScale;
				_animScale = OriginalScale;
			}
			_rb = ((Component)this).GetComponent<Rigidbody>();
			if ((Object)(object)_rb != (Object)null)
			{
				_originalMass = _rb.mass;
			}
			if ((Object)(object)_physGrabObject == (Object)null)
			{
				_physGrabObject = ((Component)this).GetComponent<PhysGrabObject>();
			}
			_roomVolumeCheck = ((Component)this).GetComponent<RoomVolumeCheck>();
			if ((Object)(object)_roomVolumeCheck != (Object)null)
			{
				_originalRoomVolumeSize = _roomVolumeCheck.currentSize;
			}
			EnemyParent componentInParent = ((Component)this).GetComponentInParent<EnemyParent>();
			_displayName = (((Object)(object)componentInParent != (Object)null) ? ((Object)((Component)componentInParent).gameObject).name : ((Object)((Component)this).gameObject).name);
			_isItem = (Object)(object)((Component)this).GetComponent<ItemAttributes>() != (Object)null;
			_itemEquippable = ((Component)this).GetComponent<ItemEquippable>();
			string text = ((Handler != null) ? Handler.GetType().Name.Replace("Handler", "").ToLower() : "base");
			EnemyParent componentInParent2 = ((Component)this).GetComponentInParent<EnemyParent>();
			if ((Object)(object)componentInParent2 != (Object)null)
			{
				int num = 0;
				ScaleController[] componentsInChildren = ((Component)componentInParent2).GetComponentsInChildren<ScaleController>();
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					if ((Object)(object)componentsInChildren[i] != (Object)(object)this)
					{
						num++;
					}
				}
				if (num > 0)
				{
					Plugin.Log.LogWarning((object)$"[SC] *** DUPLICATE: {_displayName} already has {num} other ScaleController(s) under same EnemyParent ***");
				}
			}
			_networkPV = ((MonoBehaviourPun)this).photonView ?? ((Component)this).GetComponentInParent<PhotonView>();
			PhotonView? networkPV = _networkPV;
			if (networkPV != null)
			{
				networkPV.RefreshRpcMonoBehaviourCache();
			}
			EnemyHandler.State state = HandlerState as EnemyHandler.State;
			Plugin.Log.LogDebug((object)("[SC] Registered " + _displayName + " (" + text + ")" + $"  scale={OriginalScale}" + "  mass=" + (((Object)(object)_rb != (Object)null) ? _rb.mass.ToString("F2") : "none") + "  animTarget=" + (((Object)(object)state?.AnimTarget != (Object)null) ? ((Object)((Component)state.AnimTarget).gameObject).name : "NONE") + "  navAgent=" + (((Object)(object)state?.NavAgent != (Object)null) ? "yes" : "no")));
			if (Handler is PlayerHandler && SemiFunc.RunIsLobbyMenu())
			{
				((MonoBehaviour)this).StartCoroutine(LobbyPitchDeferred());
			}
			if (ChallengeMode && Handler is PlayerHandler && !SemiFunc.RunIsLobbyMenu())
			{
				((MonoBehaviour)this).StartCoroutine(ChallengeModeDeferred());
			}
		}

		private void Update()
		{
			bool num = SemiFunc.IsMasterClientOrSingleplayer();
			if (num)
			{
				if (IsScaled && _shrinkTimer > 0f)
				{
					_shrinkTimer -= Time.deltaTime;
					if (_shrinkTimer <= 0f)
					{
						DispatchExpand();
					}
				}
				if (_bonkImmuneTimer > 0f)
				{
					_bonkImmuneTimer -= Time.deltaTime;
				}
				if (IsScaled && Handler != null)
				{
					Handler.OnUpdate(this);
				}
			}
			if (!num && IsScaled && Handler is PlayerHandler)
			{
				Handler.OnUpdate(this);
			}
		}

		private bool IsItemInInventory()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Invalid comparison between Unknown and I4
			if ((Object)(object)_itemEquippable == (Object)null)
			{
				return false;
			}
			if (_itemEquippable.IsEquipped())
			{
				return true;
			}
			return (int)_itemEquippable.currentState > 0;
		}

		private void LateUpdate()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: 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_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			bool flag = IsItemInInventory();
			bool flag2 = Handler is PlayerHandler;
			if (_transitioning && !flag2 && !flag)
			{
				float currentAnimSpeed = _currentAnimSpeed;
				Vector3 originalScale = OriginalScale;
				float num = currentAnimSpeed * ((Vector3)(ref originalScale)).magnitude;
				_animScale = Vector3.MoveTowards(_animScale, _target, num * Time.deltaTime);
				if (!HandlerOwnsScale)
				{
					_t.localScale = _animScale;
				}
				if (_animScale == _target)
				{
					_transitioning = false;
					Plugin.Log.LogDebug((object)$"[SC] LATE_ANIM DONE  {_displayName}  finalScale={_animScale}");
				}
			}
			Handler?.OnLateUpdate(this);
			if (!flag2 && !HandlerOwnsScale && IsScaled && !_transitioning && !flag)
			{
				if (_t.localScale != _target)
				{
					Plugin.Log.LogDebug((object)$"[SC] LATE_FORCE  {_displayName}  was={_t.localScale}  forcing={_target}");
				}
				_t.localScale = _target;
			}
		}

		public override void OnDisable()
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			((MonoBehaviourPunCallbacks)this).OnDisable();
			if (IsScaled && Handler is EnemyHandler)
			{
				Plugin.Log.LogDebug((object)("[SC] DISABLE (despawn) " + _displayName + "  restoring scale"));
				_t.localScale = OriginalScale;
				_animScale = OriginalScale;
				_target = OriginalScale;
				_transitioning = false;
				IsScaled = false;
				_invertedActive = false;
				_shrinkTimer = 0f;
				Scaled.Remove(this);
				if ((Object)(object)_rb != (Object)null)
				{
					_rb.mass = _originalMass;
				}
				if ((Object)(object)_roomVolumeCheck != (Object)null)
				{
					_roomVolumeCheck.currentSize = _originalRoomVolumeSize;
				}
				Handler?.OnRestore(this, isBonk: false);
				_audioPitch.RestorePitch();
				ItemHandler.OnRestoreFields(_scaledItemFields);
				_scaledItemFields = null;
			}
		}

		private void OnDestroy()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			if (IsScaled)
			{
				_t.localScale = OriginalScale;
				PlayerHandler.State obj = HandlerState as PlayerHandler.State;
				if (obj != null)
				{
					PlayerVoiceChat voiceChat = obj.PlayerAvatar.voiceChat;
					if (voiceChat != null)
					{
						voiceChat.OverridePitchCancel();
					}
				}
				Handler?.OnDestroy(this);
			}
			Scaled.Remove(this);
		}

		public void DispatchShrink(ScaleOptions options)
		{
			//IL_0045: 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_012a: 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_02bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f2: 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_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_0330: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_035a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0360: Unknown result type (might be due to invalid IL or missing references)
			//IL_0365: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0490: Unknown result type (might be due to invalid IL or missing references)
			//IL_049a: Unknown result type (might be due to invalid IL or missing references)
			if (!SemiFunc.IsMasterClientOrSingleplayer())
			{
				return;
			}
			Plugin.Log.LogDebug((object)$"[SC] DispatchShrink ENTER  {_displayName}  instanceID={((Object)this).GetInstanceID()}  IsScaled={IsScaled}  currentScale={_t.localScale}  GO={((Object)((Component)this).gameObject).name}");
			if (IsScaled)
			{
				if (Mathf.Approximately(options.Factor, _options.Factor))
				{
					DispatchExpand();
					if (_invertedActive)
					{
						_bonkImmuneTimer = _options.BonkImmuneDuration;
					}
					return;
				}
				Plugin.Log.LogDebug((object)$"[SC] RESCALE {_displayName}  {_options.Factor} → {options.Factor}");
				_options = options;
				_shrinkTimer = _options.Duration;
				if (_shrinkTimer < 0f)
				{
					_shrinkTimer = 0f;
				}
				float factor = _options.Factor;
				Vector3 val = OriginalScale * factor;
				_bonkImmuneTimer = _options.BonkImmuneDuration;
				_currentAnimSpeed = _options.Speed;
				ApplyScale(val);
				if ((Object)(object)_roomVolumeCheck != (Object)null)
				{
					_roomVolumeCheck.currentSize = _originalRoomVolumeSize * factor;
				}
				if ((Object)(object)_rb != (Object)null && !_isItem && !_options.PreserveMass)
				{
					_rb.mass = Mathf.Clamp(_originalMass * factor, 0.5f, _options.MassCap);
				}
				if ((Object)(object)_networkPV != (Object)null && PhotonNetwork.InRoom)
				{
					_networkPV.RPC("RPC_Shrink", (RpcTarget)1, new object[3]
					{
						val,
						PackOpts(),
						PackBools()
					});
				}
				return;
			}
			if (options.Factor <= 0f)
			{
				options.Factor = ScaleOptions.Default.Factor;
			}
			if (options.Speed <= 0f)
			{
				options.Speed = ScaleOptions.Default.Speed;
			}
			_options = options;
			_invertedActive = _options.InvertedMode;
			IsScaled = true;
			_shrinkTimer = _options.Duration;
			if (_shrinkTimer < 0f)
			{
				_shrinkTimer = 0f;
			}
			_currentAnimSpeed = _options.Speed;
			Scaled.Add(this);
			float factor2 = _options.Factor;
			Vector3 val2 = OriginalScale * factor2;
			Vector3 val3 = OriginalScale - val2;
			float magnitude = ((Vector3)(ref val3)).magnitude;
			float speed = _options.Speed;
			val3 = OriginalScale;
			float num = speed * ((Vector3)(ref val3)).magnitude;
			float num2 = ((num > 0f) ? (magnitude / num * 1.1f) : 0.75f);
			_bonkImmuneTimer = Mathf.Max(num2, _options.BonkImmuneDuration);
			ApplyScale(val2);
			if (factor2 < 1f)
			{
				SetForceGrabPoint(active: false);
			}
			if ((Object)(object)_roomVolumeCheck != (Object)null)
			{
				_roomVolumeCheck.currentSize = _originalRoomVolumeSize * factor2;
			}
			if ((Object)(object)_networkPV != (Object)null && PhotonNetwork.InRoom)
			{
				Plugin.Log.LogDebug((object)$"[SC] RPC_Shrink SEND  {_displayName}  viewID={_networkPV.ViewID}  isMine={_networkPV.IsMine}  target={val2}");
				_networkPV.RPC("RPC_Shrink", (RpcTarget)1, new object[3]
				{
					val2,
					PackOpts(),
					PackBools()
				});
			}
			else
			{
				Plugin.Log.LogDebug((object)string.Format("[SC] RPC_Shrink SKIP  {0}  networkPV={1}  inRoom={2}", _displayName, ((Object)(object)_networkPV == (Object)null) ? "null" : "set", PhotonNetwork.InRoom));
			}
			PlayImpactEffect();
			Plugin.Log.LogDebug((object)("[SC] SHRINK " + _displayName + $"  factor={_options.Factor}" + $"  scale {OriginalScale} → {val2}" + $"  animTime={magnitude / ((num > 0f) ? num : 1f):F2}s" + $"  bonkImmune={_bonkImmuneTimer:F2}s" + "  shrinkDuration=" + ((_shrinkTimer > 0f) ? (_shrinkTimer.ToString("F0") + "s") : "infinite")));
			if ((Object)(object)_rb != (Object)null)
			{
				if (!_isItem && !_options.PreserveMass)
				{
					_rb.mass = Mathf.Clamp(_originalMass * factor2, 0.5f, _options.MassCap);
				}
				Plugin.Log.LogDebug((object)$"[SC]   mass {_originalMass:F3} → {_rb.mass:F3}  (cap={_options.MassCap:F2}  originalMass locked at {_originalMass:F3})");
			}
			Handler?.OnScale(this);
			if (factor2 < 1f && (Object)(object)_physGrabObject != (Object)null && Handler is ValuableHandler)
			{
				_physGrabObject.OverrideIndestructible(0.5f);
			}
			if (!_options.SuppressVoicePitch)
			{
				EnemyParent componentInParent = ((Component)this).GetComponentInParent<EnemyParent>();
				_audioPitch.ApplyPitch((Component)(object)(((Object)(object)componentInParent != (Object)null) ? ((ScaleController)(object)componentInParent) : this), _options.Factor);
			}
			_scaledItemFields = ItemHandler.OnShrinkFields(this, _options.Factor);
			ScaleMapIcon(factor2);
		}

		public void DispatchExpand()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			if (SemiFunc.IsMasterClientOrSingleplayer() && IsScaled)
			{
				IsScaled = false;
				Scaled.Remove(this);
				float num = ((OriginalScale.x > 0f) ? (_t.localScale.x / OriginalScale.x) : 0f);
				Plugin.Log.LogDebug((object)("[SC] EXPAND (timer/shot) " + _displayName + $"  currentSize={num * 100f:F0}%" + string.Format("  mass {0} → {1:F3}", ((Object)(object)_rb != (Object)null) ? _rb.mass.ToString("F3") : "N/A", _originalMass)));
				_currentAnimSpeed = ResolveExpandSpeed();
				ApplyScale(OriginalScale);
				SetForceGrabPoint(active: true);
				if ((Object)(object)_networkPV != (Object)null && PhotonNetwork.InRoom)
				{
					_networkPV.RPC("RPC_Expand", (RpcTarget)1, Array.Empty<object>());
				}
				PlayImpactEffect();
				PlayCameraShake();
				if ((Object)(object)_rb != (Object)null)
				{
					_rb.mass = _originalMass;
				}
				if ((Object)(object)_roomVolumeCheck != (Object)null)
				{
					_roomVolumeCheck.currentSize = _originalRoomVolumeSize;
				}
				Handler?.OnRestore(this, isBonk: false);
				if (!_options.SuppressVoicePitch)
				{
					_audioPitch.RestorePitch();
				}
				ItemHandler.OnRestoreFields(_scaledItemFields);
				_scaledItemFields = null;
				ScaleMapIcon(1f);
			}
		}

		public void DispatchExpandNow()
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: 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_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			if (!SemiFunc.IsMasterClientOrSingleplayer() || !IsScaled || _options.IgnoreBonkExpand)
			{
				return;
			}
			if (_bonkImmuneTimer > 0f)
			{
				Plugin.Log.LogDebug((object)$"[SC] BONK BLOCKED {_displayName}  immune={_bonkImmuneTimer:F2}s remaining");
				return;
			}
			IsScaled = false;
			_shrinkTimer = 0f;
			Scaled.Remove(this);
			float num = ((OriginalScale.x > 0f) ? (_t.localScale.x / OriginalScale.x) : 0f);
			Plugin.Log.LogDebug((object)("[SC] EXPAND (bonk/instant) " + _displayName + $"  currentSize={num * 100f:F0}%" + string.Format("  mass {0} → {1:F3}", ((Object)(object)_rb != (Object)null) ? _rb.mass.ToString("F3") : "N/A", _originalMass)));
			_currentAnimSpeed = ResolveExpandSpeed();
			ApplyScale(OriginalScale);
			SetForceGrabPoint(active: true);
			if ((Object)(object)_networkPV != (Object)null && PhotonNetwork.InRoom)
			{
				_networkPV.RPC("RPC_Expand", (RpcTarget)1, Array.Empty<object>());
			}
			PlayImpactEffect();
			PlayCameraShake();
			if ((Object)(object)_rb != (Object)null)
			{
				_rb.mass = _originalMass;
			}
			if ((Object)(object)_roomVolumeCheck != (Object)null)
			{
				_roomVolumeCheck.currentSize = _originalRoomVolumeSize;
			}
			Handler?.OnRestore(this, isBonk: true);
			if (!_options.SuppressVoicePitch)
			{
				_audioPitch.RestorePitch();
			}
			ItemHandler.OnRestoreFields(_scaledItemFields);
			_scaledItemFields = null;
			ScaleMapIcon(1f);
		}

		private void ApplyScale(Vector3 target)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			_target = target;
			_animScale = _t.localScale;
			_transitioning = true;
			if (Handler is PlayerHandler)
			{
				if (_playerBounceAnim != null)
				{
					((MonoBehaviour)this).StopCoroutine(_playerBounceAnim);
				}
				_playerBounceAnim = ((MonoBehaviour)this).StartCoroutine(PlayerBounceAnim(_t.localScale, target));
			}
		}

		private void PlayImpactEffect()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			if (!_options.SuppressImpactFlash)
			{
				AssetManager instance = AssetManager.instance;
				if (instance != null)
				{
					instance.PhysImpactEffect(_t.position);
				}
			}
		}

		private void PlayCameraShake()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			if (!_options.SuppressCameraShake)
			{
				SemiFunc.CameraShakeImpactDistance(_t.position, 2f, 0.1f, 1f, 8f);
			}
		}

		private float ResolveExpandSpeed()
		{
			if (!(_options.RestoreSpeed > 0f))
			{
				return _options.Speed;
			}
			return _options.RestoreSpeed;
		}

		private void ScaleMapIcon(float factor)
		{
			//IL_0036: 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)
			MapCustom val = ((Component)this).GetComponent<MapCustom>();
			if ((Object)(object)val == (Object)null)
			{
				val = ((Component)this).GetComponentInParent<MapCustom>();
			}
			if ((Object)(object)val?.mapCustomEntity != (Object)null)
			{
				((Component)val.mapCustomEntity).transform.localScale = Vector3.one * Mathf.Max(factor, 0.3f);
			}
		}

		private void SetForceGrabPoint(bool active)
		{
			if ((Object)(object)_physGrabObject != (Object)null && (Object)(object)_physGrabObject.forceGrabPoint != (Object)null)
			{
				((Component)_physGrabObject.forceGrabPoint).gameObject.SetActive(active);
			}
		}

		private static float BackOutEase(float t)
		{
			return 1f + 2.70158f * Mathf.Pow(t - 1f, 3f) + 1.70158f * Mathf.Pow(t - 1f, 2f);
		}

		[IteratorStateMachine(typeof(<PlayerBounceAnim>d__61))]
		private IEnumerator PlayerBounceAnim(Vector3 from, Vector3 to)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: 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)
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <PlayerBounceAnim>d__61(0)
			{
				<>4__this = this,
				from = from,
				to = to
			};
		}

		[IteratorStateMachine(typeof(<ChallengeModeDeferred>d__62))]
		private IEnumerator ChallengeModeDeferred()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ChallengeModeDeferred>d__62(0)
			{
				<>4__this = this
			};
		}

		[IteratorStateMachine(typeof(<LobbyPitchDeferred>d__63))]
		private IEnumerator LobbyPitchDeferred()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <LobbyPitchDeferred>d__63(0);
		}

		private float[] PackOpts()
		{
			return new float[8] { _options.Factor, _options.Speed, _options.MassCap, _options.SpeedFactor, _options.AnimSpeedMultiplier, _options.FootstepPitchMultiplier, _options.BonkImmuneDuration, _options.RestoreSpeed };
		}

		private bool[] PackBools()
		{
			return new bool[7] { _options.PreserveMass, _options.InvertedMode, _options.SuppressImpactFlash, _options.SuppressVoicePitch, _options.IgnoreBonkExpand, _options.RejectExternalApply, _options.SuppressCameraShake };
		}

		[PunRPC]
		private void RPC_Shrink(Vector3 target, float[] opts, bool[] flags)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			Plugin.Log.LogDebug((object)string.Format("[SC] RPC_Shrink RECV  {0}  target={1}  factor={2}  speed={3}  handler={4}", _displayName, target, opts[0], opts[1], Handler?.GetType().Name ?? "null"));
			_options.Factor = opts[0];
			_options.Speed = opts[1];
			_options.MassCap = opts[2];
			_options.SpeedFactor = opts[3];
			_options.AnimSpeedMultiplier = opts[4];
			_options.FootstepPitchMultiplier = opts[5];
			_options.BonkImmuneDuration = opts[6];
			_options.RestoreSpeed = ((opts.Length > 7) ? opts[7] : 0f);
			_options.PreserveMass = flags[0];
			_options.InvertedMode = flags[1];
			_options.SuppressImpactFlash = flags.Length > 2 && flags[2];
			_options.SuppressVoicePitch = flags.Length > 3 && flags[3];
			_options.IgnoreBonkExpand = flags.Length > 4 && flags[4];
			_options.RejectExternalApply = flags.Length > 5 && flags[5];
			_options.SuppressCameraShake = flags.Length > 6 && flags[6];
			_invertedActive = flags[1];
			float factor = _options.Factor;
			IsScaled = true;
			_currentAnimSpeed = _options.Speed;
			Scaled.Add(this);
			if ((Object)(object)_rb != (Object)null && !_isItem && !_options.PreserveMass)
			{
				_rb.mass = Mathf.Clamp(_originalMass * factor, 0.5f, _options.MassCap);
			}
			if ((Object)(object)_roomVolumeCheck != (Object)null)
			{
				_roomVolumeCheck.currentSize = _originalRoomVolumeSize * factor;
			}
			ApplyScale(target);
			if (factor < 1f)
			{
				SetForceGrabPoint(active: false);
			}
			PlayImpactEffect();
			if (!_options.SuppressVoicePitch)
			{
				EnemyParent componentInParent = ((Component)this).GetComponentInParent<EnemyParent>();
				_audioPitch.ApplyPitch((Component)(object)(((Object)(object)componentInParent != (Object)null) ? ((ScaleController)(object)componentInParent) : this), factor);
			}
			_scaledItemFields = ItemHandler.OnShrinkFields(this, factor);
			Handler?.OnScale(this);
			if (factor < 1f && (Object)(object)_physGrabObject != (Object)null && Handler is ValuableHandler)
			{
				_physGrabObject.OverrideIndestructible(0.5f);
			}
			ScaleMapIcon(factor);
		}

		[PunRPC]
		private void RPC_Expand()
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			IsScaled = false;
			Scaled.Remove(this);
			if ((Object)(object)_rb != (Object)null)
			{
				_rb.mass = _originalMass;
			}
			if ((Object)(object)_roomVolumeCheck != (Object)null)
			{
				_roomVolumeCheck.currentSize = _originalRoomVolumeSize;
			}
			_currentAnimSpeed = ResolveExpandSpeed();
			ApplyScale(OriginalScale);
			SetForceGrabPoint(active: true);
			PlayImpactEffect();
			PlayCameraShake();
			if (!_options.SuppressVoicePitch)
			{
				_audioPitch.RestorePitch();
			}
			ItemHandler.OnRestoreFields(_scaledItemFields);
			_scaledItemFields = null;
			Handler?.OnRestore(this, isBonk: false);
			ScaleMapIcon(1f);
		}

		[PunRPC]
		private void RPC_PlayerPitchCancel()
		{
			PlayerHandler.State obj = HandlerState as PlayerHandler.State;
			if (obj != null)
			{
				PlayerVoiceChat voiceChat = obj.PlayerAvatar.voiceChat;
				if (voiceChat != null)
				{
					voiceChat.OverridePitchCancel();
				}
			}
		}

		public void RequestBonkExpand()
		{
			if (IsScaled)
			{
				if (SemiFunc.IsMasterClientOrSingleplayer())
				{
					DispatchExpandNow();
				}
				else if ((Object)(object)_networkPV != (Object)null && _networkPV.IsMine && PhotonNetwork.InRoom)
				{
					_networkPV.RPC("RPC_RequestExpand", (RpcTarget)2, new object[1] { true });
				}
			}
		}

		public void RequestInvertedReshrink()
		{
			if (!IsScaled && _invertedActive && !(_bonkImmuneTimer > 0f))
			{
				if (SemiFunc.IsMasterClientOrSingleplayer())
				{
					DispatchShrink(_options);
				}
				else if ((Object)(object)_networkPV != (Object)null && _networkPV.IsMine && PhotonNetwork.InRoom)
				{
					_networkPV.RPC("RPC_RequestInvertedReshrink", (RpcTarget)2, Array.Empty<object>());
				}
			}
		}

		[PunRPC]
		private void RPC_RequestInvertedReshrink()
		{
			if (SemiFunc.IsMasterClientOrSingleplayer() && !IsScaled && _invertedActive)
			{
				ScaleOptions @default = ScaleOptions.Default;
				@default.InvertedMode = true;
				@default.Duration = 0f;
				DispatchShrink(@default);
			}
		}

		public void RequestManualShrink()
		{
			if (IsScaled)
			{
				return;
			}
			if (SemiFunc.IsMasterClientOrSingleplayer())
			{
				if (AllowManualScale)
				{
					DispatchShrink(ScaleOptions.Default);
				}
			}
			else if ((Object)(object)_networkPV != (Object)null && _networkPV.IsMine && PhotonNetwork.InRoom)
			{
				_networkPV.RPC("RPC_RequestShrink", (RpcTarget)2, Array.Empty<object>());
			}
		}

		[PunRPC]
		private void RPC_RequestShrink()
		{
			if (SemiFunc.IsMasterClientOrSingleplayer() && AllowManualScale && !IsScaled)
			{
				DispatchShrink(ScaleOptions.Default);
			}
		}

		public void RequestManualExpand()
		{
			if (!IsScaled)
			{
				return;
			}
			if (SemiFunc.IsMasterClientOrSingleplayer())
			{
				if (AllowManualScale)
				{
					DispatchExpand();
				}
			}
			else if ((Object)(object)_networkPV != (Object)null && _networkPV.IsMine && PhotonNetwork.InRoom)
			{
				_networkPV.RPC("RPC_RequestExpand", (RpcTarget)2, new object[1] { false });
			}
		}

		[PunRPC]
		private void RPC_RequestExpand(bool checkImmunity)
		{
			if (SemiFunc.IsMasterClientOrSingleplayer() && IsScaled)
			{
				if (checkImmunity)
				{
					DispatchExpandNow();
				}
				else if (AllowManualScale)
				{
					DispatchExpand();
				}
			}
		}

		public static void CleanupAll()
		{
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			foreach (ScaleController item in Scaled)
			{
				if ((Object)(object)item == (Object)null)
				{
					continue;
				}
				item._audioPitch.RestorePitch();
				ItemHandler.OnRestoreFields(item._scaledItemFields);
				item._scaledItemFields = null;
				PlayerHandler.State obj = item.HandlerState as PlayerHandler.State;
				if (obj != null)
				{
					PlayerVoiceChat voiceChat = obj.PlayerAvatar.voiceChat;
					if (voiceChat != null)
					{
						voiceChat.OverridePitchCancel();
					}
				}
				item.Handler?.OnRestore(item, isBonk: false);
				item.IsScaled = false;
				item._invertedActive = false;
				item._transitioning = false;
				item._target = item.OriginalScale;
				item._animScale = item.OriginalScale;
				item._t.localScale = item.OriginalScale;
			}
			Scaled.Clear();
		}

		public override void OnJoinedRoom()
		{
			PhotonView? networkPV = _networkPV;
			if (networkPV != null)
			{
				networkPV.RefreshRpcMonoBehaviourCache();
			}
		}

		public override void OnPlayerEnteredRoom(Player newPlayer)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			if (SemiFunc.IsMasterClientOrSingleplayer())
			{
				if (ChallengeMode && Handler is PlayerHandler)
				{
					((MonoBehaviour)this).StartCoroutine(LobbyPitchDeferred());
				}
				if (IsScaled && !((Object)(object)_networkPV == (Object)null))
				{
					_networkPV.RPC("RPC_Shrink", newPlayer, new object[3]
					{
						_target,
						PackOpts(),
						PackBools()
					});
				}
			}
		}
	}
	public static class ScaleManager
	{
		public static void Apply(GameObject target)
		{
			Apply(target, ScaleOptions.Default);
		}

		public static void Apply(GameObject target, ScaleOptions options)
		{
			ScaleController controller = GetController(target);
			if (!((Object)(object)controller == (Object)null) && !IsLockedFromExternal(controller) && IsTargetAllowed(controller, options.AllowedTargets))
			{
				controller.DispatchShrink(options);
			}
		}

		public static bool ApplyIfNotScaled(GameObject target)
		{
			return ApplyIfNotScaled(target, ScaleOptions.Default);
		}

		public static bool ApplyIfNotScaled(GameObject target, ScaleOptions options)
		{
			ScaleController controller = GetController(target);
			if ((Object)(object)controller == (Object)null || controller.IsScaled)
			{
				return false;
			}
			if (IsLockedFromExternal(controller))
			{
				return false;
			}
			if (!IsTargetAllowed(controller, options.AllowedTargets))
			{
				return false;
			}
			controller.DispatchShrink(options);
			return true;
		}

		public static void ForceApply(GameObject target, ScaleOptions options)
		{
			ScaleController controller = GetController(target);
			if (!((Object)(object)controller == (Object)null) && IsTargetAllowed(controller, options.AllowedTargets))
			{
				controller.DispatchShrink(options);
			}
		}

		public static ScaleController? GetController(GameObject target)
		{
			ScaleController scaleController = target.GetComponent<ScaleController>();
			if (scaleController == null)
			{
				PlayerShrinkLink component = target.GetComponent<PlayerShrinkLink>();
				if (component == null)
				{
					return null;
				}
				scaleController = component.Controller;
			}
			return scaleController;
		}

		public static void Restore(GameObject target)
		{
			ScaleController controller = GetController(target);
			if (!((Object)(object)controller == (Object)null) && !IsLockedFromExternal(controller))
			{
				controller.DispatchExpand();
			}
		}

		public static void RestoreImmediate(GameObject target)
		{
			ScaleController controller = GetController(target);
			if (!((Object)(object)controller == (Object)null) && !IsLockedFromExternal(controller))
			{
				controller.DispatchExpandNow();
			}
		}

		public static void ForceRestore(GameObject target)
		{
			ScaleController controller = GetController(target);
			if (!((Object)(object)controller == (Object)null))
			{
				controller.DispatchExpand();
			}
		}

		public static bool UpdateOptions(GameObject target, ScaleOptions options)
		{
			ScaleController controller = GetController(target);
			if ((Object)(object)controller == (Object)null || !controller.IsScaled)
			{
				return false;
			}
			if (IsLockedFromExternal(controller))
			{
				return false;
			}
			controller._options = options;
			return true;
		}

		public static bool ForceUpdateOptions(GameObject target, ScaleOptions options)
		{
			ScaleController controller = GetController(target);
			if ((Object)(object)controller == (Object)null || !controller.IsScaled)
			{
				return false;
			}
			controller._options = options;
			return true;
		}

		public static bool IsScaled(GameObject target)
		{
			ScaleController controller = GetController(target);
			if ((Object)(object)controller != (Object)null)
			{
				return controller.IsScaled;
			}
			return false;
		}

		public static void CleanupAll()
		{
			ScaleController.CleanupAll();
		}

		private static bool IsTargetAllowed(ScaleController ctrl, ScaleTargets allowed)
		{
			IScaleHandler handler = ctrl.Handler;
			if (!(handler is PlayerHandler))
			{
				if (!(handler is EnemyHandler))
				{
					if (handler is ItemHandler || handler is VehicleHandler)
					{
						return (allowed & ScaleTargets.Items) != 0;
					}
					return (allowed & ScaleTargets.Valuables) != 0;
				}
				return (allowed & ScaleTargets.Enemies) != 0;
			}
			return (allowed & ScaleTargets.Players) != 0;
		}

		private static bool IsLockedFromExternal(ScaleController ctrl)
		{
			if (ctrl.IsScaled)
			{
				return ctrl._options.RejectExternalApply;
			}
			return false;
		}
	}
	[Flags]
	public enum ScaleTargets
	{
		None = 0,
		Players = 1,
		Enemies = 2,
		Items = 4,
		Valuables = 8,
		All = 0xF
	}
	public struct ScaleOptions
	{
		public float Factor;

		public float Duration;

		public float Speed;

		public float RestoreSpeed;

		public float BonkImmuneDuration;

		public float MassCap;

		public float SpeedFactor;

		public float AnimSpeedMultiplier;

		public float FootstepPitchMultiplier;

		public ScaleTargets AllowedTargets;

		public bool InvertedMode;

		public bool SuppressValueDropExpand;

		public bool PreserveMass;

		public bool SuppressImpactFlash;

		public bool SuppressCameraShake;

		public bool SuppressVoicePitch;

		public bool IgnoreBonkExpand;

		public bool RejectExternalApply;

		public static ScaleOptions Default
		{
			get
			{
				ScaleOptions result = default(ScaleOptions);
				result.Factor = 0.4f;
				result.Duration = 0f;
				result.Speed = 2f;
				result.RestoreSpeed = 0f;
				result.BonkImmuneDuration = 5f;
				result.MassCap = 50f;
				result.SpeedFactor = 0.75f;
				result.AnimSpeedMultiplier = 1.5f;
				result.FootstepPitchMultiplier = 1.5f;
				result.AllowedTargets = ScaleTargets.All;
				result.InvertedMode = false;
				result.SuppressValueDropExpand = false;
				result.PreserveMass = false;
				result.SuppressImpactFlash = false;
				result.SuppressCameraShake = false;
				result.SuppressVoicePitch = false;
				result.IgnoreBonkExpand = false;
				result.RejectExternalApply = false;
				return result;
			}
		}
	}
}
namespace ScalerCore.Utilities
{
	internal class AudioPitchHelper
	{
		private Sound[]? _pitchedSounds;

		private float[]? _soundOriginalPitch;

		private float[]? _soundOriginalLoopPitch;

		private static Sound[] GatherSounds(Component root)
		{
			List<Sound> list = new List<Sound>();
			MonoBehaviour[] componentsInChildren = root.GetComponentsInChildren<MonoBehaviour>(true);
			foreach (MonoBehaviour val in componentsInChildren)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				foreach (FieldInfo item in from f in ((object)val).GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
					where f.FieldType == typeof(Sound)
					select f)
				{
					object? value = item.GetValue(val);
					Sound val2 = (Sound)((value is Sound) ? value : null);
					if (val2 != null && !list.Contains(val2))
					{
						list.Add(val2);
					}
				}
			}
			return list.ToArray();
		}

		internal void ApplyPitch(Component searchRoot, float factor)
		{
			float num = 1f + (1f - factor) * 0.5f;
			_pitchedSounds = GatherSounds(searchRoot);
			_soundOriginalPitch = _pitchedSounds.Select((Sound s) => s.Pitch).ToArray();
			_soundOriginalLoopPitch = _pitchedSounds.Select((Sound s) => s.LoopPitch).ToArray();
			for (int i = 0; i < _pitchedSounds.Length; i++)
			{
				Sound val = _pitchedSounds[i];
				val.Pitch = _soundOriginalPitch[i] * num;
				float num2 = _soundOriginalLoopPitch[i];
				val.LoopPitch = num2 * num;
				if ((Object)(object)val.Source != (Object)null && val.Source.isPlaying)
				{
					AudioSource source = val.Source;
					source.pitch *= num;
				}
			}
			Plugin.Log.LogDebug((object)$"[SC]   sound pitch x{num:F2} on {_pitchedSounds.Length} Sound objects under {((Object)searchRoot.gameObject).name}");
		}

		internal void RestorePitch()
		{
			if (_pitchedSounds == null)
			{
				return;
			}
			for (int i = 0; i < _pitchedSounds.Length; i++)
			{
				Sound val = _pitchedSounds[i];
				if (val != null)
				{
					val.Pitch = _soundOriginalPitch[i];
					val.LoopPitch = _soundOriginalLoopPitch[i];
					if ((Object)(object)val.Source != (Object)null && val.Source.isPlaying)
					{
						val.Source.pitch = _soundOriginalLoopPitch[i];
					}
				}
			}
			_pitchedSounds = null;
			_soundOriginalPitch = null;
			_soundOriginalLoopPitch = null;
		}
	}
}
namespace ScalerCore.Patches
{
	internal static class EnemyPatchHelpers
	{
		internal static bool TryGetScaled(EnemyNavMeshAgent agent, out ScaleController? ctrl)
		{
			EnemyParent componentInParent = ((Component)agent).GetComponentInParent<EnemyParent>();
			ctrl = ((componentInParent != null) ? ((Component)componentInParent).GetComponentInChildren<ScaleController>() : null);
			if ((Object)(object)ctrl != (Object)null)
			{
				return ctrl.IsScaled;
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(EnemyNavMeshAgent), "OverrideAgent")]
	internal static class NavOverrideSpeedPatch
	{
		private static void Prefix(EnemyNavMeshAgent __instance, ref float speed)
		{
			if (EnemyPatchHelpers.TryGetScaled(__instance, out ScaleController ctrl))
			{
				speed *= ctrl._options.SpeedFactor;
			}
		}
	}
	[HarmonyPatch(typeof(EnemyNavMeshAgent), "UpdateAgent")]
	internal static class NavUpdateSpeedPatch
	{
		private static void Prefix(EnemyNavMeshAgent __instance, ref float speed)
		{
			if (EnemyPatchHelpers.TryGetScaled(__instance, out ScaleController ctrl))
			{
				speed *= ctrl._options.SpeedFactor;
			}
		}
	}
	[HarmonyPatch(typeof(EnemyFloater), "UpdateState")]
	internal static class FloaterChargeMoveInPatch
	{
		private static void Postfix(EnemyFloater __instance)
		{
			//IL_0047: 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_0086: Unknown result type (might be due to invalid IL or missing references)
			Enemy enemy = __instance.enemy;
			object obj;
			if (enemy == null)
			{
				obj = null;
			}
			else
			{
				EnemyRigidbody rigidbody = enemy.Rigidbody;
				obj = ((rigidbody != null) ? ((Component)rigidbody).GetComponent<ScaleController>() : null);
			}
			ScaleController scaleController = (ScaleController)obj;
			if ((Object)(object)scaleController == (Object)null || !scaleController.IsScaled)
			{
				return;
			}
			PlayerAvatar targetPlayer = __instance.targetPlayer;
			if (Object.op_Implicit((Object)(object)targetPlayer) && !(Vector3.Distance(__instance.feetTransform.position, ((Component)targetPlayer).transform.position) <= scaleController._options.Factor * 4f))
			{
				Enemy enemy2 = __instance.enemy;
				if (enemy2 != null)
				{
					enemy2.NavMeshAgent.SetDestination(((Component)targetPlayer).transform.position);
				}
			}
		}
	}
	[HarmonyPatch(typeof(HurtCollider), "PlayerHurt")]
	internal static class KnockbackPatch
	{
		private static void Prefix(HurtCollider __instance, out (bool playerKill, int playerDamage, int tumbleDamage, float force, float torque) __state)
		{
			__state = (__instance.playerKill, __instance.playerDamage, __instance.playerTumbleImpactHurtDamage, __instance.playerTumbleForce, __instance.playerTumbleTorque);
			ScaleController scaleController = null;
			if ((Object)(object)__instance.enemyHost != (Object)null)
			{
				EnemyRigidbody rigidbody = __instance.enemyHost.Rigidbody;
				scaleController = ((rigidbody != null) ? ((Component)rigidbody).GetComponent<ScaleController>() : null);
			}
			else
			{
				EnemyParent componentInParent = ((Component)__instance).GetComponentInParent<EnemyParent>();
				if ((Object)(object)componentInParent != (Object)null)
				{
					scaleController = ((Component)componentInParent).GetComponentInChildren<ScaleController>();
				}
			}
			if (!((Object)(object)scaleController == (Object)null) && scaleController.IsScaled)
			{
				if (scaleController._options.Factor < 1f)
				{
					__instance.playerKill = false;
				}
				__instance.playerDamage = Mathf.RoundToInt((float)__instance.playerDamage * scaleController._options.Factor);
				__instance.playerTumbleImpactHurtDamage = Mathf.RoundToInt((float)__instance.playerTumbleImpactHurtDamage * scaleController._options.Factor);
				__instance.playerTumbleForce *= scaleController._options.Factor;
				__instance.playerTumbleTorque *= scaleController._options.Factor;
			}
		}

		private static void Postfix(HurtCollider __instance, (bool playerKill, int playerDamage, int tumbleDamage, float force, float torque) __state)
		{
			(__instance.playerKill, __instance.playerDamage, __instance.playerTumbleImpactHurtDamage, __instance.playerTumbleForce, __instance.playerTumbleTorque) = __state;
		}
	}
	[HarmonyPatch(typeof(EnemyHeartHuggerGasGuider), "Update")]
	internal static class HeartHuggerGasPullPatch
	{
		private static void Postfix(EnemyHeartHuggerGasGuider __instance)
		{
			//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_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: 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_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 (!((Object)(object)__instance.enemyHeartHugger == (Object)null))
			{
				Enemy enemy = __instance.enemyHeartHugger.enemy;
				object obj;
				if (enemy == null)
				{
					obj = null;
				}
				else
				{
					EnemyRigidbody rigidbody = enemy.Rigidbody;
					obj = ((rigidbody != null) ? ((Component)rigidbody).GetComponent<ScaleController>() : null);
				}
				ScaleController scaleController = (ScaleController)obj;
				if (!((Object)(object)scaleController == (Object)null) && scaleController.IsScaled)
				{
					Vector3 position = __instance.enemyHeartHugger.headCenterTransform.position;
					Vector3 val = ((Component)__instance).transform.position - position;
					((Component)__instance).transform.position = position + val * scaleController._options.Factor;
				}
			}
		}
	}
	[HarmonyPatch(typeof(EnemyHealth), "Hurt")]
	internal static class EnemyBonkPatch
	{
		private static void Postfix(EnemyHealth __instance)
		{
			if (SemiFunc.IsMasterClientOrSingleplayer())
			{
				Enemy enemy = __instance.enemy;
				object obj;
				if (enemy == null)
				{
					obj = null;
				}
				else
				{
					EnemyRigidbody rigidbody = enemy.Rigidbody;
					obj = ((rigidbody != null) ? ((Component)rigidbody).GetComponent<ScaleController>() : null);
				}
				ScaleController scaleController = (ScaleController)obj;
				if (!((Object)(object)scaleController == (Object)null) && scaleController.IsScaled && !(scaleController._options.Factor >= 1f))
				{
					scaleController.DispatchExpandNow();
				}
			}
		}
	}
	[HarmonyPatch]
	internal static class EnemyVisionShrunkCrouchPatch
	{
		[CompilerGenerated]
		private sealed class <Transpiler>d__1 : IEnumerable<CodeInstruction>, IEnumerable, IEnumerator<CodeInstruction>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private CodeInstruction <>2__current;

			private int <>l__initialThreadId;

			private IEnumerable<CodeInstruction> instructions;

			public IEnumerable<CodeInstruction> <>3__instructions;

			private FieldInfo <isCrouchingField>5__2;

			private MethodInfo <helper>5__3;

			private IEnumerator<CodeInstruction> <>7__wrap3;

			CodeInstruction IEnumerator<CodeInstruction>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <Transpiler>d__1(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || (uint)(num - 1) <= 1u)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<isCrouchingField>5__2 = null;
				<helper>5__3 = null;
				<>7__wrap3 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cc: Expected O, but got Unknown
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<isCrouchingField>5__2 = AccessTools.Field(typeof(PlayerAvatar), "isCrouching");
						<helper>5__3 = AccessTools.Method(typeof(EnemyVisionShrunkCrouchPatch), "IsEffectivelyCrouching", (Type[])null, (Type[])null);
						<>7__wrap3 = instructions.GetEnumerator();
						<>1__state = -3;
						break;
					case 1:
						<>1__state = -3;
						break;
					case 2:
						<>1__state = -3;
						break;
					}
					if (<>7__wrap3.MoveNext())
					{
						CodeInstruction current = <>7__wrap3.Current;
						if (current.opcode == OpCodes.Ldfld && current.operand is FieldInfo fieldInfo && fieldInfo == <isCrouchingField>5__2)
						{
							<>2__current = new CodeInstruction(OpCodes.Call, (object)<helper>5__3);
							<>1__state = 1;
							return true;
						}
						<>2__current = current;
						<>1__state = 2;
						return true;
					}
					<>m__Finally1();
					<>7__wrap3 = null;
					return false;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<>7__wrap3 != null)
				{
					<>7__wrap3.Dispose();
				}
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<CodeInstruction> IEnumerable<CodeInstruction>.GetEnumerator()
			{
				<Transpiler>d__1 <Transpiler>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<Transpiler>d__ = this;
				}
				else
				{
					<Transpiler>d__ = new <Transpiler>d__1(0);
				}
				<Transpiler>d__.instructions = <>3__instructions;
				return <Transpiler>d__;
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<CodeInstruction>)this).GetEnumerator();
			}
		}

		private static MethodBase TargetMethod()
		{
			Type type = typeof(EnemyVision).GetNestedTypes(BindingFlags.NonPublic).FirstOrDefault((Type t) => t.Name.StartsWith("<Vision>"));
			if (type == null)
			{
				Plugin.Log.LogWarning((object)"[SC] EnemyVisionShrunkCrouchPatch: could not find Vision coroutine state machine");
				return null;
			}
			return AccessTools.Method(type, "MoveNext", (Type[])null, (Type[])null);
		}

		[IteratorStateMachine(typeof(<Transpiler>d__1))]
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <Transpiler>d__1(-2)
			{
				<>3__instructions = instructions
			};
		}

		internal static bool IsEffectivelyCrouching(PlayerAvatar pa)
		{
			if (pa.isCrouching)
			{
				return true;
			}
			ScaleController component = ((Component)pa).GetComponent<ScaleController>();
			if ((Object)(object)component != (Object)null && component.IsScaled)
			{
				return component._options.Factor < 1f;
			}
			return false;
		}
	}
}
namespace ScalerCore.Handlers
{
	internal class CartHandler : IScaleHandler
	{
		internal sealed class State
		{
			internal PhysGrabCart Cart;

			internal bool AddedEquippable;
		}

		public void Setup(ScaleController ctrl)
		{
			PhysGrabCart component = ((Component)ctrl).GetComponent<PhysGrabCart>();
			if (!((Object)(object)component == (Object)null))
			{
				ctrl.HandlerState = new State
				{
					Cart = component
				};
			}
		}

		public void OnScale(ScaleController ctrl)
		{
			State state = (State)ctrl.HandlerState;
			if (state != null)
			{
				state.AddedEquippable = PocketHelper.InjectEquippable(ctrl);
			}
		}

		public void OnRestore(ScaleController ctrl, bool isBonk)
		{
			State state = (State)ctrl.HandlerState;
			if (state != null && state.AddedEquippable)
			{
				PocketHelper.RemoveEquippable(ctrl);
				state.AddedEquippable = false;
			}
		}

		public void OnUpdate(ScaleController ctrl)
		{
		}

		public void OnLateUpdate(ScaleController ctrl)
		{
		}

		public void OnDestroy(ScaleController ctrl)
		{
		}
	}
	internal class CosmeticHandler : IScaleHandler
	{
		internal sealed class State
		{
			internal NotValuableObject NotValuable;

			internal int LastKnownHealth = -1;
		}

		public void Setup(ScaleController ctrl)
		{
			NotValuableObject component = ((Component)ctrl).GetComponent<NotValuableObject>();
			if (!((Object)(object)component == (Object)null))
			{
				ctrl.HandlerState = new State
				{
					NotValuable = component
				};
			}
		}

		public void OnScale(ScaleController ctrl)
		{
			State state = (State)ctrl.HandlerState;
			if (state != null)
			{
				state.LastKnownHealth = state.NotValuable.healthCurrent;
			}
		}

		public void OnRestore(ScaleController ctrl, bool isBonk)
		{
			State state = (State)ctrl.HandlerState;
			if (state != null)
			{
				state.LastKnownHealth = -1;
			}
		}

		public void OnUpdate(ScaleController ctrl)
		{
			State state = (State)ctrl.HandlerState;
			if (state != null && !ctrl._options.SuppressValueDropExpand)
			{
				int healthCurrent = state.NotValuable.healthCurrent;
				if (ctrl._bonkImmuneTimer > 0f)
				{
					state.LastKnownHealth = healthCurrent;
				}
				else if (state.LastKnownHealth >= 0 && healthCurrent < state.LastKnownHealth)
				{
					Plugin.Log.LogDebug((object)$"[SC] HEALTH DROP {ctrl._displayName}  {state.LastKnownHealth} -> {healthCurrent}  -> bonk expand");
					state.LastKnownHealth = -1;
					ctrl.DispatchExpandNow();
				}
				else
				{
					state.LastKnownHealth = healthCurrent;
				}
			}
		}

		public void OnLateUpdate(ScaleController ctrl)
		{
		}

		public void OnDestroy(ScaleController ctrl)
		{
		}
	}
	internal class DoorHandler : IScaleHandler
	{
		internal sealed class State
		{
			internal PhysGrabHinge Hinge;

			internal bool ShouldBreakOnShrink;
		}

		private const float AnchorDistanceThreshold = 1f;

		public void Setup(ScaleController ctrl)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			PhysGrabHinge component = ((Component)ctrl).GetComponent<PhysGrabHinge>();
			if (!((Object)(object)component == (Object)null))
			{
				State state = new State
				{
					Hinge = component
				};
				if ((Object)(object)component.hingePoint != (Object)null)
				{
					Vector3 localPosition = component.hingePoint.localPosition;
					float magnitude = ((Vector3)(ref localPosition)).magnitude;
					bool flag = component.wallTagObjects != null && component.wallTagObjects.Length != 0;
					state.ShouldBreakOnShrink = magnitude > 1f && flag;
					ManualLogSource log = Plugin.Log;
					string text = $"[SC]   Door: hingeAnchorDist={magnitude:F3}";
					GameObject[] wallTagObjects = component.wallTagObjects;
					log.LogDebug((object)(text + $"  wallTags={((wallTagObjects != null) ? wallTagObjects.Length : 0)}" + $"  willBreak={state.ShouldBreakOnShrink}" + $"  broken={component.broken}  dead={component.dead}"));
				}
				ctrl.HandlerState = state;
			}
		}

		public void OnScale(ScaleController ctrl)
		{
			State state = (State)ctrl.HandlerState;
			if (state != null && state.ShouldBreakOnShrink && !state.Hinge.broken && !state.Hinge.dead)
			{
				Plugin.Log.LogDebug((object)("[SC]   Door: breaking hinge on " + ctrl._displayName + " (anchor too far from origin)"));
				state.Hinge.HingeBreakImpulse();
				if ((Object)(object)state.Hinge.joint != (Object)null)
				{
					Object.Destroy((Object)(object)state.Hinge.joint);
					state.Hinge.joint = null;
				}
			}
		}

		public void OnRestore(ScaleController ctrl, bool isBonk)
		{
		}

		public void OnUpdate(ScaleController ctrl)
		{
		}

		public void OnLateUpdate(ScaleController ctrl)
		{
		}

		public void OnDestroy(ScaleController ctrl)
		{
		}
	}
	internal class EnemyHandler : IScaleHandler
	{
		internal sealed class State
		{
			internal EnemyRigidbody EnemyRb;

			internal EnemyNavMeshAgent? NavAgent;

			internal Transform? AnimTarget;

			internal Vector3 AnimOriginalScale;

			internal Vector3 AnimOriginalLocalPos;

			internal EnemyBombThrowerHead? BtHead;

			internal Vector3 BtHeadOriginalScale;

			internal Vector3 RbOriginalLocalPos;

			internal float OriginalDefaultSpeed;

			internal float OriginalAgentRadius;

			internal float OriginalSpeedChase;

			internal float OriginalSpeedIdle;

			internal float OriginalRotSpeedChase;

			internal float OriginalRotSpeedIdle;

			internal GrabForce? OriginalGrabForce;

			internal GrabForce? MiniGrabForce;

			internal bool OriginalsCaptured;

			internal IEnemyVisualHandler? VisualHandler;

			internal object? VisualState;
		}

		public void Setup(ScaleController ctrl)
		{
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Expected O, but got Unknown
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Expected O, but got Unknown
			EnemyParent componentInParent = ((Component)ctrl).GetComponentInParent<EnemyParent>();
			if ((Object)(object)componentInParent == (Object)null)
			{
				return;
			}
			State state = new State();
			Transform bestVisual = null;
			int bestRenderers = 0;
			Animator[] componentsInChildren = ((Component)componentInParent).GetComponentsInChildren<Animator>();
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				CheckVisualGO(((Component)componentsInChildren[i]).gameObject);
			}
			BotSystemSpringPoseAnimator[] componentsInChildren2 = ((Component)componentInParent).GetComponentsInChildren<BotSystemSpringPoseAnimator>();
			for (int i = 0; i < componentsInChildren2.Length; i++)
			{
				CheckVisualGO(((Component)componentsInChildren2[i]).gameObject);
			}
			while ((Object)(object)bestVisual != (Object)null && (Object)(object)bestVisual.parent != (Object)null && (Object)(object)bestVisual.parent != (Object)(object)((Component)componentInParent).transform)
			{
				int num = ((Component)bestVisual).GetComponentsInChildren<Renderer>().Length;
				if (((Component)bestVisual.parent).GetComponentsInChildren<Renderer>().Length <= num)
				{
					break;
				}
				bool flag = false;
				foreach (Transform item in bestVisual.parent)
				{
					Transform val = item;
					if (!((Object)(object)val == (Object)(object)bestVisual))
					{
						Animator component = ((Component)val).GetComponent<Animator>();
						if ((Object)(object)component != (Object)null && (Object)(object)component.runtimeAnimatorController != (Object)null)
						{
							flag = true;
							break;
						}
						if ((Object)(object)((Component)val).GetComponent<EnemyRigidbody>() != (Object)null)
						{
							flag = true;
							break;
						}
					}
				}
				if (flag)
				{
					break;
				}
				bestVisual = bestVisual.parent;
			}
			if ((Object)(object)bestVisual == (Object)null)
			{
				foreach (Transform item2 in ((Component)componentInParent).transform)
				{
					Transform val2 = item2;
					if (!((Object)(object)val2 == (Object)(object)ctrl._t) && !((Object)(object)((Component)val2).GetComponent<EnemyRigidbody>() != (Object)null) && !((Object)(object)((Component)val2).GetComponent<Rigidbody>() != (Object)null))
					{
						int num2 = ((Component)val2).GetComponentsInChildren<Renderer>().Length;
						if (num2 > bestRenderers)
						{
							bestRenderers = num2;
							bestVisual = val2;
						}
					}
				}
			}
			if ((Object)(object)bestVisual != (Object)null)
			{
				state.AnimTarget = bestVisual;
				state.AnimOriginalScale = state.AnimTarget.localScale;
				state.AnimOriginalLocalPos = state.AnimTarget.localPosition;
			}
			state.NavAgent = ((Component)componentInParent).GetComponentInChildren<EnemyNavMeshAgent>();
			state.EnemyRb = ((Component)ctrl).GetComponent<EnemyRigidbody>();
			EnemyBombThrowerHead componentInChildren = ((Component)componentInParent).GetComponentInChildren<EnemyBombThrowerHead>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				state.BtHead = componentInChildren;
				state.BtHeadOriginalScale = ((Component)componentInChildren).transform.localScale;
			}
			ctrl._physGrabObject = ((Component)ctrl).GetComponent<PhysGrabObject>();
			state.RbOriginalLocalPos = ctrl._t.localPosition;
			string text = EnemyVisualRegistry.ExtractEnemyName(componentInParent);
			state.VisualHandler = EnemyVisualRegistry.Resolve(text);
			state.VisualState = state.VisualHandler.Setup(ctrl, state, componentInParent);
			Plugin.Log.LogDebug((object)("[SC]   visualHandler=" + state.VisualHandler.GetType().Name + " for '" + text + "'"));
			ctrl.HandlerState = state;
			void CheckVisualGO(GameObject go)
			{
				if (!((Object)(object)go.GetComponent<EnemyRigidbody>() != (Object)null) && !((Object)(object)go.GetComponentInChildren<Renderer>() == (Object)null))
				{
					Animator component2 = go.GetComponent<Animator>();
					if (!((Object)(object)component2 != (Object)null) || !((Object)(object)component2.runtimeAnimatorController == (Object)null))
					{
						int num3 = go.GetComponentsInChildren<Renderer>().Length;
						if (num3 > bestRenderers)
						{
							bestRenderers = num3;
							bestVisual = go.transform;
						}
					}
				}
			}
		}

		public void OnScale(ScaleController ctrl)
		{
			State state = (State)ctrl.HandlerState;
			if (state == null)
			{
				return;
			}
			if ((Object)(object)state.NavAgent != (Object)null)
			{
				state.OriginalDefaultSpeed = state.NavAgent.DefaultSpeed;
				state.NavAgent.DefaultSpeed = state.OriginalDefaultSpeed * ctrl._options.SpeedFactor;
				NavMeshAgent agent = state.NavAgent.Agent;
				if ((Object)(object)agent != (Object)null)
				{
					agent.speed *= ctrl._options.SpeedFactor;
					state.OriginalAgentRadius = agent.radius;
					agent.radius *= ctrl._options.Factor;
					Plugin.Log.LogDebug((object)$"[SC]   navSpeed {state.OriginalDefaultSpeed:F2} → {state.NavAgent.DefaultSpeed:F2}  radius {state.OriginalAgentRadius:F2} → {agent.radius:F2}");
				}
			}
			if ((Object)(object)state.EnemyRb != (Object)null)
			{
				state.OriginalGrabForce = state.EnemyRb.grabForceNeeded;
				state.MiniGrabForce = ScriptableObject.CreateInstance<GrabForce>();
				float num = (((Object)(object)state.OriginalGrabForce != (Object)null) ? state.OriginalGrabForce.amount : 0f);
				state.MiniGrabForce.amount = num * ctrl._options.Factor;
				state.EnemyRb.grabForceNeeded = state.MiniGrabForce;
				state.OriginalSpeedChase = state.EnemyRb.positionSpeedChase;
				state.OriginalSpeedIdle = state.EnemyRb.positionSpeedIdle;
				state.OriginalRotSpeedChase = state.EnemyRb.rotationSpeedChase;
				state.OriginalRotSpeedIdle = state.EnemyRb.rotationSpeedIdle;
				float num2 = ctrl._options.Factor * ctrl._options.Factor;
				state.EnemyRb.positionSpeedChase = state.OriginalSpeedChase * num2;
				state.EnemyRb.positionSpeedIdle = state.OriginalSpeedIdle * num2;
				state.EnemyRb.rotationSpeedChase = state.OriginalRotSpeedChase * num2;
				state.EnemyRb.rotationSpeedIdle = state.OriginalRotSpeedIdle * num2;
				Plugin.Log.LogDebug((object)$"[SC]   grabForce {num:F2} → {state.MiniGrabForce.amount:F2}");
				Plugin.Log.LogDebug((object)$"[SC]   posSpeedChase {state.OriginalSpeedChase:F2} → {state.EnemyRb.positionSpeedChase:F2}  posSpeedIdle {state.OriginalSpeedIdle:F2} → {state.EnemyRb.positionSpeedIdle:F2}");
			}
			state.OriginalsCaptured = true;
		}

		public void OnRestore(ScaleController ctrl, bool isBonk)
		{
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			State state = (State)ctrl.HandlerState;
			if (state == null)
			{
				return;
			}
			if ((Object)(object)state.NavAgent != (Object)null)
			{
				NavMeshAgent agent = state.NavAgent.Agent;
				Plugin.Log.LogDebug((object)string.Format("[SC]   EXPAND{0} navSpeed {1} → {2:F2}  radius {3} → {4:F2}", isBonk ? "(bonk)" : "", ((Object)(object)agent != (Object)null) ? agent.speed.ToString("F2") : "N/A", state.OriginalDefaultSpeed, ((Object)(object)agent != (Object)null) ? agent.radius.ToString("F2") : "N/A", state.OriginalAgentRadius));
				state.NavAgent.DefaultSpeed = state.OriginalDefaultSpeed;
				NavMeshAgent agent2 = state.NavAgent.Agent;
				if ((Object)(object)agent2 != (Object)null)
				{
					agent2.speed = state.OriginalDefaultSpeed;
					agent2.radius = state.OriginalAgentRadius;
					if (isBonk && agent2.isOnNavMesh)
					{
						agent2.Warp(agent2.nextPosition);
					}
				}
			}
			if ((Object)(object)state.EnemyRb != (Object)null)
			{
				Plugin.Log.LogDebug((object)string.Format("[SC]   EXPAND{0} posSpeedChase {1:F2} → {2:F2}  posSpeedIdle {3:F2} → {4:F2}", isBonk ? "(bonk)" : "", state.EnemyRb.positionSpeedChase, state.OriginalSpeedChase, state.EnemyRb.positionSpeedIdle, state.OriginalSpeedIdle));
				if ((Object)(object)state.OriginalGrabForce != (Object)null)
				{
					state.EnemyRb.grabForceNeeded = state.OriginalGrabForce;
				}
				if ((Object)(object)state.MiniGrabForce != (Object)null)
				{
					Object.Destroy((Object)(object)state.MiniGrabForce);
					state.MiniGrabForce = null;
				}
				state.EnemyRb.positionSpeedChase = state.OriginalSpeedChase;
				state.EnemyRb.positionSpeedIdle = state.OriginalSpeedIdle;
				state.EnemyRb.rotationSpeedChase = state.OriginalRotSpeedChase;
				state.EnemyRb.rotationSpeedIdle = state.OriginalRotSpeedIdle;
			}
			if (isBonk || !ctrl._transitioning)
			{
				state.VisualHandler?.OnRestore(ctrl, state, state.VisualState);
			}
		}

		public void OnUpdate(ScaleController ctrl)
		{
			if ((Object)(object)ctrl._rb != (Object)null && !ctrl._options.PreserveMass)
			{
				float num = Mathf.Clamp(ctrl._originalMass * ctrl._options.Factor, 0.5f, ctrl._options.MassCap);
				if (Mathf.Abs(ctrl._rb.mass - num) > 0.001f)
				{
					ctrl._rb.mass = num;
				}
			}
			if (ctrl._options.Factor < 1f && (Object)(object)ctrl._physGrabObject != (Object)null && ctrl._physGrabObject.playerGrabbing.Count > 0)
			{
				ctrl._physGrabObject.OverrideMinGrabStrength(5f, 0.1f);
			}
		}

		public void OnLateUpdate(ScaleController ctrl)
		{
			//IL_0011: 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)
			State state = (State)ctrl.HandlerState;
			if (state != null && ctrl.OriginalScale.x != 0f && (ctrl.IsScaled || ctrl._transitioning))
			{
				float ratio = ctrl._animScale.x / ctrl.OriginalScale.x;
				if (state.VisualHandler != null)
				{
					state.VisualHandler.OnLateUpdate(ctrl, state, state.VisualState, ratio);
				}
			}
		}

		public void OnDestroy(ScaleController ctrl)
		{
			State state = (State)ctrl.HandlerState;
			if (state != null && state.VisualHandler != null)
			{
				state.VisualHandler.OnRestore(ctrl, state, state.VisualState);
			}
		}
	}
	internal interface IEnemyVisualHandler
	{
		object? Setup(ScaleController ctrl, EnemyHandler.State state, EnemyParent ep);

		void OnLateUpdate(ScaleController ctrl, EnemyHandler.State state, object? visualState, float ratio);

		void OnRestore(ScaleController ctrl, EnemyHandler.State state, object? visualState);
	}
	internal static class EnemyVisualRegistry
	{
		private static readonly Dictionary<string, IEnemyVisualHandler> _overrides = new Dictionary<string, IEnemyVisualHandler>();

		private static readonly IEnemyVisualHandler _default = new DefaultVisualHandler();

		private static bool _registered;

		internal static string ExtractEnemyName(EnemyParent ep)
		{
			string text = ((Object)((Component)ep).gameObject).name;
			int num = text.IndexOf("(Clone)");
			if (num >= 0)
			{
				text = text.Substring(0, num);
			}
			if (text.StartsWith("Enemy - "))
			{
				text = text.Substring("Enemy - ".Length);
			}
			return text.Trim();
		}

		internal static IEnemyVisualHandler Resolve(string enemyName)
		{
			EnsureRegistered();
			if (!_overrides.TryGetValue(enemyName, out IEnemyVisualHandler value))
			{
				return _default;
			}
			return value;
		}

		private static void EnsureRegistered()
		{
			if (!_registered)
			{
				_registered = true;
				SinkerVisualHandler value = new SinkerVisualHandler();
				HeartHuggerVisualHandler value2 = new HeartHuggerVisualHandler();
				LoomVisualHandler value3 = new LoomVisualHandler();
				TricycleVisualHandler value4 = new TricycleVisualHandler();
				BirthdayBoyVisualHandler value5 = new BirthdayBoyVisualHandler();
				_overrides["Tumbler"] = value;
				_overrides["Floater"] = value;
				_overrides["Runner"] = value;
				_overrides["Slow Walker"] = value;
				_overrides["Elsa"] = value;
				_overrides["Heart Hugger"] = value2;
				_overrides["Shadow"] = value3;
				_overrides["Tricycle"] = value4;
				_overrides["Birthday boy"] = value5;
			}
		}
	}
	public interface IScaleHandler
	{
		void Setup(ScaleController ctrl);

		void OnScale(ScaleController ctrl);

		void OnRestore(ScaleController ctrl, bool isBonk);

		void OnUpdate(ScaleController ctrl);

		void OnLateUpdate(ScaleController ctrl);

		void OnDestroy(ScaleController ctrl);
	}
	internal class ItemHandler : IScaleHandler
	{
		internal struct ScaledField
		{
			public object comp;

			public FieldInfo field;

			public float original;
		}

		internal sealed class State
		{
			internal ItemOrb? ItemOrb;

			internal bool AddedEquippable;
		}

		private static readonly string[] _floatFieldsToScale = new string[9] { "explosionSize", "explosionForceMultiplier", "orbRadiusMultiplier", "maxSpeedKmh", "softMaxSpeedKmh", "maxForwardSpeed", "maxReverseSpeed", "hyperMaxSpeed", "bikeForwardSpeed" };

		private static readonly string[] _intFieldsToScale = new string[2] { "explosionDamage", "explosionDamageEnemy" };

		private static readonly string[] _soFieldNames = new string[1] { "explosionPreset" };

		public void Setup(ScaleController ctrl)
		{
			State state = new State();
			state.ItemOrb = ((Component)ctrl).GetComponent<ItemOrb>();
			ctrl.HandlerState = state;
		}

		public void OnScale(ScaleController ctrl)
		{
			State state = (St