Decompiled source of Glissando v1.0.1

Glissando.dll

Decompiled 3 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.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Glissando.Settings;
using Glissando.Utils;
using GlobalEnums;
using HarmonyLib;
using HutongGames.PlayMaker;
using HutongGames.PlayMaker.Actions;
using InControl;
using Microsoft.CodeAnalysis;
using Silksong.FsmUtil;
using Silksong.ModMenu.Elements;
using Silksong.ModMenu.Models;
using Silksong.ModMenu.Plugin;
using Silksong.ModMenu.Screens;
using TeamCherry.Localization;
using TeamCherry.SharedUtils;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Glissando")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1+f777721deb722787015a01984a324b4e0f3a14ed")]
[assembly: AssemblyProduct("Glissando")]
[assembly: AssemblyTitle("Glissando")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/kaycodes13/Silksong.Glissando")]
[assembly: NeutralResourcesLanguage("EN")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	[Embedded]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	[Embedded]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace Microsoft.CodeAnalysis
{
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace Glissando
{
	[BepInDependency("org.silksong-modding.fsmutil", "0.3.17")]
	[BepInDependency("org.silksong-modding.modmenu", "0.7.6")]
	[BepInDependency("org.silksong-modding.i18n", "1.1.1")]
	[BepInPlugin("io.github.kaycodes13.glissando", "Glissando", "1.0.1")]
	public class GlissandoPlugin : BaseUnityPlugin, IModMenuCustomMenu, IModMenuInterface
	{
		private const int FLIP_FRAME_LIMIT = 5;

		private const float RESPAWN_TIME_LIMIT = 5f;

		private static int flipTimer = 0;

		private static float respawnTimer = 0f;

		private Coroutine? respawnCoro;

		public const string Id = "io.github.kaycodes13.glissando";

		public static bool GravityIsFlipped { get; internal set; } = false;

		internal static GlissandoPlugin Instance { get; private set; } = null;

		internal static ManualLogSource Log { get; private set; } = null;

		internal static ModSettings Settings { get; } = new ModSettings();

		private Harmony Harmony { get; } = new Harmony("io.github.kaycodes13.glissando");

		public static string Name => "Glissando";

		public static string Version => "1.0.1";

		private void Awake()
		{
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			Settings.BindConfigEntries();
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Plugin " + Name + " (io.github.kaycodes13.glissando) has loaded!"));
		}

		private void Start()
		{
			Harmony.PatchAll();
		}

		private void OnDestroy()
		{
			Harmony.UnpatchSelf();
			if (GravityIsFlipped)
			{
				FlipGravity(HeroController.instance, jumpBoost: false, force: true);
				GravityIsFlipped = false;
			}
		}

		private void Update()
		{
			//IL_0037: 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)
			GameManager silentInstance = GameManager.SilentInstance;
			if (silentInstance != null && silentInstance.IsGameplayScene() && !silentInstance.IsGamePaused() && !silentInstance.hero_ctrl.controlReqlinquished && respawnTimer <= 0f && (int)Settings.RespawnKey != 0 && Input.GetKeyDown(Settings.RespawnKey))
			{
				respawnTimer = 5f;
				QueueRespawnHero();
			}
			if (respawnTimer > 0f)
			{
				respawnTimer -= Time.deltaTime;
			}
			if (flipTimer > 0)
			{
				flipTimer--;
			}
		}

		internal static void QueueRespawnHero()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Invalid comparison between Unknown and I4
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Invalid comparison between Unknown and I4
			GameManager gm = GameManager.SilentInstance;
			HeroController hc;
			SpriteRenderer screenFader;
			if (gm != null && !gm.IsNonGameplayScene() && ((int)gm.GameState == 4 || (int)gm.GameState == 5) && Instance.respawnCoro == null)
			{
				hc = HeroController.instance;
				screenFader = null;
				Transform val = ((Component)gm.cameraCtrl.fadeFSM).transform.Find("Screen Fader");
				if (val != null)
				{
					screenFader = ((Component)val).GetComponent<SpriteRenderer>();
				}
				Instance.respawnCoro = ((MonoBehaviour)Instance).StartCoroutine(RespawnHero());
			}
			void ForceRemaskerUpdate(bool _)
			{
				//IL_0048: Unknown result type (might be due to invalid IL or missing references)
				//IL_0052: Expected O, but got Unknown
				Remasker[] array = Object.FindObjectsByType<Remasker>((FindObjectsSortMode)0);
				foreach (Remasker obj in array)
				{
					bool activeSelf = ((Component)obj).gameObject.activeSelf;
					((Component)obj).gameObject.SetActive(false);
					((Component)obj).gameObject.SetActive(activeSelf);
				}
				hc.heroInPositionDelayed -= new HeroInPosition(ForceRemaskerUpdate);
			}
			IEnumerator RespawnHero()
			{
				TransitionPoint.IsTransitionBlocked = true;
				if (gm.IsGamePaused())
				{
					IEnumerator unpauseIterator = gm.PauseGameToggle(false);
					while (unpauseIterator.MoveNext())
					{
						yield return unpauseIterator.Current;
					}
				}
				yield return (object)new WaitForEndOfFrame();
				hc.doingHazardRespawn = true;
				hc.SetState((ActorStates)7);
				hc.heroInPositionDelayed += new HeroInPosition(ForceRemaskerUpdate);
				if (Object.op_Implicit((Object)(object)screenFader))
				{
					hc.StartInvulnerable(0.56f);
					gm.cameraCtrl.FadeOut((CameraFadeType)2);
					while (Object.op_Implicit((Object)(object)screenFader) && screenFader.color.a < 1f)
					{
						yield return null;
					}
				}
				gm.HazardRespawn();
				while ((int)hc.hero_state == 7 || hc.doingHazardRespawn)
				{
					yield return null;
				}
				TransitionPoint.IsTransitionBlocked = false;
				Instance.respawnCoro = null;
			}
		}

		internal static void FlipGravity(HeroController hc, bool jumpBoost = false, bool force = false)
		{
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Expected O, but got Unknown
			if (!Object.op_Implicit((Object)(object)hc) || (flipTimer > 0 && !force))
			{
				return;
			}
			GravityIsFlipped = !GravityIsFlipped;
			flipTimer = 5;
			HeroController obj = hc;
			obj.MAX_FALL_VELOCITY *= -1f;
			HeroController obj2 = hc;
			obj2.MAX_FALL_VELOCITY_WEIGHTED *= -1f;
			HeroController obj3 = hc;
			obj3.MAX_FALL_VELOCITY_DJUMP *= -1f;
			HeroController obj4 = hc;
			obj4.BOUNCE_VELOCITY *= -1f;
			HeroController obj5 = hc;
			obj5.FLOAT_SPEED *= -1f;
			HeroController obj6 = hc;
			obj6.JUMP_SPEED *= -1f;
			HeroController obj7 = hc;
			obj7.JUMP_SPEED_UPDRAFT_EXIT *= -1f;
			HeroController obj8 = hc;
			obj8.WALLSLIDE_ACCEL *= -1f;
			HeroController obj9 = hc;
			obj9.WALLSLIDE_SHUTTLECOCK_VEL *= -1f;
			HeroController obj10 = hc;
			obj10.WALLCLING_DECEL *= -1f;
			HeroController obj11 = hc;
			obj11.DEFAULT_GRAVITY *= -1f;
			HeroController obj12 = hc;
			obj12.AIR_HANG_GRAVITY *= -1f;
			HeroController obj13 = hc;
			obj13.AIR_HANG_ACCEL *= -1f;
			Rigidbody2D rb2d = hc.rb2d;
			rb2d.gravityScale *= -1f;
			Vector3 localScale = hc.transform.localScale;
			localScale.y *= -1f;
			hc.transform.localScale = localScale;
			float yVel = (jumpBoost ? (0f - hc.JUMP_SPEED / 2f) : 0f);
			((MonoBehaviour)hc).StartCoroutine(ApplyBoostVelocity());
			ConfigGroup[] configs = hc.configs;
			foreach (ConfigGroup val in configs)
			{
				bool flag = false;
				foreach (Transform item in val.ActiveRoot.transform)
				{
					Transform val2 = item;
					if (!Object.op_Implicit((Object)(object)val2))
					{
						continue;
					}
					NailSlashTravel component = ((Component)val2).GetComponent<NailSlashTravel>();
					if (component != null)
					{
						if ((Object)(object)val.ChargeSlash == (Object)(object)((Component)val2).gameObject)
						{
							flag = true;
						}
						((MonoBehaviour)hc).StartCoroutine(InvertNailTravel(component));
					}
				}
				if (!flag && Object.op_Implicit((Object)(object)val.ChargeSlash))
				{
					NailSlashTravel component2 = val.ChargeSlash.GetComponent<NailSlashTravel>();
					if (component2 != null)
					{
						((MonoBehaviour)hc).StartCoroutine(InvertNailTravel(component2));
					}
				}
			}
			IEnumerator ApplyBoostVelocity()
			{
				yield return null;
				hc.rb2d.linearVelocityY = yVel;
			}
			static IEnumerator InvertNailTravel(NailSlashTravel nailTravel)
			{
				while (nailTravel.travelRoutine != null)
				{
					yield return null;
				}
				Vector2 travelDistance = nailTravel.travelDistance;
				Vector2 val3 = travelDistance;
				val3.y = 0f - travelDistance.y;
				travelDistance = val3;
				nailTravel.travelDistance = travelDistance;
				nailTravel.groundedYOffset *= -1f;
				if (nailTravel.maxYOffset != null)
				{
					OverrideFloat maxYOffset = nailTravel.maxYOffset;
					((OverrideValue<float>)(object)maxYOffset).Value = ((OverrideValue<float>)(object)maxYOffset).Value * -1f;
				}
			}
		}

		internal static void FlipHeroVelocity()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)HeroController.instance))
			{
				Vector2 linearVelocity = HeroController.instance.rb2d.linearVelocity;
				Vector2 val = linearVelocity;
				val.y = 0f - linearVelocity.y;
				linearVelocity = val;
				HeroController.instance.rb2d.linearVelocity = linearVelocity;
			}
		}

		public string ModMenuName()
		{
			return Settings.ModMenuName();
		}

		public AbstractMenuScreen BuildCustomMenu()
		{
			return Settings.BuildCustomMenu();
		}
	}
}
namespace Glissando.Utils
{
	internal static class FsmFlipUtil
	{
		internal const string FLIP_BOOL_NAME = "io.github.kaycodes13.glissando Is Flipped";

		internal static void DoGravityFlipEdit(this PlayMakerFSM fsm, HeroController hc, FsmState[] checkStates, FsmState[]? affectedStates = null, Action? otherEdits = null)
		{
			if (affectedStates == null)
			{
				affectedStates = fsm.FsmStates;
			}
			FsmStateAction[] affectedActions = affectedStates.SelectMany((FsmState x) => x.Actions).ToArray();
			FsmBool isFlipped = FsmUtil.GetBoolVariable(fsm, "io.github.kaycodes13.glissando Is Flipped");
			foreach (FsmState val in checkStates)
			{
				if (val != null)
				{
					FsmUtil.InsertMethod(val, 0, (Action)FlipState, false);
				}
			}
			void FlipState()
			{
				if (isFlipped.Value != GlissandoPlugin.GravityIsFlipped)
				{
					isFlipped.Value = GlissandoPlugin.GravityIsFlipped;
					affectedActions.FlipHeroMotion(hc);
					otherEdits?.Invoke();
				}
			}
		}

