plugins\Alas.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using BoplFixedMath;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Alas
{
	internal static class AbilityRegistration
	{
		private static bool _injected;

		public static Texture2D LoadEmbeddedPng(string logicalLeafName)
		{
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Expected O, but got Unknown
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			string text = null;
			string[] manifestResourceNames = executingAssembly.GetManifestResourceNames();
			foreach (string text2 in manifestResourceNames)
			{
				if (text2.EndsWith(logicalLeafName, StringComparison.OrdinalIgnoreCase) || text2.IndexOf(logicalLeafName, StringComparison.OrdinalIgnoreCase) >= 0)
				{
					text = text2;
					break;
				}
			}
			if (text == null)
			{
				Plugin.Log.LogError((object)("Embedded PNG not found: " + logicalLeafName));
				return null;
			}
			using Stream stream = executingAssembly.GetManifestResourceStream(text);
			if (stream == null)
			{
				return null;
			}
			byte[] array = new byte[stream.Length];
			stream.Read(array, 0, array.Length);
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
			if (!ImageConversion.LoadImage(val, array, false))
			{
				Plugin.Log.LogError((object)("LoadImage failed: " + logicalLeafName));
				return null;
			}
			((Texture)val).filterMode = (FilterMode)1;
			((Texture)val).wrapMode = (TextureWrapMode)1;
			((Object)val).name = logicalLeafName;
			return val;
		}

		public static Sprite MakeSprite(Texture2D tex, float ppu = 100f)
		{
			//IL_0024: 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)
			if ((Object)(object)tex == (Object)null)
			{
				return null;
			}
			return Sprite.Create(tex, new Rect(0f, 0f, (float)((Texture)tex).width, (float)((Texture)tex).height), new Vector2(0.5f, 0.5f), ppu);
		}

		public static void TryInject(AbilityGrid grid)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			if (_injected || (Object)(object)grid == (Object)null)
			{
				return;
			}
			NamedSpriteList value = Traverse.Create((object)grid).Field("abilityIcons").GetValue<NamedSpriteList>();
			if (value?.sprites == null)
			{
				Plugin.Log.LogWarning((object)"Alas: abilityIcons missing — cannot register.");
				return;
			}
			foreach (NamedSprite sprite in value.sprites)
			{
				if (sprite.name == "Alas")
				{
					_injected = true;
					return;
				}
			}
			NamedSprite val = default(NamedSprite);
			NamedSprite val2 = default(NamedSprite);
			bool flag = false;
			bool flag2 = false;
			foreach (NamedSprite sprite2 in value.sprites)
			{
				if (sprite2.name == "Invisibility")
				{
					val = sprite2;
					flag = true;
				}
				if (sprite2.name == "Random")
				{
					val2 = sprite2;
					flag2 = true;
				}
			}
			if (!flag || (Object)(object)val.associatedGameObject == (Object)null)
			{
				Plugin.Log.LogError((object)"Alas: base ability Invisibility not found in grid.");
				return;
			}
			NamedSprite val3 = val;
			GameObject val4 = Object.Instantiate<GameObject>(val3.associatedGameObject);
			Object.DontDestroyOnLoad((Object)(object)val4);
			((Object)val4).name = "Alas";
			InstantAbility component = val4.GetComponent<InstantAbility>();
			if ((Object)(object)component != (Object)null)
			{
				component.SetCoolDown((Fix)5f);
			}
			float num = 100f;
			if (flag2 && (Object)(object)val2.sprite != (Object)null)
			{
				num = val2.sprite.pixelsPerUnit;
			}
			else if ((Object)(object)val3.sprite != (Object)null)
			{
				num = val3.sprite.pixelsPerUnit;
			}
			Texture2D abilityIconTexture = Plugin.AbilityIconTexture;
			Sprite val5;
			if ((Object)(object)abilityIconTexture != (Object)null)
			{
				val5 = Sprite.Create(abilityIconTexture, new Rect(0f, 0f, (float)((Texture)abilityIconTexture).width, (float)((Texture)abilityIconTexture).height), new Vector2(0.5f, 0.5f), num);
				if (flag2 && (Object)(object)val2.sprite != (Object)null)
				{
					((Texture)val5.texture).filterMode = ((Texture)val2.sprite.texture).filterMode;
					((Texture)val5.texture).wrapMode = ((Texture)val2.sprite.texture).wrapMode;
				}
			}
			else
			{
				val5 = val3.sprite;
			}
			NamedSprite item = default(NamedSprite);
			((NamedSprite)(ref item))..ctor("Alas", val5, val4, false);
			value.sprites.Add(item);
			_injected = true;
			Plugin.Log.LogInfo((object)"Alas: registered in AbilityGrid (no OctoLib).");
		}
	}
	[HarmonyPatch(typeof(AbilityGrid), "Awake")]
	internal static class AlasAbilityGridInjectPatch
	{
		[HarmonyPrefix]
		[HarmonyPriority(800)]
		private static void Prefix(AbilityGrid __instance)
		{
			AbilityRegistration.TryInject(__instance);
		}
	}
	internal static class AlasUtil
	{
		public static bool IsAlasObject(Object obj)
		{
			if (obj != (Object)null && obj.name != null)
			{
				return obj.name.Contains("Alas");
			}
			return false;
		}

		public static bool IsAlasActiveOn(SlimeController slime, int abilityIndex)
		{
			if ((Object)(object)slime == (Object)null || abilityIndex < 0)
			{
				return false;
			}
			WingsFlight component = ((Component)slime).GetComponent<WingsFlight>();
			if ((Object)(object)component != (Object)null && component.Active)
			{
				return component.AbilityIndex == abilityIndex;
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(AbilityGrid), "Awake")]
	internal static class AlasCooldownPatch
	{
		[HarmonyPostfix]
		[HarmonyPriority(0)]
		private static void Postfix(AbilityGrid __instance)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			NamedSpriteList value = Traverse.Create((object)__instance).Field("abilityIcons").GetValue<NamedSpriteList>();
			if (value?.sprites == null)
			{
				return;
			}
			foreach (NamedSprite sprite in value.sprites)
			{
				if (!(sprite.name != "Alas") && !((Object)(object)sprite.associatedGameObject == (Object)null))
				{
					InstantAbility component = sprite.associatedGameObject.GetComponent<InstantAbility>();
					if ((Object)(object)component != (Object)null)
					{
						component.SetCoolDown((Fix)5f);
					}
				}
			}
		}
	}
	[HarmonyPatch(typeof(Invisibility), "CastInvisibility")]
	internal static class AlasCastPatch
	{
		internal static WingsFlight LastFlight;

		internal static bool LastEndedActive;

		[HarmonyPrefix]
		private static bool Prefix(Invisibility __instance)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			if (!AlasUtil.IsAlasObject((Object)(object)((Component)__instance).gameObject))
			{
				return true;
			}
			InstantAbility component = ((Component)__instance).GetComponent<InstantAbility>();
			if ((Object)(object)component == (Object)null)
			{
				return false;
			}
			SlimeController slimeController = ((AbilityMonoBehaviour)component).GetSlimeController();
			if ((Object)(object)slimeController == (Object)null)
			{
				return false;
			}
			int abilityButtonUsedIndex = Traverse.Create((object)component).Field("playerInfo").GetValue<PlayerInfo>()
				.AbilityButtonUsedIndex012;
			WingsFlight wingsFlight = ((Component)slimeController).GetComponent<WingsFlight>();
			if ((Object)(object)wingsFlight == (Object)null)
			{
				wingsFlight = ((Component)slimeController).gameObject.AddComponent<WingsFlight>();
			}
			bool active = wingsFlight.Active;
			bool flag = wingsFlight.HandleCast(slimeController, component, abilityButtonUsedIndex);
			if (active != flag)
			{
				LastFlight = wingsFlight;
				LastEndedActive = flag;
			}
			else if (flag)
			{
				LastFlight = wingsFlight;
				LastEndedActive = true;
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(SlimeController), "EnterAbility")]
	internal static class AlasEnterAbilityPostfix
	{
		[HarmonyPostfix]
		[HarmonyPriority(0)]
		private static void Postfix(SlimeController __instance, int abilityIndex)
		{
			WingsFlight lastFlight = AlasCastPatch.LastFlight;
			if (!((Object)(object)lastFlight == (Object)null) && !((Object)(object)lastFlight != (Object)(object)((Component)__instance).GetComponent<WingsFlight>()))
			{
				if (AlasCastPatch.LastEndedActive)
				{
					lastFlight.ReassertAfterEnterAbility();
				}
				else
				{
					lastFlight.ReassertDeactivateCooldown();
				}
				AlasCastPatch.LastFlight = null;
			}
		}
	}
	[HarmonyPatch(typeof(SlimeController), "isAbilityReady")]
	internal static class AlasReadyPatch
	{
		[HarmonyPostfix]
		private static void Postfix(SlimeController __instance, int abilityIndex, ref bool __result)
		{
			if (AlasUtil.IsAlasActiveOn(__instance, abilityIndex))
			{
				__result = true;
			}
		}
	}
	[HarmonyPatch(typeof(SlimeController), "isAbilityCastable")]
	internal static class AlasCastablePatch
	{
		[HarmonyPostfix]
		private static void Postfix(SlimeController __instance, int abilityIndex, ref bool __result)
		{
			if (AlasUtil.IsAlasActiveOn(__instance, abilityIndex))
			{
				__result = true;
			}
		}
	}
	[HarmonyPatch(typeof(SlimeController), "AddAbility")]
	internal static class AlasAddAbilityReadyPatch
	{
		[HarmonyPostfix]
		private static void Postfix(SlimeController __instance)
		{
			AlasReadyHelper.EnsureAlasSlotsReady(__instance);
		}
	}
	[HarmonyPatch(typeof(SlimeController), "AddAdditionalAbility")]
	internal static class AlasAddAdditionalReadyPatch
	{
		[HarmonyPostfix]
		private static void Postfix(SlimeController __instance)
		{
			AlasReadyHelper.EnsureAlasSlotsReady(__instance);
		}
	}
	[HarmonyPatch(typeof(SlimeController), "Init")]
	internal static class AlasInitReadyPatch
	{
		[HarmonyPostfix]
		private static void Postfix(SlimeController __instance)
		{
			AlasReadyHelper.EnsureAlasSlotsReady(__instance);
		}
	}
	[HarmonyPatch(typeof(SlimeController), "BeforeSpawnInit")]
	internal static class AlasBeforeSpawnReadyPatch
	{
		[HarmonyPostfix]
		private static void Postfix(SlimeController __instance)
		{
			AlasReadyHelper.EnsureAlasSlotsReady(__instance);
		}
	}
	internal static class AlasReadyHelper
	{
		public static void EnsureAlasSlotsReady(SlimeController slime)
		{
			//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_0092: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)slime == (Object)null)
			{
				return;
			}
			List<AbilityMonoBehaviour> value = Traverse.Create((object)slime).Field("abilities").GetValue<List<AbilityMonoBehaviour>>();
			Fix[] value2 = Traverse.Create((object)slime).Field("abilityCooldownTimers").GetValue<Fix[]>();
			if (value == null || value2 == null)
			{
				return;
			}
			for (int i = 0; i < value.Count && i < value2.Length; i++)
			{
				AbilityMonoBehaviour val = value[i];
				if (!((Object)(object)val == (Object)null) && !((MonoUpdatable)val).IsDestroyed && AlasUtil.IsAlasObject((Object)(object)((Component)val).gameObject))
				{
					value2[i] = (Fix)100000L;
					InstantAbility component = ((Component)val).GetComponent<InstantAbility>();
					if ((Object)(object)component != (Object)null)
					{
						component.SetCoolDown((Fix)5f);
					}
				}
			}
		}
	}
	[HarmonyPatch(typeof(SlimeController), "Jump")]
	internal static class JumpPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(SlimeController __instance)
		{
			WingsFlight component = ((Component)__instance).GetComponent<WingsFlight>();
			if ((Object)(object)component == (Object)null || !component.Active)
			{
				return true;
			}
			component.TryFlap();
			return false;
		}
	}
	[HarmonyPatch(typeof(SlimeController), "OldUpdate")]
	internal static class AirFlapPatch
	{
		[HarmonyPostfix]
		private static void Postfix(SlimeController __instance)
		{
			WingsFlight component = ((Component)__instance).GetComponent<WingsFlight>();
			if (!((Object)(object)component == (Object)null) && component.Active && (!((Object)(object)__instance.playerPhysics != (Object)null) || !__instance.playerPhysics.IsGrounded()) && !__instance.suppressInput)
			{
				PlayerHandler obj = PlayerHandler.Get();
				Player val = ((obj != null) ? obj.GetPlayer(__instance.GetPlayerId()) : null);
				if (val != null && val.IsAlive && val.jumpButton_PressedThisFrame())
				{
					component.TryFlap();
				}
			}
		}
	}
	[BepInPlugin("com.Jero.Alas", "Alas", "1.1.7")]
	public class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Log;

		internal static Assembly ModAssembly;

		internal static Texture2D AbilityIconTexture;

		internal static Sprite WingOpenSprite;

		internal static Sprite WingClosedSprite;

		private void Awake()
		{
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			ModAssembly = Assembly.GetExecutingAssembly();
			AbilityIconTexture = AbilityRegistration.LoadEmbeddedPng("AbilityIcon.png");
			if ((Object)(object)AbilityIconTexture == (Object)null)
			{
				Log.LogError((object)"Failed to load AbilityIcon.png — ability may have no icon.");
			}
			WingOpenSprite = AbilityRegistration.MakeSprite(AbilityRegistration.LoadEmbeddedPng("WingOpen.png"), 48f);
			WingClosedSprite = AbilityRegistration.MakeSprite(AbilityRegistration.LoadEmbeddedPng("WingClosed.png"), 48f);
			if ((Object)(object)WingOpenSprite == (Object)null || (Object)(object)WingClosedSprite == (Object)null)
			{
				Log.LogError((object)"Wing sprites failed to load.");
			}
			new Harmony("com.Jero.Alas").PatchAll();
			Log.LogInfo((object)"Alas 1.1.7 loaded — BepInEx only (no OctoLib / FixedConfig).");
		}
	}
	internal static class PluginInfo
	{
		public const string GUID = "com.Jero.Alas";

		public const string Name = "Alas";

		public const string Version = "1.1.7";
	}
	public class WingsFlight : MonoBehaviour
	{
		public const float DurationSeconds = 7f;

		public const float CooldownSeconds = 5f;

		public const float FlapCooldownSeconds = 0.22f;

		public const float FlapJumpFraction = 1f;

		public const float CancelGraceSeconds = 0.25f;

		public const float CancelReactivateLockoutSeconds = 0.35f;

		public const float FlapAnimSeconds = 0.28f;

		public const float WingSizeMul = 1f;

		public const float WingSideMul = 0.62f;

		public const float AirTiltDegrees = 14f;

		public const float AirFoldAmount = 0.08f;

		public const float AirMotionSmooth = 10f;

		private SlimeController _slime;

		private InstantAbility _source;

		private int _abilityIndex = -1;

		private float _activeElapsed;

		private SpriteRenderer _leftWing;

		private SpriteRenderer _rightWing;

		private float _flapAnimT;

		private float _lastFlapRealtime = -999f;

		private int _activateFrame = -1;

		private float _airMotion;

		private float _blockActivateUntilRealtime = -999f;

		public bool Active { get; private set; }

		public int AbilityIndex => _abilityIndex;

		public bool HandleCast(SlimeController slime, InstantAbility source, int abilityIndex)
		{
			_slime = slime;
			_source = source;
			_abilityIndex = abilityIndex;
			if (Active)
			{
				if (Time.frameCount <= _activateFrame + 2 || _activeElapsed < 0.25f)
				{
					Plugin.Log.LogInfo((object)"Alas: ignored duplicate cast (grace)");
					return true;
				}
				Deactivate();
				_blockActivateUntilRealtime = Time.realtimeSinceStartup + 0.35f;
				return false;
			}
			if (Time.realtimeSinceStartup < _blockActivateUntilRealtime)
			{
				Plugin.Log.LogInfo((object)"Alas: blocked re-activate after cancel");
				return false;
			}
			Activate();
			return true;
		}

		private void Activate()
		{
			Active = true;
			_activeElapsed = 0f;
			_flapAnimT = 0f;
			_airMotion = 0f;
			_activateFrame = Time.frameCount;
			EnsureVisuals();
			SetVisualsVisible(visible: true);
			SetCooldownState(7f, 0.01f);
			Plugin.Log.LogInfo((object)$"Alas ON — player {_slime.GetPlayerId()}");
		}

		private void Deactivate()
		{
			if (Active)
			{
				Active = false;
				SetVisualsVisible(visible: false);
				SetCooldownState(5f, 0f);
				ManualLogSource log = Plugin.Log;
				object arg = 5f;
				SlimeController slime = _slime;
				log.LogInfo((object)$"Alas OFF — {arg:0}s cooldown — player {((slime != null) ? new int?(slime.GetPlayerId()) : ((int?)null))}");
			}
		}

		private void SetCooldownState(float cooldownMax, float timerProgress)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_source != (Object)null)
			{
				_source.SetCoolDown((Fix)cooldownMax);
			}
			if (!((Object)(object)_slime == (Object)null) && _abilityIndex >= 0)
			{
				Fix[] value = Traverse.Create((object)_slime).Field("abilityCooldownTimers").GetValue<Fix[]>();
				if (value != null && _abilityIndex < value.Length)
				{
					value[_abilityIndex] = (Fix)timerProgress;
				}
			}
		}

		public void ReassertAfterEnterAbility()
		{
			if (Active && !((Object)(object)_slime == (Object)null) && _abilityIndex >= 0)
			{
				SetCooldownState(7f, Mathf.Max(0.01f, _activeElapsed));
			}
		}

		public void ReassertDeactivateCooldown()
		{
			SetCooldownState(5f, 0f);
		}

		private void Update()
		{
			if (Active && !((Object)(object)_slime == (Object)null))
			{
				_activeElapsed += Time.deltaTime;
				if (_flapAnimT > 0f)
				{
					_flapAnimT = Mathf.Max(0f, _flapAnimT - Time.deltaTime / 0.28f);
				}
				SetCooldownState(7f, Mathf.Min(_activeElapsed, 6.95f));
				if (_activeElapsed >= 7f)
				{
					Deactivate();
				}
			}
		}

		public bool TryFlap()
		{
			//IL_007e: 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_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			if (!Active || (Object)(object)_slime == (Object)null)
			{
				return false;
			}
			float realtimeSinceStartup = Time.realtimeSinceStartup;
			if (realtimeSinceStartup - _lastFlapRealtime < 0.22f)
			{
				return false;
			}
			_lastFlapRealtime = realtimeSinceStartup;
			_flapAnimT = 1f;
			PlayerPhysics playerPhysics = _slime.playerPhysics;
			PlayerBody body = _slime.body;
			if ((Object)(object)playerPhysics == (Object)null || (Object)(object)body == (Object)null)
			{
				return false;
			}
			if (playerPhysics.IsGrounded())
			{
				playerPhysics.UnGround(true, true);
			}
			Fix val = playerPhysics.jumpStrength * (Fix)1f;
			body.selfImposedVelocity = new Vec2(body.selfImposedVelocity.x, val);
			return true;
		}

		private void EnsureVisuals()
		{
			if (!((Object)(object)_leftWing != (Object)null) || !((Object)(object)_rightWing != (Object)null))
			{
				_leftWing = CreateWing("WingLeft");
				_rightWing = CreateWing("WingRight");
			}
		}

		private SpriteRenderer CreateWing(string name)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.transform.SetParent(((Component)this).transform, false);
			SpriteRenderer obj = val.AddComponent<SpriteRenderer>();
			obj.sprite = (((Object)(object)Plugin.WingOpenSprite != (Object)null) ? Plugin.WingOpenSprite : Plugin.WingClosedSprite);
			((Renderer)obj).sortingOrder = 8;
			((Renderer)obj).enabled = true;
			return obj;
		}

		private void SetVisualsVisible(bool visible)
		{
			if ((Object)(object)_leftWing != (Object)null)
			{
				((Renderer)_leftWing).enabled = visible;
			}
			if ((Object)(object)_rightWing != (Object)null)
			{
				((Renderer)_rightWing).enabled = visible;
			}
		}

		private void LateUpdate()
		{
			if (Active && !((Object)(object)_slime == (Object)null))
			{
				EnsureVisuals();
				UpdateWingPose();
			}
		}

		private void UpdateWingPose()
		{
			//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_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0291: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_031e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bb: 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)
			SpriteRenderer playerSprite = _slime.GetPlayerSprite();
			if ((Object)(object)playerSprite != (Object)null)
			{
				if ((Object)(object)_leftWing != (Object)null)
				{
					((Renderer)_leftWing).sortingLayerID = ((Renderer)playerSprite).sortingLayerID;
					((Renderer)_leftWing).sortingOrder = ((Renderer)playerSprite).sortingOrder - 1;
				}
				if ((Object)(object)_rightWing != (Object)null)
				{
					((Renderer)_rightWing).sortingLayerID = ((Renderer)playerSprite).sortingLayerID;
					((Renderer)_rightWing).sortingOrder = ((Renderer)playerSprite).sortingOrder - 1;
				}
			}
			float num = 0f;
			if (_flapAnimT > 0f)
			{
				num = Mathf.Sin((1f - _flapAnimT) * (float)Math.PI);
			}
			float num2 = 0f;
			if ((Object)(object)_slime.body != (Object)null)
			{
				num2 = (float)_slime.body.Velocity.y;
			}
			float num3 = Mathf.Clamp(num2 / 18f, -1f, 1f);
			_airMotion = Mathf.Lerp(_airMotion, num3, 1f - Mathf.Exp(-10f * Time.deltaTime));
			Sprite sprite = ((num > 0.45f) ? (Plugin.WingClosedSprite ?? Plugin.WingOpenSprite) : (Plugin.WingOpenSprite ?? Plugin.WingClosedSprite));
			if ((Object)(object)_leftWing != (Object)null)
			{
				_leftWing.sprite = sprite;
			}
			if ((Object)(object)_rightWing != (Object)null)
			{
				_rightWing.sprite = sprite;
			}
			float num4 = (float)_slime.body.fixtrans.Scale;
			float num5 = num4 * 1f;
			float num6 = 0.62f * num4;
			float num7 = (0.04f + num * 0.05f) * num4 + _airMotion * 0.05f * num4;
			float num8 = Mathf.Lerp(1f, 0.84f, num) - Mathf.Abs(_airMotion) * 0.08f * 0.35f;
			float num9 = Mathf.Lerp(-4f, -18f, num) - _airMotion * 14f;
			bool flag = _slime.isFacingRight();
			float num10 = (flag ? (0f - num6) : num6);
			float num11 = (flag ? num6 : (0f - num6));
			if ((Object)(object)_leftWing != (Object)null)
			{
				((Component)_leftWing).transform.localPosition = new Vector3(num10, num7, 0f);
				_leftWing.flipX = flag;
				((Component)_leftWing).transform.localScale = new Vector3(num8 * num5, num5 * 0.95f, 1f);
				((Component)_leftWing).transform.localRotation = Quaternion.Euler(0f, 0f, flag ? num9 : (0f - num9));
			}
			if ((Object)(object)_rightWing != (Object)null)
			{
				((Component)_rightWing).transform.localPosition = new Vector3(num11, num7, 0f);
				_rightWing.flipX = !flag;
				((Component)_rightWing).transform.localScale = new Vector3(num8 * num5, num5 * 0.95f, 1f);
				((Component)_rightWing).transform.localRotation = Quaternion.Euler(0f, 0f, flag ? (0f - num9) : num9);
			}
		}

		private void OnDestroy()
		{
			if ((Object)(object)_leftWing != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)_leftWing).gameObject);
			}
			if ((Object)(object)_rightWing != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)_rightWing).gameObject);
			}
		}
	}
}