plugins\Alas.dll

Decompiled 8 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
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 OctoLib;
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 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;
		}

		public static bool CanCastAlasEarly(SlimeController slime, int abilityIndex)
		{
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)slime == (Object)null || abilityIndex < 0)
			{
				return false;
			}
			WingsFlight component = ((Component)slime).GetComponent<WingsFlight>();
			if ((Object)(object)component != (Object)null && component.ChargeFrozen && component.AbilityIndex == abilityIndex)
			{
				return false;
			}
			List<AbilityMonoBehaviour> value = Traverse.Create((object)slime).Field("abilities").GetValue<List<AbilityMonoBehaviour>>();
			if (value == null || abilityIndex >= value.Count)
			{
				return false;
			}
			AbilityMonoBehaviour val = value[abilityIndex];
			if ((Object)(object)val == (Object)null || ((MonoUpdatable)val).IsDestroyed || !IsAlasObject((Object)(object)((Component)val).gameObject))
			{
				return false;
			}
			Fix[] value2 = Traverse.Create((object)slime).Field("abilityCooldownTimers").GetValue<Fix[]>();
			if (value2 == null || abilityIndex >= value2.Length)
			{
				return false;
			}
			float num = (float)value2[abilityIndex];
			float num2 = 7f;
			if (num > num2)
			{
				return true;
			}
			return num > 0.15f;
		}

		public static bool IsAlasFrozenOn(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.ChargeFrozen)
			{
				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)7f);
					}
				}
			}
		}
	}
	[HarmonyPatch(typeof(Invisibility), "CastInvisibility")]
	internal static class AlasCastPatch
	{
		internal static WingsFlight LastFlight;

		internal static bool LastEndedActive;

		internal static float LastUsed;

		[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;
			float cooldownTimerSnapshot = wingsFlight.CooldownTimerSnapshot;
			bool flag = wingsFlight.HandleCast(slimeController, component, abilityButtonUsedIndex);
			if (active != flag)
			{
				LastFlight = wingsFlight;
				LastEndedActive = flag;
				LastUsed = ((active && !flag) ? cooldownTimerSnapshot : 0f);
			}
			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.LastUsed, expiredNaturally: false);
				}
				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.IsAlasFrozenOn(__instance, abilityIndex))
			{
				__result = false;
			}
			else if (AlasUtil.IsAlasActiveOn(__instance, abilityIndex) || AlasUtil.CanCastAlasEarly(__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.IsAlasFrozenOn(__instance, abilityIndex))
			{
				__result = false;
			}
			else if (AlasUtil.IsAlasActiveOn(__instance, abilityIndex) || AlasUtil.CanCastAlasEarly(__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)7f);
					}
				}
			}
		}
	}
	[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)
			{
				return;
			}
			component.SyncTankAfterGameUpdate();
			if (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.5")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Log;

		internal static Assembly ModAssembly;

		internal static Sprite WingOpenSprite;

		internal static Sprite WingClosedSprite;

		private void Awake()
		{
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			ModAssembly = Assembly.GetExecutingAssembly();
			Texture2D val = Textures.LoadFromAssembly("AbilityIcon", ModAssembly, true);
			if ((Object)(object)val == (Object)null)
			{
				Log.LogError((object)"Failed to load AbilityIcon.png — ability will have no icon.");
			}
			else
			{
				((Texture)val).filterMode = (FilterMode)1;
				((Texture)val).wrapMode = (TextureWrapMode)1;
				try
				{
					val.Apply(false, false);
				}
				catch
				{
				}
			}
			WingOpenSprite = MakeSprite(Textures.LoadFromAssembly("WingOpen", ModAssembly, true));
			WingClosedSprite = MakeSprite(Textures.LoadFromAssembly("WingClosed", ModAssembly, true));
			if ((Object)(object)WingOpenSprite == (Object)null || (Object)(object)WingClosedSprite == (Object)null)
			{
				Log.LogError((object)"Wing sprites failed to load.");
			}
			Abilities.NewAbilityWithBase("Invisibility", "Alas", val);
			Abilities.AbilitySetCooldown("Alas", (Fix)7f);
			Abilities.AbilitySetOffensive("Alas", false);
			Localization.AddTranslation("Alas", (Language)0, "Wings");
			Localization.AddTranslation("Alas", (Language)2, "Alas");
			new Harmony("com.Jero.Alas").PatchAll();
			Log.LogInfo((object)"Alas 1.1.5 loaded — red lock blocks cast; remanente burns idle.");
		}

		private static Sprite MakeSprite(Texture2D tex)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)tex == (Object)null)
			{
				return null;
			}
			((Texture)tex).filterMode = (FilterMode)1;
			return Sprite.Create(tex, new Rect(0f, 0f, (float)((Texture)tex).width, (float)((Texture)tex).height), new Vector2(0.5f, 0.5f), 48f);
		}
	}
	internal static class PluginInfo
	{
		public const string GUID = "com.Jero.Alas";

		public const string Name = "Alas";

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

		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 static readonly Color FrozenCdTint = new Color(1f, 0.15f, 0.15f, 1f);

		private const string CdColorProperty = "_CDColor";

		private static readonly int CdColorId = Shader.PropertyToID("_CDColor");

		private SlimeController _slime;

		private InstantAbility _source;

		private int _abilityIndex = -1;

		private float _activeElapsed;

		private float _startCharge = 7f;

		private bool _chargeFrozen;

		private float _frozenCharge;

		private bool _cdColorSaved;

		private Color _savedCdColor;

		private bool _spriteColorSaved;

		private Color _savedSpriteColor;

		private SpriteRenderer _leftWing;

		private SpriteRenderer _rightWing;

		private float _flapAnimT;

		private float _lastFlapRealtime = -999f;

		private int _activateFrame = -1;

		private float _airMotion;

		private float _blockActivateUntilRealtime = -999f;

		private float _lastFreezeBurnRealtime = -1f;

		public bool Active { get; private set; }

		public int AbilityIndex => _abilityIndex;

		public bool ChargeFrozen => _chargeFrozen;

		public float CooldownTimerSnapshot
		{
			get
			{
				if (!Active)
				{
					if (!_chargeFrozen)
					{
						return ReadChargeFromTimer();
					}
					return _frozenCharge;
				}
				return CurrentCharge;
			}
		}

		private float CurrentCharge => Mathf.Max(0f, _startCharge - _activeElapsed);

		public float ActiveElapsed => _activeElapsed;

		private float ReadTimer()
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_slime == (Object)null || _abilityIndex < 0)
			{
				return 8f;
			}
			Fix[] value = Traverse.Create((object)_slime).Field("abilityCooldownTimers").GetValue<Fix[]>();
			if (value == null || _abilityIndex >= value.Length)
			{
				return 8f;
			}
			return (float)value[_abilityIndex];
		}

		private float ReadChargeFromTimer()
		{
			float num = ReadTimer();
			if (num > 7f)
			{
				return 7f;
			}
			return Mathf.Clamp(num, 0f, 7f);
		}

		private float ReadCharge()
		{
			if (_chargeFrozen)
			{
				return _frozenCharge;
			}
			return ReadChargeFromTimer();
		}

		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(expiredNaturally: false);
				_blockActivateUntilRealtime = Time.realtimeSinceStartup + 0.35f;
				return false;
			}
			if (_chargeFrozen)
			{
				Plugin.Log.LogInfo((object)"Alas: blocked — charge frozen (red lock)");
				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;
			_startCharge = Mathf.Max(0.15f, ReadCharge());
			ClearFrozenCharge();
			EnsureVisuals();
			SetVisualsVisible(visible: true);
			SetCooldownState(7f, _startCharge);
			Plugin.Log.LogInfo((object)$"Alas ON charge={_startCharge:0.00}s — player {_slime.GetPlayerId()}");
		}

		private void Deactivate(bool expiredNaturally)
		{
			if (!Active)
			{
				return;
			}
			float currentCharge = CurrentCharge;
			Active = false;
			SetVisualsVisible(visible: false);
			if (expiredNaturally)
			{
				ClearFrozenCharge();
				SetCooldownState(7f, 0f);
			}
			else
			{
				_frozenCharge = Mathf.Clamp(currentCharge, 0f, 7f);
				_chargeFrozen = _frozenCharge > 0.001f;
				SetCooldownState(7f, _frozenCharge);
				if (_chargeFrozen)
				{
					ApplyFrozenCdTint(force: true);
				}
				else
				{
					ClearFrozenCharge();
				}
			}
			ManualLogSource log = Plugin.Log;
			object[] array = new object[4];
			SlimeController slime = _slime;
			array[0] = ((slime != null) ? new int?(slime.GetPlayerId()) : ((int?)null));
			array[1] = currentCharge;
			array[2] = _chargeFrozen;
			array[3] = expiredNaturally;
			log.LogInfo((object)string.Format("Alas OFF player {0} chargeLeft={1:0.00}s frozen={2} natural={3}", array));
		}

		private void SetCooldownState(float cooldownMax, float charge)
		{
			//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)charge;
				}
			}
		}

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

		public void ReassertDeactivateCooldown(float chargeLeft, bool expiredNaturally)
		{
			if (expiredNaturally)
			{
				ClearFrozenCharge();
				SetCooldownState(7f, 0f);
				return;
			}
			_frozenCharge = Mathf.Clamp(chargeLeft, 0f, 7f);
			_chargeFrozen = _frozenCharge > 0.001f;
			SetCooldownState(7f, _frozenCharge);
			if (_chargeFrozen)
			{
				ApplyFrozenCdTint(force: true);
			}
			else
			{
				ClearFrozenCharge();
			}
		}

		public void SyncTankAfterGameUpdate()
		{
			if (!((Object)(object)_slime == (Object)null) && _abilityIndex >= 0 && !Active && _chargeFrozen)
			{
				float realtimeSinceStartup = Time.realtimeSinceStartup;
				float num = ((_lastFreezeBurnRealtime < 0f) ? Time.deltaTime : (realtimeSinceStartup - _lastFreezeBurnRealtime));
				_lastFreezeBurnRealtime = realtimeSinceStartup;
				if (num < 0f)
				{
					num = 0f;
				}
				if (num > 0.1f)
				{
					num = 0.1f;
				}
				_frozenCharge = Mathf.Max(0f, _frozenCharge - num);
				SetCooldownState(7f, _frozenCharge);
				ApplyFrozenCdTint(force: false);
				if (_frozenCharge <= 0.001f)
				{
					ClearFrozenCharge();
					SetCooldownState(7f, 0f);
				}
			}
		}

		private void ClearFrozenCharge()
		{
			_chargeFrozen = false;
			_frozenCharge = 0f;
			_lastFreezeBurnRealtime = -1f;
			RestoreCdTint();
		}

		private AbilityReadyIndicator GetIndicator()
		{
			if ((Object)(object)_slime == (Object)null || _abilityIndex < 0)
			{
				return null;
			}
			AbilityReadyIndicator[] value = Traverse.Create((object)_slime).Field("AbilityReadyIndicators").GetValue<AbilityReadyIndicator[]>();
			if (value == null || _abilityIndex >= value.Length)
			{
				return null;
			}
			return value[_abilityIndex];
		}

		private Material GetIndicatorMaterial()
		{
			AbilityReadyIndicator indicator = GetIndicator();
			if ((Object)(object)indicator == (Object)null)
			{
				return null;
			}
			SpriteRenderer spriteRen = indicator.GetSpriteRen();
			if ((Object)(object)spriteRen == (Object)null)
			{
				return null;
			}
			return ((Renderer)spriteRen).material;
		}

		private void ApplyFrozenCdTint(bool force)
		{
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			AbilityReadyIndicator indicator = GetIndicator();
			if ((Object)(object)indicator == (Object)null)
			{
				return;
			}
			SpriteRenderer spriteRen = indicator.GetSpriteRen();
			Material val = (((Object)(object)spriteRen != (Object)null) ? ((Renderer)spriteRen).material : null);
			if ((Object)(object)val != (Object)null)
			{
				if (!_cdColorSaved)
				{
					_savedCdColor = (Color)(val.HasProperty(CdColorId) ? val.GetColor(CdColorId) : new Color(0.66f, 0.66f, 0.66f, 0.55f));
					_cdColorSaved = true;
				}
				float num = _savedCdColor.a;
				if (num < 0.2f)
				{
					num = 0.55f;
				}
				val.SetColor(CdColorId, new Color(FrozenCdTint.r, FrozenCdTint.g, FrozenCdTint.b, num));
			}
			if ((Object)(object)spriteRen != (Object)null)
			{
				if (!_spriteColorSaved)
				{
					_savedSpriteColor = spriteRen.color;
					_spriteColorSaved = true;
				}
				Color color = spriteRen.color;
				spriteRen.color = new Color(1f, 0.45f, 0.45f, color.a);
			}
			if (force || _frozenCharge < 7f)
			{
				float cooldownProgress = Mathf.Clamp01(_frozenCharge / 7f);
				indicator.SetCooldownProgress(cooldownProgress);
			}
		}

		private void RestoreCdTint()
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			AbilityReadyIndicator indicator = GetIndicator();
			SpriteRenderer val = (((Object)(object)indicator != (Object)null) ? indicator.GetSpriteRen() : null);
			Material val2 = (((Object)(object)val != (Object)null) ? ((Renderer)val).material : null);
			if (_cdColorSaved && (Object)(object)val2 != (Object)null)
			{
				val2.SetColor(CdColorId, _savedCdColor);
			}
			_cdColorSaved = false;
			if (_spriteColorSaved && (Object)(object)val != (Object)null)
			{
				val.color = _savedSpriteColor;
			}
			_spriteColorSaved = false;
		}

		private void Update()
		{
			if (!Active && _chargeFrozen)
			{
				SyncTankAfterGameUpdate();
			}
			if (Active && !((Object)(object)_slime == (Object)null))
			{
				_activeElapsed += Time.deltaTime;
				if (_flapAnimT > 0f)
				{
					_flapAnimT = Mathf.Max(0f, _flapAnimT - Time.deltaTime / 0.28f);
				}
				float num = Mathf.Max(0f, CurrentCharge);
				SetCooldownState(7f, num);
				if (num <= 0.001f || _activeElapsed >= _startCharge)
				{
					Deactivate(expiredNaturally: true);
				}
			}
		}

		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 && _chargeFrozen)
			{
				ApplyFrozenCdTint(force: false);
			}
			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()
		{
			RestoreCdTint();
			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);
			}
		}
	}
}