		internal static void FlipHeroMotion(this FsmStateAction[] actions, HeroController hc)
		{
			actions = (from x in actions
				where x != null
				where x.FlipHeroMotion<FsmStateAction>(hc)
				select x).ToArray();
		}

		private static bool FlipHeroMotion<T>(this T action, HeroController hc) where T : FsmStateAction
		{
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: 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_0348: Unknown result type (might be due to invalid IL or missing references)
			//IL_034a: Unknown result type (might be due to invalid IL or missing references)
			//IL_034d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0367: Expected I4, but got Unknown
			//IL_0371: Unknown result type (might be due to invalid IL or missing references)
			//IL_0380: Unknown result type (might be due to invalid IL or missing references)
			//IL_038f: Unknown result type (might be due to invalid IL or missing references)
			//IL_039e: Unknown result type (might be due to invalid IL or missing references)
			GameObject gameObject = ((Component)hc).gameObject;
			object obj = action;
			SetVelocity2d val = (SetVelocity2d)((obj is SetVelocity2d) ? obj : null);
			if (val != null)
			{
				if ((Object)(object)FSMUtility.GetSafe(val.gameObject, (FsmStateAction)(object)val) == (Object)(object)gameObject)
				{
					FsmFloat y = val.y;
					y.Value *= -1f;
					Vector2 value = val.vector.Value;
					FsmVector2 vector = val.vector;
					Vector2 value2 = value;
					value2.y = 0f - value.y;
					vector.Value = value2;
				}
				return true;
			}
			object obj2 = action;
			SetVelocityByScale val2 = (SetVelocityByScale)((obj2 is SetVelocityByScale) ? obj2 : null);
			if (val2 != null)
			{
				if ((Object)(object)FSMUtility.GetSafe(val2.gameObject, (FsmStateAction)(object)val2) == (Object)(object)gameObject)
				{
					FsmFloat ySpeed = val2.ySpeed;
					ySpeed.Value *= -1f;
				}
				return true;
			}
			object obj3 = action;
			AddForce2d val3 = (AddForce2d)((obj3 is AddForce2d) ? obj3 : null);
			if (val3 != null)
			{
				if ((Object)(object)FSMUtility.GetSafe(val3.gameObject, (FsmStateAction)(object)val3) == (Object)(object)gameObject)
				{
					FsmFloat y2 = val3.y;
					y2.Value *= -1f;
				}
				return true;
			}
			object obj4 = action;
			Translate val4 = (Translate)((obj4 is Translate) ? obj4 : null);
			if (val4 != null)
			{
				if ((Object)(object)FSMUtility.GetSafe(val4.gameObject, (FsmStateAction)(object)val4) == (Object)(object)gameObject)
				{
					FsmFloat y3 = val4.y;
					y3.Value *= -1f;
				}
				return true;
			}
			object obj5 = action;
			ClampVelocity2D val5 = (ClampVelocity2D)((obj5 is ClampVelocity2D) ? obj5 : null);
			if (val5 != null)
			{
				if ((Object)(object)FSMUtility.GetSafe(val5.gameObject, (FsmStateAction)(object)val5) == (Object)(object)gameObject)
				{
					FsmFloat yMax = val5.yMax;
					yMax.Value *= -1f;
					FsmFloat yMin = val5.yMin;
					yMin.Value *= -1f;
					ClampVelocity2D val6 = val5;
					FsmFloat yMax2 = val5.yMax;
					FsmFloat yMin2 = val5.yMin;
					val5.yMin = yMax2;
					val6.yMax = yMin2;
				}
				return true;
			}
			object obj6 = action;
			AccelerateToY val7 = (AccelerateToY)((obj6 is AccelerateToY) ? obj6 : null);
			if (val7 != null)
			{
				if ((Object)(object)FSMUtility.GetSafe(val7.gameObject, (FsmStateAction)(object)val7) == (Object)(object)gameObject)
				{
					FsmFloat targetSpeed = val7.targetSpeed;
					targetSpeed.Value *= -1f;
				}
				return true;
			}
			object obj7 = action;
			SetGravity2dScale val8 = (SetGravity2dScale)((obj7 is SetGravity2dScale) ? obj7 : null);
			if (val8 != null)
			{
				if ((Object)(object)FSMUtility.GetSafe(val8.gameObject, (FsmStateAction)(object)val8) == (Object)(object)gameObject)
				{
					FsmFloat gravityScale = val8.gravityScale;
					gravityScale.Value *= -1f;
				}
				return true;
			}
			object obj8 = action;
			SetGravity2dScaleV2 val9 = (SetGravity2dScaleV2)((obj8 is SetGravity2dScaleV2) ? obj8 : null);
			if (val9 != null)
			{
				if ((Object)(object)FSMUtility.GetSafe(val9.gameObject, (FsmStateAction)(object)val9) == (Object)(object)gameObject)
				{
					FsmFloat gravityScale2 = val9.gravityScale;
					gravityScale2.Value *= -1f;
				}
				return true;
			}
			object obj9 = action;
			SetVelocity2dConditional val10 = (SetVelocity2dConditional)((obj9 is SetVelocity2dConditional) ? obj9 : null);
			if (val10 != null)
			{
				if ((Object)(object)FSMUtility.GetSafe(val10.gameObject, (FsmStateAction)(object)val10) == (Object)(object)gameObject)
				{
					FsmFloat y4 = val10.y;
					y4.Value *= -1f;
					FsmFloat value3 = val10.yCondition.value;
					value3.Value *= -1f;
					ComparisonType comparisonType = val10.yCondition.comparisonType;
					switch (comparisonType - 1)
					{
					case 0:
						val10.yCondition.comparisonType = (ComparisonType)2;
						break;
					case 1:
						val10.yCondition.comparisonType = (ComparisonType)1;
						break;
					case 3:
						val10.yCondition.comparisonType = (ComparisonType)5;
						break;
					case 4:
						val10.yCondition.comparisonType = (ComparisonType)4;
						break;
					}
				}
				return true;
			}
			object obj10 = action;
			CheckCollisionSide val11 = (CheckCollisionSide)((obj10 is CheckCollisionSide) ? obj10 : null);
			if (val11 != null)
			{
				if ((Object)(object)FSMUtility.GetSafe(val11.collidingObject, (FsmStateAction)(object)val11) == (Object)(object)gameObject)
				{
					CheckCollisionSide val12 = val11;
					FsmEvent topHitEvent = val11.topHitEvent;
					FsmEvent bottomHitEvent = val11.bottomHitEvent;
					val11.bottomHitEvent = topHitEvent;
					val12.topHitEvent = bottomHitEvent;
				}
				return true;
			}
			object obj11 = action;
			CheckCollisionSideV2 val13 = (CheckCollisionSideV2)((obj11 is CheckCollisionSideV2) ? obj11 : null);
			if (val13 != null)
			{
				if ((Object)(object)FSMUtility.GetSafe(val13.collidingObject, (FsmStateAction)(object)val13) == (Object)(object)gameObject)
				{
					CheckCollisionSideV2 val14 = val13;
					FsmEvent bottomHitEvent = val13.topHitEvent;
					FsmEvent topHitEvent = val13.bottomHitEvent;
					val13.bottomHitEvent = bottomHitEvent;
					val14.topHitEvent = topHitEvent;
				}
				return true;
			}
			object obj12 = action;
			CheckCollisionSideEnter val15 = (CheckCollisionSideEnter)((obj12 is CheckCollisionSideEnter) ? obj12 : null);
			if (val15 != null)
			{
				if (Object.op_Implicit((Object)(object)val15.col2d) && (Object)(object)((Component)val15.col2d).gameObject == (Object)(object)gameObject)
				{
					CheckCollisionSideEnter val16 = val15;
					CheckCollisionSideEnter val17 = val15;
					FsmEvent topHitEvent = val15.topHitEvent;
					FsmEvent bottomHitEvent = val15.bottomHitEvent;
					val16.bottomHitEvent = topHitEvent;
					val17.topHitEvent = bottomHitEvent;
				}
				return true;
			}
			object obj13 = action;
			CheckCollisionSideEnterV2 val18 = (CheckCollisionSideEnterV2)((obj13 is CheckCollisionSideEnterV2) ? obj13 : null);
			if (val18 != null)
			{
				if (Object.op_Implicit((Object)(object)val18.col2d) && (Object)(object)((Component)val18.col2d).gameObject == (Object)(object)gameObject)
				{
					CheckCollisionSideEnterV2 val19 = val18;
					CheckCollisionSideEnterV2 val20 = val18;
					FsmEvent bottomHitEvent = val18.topHitEvent;
					FsmEvent topHitEvent = val18.bottomHitEvent;
					val19.bottomHitEvent = bottomHitEvent;
					val20.topHitEvent = topHitEvent;
				}
				return true;
			}
			return false;
		}
	}
	internal static class ILUtil
	{
		internal static CodeInstruction InvertFloatIfFlipped()
		{
			return Transpilers.EmitDelegate<Func<float, float>>((Func<float, float>)InvertFloat);
			static float InvertFloat(float value)
			{
				if (GlissandoPlugin.GravityIsFlipped)
				{
					return 0f - value;
				}
				return value;
			}
		}

		internal static bool Ldloc(CodeInstruction x)
		{
			int index;
			return Ldloc(x, out index);
		}

		internal static bool Ldloc(CodeInstruction x, int index)
		{
			if (Ldloc(x, out var index2))
			{
				return index == index2;
			}
			return false;
		}

		internal static bool Ldloc(CodeInstruction x, out int index)
		{
			index = -1;
			if (x.opcode == OpCodes.Ldloc_0)
			{
				index = 0;
			}
			else if (x.opcode == OpCodes.Ldloc_1)
			{
				index = 1;
			}
			else if (x.opcode == OpCodes.Ldloc_2)
			{
				index = 2;
			}
			else if (x.opcode == OpCodes.Ldloc_3)
			{
				index = 3;
			}
			else if ((x.opcode == OpCodes.Ldloc || x.opcode == OpCodes.Ldloc_S) && x.operand is LocalBuilder localBuilder)
			{
				index = localBuilder.LocalIndex;
			}
			return index >= 0;
		}

		internal static bool Stloc(CodeInstruction x)
		{
			int index;
			return Stloc(x, out index);
		}

		internal static bool Stloc(CodeInstruction x, int index)
		{
			if (Stloc(x, out var index2))
			{
				return index == index2;
			}
			return false;
		}

		internal static bool Stloc(CodeInstruction x, out int index)
		{
			index = -1;
			if (x.opcode == OpCodes.Stloc_0)
			{
				index = 0;
			}
			else if (x.opcode == OpCodes.Stloc_1)
			{
				index = 1;
			}
			else if (x.opcode == OpCodes.Stloc_2)
			{
				index = 2;
			}
			else if (x.opcode == OpCodes.Stloc_3)
			{
				index = 3;
			}
			else if ((x.opcode == OpCodes.Stloc || x.opcode == OpCodes.Stloc_S) && x.operand is LocalBuilder localBuilder)
			{
				index = localBuilder.LocalIndex;
			}
			return index >= 0;
		}

		internal static bool Ldfld(CodeInstruction x)
		{
			string name;
			return Ldfld(x, out name);
		}

		internal static bool Ldfld(CodeInstruction x, string name)
		{
			if (Ldfld(x, out string name2))
			{
				return name == name2;
			}
			return false;
		}

		internal static bool Ldfld(CodeInstruction x, out string name)
		{
			name = "";
			if (x.opcode == OpCodes.Ldfld && x.operand is FieldInfo fieldInfo)
			{
				name = fieldInfo.Name;
			}
			return !string.IsNullOrWhiteSpace(name);
		}

