Decompiled source of ScalerCore v0.4.4

ScalerCore.dll

Decompiled 2 weeks 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 ExitGames.Client.Photon;
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.4.4.0")]
[assembly: AssemblyInformationalVersion("0.4.4+c1e37065e0ee1aaf874bc1281ba7e8ce46082a46")]
[assembly: AssemblyProduct("ScalerCore")]
[assembly: AssemblyTitle("ScalerCore")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.4.4.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.4.4";
	}
	[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;
				if (num || flag)
				{
					((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(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(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;
			}
			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(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;
			}
		}
	}
	public class PlayerShrinkLink : MonoBehaviour
	{
		public ScaleController Controller;
	}
	[BepInPlugin("Vippy.ScalerCore", "ScalerCore", "0.4.4")]
	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__56 : 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__56(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__57 : 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__57(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__55 : 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__55(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;

		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 ScaleTargets TargetType
		{
			get
			{
				if (!(Handler is PlayerHandler))
				{
					if (!(Handler is EnemyHandler))
					{
						if (!(Handler is ItemHandler))
						{
							return ScaleTargets.Valuables;
						}
						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_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: 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_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_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: 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 speed = _options.Speed;
				Vector3 originalScale = OriginalScale;
				float num = speed * ((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_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_02af: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_030e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0338: Unknown result type (might be due to invalid IL or missing references)
			//IL_033e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0343: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0438: Unknown result type (might be due to invalid IL or missing references)
			//IL_0483: Unknown result type (might be due to invalid IL or missing references)
			//IL_048d: 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;
				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;
			}
			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));
			}
			AssetManager instance = AssetManager.instance;
			if (instance != null)
			{
				instance.PhysImpactEffect(_t.position);
			}
			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);
			}
			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_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			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)));
				ApplyScale(OriginalScale);
				SetForceGrabPoint(active: true);
				if ((Object)(object)_networkPV != (Object)null && PhotonNetwork.InRoom)
				{
					_networkPV.RPC("RPC_Expand", (RpcTarget)1, Array.Empty<object>());
				}
				AssetManager instance = AssetManager.instance;
				if (instance != null)
				{
					instance.PhysImpactEffect(_t.position);
				}
				SemiFunc.CameraShakeImpactDistance(_t.position, 2f, 0.1f, 1f, 8f);
				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;
				ScaleMapIcon(1f);
			}
		}

		public void DispatchExpandNow()
		{
			//IL_0063: 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_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			if (!SemiFunc.IsMasterClientOrSingleplayer() || !IsScaled)
			{
				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)));
			ApplyScale(OriginalScale);
			SetForceGrabPoint(active: true);
			if ((Object)(object)_networkPV != (Object)null && PhotonNetwork.InRoom)
			{
				_networkPV.RPC("RPC_Expand", (RpcTarget)1, Array.Empty<object>());
			}
			AssetManager instance = AssetManager.instance;
			if (instance != null)
			{
				instance.PhysImpactEffect(_t.position);
			}
			SemiFunc.CameraShakeImpactDistance(_t.position, 2f, 0.1f, 1f, 8f);
			if ((Object)(object)_rb != (Object)null)
			{
				_rb.mass = _originalMass;
			}
			if ((Object)(object)_roomVolumeCheck != (Object)null)
			{
				_roomVolumeCheck.currentSize = _originalRoomVolumeSize;
			}
			Handler?.OnRestore(this, isBonk: true);
			_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 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__55))]
		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__55(0)
			{
				<>4__this = this,
				from = from,
				to = to
			};
		}

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

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

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

		private bool[] PackBools()
		{
			return new bool[2] { _options.PreserveMass, _options.InvertedMode };
		}

		[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_017c: 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_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: 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.PreserveMass = flags[0];
			_options.InvertedMode = flags[1];
			_invertedActive = flags[1];
			float factor = _options.Factor;
			IsScaled = true;
			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);
			}
			AssetManager instance = AssetManager.instance;
			if (instance != null)
			{
				instance.PhysImpactEffect(_t.position);
			}
			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_0053: 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)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			IsScaled = false;
			Scaled.Remove(this);
			if ((Object)(object)_rb != (Object)null)
			{
				_rb.mass = _originalMass;
			}
			if ((Object)(object)_roomVolumeCheck != (Object)null)
			{
				_roomVolumeCheck.currentSize = _originalRoomVolumeSize;
			}
			ApplyScale(OriginalScale);
			SetForceGrabPoint(active: true);
			AssetManager instance = AssetManager.instance;
			if (instance != null)
			{
				instance.PhysImpactEffect(_t.position);
			}
			SemiFunc.CameraShakeImpactDistance(_t.position, 2f, 0.1f, 1f, 8f);
			_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) && (!(controller.Handler is PlayerHandler) || (options.AllowedTargets & ScaleTargets.Players) != 0) && (!(controller.Handler is EnemyHandler) || (options.AllowedTargets & ScaleTargets.Enemies) != 0) && (!(controller.Handler is ItemHandler) || (options.AllowedTargets & ScaleTargets.Items) != 0) && (!(controller.Handler is ValuableHandler) || (options.AllowedTargets & ScaleTargets.Valuables) != 0))
			{
				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 (controller.Handler is PlayerHandler && (options.AllowedTargets & ScaleTargets.Players) == 0)
			{
				return false;
			}
			if (controller.Handler is EnemyHandler && (options.AllowedTargets & ScaleTargets.Enemies) == 0)
			{
				return false;
			}
			if (controller.Handler is ItemHandler && (options.AllowedTargets & ScaleTargets.Items) == 0)
			{
				return false;
			}
			if (controller.Handler is ValuableHandler && (options.AllowedTargets & ScaleTargets.Valuables) == 0)
			{
				return false;
			}
			controller.DispatchShrink(options);
			return true;
		}

		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))
			{
				controller.DispatchExpand();
			}
		}

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

		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();
		}
	}
	[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 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 static ScaleOptions Default
		{
			get
			{
				ScaleOptions result = default(ScaleOptions);
				result.Factor = 0.4f;
				result.Duration = 0f;
				result.Speed = 2f;
				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;
				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))
				{
					ScaleManager.RestoreImmediate(((Component)scaleController).gameObject);
				}
			}
		}
	}
	[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 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[3] { "explosionSize", "explosionForceMultiplier", "orbRadiusMultiplier" };

		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 = (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)
		{
			State state = (State)ctrl.HandlerState;
			if ((Object)(object)state?.ItemOrb != (Object)null)
			{
				OnUpdateOrb(state.ItemOrb, ctrl._options.Factor);
			}
		}

		public void OnLateUpdate(ScaleController ctrl)
		{
		}

		public void OnDestroy(ScaleController ctrl)
		{
		}

		internal static List<ScaledField>? OnShrinkFields(ScaleController ctrl, float factor)
		{
			List<ScaledField> list = new List<ScaledField>();
			List<object> list2 = new List<object>();
			MonoBehaviour[] components = ((Component)ctrl).GetComponents<MonoBehaviour>();
			foreach (MonoBehaviour val in components)
			{
				if ((Object)(object)val == (Object)null || (Object)(object)val == (Object)(object)ctrl)
				{
					continue;
				}
				list2.Add(val);
				Type type = ((object)val).GetType();
				string[] soFieldNames = _soFieldNames;
				foreach (string text in soFieldNames)
				{
					FieldInfo field = type.GetField(text, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					if (!(field == null))
					{
						object value = field.GetValue(val);
						if (value != null)
						{
							list2.Add(value);
							Plugin.Log.LogDebug((object)("[SC]   following SO ref " + type.Name + "." + text + " -> " + value.GetType().Name));
						}
					}
				}
			}
			foreach (object item in list2)
			{
				Type type2 = item.GetType();
				string[] soFieldNames = _floatFieldsToScale;
				foreach (string text2 in soFieldNames)
				{
					FieldInfo field2 = type2.GetField(text2, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					if (!(field2 == null) && !(field2.FieldType != typeof(float)))
					{
						float num = (float)field2.GetValue(item);
						list.Add(new ScaledField
						{
							comp = item,
							field = field2,
							original = num
						});
						field2.SetValue(item, num * factor);
						Plugin.Log.LogDebug((object)$"[SC]   itemField {type2.Name}.{text2} {num:F2} -> {num * factor:F2}");
					}
				}
				soFieldNames = _intFieldsToScale;
				foreach (string text3 in soFieldNames)
				{
					FieldInfo field3 = type2.GetField(text3, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					if (!(field3 == null) && !(field3.FieldType != typeof(int)))
					{
						int num2 = (int)field3.GetValue(item);
						int num3 = Mathf.RoundToInt((float)num2 * factor);
						list.Add(new ScaledField
						{
							comp = item,
							field = field3,
							original = num2
						});
						field3.SetValue(item, num3);
						Plugin.Log.LogDebug((object)$"[SC]   itemField {type2.Name}.{text3} {num2} -> {num3}");
					}
				}
			}
			if (list.Count == 0)
			{
				Plugin.Log.LogDebug((object)("[SC]   itemField scan: no scalable fields found on " + ((Object)((Component)ctrl).gameObject).name));
				return null;
			}
			return list;
		}

		internal static void OnRestoreFields(List<ScaledField>? scaledFields)
		{
			if (scaledFields == null)
			{
				return;
			}
			foreach (ScaledField scaledField in scaledFields)
			{
				if (scaledField.comp != null)
				{
					if (scaledField.field.FieldType == typeof(int))
					{
						scaledField.field.SetValue(scaledField.comp, (int)scaledField.original);
					}
					else
					{
						scaledField.field.SetValue(scaledField.comp, scaledField.original);
					}
				}
			}
		}

		internal static void OnUpdateOrb(ItemOrb itemOrb, float factor)
		{
			itemOrb.orbRadius = itemOrb.orbRadiusOriginal * factor;
		}
	}
	internal class PlayerHandler : IScaleHandler
	{
		internal sealed class State
		{
			internal PlayerAvatar PlayerAvatar;

			internal PlayerExpression? PlayerExpression;

			internal Vector3 OriginalCamOffset;

			internal float OriginalCrouchPos;

			internal float OriginalCrawlPos;

			internal CameraCrawlPosition? CameraCrawl;

			internal PlayerVisionTarget? VisionTarget;

			internal float VisionStandPos;

			internal float VisionCrouchPos;

			internal float VisionCrawlPos;

			internal CapsuleCollider? StandCheckCollider;

			internal float OriginalStandCheckHeight;

			internal float OriginalStandCheckRadius;

			internal Vector3 OriginalStandCheckOffset;

			internal Vector3 OriginalStandCollision;

			internal Vector3 OriginalCrouchCollision;

			internal float OriginalGrabMinDist;

			internal float OriginalGrabMaxDist;

			internal float OriginalFOV;

			internal float OriginalNearClip;

			internal bool WasExpressing;

			internal float TumbleFollowOriginalY = float.NaN;

			internal bool WasTumbling;

			internal Transform? MenuAvatarTransform;

			internal Vector3 MenuAvatarOriginalScale;

			internal PlayerAvatar? MenuPlayerAvatar;

			internal PlayerExpression? MenuExpression;

			internal PlayerEyes? MenuEyes;
		}

		public const float Multiplier = 3f;

		public const int Priority = 4;

		public const float SpringSpeedIn = 3f;

		public const float SpringDampIn = 0.5f;

		public const float SpringSpeedOut = 5f;

		public const float SpringDampOut = 0.5f;

		public const float PupilReturnSpeed = 3f;

		private static (float strength, float range) GetGrabFactors(float factor)
		{
			float num = factor * 1.5f;
			float num2 = ((factor < 1f) ? 1f : 2f);
			return (Mathf.Clamp(num, 0.6f, num2), factor);
		}

		public void Setup(ScaleController ctrl)
		{
			//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)
			PlayerAvatar component = ((Component)ctrl).GetComponent<PlayerAvatar>();
			if (!((Object)(object)component == (Object)null))
			{
				State state = new State
				{
					PlayerAvatar = component
				};
				if ((Object)(object)component.playerAvatarVisuals != (Object)null)
				{
					ctrl._t = ((Component)component.playerAvatarVisuals).transform;
					ctrl.OriginalScale = ctrl._t.localScale;
					ctrl._target = ctrl.OriginalScale;
					ctrl._animScale = ctrl.OriginalScale;
					state.PlayerExpression = ((Component)component.playerAvatarVisuals).GetComponent<PlayerExpression>();
				}
				PlayerAvatarCollision component2 = ((Component)component).GetComponent<PlayerAvatarCollision>();
				if ((Object)(object)component2?.CollisionTransform != (Object)null)
				{
					(((Component)component2.CollisionTransform).GetComponent<PlayerShrinkLink>() ?? ((Component)component2.CollisionTransform).gameObject.AddComponent<PlayerShrinkLink>()).Controller = ctrl;
					Plugin.Log.LogDebug((object)("[SC] PlayerShrinkLink attached → " + ((Object)((Component)component2.CollisionTransform).gameObject).name + "  colliderGO=" + (((Object)(object)component2.Collider != (Object)null) ? ((Object)((Component)component2.Collider).gameObject).name : "null") + "  avatar=" + ((Object)((Component)ctrl).gameObject).name));
				}
				else
				{
					Plugin.Log.LogWarning((object)$"[SC] PlayerShrinkLink SKIP  pac={(Object)(object)component2 != (Object)null}  collisionXform={(Object)(object)component2?.CollisionTransform != (Object)null}  avatar={((Obj