		internal static bool Stfld(CodeInstruction x)
		{
			string name;
			return Stfld(x, out name);
		}

		internal static bool Stfld(CodeInstruction x, string name)
		{
			if (Stfld(x, out string name2))
			{
				return name == name2;
			}
			return false;
		}

		internal static bool Stfld(CodeInstruction x, out string name)
		{
			name = "";
			if (x.opcode == OpCodes.Stfld && x.operand is FieldInfo fieldInfo)
			{
				name = fieldInfo.Name;
			}
			return !string.IsNullOrWhiteSpace(name);
		}

		internal static bool Ldarg(CodeInstruction x)
		{
			int index;
			return Ldarg(x, out index);
		}

		internal static bool Ldarg(CodeInstruction x, int index)
		{
			if (Ldarg(x, out var index2))
			{
				return index == index2;
			}
			return false;
		}

		internal static bool Ldarg(CodeInstruction x, out int index)
		{
			index = -1;
			if (x.opcode == OpCodes.Ldarg_0)
			{
				index = 0;
			}
			else if (x.opcode == OpCodes.Ldarg_1)
			{
				index = 1;
			}
			else if (x.opcode == OpCodes.Ldarg_2)
			{
				index = 2;
			}
			else if (x.opcode == OpCodes.Ldarg_3)
			{
				index = 3;
			}
			else if ((x.opcode == OpCodes.Ldarg || x.opcode == OpCodes.Ldarg_S) && x.operand is ParameterBuilder parameterBuilder)
			{
				index = parameterBuilder.Position;
			}
			return index >= 0;
		}

		internal static bool Br(CodeInstruction x)
		{
			if (!(x.opcode == OpCodes.Br))
			{
				return x.opcode == OpCodes.Br_S;
			}
			return true;
		}

		internal static bool Brfalse(CodeInstruction x)
		{
			if (!(x.opcode == OpCodes.Brfalse))
			{
				return x.opcode == OpCodes.Brfalse_S;
			}
			return true;
		}

		internal static bool Brtrue(CodeInstruction x)
		{
			if (!(x.opcode == OpCodes.Brtrue))
			{
				return x.opcode == OpCodes.Brtrue_S;
			}
			return true;
		}

		internal static bool CallRelaxed(CodeInstruction x, string name)
		{
			if ((x.opcode == OpCodes.Call || x.opcode == OpCodes.Callvirt) && x.operand is MethodInfo methodInfo)
			{
				return methodInfo.Name == name;
			}
			return false;
		}

		internal static bool Call(CodeInstruction x, string name)
		{
			if (x.opcode == OpCodes.Call && x.operand is MethodInfo methodInfo)
			{
				return methodInfo.Name == name;
			}
			return false;
		}

		internal static bool Call(CodeInstruction x, Type declaringType, string name)
		{
			if (x.opcode == OpCodes.Call && x.operand is MethodInfo methodInfo && methodInfo.DeclaringType == declaringType)
			{
				return methodInfo.Name == name;
			}
			return false;
		}

		internal static bool Callvirt(CodeInstruction x, string name)
		{
			if (x.opcode == OpCodes.Callvirt && x.operand is MethodInfo methodInfo)
			{
				return methodInfo.Name == name;
			}
			return false;
		}
	}
	internal static class LangUtil
	{
		internal const string SHEET = "Mods.io.github.kaycodes13.glissando";

		public static LocalisedString String(string key)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return new LocalisedString("Mods.io.github.kaycodes13.glissando", key);
		}
	}
}
namespace Glissando.Settings
{
	internal enum FaydownState
	{
		FlipGravity,
		DoubleJump,
		Disabled
	}
	internal static class FaydownStateExt
	{
		public static bool FlipsGravity(this FaydownState state)
		{
			return state == FaydownState.FlipGravity;
		}

		public static ListChoiceModel<FaydownState> LocalisedChoiceModel()
		{
			return new ListChoiceModel<FaydownState>(Enum.GetValues(typeof(FaydownState)).Cast<FaydownState>().ToList())
			{
				DisplayFn = (int _, FaydownState val) => LocalizedText.op_Implicit(LangUtil.String(val.MenuLangKey()))
			};
		}

		public static string MenuLangKey(this FaydownState state)
		{
			return state.LangKey("MENU_FLIPDOWN");
		}

		public static string InventoryLangKey(this FaydownState state)
		{
			return state.LangKey("INV_DESC_DRESS_DJ");
		}

		private static string LangKey(this FaydownState state, string prefix)
		{
			return state switch
			{
				FaydownState.FlipGravity => prefix + "_FLIPS", 
				FaydownState.DoubleJump => prefix + "_JUMPS", 
				FaydownState.Disabled => prefix + "_OFF", 
				_ => throw new ArgumentOutOfRangeException("state"), 
			};
		}
	}
	internal class ModSettings : IModMenuCustomMenu, IModMenuInterface
	{
		private const FaydownState FAYDOWN_STATE_DEFAULT = FaydownState.DoubleJump;

		private const KeyCode RESPAWN_KEY_DEFAULT = (KeyCode)0;

		private ConfigEntry<FaydownState>? faydownState;

		private ChoiceElement<FaydownState>? faydownOption;

		private ConfigEntry<KeyCode>? respawnKey;

		private KeyBindElement? respawnKeyOption;

		private static ConfigFile Config => ((BaseUnityPlugin)GlissandoPlugin.Instance).Config;

		public FaydownState FaydownState => faydownState?.Value ?? FaydownState.DoubleJump;

		public KeyCode RespawnKey => (KeyCode)(((??)respawnKey?.Value) ?? 0);

		public void BindConfigEntries()
		{
			respawnKey = Config.Bind<KeyCode>("", "RespawnKeybind", (KeyCode)0, (ConfigDescription)null);
			faydownState = Config.Bind<FaydownState>("", "FayfornsGift", FaydownState.DoubleJump, (ConfigDescription)null);
		}

		public string ModMenuName()
		{
			return GlissandoPlugin.Name;
		}

		public AbstractMenuScreen BuildCustomMenu()
		{
			//IL_0005: 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_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			//IL_0067: 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_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Expected O, but got Unknown
			TextButton val = new TextButton(LocalizedText.op_Implicit(LangUtil.String("MENU_RESPAWN_BUTTON")))
			{
				OnSubmit = GlissandoPlugin.QueueRespawnHero
			};
			respawnKeyOption = new KeyBindElement(LocalizedText.op_Implicit(LangUtil.String("MENU_RESPAWN_KEY_LABEL")));
			SyncEntryAndElement<KeyCode>(respawnKey, (SelectableValueElement<KeyCode>)(object)respawnKeyOption);
			faydownOption = new ChoiceElement<FaydownState>(LocalizedText.op_Implicit(LangUtil.String("MENU_FLIPDOWN_LABEL")), (IChoiceModel<FaydownState>)(object)FaydownStateExt.LocalisedChoiceModel(), LocalizedText.op_Implicit(LangUtil.String("MENU_FLIPDOWN_DESC")));
			SyncEntryAndElement<FaydownState>(faydownState, (SelectableValueElement<FaydownState>)(object)faydownOption);
			SimpleMenuScreen val2 = new SimpleMenuScreen(ModMenuName());
			MenuElement[] array = (MenuElement[])(object)new MenuElement[3]
			{
				(MenuElement)val,
				(MenuElement)respawnKeyOption,
				(MenuElement)faydownOption
			};
			val2.AddRange((IEnumerable<MenuElement>)array);
			MenuElement[] array2 = array;
			for (int i = 0; i < array2.Length; i++)
			{
				array2[i].Container.transform.SetParent(((AbstractMenuScreen)val2).Container.transform, false);
			}
			return (AbstractMenuScreen)(object)val2;
		}

		private static void SyncEntryAndElement<T>(ConfigEntry<T> cfg, SelectableValueElement<T> elt)
		{
			elt.Value = cfg.Value;
			cfg.SettingChanged += delegate
			{
				if (elt != null && !object.Equals(elt.Value, cfg.Value))
				{
					elt.Value = cfg.Value;
				}
			};
			elt.OnValueChanged += delegate(T newVal)
			{
				cfg.Value = newVal;
			};
		}
	}
}
namespace Glissando.Patches
{
	[HarmonyPatch(typeof(HeroController))]
	internal static class AttacksPatch
	{
		[HarmonyPatch(typeof(DamageEnemies), "SetDirection")]
		[HarmonyPostfix]
		private static void FlipNonFsmAttackDirections(DamageEnemies __instance, ref float newDirection)
		{
			if (GlissandoPlugin.GravityIsFlipped && DamageEnemies.IsNailAttackObject(((Component)__instance).gameObject))
			{
				int cardinalDirection = DirectionUtils.GetCardinalDirection(newDirection);
				if (cardinalDirection == 3 || cardinalDirection == 1)
				{
					__instance.FlipDirection();
				}
			}
		}

		[HarmonyPatch("DownAttack")]
		[HarmonyPostfix]
		[HarmonyPriority(0)]
		private static void FlipDownspikeStart(HeroController __instance)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			if ((int)__instance.Config.DownSlashType == 0)
			{
				if (GlissandoPlugin.GravityIsFlipped && __instance.Config.DownspikeThrusts)
				{
					GlissandoPlugin.FlipHeroVelocity();
				}
				DamageEnemies enemyDamager = ((NailAttackBase)__instance.currentDownspike).EnemyDamager;
				int cardinalDirection = DirectionUtils.GetCardinalDirection(enemyDamager.direction);
				if ((GlissandoPlugin.GravityIsFlipped && cardinalDirection == 3) || (!GlissandoPlugin.GravityIsFlipped && cardinalDirection == 1))
				{
					enemyDamager.FlipDirection();
				}
			}
		}

		[HarmonyPatch("Downspike")]
		[HarmonyPostfix]
		[HarmonyPriority(0)]
		private static void FlipDownspikeMiddle(HeroController __instance)
		{
			if (GlissandoPlugin.GravityIsFlipped && __instance.Config.DownspikeThrusts)
			{
				GlissandoPlugin.FlipHeroVelocity();
			}
		}

		[HarmonyPatch("FinishDownspike", new Type[] { typeof(bool) })]
		[HarmonyPostfix]
		[HarmonyPriority(0)]
		private static void FlipDownspikeEnd(HeroController __instance)
		{
			if (GlissandoPlugin.GravityIsFlipped && !__instance.cState.floating && !__instance.startWithBalloonBounce)
			{
				GlissandoPlugin.FlipHeroVelocity();
			}
		}
	}
	[HarmonyPatch]
	internal static class BouncePhysicsPatch
	{
		[HarmonyPatch(typeof(BounceShared), "BouncePull")]
		[HarmonyPrefix]
		private static void InvertBouncePullPos(Transform transform, ref Vector2 heroBouncePos)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			if (GlissandoPlugin.GravityIsFlipped)
			{
				float num = Mathf.Abs(heroBouncePos.y - transform.position.y);
				float y = ((heroBouncePos.y > transform.position.y) ? (transform.position.y - num) : (transform.position.y + num));
				Vector2 val = heroBouncePos;
				val.y = y;
				heroBouncePos = val;
			}
		}

		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> InvertBouncePullPos(IEnumerable<CodeInstruction> instructions)
		{
			//IL_001e: 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_0052: Expected O, but got Unknown
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Expected O, but got Unknown
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Expected O, but got Unknown
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Expected O, but got Unknown
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Expected O, but got Unknown
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Expected O, but got Unknown
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Expected O, but got Unknown
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Expected O, but got Unknown
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Expected O, but got Unknown
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Expected O, but got Unknown
			string fromPosName = "";
			string toPosName = "";
			return new CodeMatcher(instructions, (ILGenerator)null).Start().MatchEndForward((CodeMatch[])(object)new CodeMatch[3]
			{
				new CodeMatch((Func<CodeInstruction, bool>)ILUtil.Ldfld, (string)null),
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => ILUtil.Callvirt(x, "get_position")), (string)null),
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => ILUtil.Stfld(x, out fromPosName)), (string)null)
			}).MatchEndForward((CodeMatch[])(object)new CodeMatch[2]
			{
				new CodeMatch((OpCode?)OpCodes.Newobj, (object)null, (string)null),
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => ILUtil.Stfld(x, out toPosName)), (string)null)
			})
				.MatchEndForward((CodeMatch[])(object)new CodeMatch[1]
				{
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => x.opcode == OpCodes.Bge_Un || x.opcode == OpCodes.Bge_Un_S), (string)null)
				})
				.MatchEndBackwards((CodeMatch[])(object)new CodeMatch[2]
				{
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => x.opcode == OpCodes.Ldflda && x.operand is FieldInfo fieldInfo && fieldInfo.Name == fromPosName), (string)null),
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => ILUtil.Ldfld(x, "y")), (string)null)
				})
				.Advance(1)
				.Insert((CodeInstruction[])(object)new CodeInstruction[1] { ILUtil.InvertFloatIfFlipped() })
				.MatchEndBackwards((CodeMatch[])(object)new CodeMatch[2]
				{
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => x.opcode == OpCodes.Ldflda && x.operand is FieldInfo fieldInfo && fieldInfo.Name == toPosName), (string)null),
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => ILUtil.Ldfld(x, "y")), (string)null)
				})
				.Advance(1)
				.Insert((CodeInstruction[])(object)new CodeInstruction[1] { ILUtil.InvertFloatIfFlipped() })
				.InstructionEnumeration();
		}

		[HarmonyPatch(typeof(HitRigidbody2D), "Hit")]
		[HarmonyPrefix]
		private static void InvertHitRb2d(ref HitInstance damageInstance)
		{
			UnflipHitDirection(ref damageInstance);
		}

		[HarmonyPatch(typeof(BounceBalloon), "Hit")]
		[HarmonyPrefix]
		private static void InvertBounceBalloon(ref HitInstance damageInstance)
		{
			UnflipHitDirection(ref damageInstance);
		}

		[HarmonyPatch(typeof(BounceBalloon), "RaiseMovement")]
		[HarmonyPostfix]
		private static void InvertBounceBalloon2()
		{
			if (GlissandoPlugin.GravityIsFlipped)
			{
				GlissandoPlugin.FlipHeroVelocity();
			}
		}

		[HarmonyPatch(typeof(BouncePod), "Hit")]
		[HarmonyPrefix]
		private static void InvertBouncePod(ref HitInstance damageInstance)
		{
			UnflipHitDirection(ref damageInstance);
		}

		[HarmonyPatch(typeof(BouncePod), "Hit")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> InvertBouncePod(IEnumerable<CodeInstruction> instructions)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Expected O, but got Unknown
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Expected O, but got Unknown
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Expected O, but got Unknown
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Expected O, but got Unknown
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Expected O, but got Unknown
			int heroIndex = -1;
			return new CodeMatcher(instructions, (ILGenerator)null).Start().MatchEndForward((CodeMatch[])(object)new CodeMatch[2]
			{
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => ILUtil.Call(x, typeof(HeroController), "get_instance")), (string)null),
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => ILUtil.Stloc(x, out heroIndex)), (string)null)
			}).Start()
				.MatchEndForward((CodeMatch[])(object)new CodeMatch[4]
				{
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => ILUtil.Ldloc(x, heroIndex)), (string)null),
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => ILUtil.Callvirt(x, "get_transform")), (string)null),
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => ILUtil.Callvirt(x, "get_position")), (string)null),
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => ILUtil.Ldfld(x, "y")), (string)null)
				})
				.Advance(1)
				.Insert((CodeInstruction[])(object)new CodeInstruction[1] { ILUtil.InvertFloatIfFlipped() })
				.MatchEndForward((CodeMatch[])(object)new CodeMatch[1]
				{
					new CodeMatch((OpCode?)OpCodes.Add, (object)null, (string)null)
				})
				.Advance(1)
				.Insert((CodeInstruction[])(object)new CodeInstruction[1] { ILUtil.InvertFloatIfFlipped() })
				.InstructionEnumeration();
		}

		[HarmonyPatch(typeof(NailSlashRecoil), "GetActualHitDirection")]
		[HarmonyPostfix]
		private static void InvertNSRecoil(ref float __result)
		{
			int cardinalDirection = DirectionUtils.GetCardinalDirection(__result);
			if (GlissandoPlugin.GravityIsFlipped && (cardinalDirection == 1 || cardinalDirection == 3))
			{
				__result += 180f;
			}
		}

		private static void UnflipHitDirection(ref HitInstance damageInstance)
		{
			//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_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			if (GlissandoPlugin.GravityIsFlipped && ((HitInstance)(ref damageInstance)).IsNailDamage)
			{
				if (damageInstance.Direction == 90f)
				{
					HitInstance val = damageInstance;
					val.Direction = 270f;
					damageInstance = val;
				}
				else if (damageInstance.Direction == 270f)
				{
					HitInstance val = damageInstance;
					val.Direction = 90f;
					damageInstance = val;
				}
			}
		}
	}
	[HarmonyPatch(typeof(HeroController))]
	internal static class ControlsPatch
	{
		[HarmonyPatch("CanSuperJump")]
		[HarmonyPostfix]
		private static void DisableSilkSoar(ref bool __result)
		{
			if (GlissandoPlugin.GravityIsFlipped)
			{
				__result = false;
			}
		}

		[HarmonyPatch("CanDoubleJump")]
		[HarmonyPostfix]
		private static void AllowFloatOnDownAndJump(HeroController __instance, ref bool __result)
		{
			if (__result)
			{
				bool flag = GlissandoPlugin.Settings.FaydownState != FaydownState.Disabled && !((OneAxisInputControl)__instance.inputHandler.inputActions.Down).IsPressed;
				__result = flag;
			}
		}

		[HarmonyPatch("Awake")]
		[HarmonyPostfix]
		private static void FixFlippingOnReload()
		{
			GlissandoPlugin.GravityIsFlipped = false;
		}

		[HarmonyPatch("HeroJump", new Type[] { typeof(bool) })]
		[HarmonyPostfix]
		private static void FlipOnJump(HeroController __instance)
		{
			GlissandoPlugin.FlipGravity(__instance, jumpBoost: true);
			__instance.CancelHeroJump();
		}

		[HarmonyPatch("HeroJumpNoEffect")]
		[HarmonyPostfix]
		private static void FlipOnBackflip(HeroController __instance)
		{
			GlissandoPlugin.FlipGravity(__instance, jumpBoost: true);
			__instance.CancelHeroJump();
		}

		[HarmonyPatch("DoDoubleJump")]
		[HarmonyPostfix]
		private static void FlipOnDoubleJump(HeroController __instance)
		{
			if (GlissandoPlugin.Settings.FaydownState.FlipsGravity())
			{
				GlissandoPlugin.FlipGravity(__instance);
				__instance.CancelHeroJump();
			}
		}

		[HarmonyPatch("HazardRespawn")]
		[HarmonyPrefix]
		private static void FlipOnHazardRespawn(HeroController __instance)
		{
			if (GlissandoPlugin.GravityIsFlipped)
			{
				GlissandoPlugin.FlipGravity(__instance, jumpBoost: false, force: true);
			}
		}

		[HarmonyPatch("Respawn")]
		[HarmonyPrefix]
		private static void FlipOnRespawn(HeroController __instance)
		{
			if (GlissandoPlugin.GravityIsFlipped)
			{
				GlissandoPlugin.FlipGravity(__instance, jumpBoost: false, force: true);
			}
		}
	}
	[HarmonyPatch]
	internal static class FaydownUIPatch
	{
		private static string[]? langKeys;

		[HarmonyPatch(typeof(Language), "Get", new Type[]
		{
			typeof(string),
			typeof(string)
		})]
		[HarmonyPrefix]
		private static void ReplaceFaydownStrings(ref string key, ref string sheetTitle)
		{
			if (langKeys == null)
			{
				langKeys = Language.GetKeys("Mods.io.github.kaycodes13.glissando").ToArray();
			}
			if (key == "PROMPT_DJ")
			{
				if (GlissandoPlugin.Settings.FaydownState.FlipsGravity())
				{
					sheetTitle = "Mods.io.github.kaycodes13.glissando";
				}
			}
			else if (key == "INV_DESC_DRESS_DJ")
			{
				sheetTitle = "Mods.io.github.kaycodes13.glissando";
				key = GlissandoPlugin.Settings.FaydownState.InventoryLangKey();
			}
			else if (langKeys.Contains(key))
			{
				sheetTitle = "Mods.io.github.kaycodes13.glissando";
			}
		}

		[HarmonyPatch(typeof(CollectableItemStates), "GetDescription")]
		[HarmonyPrefix]
		private static void AddExtraDescription(CollectableItemStates __instance)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: 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)
			if (!(((Object)__instance).name != "Dresses"))
			{
				int currentStateIndex = __instance.GetCurrentStateIndex();
				if (LocalisedString.op_Implicit(__instance.states[currentStateIndex].DescriptionExtra) == LocalisedString.op_Implicit(default(LocalisedString)) && __instance.states[currentStateIndex].Test.TestGroups.SelectMany((TestGroup y) => y.Tests).Any((Test z) => z.FieldName == "hasDoubleJump"))
				{
					ItemState[] states = __instance.states;
					ItemState val = __instance.states[currentStateIndex];
					val.DescriptionExtra = LangUtil.String("INV_DESC_DRESS_DJ_EXTRA");
					states[currentStateIndex] = val;
				}
			}
		}
	}
	[HarmonyPatch]
	internal static class HeroFsmsPatch
	{
		private static bool didDownAttackEdit;

		private static bool didSprintEdit;

		private static bool didChargeAttackEdit;

		private static bool didScrambleEdit;

		private static bool didToolsEdit;

		private static bool didSpellsEdit;

		[HarmonyPatch(typeof(PlayerData), "SetupNewPlayerData")]
		[HarmonyPrefix]
		private static void ResetOnNewGame()
		{
			ResetEditedState();
		}

		[HarmonyPatch(typeof(PlayerData), "SetupExistingPlayerData")]
		[HarmonyPrefix]
		private static void ResetOnLoadGame()
		{
			ResetEditedState();
		}

		[HarmonyPatch(typeof(HeroController), "Start")]
		[HarmonyPrefix]
		[HarmonyPriority(800)]
		private static void HeroStart(HeroController __instance)
		{
			EditDrifterCloak(__instance);
			if (!didDownAttackEdit)
			{
				EditDownAttacks(__instance);
			}
			if (!didSprintEdit)
			{
				EditSprint(__instance);
			}
			if (!didChargeAttackEdit)
			{
				EditChargeAttacks(__instance);
			}
			if (!didScrambleEdit)
			{
				EditWallScramble(__instance);
			}
			if (!didToolsEdit)
			{
				EditTools(__instance);
			}
			if (!didSpellsEdit)
			{
				EditSpells(__instance);
			}
		}

		[HarmonyPatch(typeof(PlayMakerFSM), "Start")]
		[HarmonyPrefix]
		[HarmonyPriority(800)]
		private static void PFSMStart(PlayMakerFSM __instance)
		{
			if (((Object)((Component)__instance).gameObject).name.StartsWith("Tool Lightning Rod"))
			{
				EditVoltvesselSpear(__instance);
				return;
			}
			if (((Object)((Component)__instance).gameObject).name.StartsWith("Hero Conch Projectile"))
			{
				EditConchCutter(__instance);
				return;
			}
			HeroController component = ((Component)__instance).GetComponent<HeroController>();
			if (Object.op_Implicit((Object)(object)component))
			{
				if (!didDownAttackEdit && __instance == component.crestAttacksFSM)
				{
					EditDownAttacks(component);
				}
				else if (!didSprintEdit && __instance == component.sprintFSM)
				{
					EditSprint(component);
				}
				else if (!didChargeAttackEdit && __instance.FsmName == "Nail Arts")
				{
					EditChargeAttacks(component);
				}
				else if (!didScrambleEdit && __instance == component.wallScrambleFSM)
				{
					EditWallScramble(component);
				}
				else if (!didToolsEdit && __instance == component.toolsFSM)
				{
					EditTools(component);
				}
				else if (!didSpellsEdit && __instance == component.silkSpecialFSM)
				{
					EditSpells(component);
				}
			}
		}

		private static void ResetEditedState()
		{
			didDownAttackEdit = (didSprintEdit = (didChargeAttackEdit = (didScrambleEdit = (didToolsEdit = false))));
		}

		private static void EditDrifterCloak(HeroController hc)
		{
			PlayMakerFSM umbrellaFSM = hc.umbrellaFSM;
			if (!umbrellaFSM.Fsm.preprocessed)
			{
				umbrellaFSM.Preprocess();
			}
			FsmState bumpL = FsmUtil.GetState(umbrellaFSM, "Bump L");
			umbrellaFSM.DoGravityFlipEdit(hc, (FsmState[])(object)new FsmState[1] { FsmUtil.GetState(umbrellaFSM, "Antic") }, (FsmState[]?)(object)new FsmState[5]
			{
				FsmUtil.GetState(umbrellaFSM, "Inflate"),
				FsmUtil.GetState(umbrellaFSM, "Start"),
				FsmUtil.GetState(umbrellaFSM, "Float Idle"),
				bumpL,
				FsmUtil.GetState(umbrellaFSM, "Bump R")
			}, FlipBumpL);
			void FlipBumpL()
			{
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0034: Unknown result type (might be due to invalid IL or missing references)
				//IL_004b: 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_0064: Expected O, but got Unknown
				//IL_0064: Unknown result type (might be due to invalid IL or missing references)
				//IL_0066: Expected O, but got Unknown
				//IL_0066: Unknown result type (might be due to invalid IL or missing references)
				FloatClamp val = (FloatClamp)Array.Find(bumpL.Actions, delegate(FsmStateAction x)
				{
					FloatClamp val4 = (FloatClamp)(object)((x is FloatClamp) ? x : null);
					return val4 != null && ((NamedVariable)val4.floatVariable).Name.Contains("Velocity");
				});
				FsmFloat minValue = val.minValue;
				minValue.Value *= -1f;
				FsmFloat maxValue = val.maxValue;
				maxValue.Value *= -1f;
				FloatClamp val2 = val;
				FloatClamp val3 = val;
				FsmFloat maxValue2 = val.maxValue;
				FsmFloat minValue2 = val.minValue;
				val2.minValue = maxValue2;
				val3.maxValue = minValue2;
			}
		}

		private unsafe static void EditDownAttacks(HeroController hc)
		{
			didDownAttackEdit = true;
			_ = ((Component)hc).gameObject;
			PlayMakerFSM crestAttacksFSM = hc.crestAttacksFSM;
			if (!crestAttacksFSM.Fsm.preprocessed)
			{
				crestAttacksFSM.Preprocess();
			}
			string[] source = new string[8] { "Rpr DownSlash", "Witch Downslash", "Followup Slash", "SpinSlash", "SpinSlashRage", "Shaman Downslash", "Toolmaster Downslash", "Toolmaster Downslash Charged" };
			FsmGameObject[] downAttacks = (from x in source.Select(new Func<string, FsmGameObject>(crestAttacksFSM, (nint)(delegate*<PlayMakerFSM, string, FsmGameObject>)(&FsmUtil.FindGameObjectVariable)))
				where x != null
				select x).Cast<FsmGameObject>().ToArray();
			FsmState state = FsmUtil.GetState(crestAttacksFSM, "Idle");
			crestAttacksFSM.DoGravityFlipEdit(hc, state.Transitions.Select((FsmTransition x) => x.ToFsmState).ToArray(), null, FlipKnockbackDirection);
			void FlipKnockbackDirection()
			{
				foreach (GameObject item in downAttacks.Select((FsmGameObject x) => x.Value))
				{
					DamageEnemies component = item.GetComponent<DamageEnemies>();
					if (Object.op_Implicit((Object)(object)component))
					{
						int cardinalDirection = DirectionUtils.GetCardinalDirection(component.direction);
						if ((GlissandoPlugin.GravityIsFlipped && cardinalDirection == 3) || (!GlissandoPlugin.GravityIsFlipped && cardinalDirection == 1))
						{
							component.FlipDirection();
						}
					}
				}
			}
		}

		private static void EditSprint(HeroController hc)
		{
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Expected O, but got Unknown
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: 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_010b: Expected O, but got Unknown
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Expected O, but got Unknown
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Expected O, but got Unknown
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Expected O, but got Unknown
			didSprintEdit = true;
			_ = ((Component)hc).gameObject;
			PlayMakerFSM fsm = hc.sprintFSM;
			if (!fsm.Fsm.preprocessed)
			{
				fsm.Preprocess();
			}
			string text = "Shuttlecock";
			FsmUtil.GetBoolVariable(fsm, "io.github.kaycodes13.glissando Is Flipped");
			FsmBool boolVariable = FsmUtil.GetBoolVariable(fsm, "io.github.kaycodes13.glissando Should Pirouette");
			FsmString sprintAirAnim = FsmUtil.FindStringVariable(fsm, "Sprint Air Anim");
			FsmState state = FsmUtil.GetState(fsm, "Air Sprint L");
			FsmState state2 = FsmUtil.GetState(fsm, "Air Sprint R");
			FsmState state3 = FsmUtil.GetState(fsm, "Air Sprint Loop");
			FsmState state4 = FsmUtil.GetState(fsm, "Jump Antic");
			FsmUtil.InsertAction(FsmUtil.GetState(fsm, "Dashed"), 0, (FsmStateAction)new SetBoolValue
			{
				boolVariable = boolVariable,
				boolValue = FsmBool.op_Implicit(false)
			});
			FsmUtil.InsertAction(state4, 0, (FsmStateAction)new SetBoolValue
			{
				boolVariable = boolVariable,
				boolValue = FsmBool.op_Implicit(true)
			});
			FsmState[] array = (FsmState[])(object)new FsmState[2] { state, state2 };
			foreach (FsmState obj in array)
			{
				int num = Array.FindIndex(obj.Actions, delegate(FsmStateAction x)
				{
					Tk2dPlayAnimationWithEvents val = (Tk2dPlayAnimationWithEvents)(object)((x is Tk2dPlayAnimationWithEvents) ? x : null);
					return val != null && ((NamedVariable)val.clipName).UsesVariable && ((NamedVariable)val.clipName).Name == ((NamedVariable)sprintAirAnim).Name;
				});
				FsmUtil.InsertAction(obj, num, (FsmStateAction)new ConvertBoolToString
				{
					boolVariable = boolVariable,
					stringVariable = sprintAirAnim,
					falseString = sprintAirAnim,
					trueString = FsmString.op_Implicit(text)
				});
			}
			int num2 = Array.FindIndex(state3.Actions, delegate(FsmStateAction x)
			{
				Tk2dPlayAnimation val = (Tk2dPlayAnimation)(object)((x is Tk2dPlayAnimation) ? x : null);
				return val != null && val.clipName.Value == "Sprint Air Loop";
			});
			FsmUtil.InsertAction(state3, 1 + num2, (FsmStateAction)new tk2dPlayAnimationConditional
			{
				Target = new FsmOwnerDefault(),
				AnimName = FsmString.op_Implicit(text),
				Condition = boolVariable
			});
			fsm.DoGravityFlipEdit(hc, (FsmState[])(object)new FsmState[4]
			{
				FsmUtil.GetState(fsm, "Start Sprint"),
				state,
				state2,
				FsmUtil.GetState(fsm, "Start Attack")
			}, (FsmState[]?)(object)new FsmState[11]
			{
				FsmUtil.GetState(fsm, "Start Sprint"),
				FsmUtil.GetState(fsm, "Bump Up"),
				FsmUtil.GetState(fsm, "Bump Up 2"),
				FsmUtil.GetState(fsm, "Witch Lash Start"),
				FsmUtil.GetState(fsm, "Reaper End"),
				FsmUtil.GetState(fsm, "Wanderer Recoil"),
				FsmUtil.GetState(fsm, "RecoilStab Dash"),
				FsmUtil.GetState(fsm, "Warrior Leap"),
				FsmUtil.GetState(fsm, "Warrior Slash"),
				FsmUtil.GetState(fsm, "Shaman Leap"),
				FsmUtil.GetState(fsm, "Shaman Slash")
			}, ReaperCurveFloat);
			void ReaperCurveFloat()
			{
				//IL_0033: Unknown result type (might be due to invalid IL or missing references)
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				//IL_0066: Unknown result type (might be due to invalid IL or missing references)
				AnimationCurve curve = FsmUtil.GetFirstActionOfType<CurveFloat>(FsmUtil.GetState(fsm, "Reaper Upper")).animCurve.curve;
				List<Keyframe> list = new List<Keyframe>();
				Keyframe[] keys = curve.keys;
				for (int j = 0; j < keys.Length; j++)
				{
					Keyframe val = keys[j];
					list.Add(new Keyframe(((Keyframe)(ref val)).time, 0f - ((Keyframe)(ref val)).value, ((Keyframe)(ref val)).inTangent, ((Keyframe)(ref val)).outTangent, ((Keyframe)(ref val)).inWeight, ((Keyframe)(ref val)).outWeight));
				}
				curve.SetKeys(list.ToArray());
			}
		}

		private static void EditChargeAttacks(HeroController hc)
		{
			didChargeAttackEdit = true;
			PlayMakerFSM fsm = FsmUtil.GetFsmPreprocessed(((Component)hc).gameObject, "Nail Arts");
			fsm.DoGravityFlipEdit(hc, (FsmState[])(object)new FsmState[1] { FsmUtil.GetState(fsm, "Take Control") }, null, ConditionalVelocities);
			void ConditionalVelocities()
			{
				ConvertBoolToFloat[] array = (ConvertBoolToFloat[])(object)new ConvertBoolToFloat[2]
				{
					FsmUtil.GetFirstActionOfType<ConvertBoolToFloat>(FsmUtil.GetState(fsm, "Antic Drill")),
					FsmUtil.GetFirstActionOfType<ConvertBoolToFloat>(FsmUtil.GetState(fsm, "Warrior2 Leap"))
				};
				foreach (ConvertBoolToFloat obj in array)
				{
					FsmFloat trueValue = obj.trueValue;
					trueValue.Value *= -1f;
					FsmFloat falseValue = obj.falseValue;
					falseValue.Value *= -1f;
				}
				FloatClamp firstActionOfType = FsmUtil.GetFirstActionOfType<FloatClamp>(FsmUtil.GetState(fsm, "Queued Spin"));
				FsmFloat minValue = firstActionOfType.minValue;
				minValue.Value *= -1f;
				FsmFloat maxValue = firstActionOfType.maxValue;
				maxValue.Value *= -1f;
				FloatClamp val = firstActionOfType;
				FloatClamp val2 = firstActionOfType;
				FsmFloat maxValue2 = firstActionOfType.maxValue;
				FsmFloat minValue2 = firstActionOfType.minValue;
				val.minValue = maxValue2;
				val2.maxValue = minValue2;
			}
		}

		private static void EditWallScramble(HeroController hc)
		{
			didScrambleEdit = true;
			PlayMakerFSM wallScrambleFSM = hc.wallScrambleFSM;
			if (!wallScrambleFSM.Fsm.preprocessed)
			{
				wallScrambleFSM.Preprocess();
			}
			FsmState startScramble = FsmUtil.GetState(wallScrambleFSM, "Start Scramble");
			FsmState scrambleUp = FsmUtil.GetState(wallScrambleFSM, "Scramble Up");
			wallScrambleFSM.DoGravityFlipEdit(hc, (FsmState[])(object)new FsmState[1] { startScramble }, null, ConditionalVelocities);
			void ConditionalVelocities()
			{
				ConvertBoolToFloat obj = FsmUtil.GetActionsOfType<ConvertBoolToFloat>(startScramble).First((ConvertBoolToFloat x) => ((NamedVariable)x.floatVariable).Name == "Scramble Speed");
				FsmFloat trueValue = obj.trueValue;
				trueValue.Value *= -1f;
				FsmFloat falseValue = obj.falseValue;
				falseValue.Value *= -1f;
				ConvertBoolToFloat obj2 = FsmUtil.GetActionsOfType<ConvertBoolToFloat>(scrambleUp).First((ConvertBoolToFloat x) => ((NamedVariable)x.floatVariable).Name == "Down Force");
				FsmFloat trueValue2 = obj2.trueValue;
				trueValue2.Value *= -1f;
				FsmFloat falseValue2 = obj2.falseValue;
				falseValue2.Value *= -1f;
				FloatCompare obj3 = FsmUtil.GetActionsOfType<FloatCompare>(scrambleUp).First((FloatCompare x) => ((NamedVariable)x.float1).UsesVariable && ((NamedVariable)x.float1).Name == "Y Speed");
				FsmFloat @float = obj3.float2;
				@float.Value *= -1f;
				FloatCompare val = obj3;
				FloatCompare val2 = obj3;
				FsmEvent greaterThan = obj3.greaterThan;
				FsmEvent lessThan = obj3.lessThan;
				val.lessThan = greaterThan;
				val2.greaterThan = lessThan;
			}
		}

		private unsafe static void EditTools(HeroController hc)
		{
			didToolsEdit = true;
			_ = ((Component)hc).gameObject;
			PlayMakerFSM fsm = hc.toolsFSM;
			if (!fsm.Fsm.preprocessed)
			{
				fsm.Preprocess();
			}
			FsmBool isFlipped = FsmUtil.GetBoolVariable(fsm, "io.github.kaycodes13.glissando Is Flipped");
			string[] source = new string[2] { "Take Control", "TriPin Type" };
			fsm.DoGravityFlipEdit(hc, source.Select(new Func<string, FsmState>(fsm, (nint)(delegate*<PlayMakerFSM, string, FsmState>)(&FsmUtil.GetState))).ToArray(), fsm.FsmStates.Where(delegate(FsmState x)
			{
				string name = x.Name;
				return !name.Contains("Scuttle") && !name.Contains("Rosary Cannon") && !name.StartsWith("RC") && !name.Contains("Shoot");
			}).ToArray(), EditSilkshotA);
			EditTripin();
			EditPlasmiumPhial();
			EditSnareSetter();
			EditDelverDrill();
			void EditDelverDrill()
			{
				FsmState state = FsmUtil.GetState(fsm, "Screw Antic");
				ConvertBoolToFloat boolToFloat = FsmUtil.GetFirstActionOfType<ConvertBoolToFloat>(state);
				int num = 1 + Array.IndexOf(state.Actions, (FsmStateAction)(object)boolToFloat);
				FsmUtil.InsertMethod(state, num, (Action)delegate
				{
					if (isFlipped.Value)
					{
						FsmFloat floatVariable = boolToFloat.floatVariable;
						floatVariable.Value *= -1f;
					}
				}, false);
			}
			void EditPlasmiumPhial()
			{
				FsmState state = FsmUtil.GetState(fsm, "Syringe Antic");
				ConvertBoolToFloat boolToFloat = FsmUtil.GetFirstActionOfType<ConvertBoolToFloat>(state);
				int num = 1 + Array.IndexOf(state.Actions, (FsmStateAction)(object)boolToFloat);
				FsmUtil.InsertMethod(state, num, (Action)delegate
				{
					if (isFlipped.Value)
					{
						FsmFloat floatVariable = boolToFloat.floatVariable;
						floatVariable.Value *= -1f;
					}
				}, false);
			}
			void EditSilkshotA()
			{
				FsmStateAction[] actions = FsmUtil.GetState(fsm, "WebShot A Dir").Actions;
				foreach (FsmStateAction obj in actions)
				{
					RandomFloat val = (RandomFloat)(object)((obj is RandomFloat) ? obj : null);
					if (val != null)
					{
						FsmFloat storeResult = val.storeResult;
						if (((storeResult != null) ? ((NamedVariable)storeResult).Name : null) == "Angle")
						{
							FsmFloat min = val.min;
							min.Value *= -1f;
							FsmFloat max = val.max;
							max.Value *= -1f;
							RandomFloat val2 = val;
							RandomFloat val3 = val;
							FsmFloat max2 = val.max;
							FsmFloat min2 = val.min;
							val2.min = max2;
							val3.max = min2;
						}
					}
					SetFloatValue val4 = (SetFloatValue)(object)((obj is SetFloatValue) ? obj : null);
					if (val4 != null)
					{
						FsmFloat floatVariable = val4.floatVariable;
						if (((floatVariable != null) ? ((NamedVariable)floatVariable).Name : null) == "Angle Change")
						{
							FsmFloat floatValue = val4.floatValue;
							floatValue.Value *= -1f;
						}
					}
				}
			}
			void EditSnareSetter()
			{
				FsmState state = FsmUtil.GetState(fsm, "Snare Land");
				FsmGameObject loopEffect = FsmUtil.FindGameObjectVariable(fsm, "Loop Effect");
				int num = Array.FindLastIndex(state.Actions, delegate(FsmStateAction x)
				{
					SpawnObjectFromGlobalPool val = (SpawnObjectFromGlobalPool)(object)((x is SpawnObjectFromGlobalPool) ? x : null);
					return val != null && val.storeObject == loopEffect;
				});
				FsmUtil.InsertMethod(state, 1 + num, (Action)delegate
				{
					//IL_0011: Unknown result type (might be due to invalid IL or missing references)
					//IL_0016: Unknown result type (might be due to invalid IL or missing references)
					//IL_0035: Unknown result type (might be due to invalid IL or missing references)
					Transform transform = loopEffect.Value.transform;
					Vector3 localScale = transform.localScale;
					localScale.y = ((!isFlipped.Value) ? 1 : (-1));
					transform.localScale = localScale;
				}, false);
				FsmState state2 = FsmUtil.GetState(fsm, "Snare Set");
				FsmGameObject spawned = FsmUtil.FindGameObjectVariable(fsm, "Spawned");
				int num2 = Array.FindLastIndex(state2.Actions, delegate(FsmStateAction x)
				{
					SetGameObject val = (SetGameObject)(object)((x is SetGameObject) ? x : null);
					return val != null && val.variable == spawned;
				});
				FsmUtil.InsertMethod(state2, num2, (Action)delegate
				{
					//IL_0011: Unknown result type (might be due to invalid IL or missing references)
					//IL_0016: Unknown result type (might be due to invalid IL or missing references)
					//IL_0035: Unknown result type (might be due to invalid IL or missing references)
					Transform transform = spawned.Value.transform;
					Vector3 localScale = transform.localScale;
					localScale.y = ((!isFlipped.Value) ? 1 : (-1));
					transform.localScale = localScale;
				}, false);
			}
			void EditTripin()
			{
				FsmState[] obj = new FsmState[4]
				{
					FsmUtil.GetState(fsm, "TriPin Ground L"),
					FsmUtil.GetState(fsm, "TriPin Ground R"),
					FsmUtil.GetState(fsm, "TriPin Air L"),
					FsmUtil.GetState(fsm, "TriPin Air R")
				};
				FsmUtil.GetFloatVariable(fsm, "io.github.kaycodes13.glissando Projectile Rotation Angle");
				FsmState[] array = (FsmState[])(object)obj;
				foreach (FsmState val in array)
				{
					foreach (SpawnObjectFromGlobalPool item in FsmUtil.GetActionsOfType<SpawnObjectFromGlobalPool>(val).Skip(1))
					{
						int num = Array.IndexOf(val.Actions, (FsmStateAction)(object)item);
						FsmUtil.InsertMethod(val, num, (Action)FlipProjectile, false);
					}
					FsmUtil.AddMethod(val, (Action)FlipProjectile, false);
				}
			}
			void FlipProjectile()
			{
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				//IL_003d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0065: Unknown result type (might be due to invalid IL or missing references)
				//IL_006a: 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_0088: Unknown result type (might be due to invalid IL or missing references)
				//IL_008d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0091: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
				GameObject value = FsmUtil.FindGameObjectVariable(fsm, "Projectile").Value;
				Transform transform = value.transform;
				Rigidbody2D component = value.GetComponent<Rigidbody2D>();
				Vector3 localScale = transform.localScale;
				localScale.y = ((!GlissandoPlugin.GravityIsFlipped) ? 1 : (-1));
				transform.localScale = localScale;
				if (GlissandoPlugin.GravityIsFlipped)
				{
					float num = Mathf.Abs(Vector2.op_Implicit(FsmUtil.FindGameObjectVariable(fsm, "Self").Value.transform.position).y - transform.position.y);
					localScale = transform.position;
					localScale.y = transform.position.y + 2f * num;
					transform.position = localScale;
					transform.eulerAngles = -transform.eulerAngles;
					component.linearVelocityY = 0f - component.linearVelocityY;
				}
			}
		}

		private static void EditSpells(HeroController hc)
		{
			didSpellsEdit = true;
			PlayMakerFSM fsm = hc.silkSpecialFSM;
			if (!fsm.Fsm.preprocessed)
			{
				fsm.Preprocess();
			}
			string[] source = new string[6] { "Parry Flip?", "Silk Charge Flip?", "A Sphere Flip?", "N throw Flip?", "B Needle Flip?", "S Bomb Flip?" };
			fsm.DoGravityFlipEdit(hc, source.Select((string x) => FsmUtil.GetState(fsm, x)).ToArray());
			FsmUtil.AddMethod(FsmUtil.GetState(fsm, "Taunt Antic"), (Action)FlipCancel, false);
			FsmUtil.AddMethod(FsmUtil.GetState(fsm, "Taunt Rings"), (Action)FlipCancel, false);
			void FlipCancel()
			{
				if (GlissandoPlugin.GravityIsFlipped)
				{
					Extensions.SendEventSafe(fsm, "CANCEL TAUNT");
				}
			}
		}

		private static void EditVoltvesselSpear(PlayMakerFSM fsm)
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Expected O, but got Unknown
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Expected O, but got Unknown
			FsmFloat landAngle;
			FsmFloat rightAngle;
			FsmFloat leftAngle;
			FsmFloat upAngle;
			FsmFloat downAngle;
			if (FsmUtil.FindBoolVariable(fsm, "io.github.kaycodes13.glissando") == null)
			{
				FsmUtil.AddBoolVariable(fsm, "io.github.kaycodes13.glissando");
				FsmState state = FsmUtil.GetState(fsm, "Land Angle");
				FsmFloat floatVariable = FsmUtil.GetFloatVariable(fsm, "Normal Y Pos");
				int num = Array.FindIndex(state.Actions, delegate(FsmStateAction x)
				{
					GetVector2XY val = (GetVector2XY)(object)((x is GetVector2XY) ? x : null);
					return val != null && ((NamedVariable)val.vector2Variable).Name == "Hit Normal";
				});
				FsmUtil.InsertActions(state, 1 + num, (FsmStateAction[])(object)new FsmStateAction[2]
				{
					(FsmStateAction)new SetFloatValue
					{
						floatVariable = floatVariable,
						floatValue = FsmUtil.FindFloatVariable(fsm, "Normal Y")
					},
					(FsmStateAction)new FloatAbs
					{
						floatVariable = floatVariable
					}
				});
				FsmUtil.GetActionsOfType<FloatCompare>(state).First((FloatCompare x) => x.lessThan.Name == "FLOOR").float2 = floatVariable;
				landAngle = FsmUtil.FindFloatVariable(fsm, "Land Rotation");
				rightAngle = FsmUtil.FindFloatVariable(fsm, "Hit Rotation R");
				leftAngle = FsmUtil.FindFloatVariable(fsm, "Hit Rotation L");
				upAngle = FsmUtil.FindFloatVariable(fsm, "Hit Rotation U");
				downAngle = FsmUtil.FindFloatVariable(fsm, "Hit Rotation D");
				FsmUtil.AddMethod(FsmUtil.GetState(fsm, "Floor"), (Action)FlipSpearAngles, false);
			}
			void FlipSpearAngles()
			{
				if (GlissandoPlugin.GravityIsFlipped)
				{
					FsmFloat obj = upAngle;
					FsmFloat obj2 = downAngle;
					float num2 = (landAngle.Value = 90f);
					float value = (obj2.Value = num2);
					obj.Value = value;
					leftAngle.Value = 45f;
					rightAngle.Value = 135f;
				}
			}
		}

		private static void EditConchCutter(PlayMakerFSM fsm)
		{
			FsmFloat scaleX;
			if (FsmUtil.FindBoolVariable(fsm, "io.github.kaycodes13.glissando") == null)
			{
				FsmUtil.AddBoolVariable(fsm, "io.github.kaycodes13.glissando");
				scaleX = FsmUtil.FindFloatVariable(fsm, "Scale X");
				FsmState state = FsmUtil.GetState(fsm, "Dir");
				int num = Array.FindIndex(state.Actions, (FsmStateAction x) => x is FloatSignTest);
				FsmUtil.InsertMethod(state, num, (Action)PickDirection, false);
				FsmUtil.AddTransition(state, "UL", "UL");
				FsmUtil.AddTransition(state, "UR", "UR");
			}
			void PickDirection()
			{
				string obj = (GlissandoPlugin.GravityIsFlipped ? "U" : "D");
				string text = ((scaleX.Value < 0f) ? "L" : "R");
				string text2 = obj + text;
				fsm.Fsm.Event(text2);
			}
		}
	}
	[HarmonyPatch(typeof(HeroController))]
	internal static class HeroPhysicsPatch
	{
		[HarmonyPatch("FindCollisionDirection")]
		[HarmonyPostfix]
		private static void FlippedCollisionDirection(ref CollisionSide __result)
		{
			if (GlissandoPlugin.GravityIsFlipped)
			{
				if ((int)__result == 0)
				{
					__result = (CollisionSide)3;
				}
				else if ((int)__result == 3)
				{
					__result = (CollisionSide)0;
				}
			}
		}

		[HarmonyPatch("CheckTouchingGround", new Type[] { typeof(bool) })]
		[HarmonyPostfix]
		private static void FlippedGroundCheck(HeroController __instance, ref bool __result)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			if (GlissandoPlugin.GravityIsFlipped)
			{
				Bounds bounds = __instance.col2d.bounds;
				Vector3 min = ((Bounds)(ref bounds)).min;
				Vector3 max = ((Bounds)(ref bounds)).max;
				Vector3 val = default(Vector3);
				((Vector3)(ref val))..ctor(((Bounds)(ref bounds)).center.x, max.y);
				Vector3 val2 = default(Vector3);
				((Vector3)(ref val2))..ctor(min.x, max.y);
				Vector3 val3 = default(Vector3);
				((Vector3)(ref val3))..ctor(max.x, max.y);
				bool flag = (__instance.checkTouchGround.IsTouchingGround = IsRayHitting(Vector2.op_Implicit(val2)) || IsRayHitting(Vector2.op_Implicit(val3)) || IsRayHitting(Vector2.op_Implicit(val)));
				__result = flag;
			}
			static bool IsRayHitting(Vector2 origin)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				return Helper.IsRayHittingNoTriggers(origin, Vector2.up, 0.16f, 8448);
			}
		}

		[HarmonyPatch("CheckNearRoof")]
		[HarmonyPostfix]
		private static void FlippedRoofCheck(HeroController __instance, ref bool __result)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: 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_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: 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_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			if (GlissandoPlugin.GravityIsFlipped)
			{
				Bounds bounds = __instance.col2d.bounds;
				Vector3 min = ((Bounds)(ref bounds)).min;
				Vector3 max = ((Bounds)(ref bounds)).max;
				Vector3 center = ((Bounds)(ref bounds)).center;
				Vector3 size = ((Bounds)(ref bounds)).size;
				Vector2 val = Vector2.op_Implicit(min);
				Vector2 val2 = new Vector2(max.x, min.y);
				Vector2 val3 = default(Vector2);
				((Vector2)(ref val3))..ctor(center.x + size.x / 4f, min.y);
				Vector2 val4 = default(Vector2);
				((Vector2)(ref val4))..ctor(center.x - size.x / 4f, min.y);
				Vector2 val5 = default(Vector2);
				((Vector2)(ref val5))..ctor(-0.5f, -1f);
				Vector2 val6 = default(Vector2);
				((Vector2)(ref val6))..ctor(0.5f, -1f);
				Vector2 down = Vector2.down;
				if (!Helper.IsRayHittingNoTriggers(val2, val5, 2f, 8448) && !Helper.IsRayHittingNoTriggers(val, val6, 2f, 8448) && !Helper.IsRayHittingNoTriggers(val3, down, 1f, 8448))
				{
					__result = Helper.IsRayHittingNoTriggers(val4, down, 1f, 8448);
				}
				else
				{
					__result = true;
				}
			}
		}

		[HarmonyPatch("FallCheck")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> FlippedFallCheck(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Expected O, but got Unknown
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Expected O, but got Unknown
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Expected O, but got Unknown
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Expected O, but got Unknown
			return new CodeMatcher(instructions, (ILGenerator)null).Start().MatchEndForward((CodeMatch[])(object)new CodeMatch[2]
			{
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => ILUtil.Callvirt(x, "get_linearVelocity")), (string)null),
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => ILUtil.Ldfld(x, "y")), (string)null)
			}).Advance(1)
				.Insert((CodeInstruction[])(object)new CodeInstruction[1] { ILUtil.InvertFloatIfFlipped() })
				.MatchEndForward((CodeMatch[])(object)new CodeMatch[2]
				{
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => ILUtil.Callvirt(x, "get_linearVelocity")), (string)null),
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => ILUtil.Ldfld(x, "y")), (string)null)
				})
				.Advance(1)
				.Insert((CodeInstruction[])(object)new CodeInstruction[1] { ILUtil.InvertFloatIfFlipped() })
				.MatchEndForward((CodeMatch[])(object)new CodeMatch[2]
				{
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => ILUtil.Ldfld(x, "MAX_FALL_VELOCITY")), (string)null),
					new CodeMatch((OpCode?)OpCodes.Neg, (object)null, (string)null)
				})
				.Insert((CodeInstruction[])(object)new CodeInstruction[1] { ILUtil.InvertFloatIfFlipped() })
				.InstructionEnumeration();
		}

		[HarmonyPatch("FixedUpdate")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> FlippedPhysicsUpdate(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Expected O, but got Unknown
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Expected O, but got Unknown
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Expected O, but got Unknown
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Expected O, but got Unknown
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Expected O, but got Unknown
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Expected O, but got Unknown
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Expected O, but got Unknown
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Expected O, but got Unknown
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Expected O, but got Unknown
			//IL_0269: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Expected O, but got Unknown
			//IL_0291: Unknown result type (might be due to invalid IL or missing references)
			//IL_0297: Expected O, but got Unknown
			//IL_0300: Unknown result type (might be due to invalid IL or missing references)
			//IL_0306: Expected O, but got Unknown
			//IL_0314: Unknown result type (might be due to invalid IL or missing references)
			//IL_031a: Expected O, but got Unknown
			//IL_033c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0342: Expected O, but got Unknown
			//IL_03ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b1: Expected O, but got Unknown
			//IL_03bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c5: Expected O, but got Unknown
			//IL_03e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ed: Expected O, but got Unknown
			return new CodeMatcher(instructions, (ILGenerator)null).Start().MatchEndForward((CodeMatch[])(object)new CodeMatch[2]
			{
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => ILUtil.Call(x, "GetMaxFallVelocity")), (string)null),
				new CodeMatch((Func<CodeInstruction, bool>)ILUtil.Stloc, (string)null)
			}).MatchEndForward((CodeMatch[])(object)new CodeMatch[2]
			{
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => ILUtil.Callvirt(x, "get_linearVelocity")), (string)null),
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => ILUtil.Ldfld(x, "y")), (string)null)
			})
				.ThrowIfInvalid("clamp comparison - yvel")
				.Advance(1)
				.Insert((CodeInstruction[])(object)new CodeInstruction[1] { ILUtil.InvertFloatIfFlipped() })
				.MatchEndForward((CodeMatch[])(object)new CodeMatch[2]
				{
					new CodeMatch((Func<CodeInstruction, bool>)ILUtil.Ldloc, (string)null),
					new CodeMatch((OpCode?)OpCodes.Neg, (object)null, (string)null)
				})
				.ThrowIfInvalid("clamp comparison - maxvel")
				.Insert((CodeInstruction[])(object)new CodeInstruction[1] { ILUtil.InvertFloatIfFlipped() })
				.MatchEndForward((CodeMatch[])(object)new CodeMatch[2]
				{
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => ILUtil.Ldfld(x, "didAirHang")), (string)null),
					new CodeMatch((Func<CodeInstruction, bool>)ILUtil.Brtrue, (string)null)
				})
				.MatchEndForward((CodeMatch[])(object)new CodeMatch[3]
				{
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => ILUtil.Callvirt(x, "get_linearVelocity")), (string)null),
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => ILUtil.Ldfld(x, "y")), (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldc_R4, (object)0f, (string)null)
				})
				.ThrowIfInvalid("air hang comparison")
				.Insert((CodeInstruction[])(object)new CodeInstruction[1] { ILUtil.InvertFloatIfFlipped() })
				.MatchStartForward((CodeMatch[])(object)new CodeMatch[3]
				{
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => ILUtil.Callvirt(x, "get_gravityScale")), (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null),
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => ILUtil.Ldfld(x, "DEFAULT_GRAVITY")), (string)null)
				})
				.ThrowIfInvalid("default grav comparison - air hang")
				.Advance(1)
				.Insert((CodeInstruction[])(object)new CodeInstruction[1] { ILUtil.InvertFloatIfFlipped() })
				.Advance(3)
				.Insert((CodeInstruction[])(object)new CodeInstruction[1] { ILUtil.InvertFloatIfFlipped() })
				.MatchStartForward((CodeMatch[])(object)new CodeMatch[3]
				{
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => ILUtil.Callvirt(x, "get_gravityScale")), (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null),
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => ILUtil.Ldfld(x, "DEFAULT_GRAVITY")), (string)null)
				})
				.ThrowIfInvalid("default grav comparison - lt")
				.Advance(1)
				.Insert((CodeInstruction[])(object)new CodeInstruction[1] { ILUtil.InvertFloatIfFlipped() })
				.Advance(3)
				.Insert((CodeInstruction[])(object)new CodeInstruction[1] { ILUtil.InvertFloatIfFlipped() })
				.MatchStartForward((CodeMatch[])(object)new CodeMatch[3]
				{
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => ILUtil.Callvirt(x, "get_gravityScale")), (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null),
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => ILUtil.Ldfld(x, "DEFAULT_GRAVITY")), (string)null)
				})
				.ThrowIfInvalid("default grav comparison - gt")
				.Advance(1)
				.Insert((CodeInstruction[])(object)new CodeInstruction[1] { ILUtil.InvertFloatIfFlipped() })
				.Advance(3)
				.Insert((CodeInstruction[])(object)new CodeInstruction[1] { ILUtil.InvertFloatIfFlipped() })
				.InstructionEnumeration();
		}

		[HarmonyPatch("JumpReleased")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> FlippedJumpReleased(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			return new CodeMatcher(instructions, (ILGenerator)null).Start().MatchEndForward((CodeMatch[])(object)new CodeMatch[2]
			{
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => ILUtil.Callvirt(x, "get_linearVelocity")), (string)null),
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => ILUtil.Ldfld(x, "y")), (string)null)
			}).Advance(1)
				.Insert((CodeInstruction[])(object)new CodeInstruction[1] { ILUtil.InvertFloatIfFlipped() })
				.InstructionEnumeration();
		}

		[HarmonyPatch("AffectedByGravity")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> FlippedAffectedByGravity(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Expected O, but got Unknown
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Expected O, but got Unknown
			return new CodeMatcher(instructions, (ILGenerator)null).Start().MatchEndForward((CodeMatch[])(object)new CodeMatch[2]
			{
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => ILUtil.Callvirt(x, "get_gravityScale")), (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldsfld, (object)null, (string)null)
			}).Insert((CodeInstruction[])(object)new CodeInstruction[1] { ILUtil.InvertFloatIfFlipped() })
				.MatchEndForward((CodeMatch[])(object)new CodeMatch[2]
				{
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => ILUtil.Callvirt(x, "get_gravityScale")), (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldsfld, (object)null, (string)null)
				})
				.Insert((CodeInstruction[])(object)new CodeInstruction[1] { ILUtil.InvertFloatIfFlipped() })
				.InstructionEnumeration();
		}
	}
	[HarmonyPatch(typeof(PlayMakerFSM), "Start")]
	internal class IntroWeaknessPatch
	{
		private static void Prefix(PlayMakerFSM __instance)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)((Component)__instance).gameObject).name.StartsWith("Weakness Scene"))
			{
				return;
			}
			Scene activeScene = SceneManager.GetActiveScene();
			if (!(((Scene)(ref activeScene)).name != "Bonetown"))
			{
				FsmState state = FsmUtil.GetState(__instance, "Wait For Entry");
				if (state != null)
				{
					FsmUtil.InsertMethod(state, 0, (Action)UnflipGravity, false);
				}
				FsmState state2 = FsmUtil.GetState(__instance, "Wait For Entry 2");
				if (state2 != null)
				{
					FsmUtil.InsertMethod(state2, 0, (Action)UnflipGravity, false);
				}
			}
			static void UnflipGravity()
			{
				if (GlissandoPlugin.GravityIsFlipped)
				{
					GlissandoPlugin.FlipGravity(HeroController.instance, jumpBoost: false, force: true);
				}
			}
		}
	}
	[HarmonyPatch(typeof(HeroController))]
	internal static class SpecialRespawnPatch
	{
		[HarmonyPatch("FinishedEnteringScene")]
		[HarmonyPrefix]
		private static void OpeningSequenceDetection(HeroController __instance, ref bool __state)
		{
			__state = __instance.isEnteringFirstLevel;
		}

		[HarmonyPatch("FinishedEnteringScene")]
		[HarmonyPostfix]
		private static void OpeningSequenceSetRespawn(HeroController __instance, ref bool __state)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			if (__state)
			{
				__instance.SetHazardRespawn(__instance.transform.position, __instance.cState.facingRight);
			}
		}

		[HarmonyPatch("Update10")]
		[HarmonyPostfix]
		private static void OutOfBoundsAutomaticRespawn(HeroController __instance)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			if (__instance.gm.IsGameplayScene() && GlissandoPlugin.GravityIsFlipped && __instance.transform.position.y > __instance.gm.sceneHeight + 20f)
			{
				GlissandoPlugin.QueueRespawnHero();
			}
		}
	}
	[HarmonyPatch(typeof(HeroController), "ThrowTool")]
	internal static class ToolsPatch
	{
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Expected O, but got Unknown
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Expected O, but got Unknown
			return new CodeMatcher(instructions, (ILGenerator)null).Start().MatchStartForward((CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => ILUtil.Ldfld(x, "ThrowVelocity")), (string)null)
			}).MatchStartForward((CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((Func<CodeInstruction, bool>)ILUtil.Stloc, (string)null)
			})
				.Insert((CodeInstruction[])(object)new CodeInstruction[1] { Transpilers.EmitDelegate<Func<Vector2, Vector2>>((Func<Vector2, Vector2>)InvertVectorIfFlipped) })
				.Start()
				.MatchEndForward((CodeMatch[])(object)new CodeMatch[2]
				{
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => ILUtil.Call(x, "Spawn")), (string)null),
					new CodeMatch((Func<CodeInstruction, bool>)ILUtil.Stloc, (string)null)
				})
				.Insert((CodeInstruction[])(object)new CodeInstruction[1] { Transpilers.EmitDelegate<Func<GameObject, GameObject>>((Func<GameObject, GameObject>)InvertToolScaleIfFlipped) })
				.InstructionEnumeration();
			static GameObject InvertToolScaleIfFlipped(GameObject go)
			{
				ClockworkHatchling val = default(ClockworkHatchling);
				if (!go.TryGetComponent<ClockworkHatchling>(ref val))
				{
					Extensions.FlipLocalScale(go.transform, false, GlissandoPlugin.GravityIsFlipped, false);
				}
				return go;
			}
			static Vector2 InvertVectorIfFlipped(Vector2 vec)
			{
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				if (GlissandoPlugin.GravityIsFlipped)
				{
					return new Vector2(vec.x, 0f - vec.y);
				}
				return vec;
			}
		}
	}
	[HarmonyPatch]
	internal static class VisualEffectsPatch
	{
		private static readonly Dictionary<string, string> downToUp = new Dictionary<string, string>
		{
			{ "LookDown", "LookUp" },
			{ "LookDownEnd", "LookUpEnd" },
			{ "LookDownToIdle", "LookUpToIdle" },
			{ "Ring Look Down", "Ring Look Up" },
			{ "Ring Look Down End", "Ring Look Up End" },
			{ "LookDown Updraft", "LookUp Updraft" },
			{ "LookDownEnd Updraft", "LookUpEnd Updraft" },
			{ "LookDown Windy", "LookUp Windy" },
			{ "LookDownEnd Windy", "LookUpEnd Windy" },
			{ "Hurt Look Down", "Hurt Look Up" },
			{ "Hurt Look Down Windy", "Hurt Look Up Windy" },
			{ "Hurt Look Down Windy End", "Hurt Look Up Windy End" }
		};

		private static readonly Dictionary<string, string> upToDown = downToUp.ToDictionary<KeyValuePair<string, string>, string, string>((KeyValuePair<string, string> i) => i.Value, (KeyValuePair<string, string> i) => i.Key);

		[HarmonyPatch(typeof(RunEffects), "Update")]
		[HarmonyPrefix]
		private static void FlipRunEffects(RunEffects __instance)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0068: Unknown result type (might be due to invalid IL or missing references)
			if (__instance.isHeroEffect && __instance.hasHC)
			{
				HeroController hc = __instance.hc;
				Transform transform = ((Component)__instance).transform;
				float num = (((Object)(object)transform.parent == (Object)(object)hc.transform) ? 1f : hc.transform.localScale.y);
				if (transform.localScale.y != num)
				{
					Vector3 localScale = transform.localScale;
					localScale.y = num;
					transform.localScale = localScale;
				}
			}
		}

		[HarmonyPatch(typeof(JumpEffects), "Play")]
		[HarmonyPrefix]
		private static void FlipJumpEffects(JumpEffects __instance, GameObject owner)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			HeroController val = default(HeroController);
			if (owner.TryGetComponent<HeroController>(ref val))
			{
				Transform transform = ((Component)__instance).transform;
				Vector3 localScale = transform.localScale;
				localScale.y = val.transform.localScale.y;
				transform.localScale = localScale;
			}
		}

		[HarmonyPatch(typeof(JumpEffects), "CheckForFall")]
		[HarmonyPostfix]
		private static void FlipJumpEffectsFallCheck(JumpEffects __instance)
		{
			HeroController val = default(HeroController);
			if (GlissandoPlugin.GravityIsFlipped && __instance.ownerObject.TryGetComponent<HeroController>(ref val) && (__instance.ownerPos.y - __instance.previousOwnerPos.y) / Time.deltaTime > 0f)
			{
				__instance.jumpPuff.SetActive(false);
				__instance.dustTrail.GetComponent<ParticleSystem>().Stop();
				__instance.checkForFall = false;
			}
		}

		[HarmonyPatch(typeof(HardLandEffect), "OnEnable")]
		[HarmonyPrefix]
		private static void FlipHardLandEffect(HardLandEffect __instance)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			float y = ((!GlissandoPlugin.GravityIsFlipped) ? 1 : (-1));
			Transform transform = ((Component)__instance).transform;
			Vector3 localScale = ((Component)__instance).transform.localScale;
			localScale.y = y;
			transform.localScale = localScale;
		}

		[HarmonyPatch(typeof(SoftLandEffect), "OnEnable")]
		[HarmonyPrefix]
		private static void FlipSoftLandEffect(SoftLandEffect __instance)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			float y = ((!GlissandoPlugin.GravityIsFlipped) ? 1 : (-1));
			Transform transform = ((Component)__instance).transform;
			Vector3 localScale = ((Component)__instance).transform.localScale;
			localScale.y = y;
			transform.localScale = localScale;
		}

		[HarmonyPatch(typeof(HeroAnimationController), "GetClip")]
		[HarmonyPrefix]
		private static void FlipLookAnimations(ref string clipName)
		{
			if (GlissandoPlugin.GravityIsFlipped)
			{
				string value2;
				if (downToUp.TryGetValue(clipName,