Decompiled source of Lluvia v1.0.1

plugins\Lluvia.dll

Decompiled 3 hours 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(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Lluvia")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Bopl Battle raining arrows. Hold 15s like Time Stop, then arrows rain across the map.")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1")]
[assembly: AssemblyProduct("Lluvia")]
[assembly: AssemblyTitle("Lluvia")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.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 Lluvia
{
	public static class AbilityApiClonesFix
	{
		private const string Culprit = "AbilityApi";

		private static bool done;

		public static void Ensure()
		{
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Expected O, but got Unknown
			if (done)
			{
				return;
			}
			MethodInfo methodInfo = AccessTools.Method(typeof(PlayerCollision), "killPlayer", (Type[])null, (Type[])null);
			if (methodInfo == null)
			{
				done = true;
				return;
			}
			Patches patchInfo = Harmony.GetPatchInfo((MethodBase)methodInfo);
			if (patchInfo == null || patchInfo.Prefixes == null || patchInfo.Prefixes.Count == 0)
			{
				return;
			}
			List<MethodInfo> list = new List<MethodInfo>();
			foreach (Patch prefix in patchInfo.Prefixes)
			{
				MethodInfo patchMethod = prefix.PatchMethod;
				if (!(patchMethod == null) && !(patchMethod.DeclaringType == null) && patchMethod.DeclaringType.FullName.Contains("AbilityApi"))
				{
					list.Add(patchMethod);
				}
			}
			if (list.Count == 0)
			{
				done = true;
				return;
			}
			Harmony val = new Harmony("lluvia.abilityapi.clonefix");
			foreach (MethodInfo item in list)
			{
				val.Unpatch((MethodBase)methodInfo, item);
			}
			done = true;
		}
	}
	internal static class ArrowRain
	{
		private sealed class Storm
		{
			public int playerId;

			public Material material;

			public int ticksLeft;

			public int shots;
		}

		private static readonly List<Storm> live = new List<Storm>();

		public static void Begin(CastSpell caster)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: 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_0028: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)caster == (Object)null))
			{
				PlayerInfo val = GameAccess.InfoOf(caster);
				live.Add(new Storm
				{
					playerId = val.playerId,
					material = val.playerMaterial,
					ticksLeft = 300,
					shots = 0
				});
			}
		}

		public static void Tick()
		{
			for (int num = live.Count - 1; num >= 0; num--)
			{
				Storm storm = live[num];
				int num2 = 300 - storm.ticksLeft;
				for (int i = 0; i < 6; i++)
				{
					int num3 = 14 + i % 6;
					int num4 = i * 7 % num3;
					if ((num2 + num4) % num3 == 0)
					{
						Spawn(storm, i);
					}
				}
				storm.ticksLeft--;
				if (storm.ticksLeft <= 0)
				{
					live.RemoveAt(num);
				}
			}
		}

		public static void ForgetAll()
		{
			live.Clear();
		}

		private static void Spawn(Storm storm, int stream)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: 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_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_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: 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_0044: 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_004a: 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_004c: 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_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: 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_0069: 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_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: 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_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: 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)
			//IL_007e: 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_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: 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_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: 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_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: 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_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: 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_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			BoplBody val = LluviaAbility.ResolveArrowPrefab();
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			Fix val2 = SceneBounds.Camera_XMin;
			Fix val3 = SceneBounds.Camera_XMax;
			if (val3 <= val2)
			{
				val2 = SceneBounds.BlastZone_XMin;
				val3 = SceneBounds.BlastZone_XMax;
			}
			if (val3 <= val2)
			{
				return;
			}
			Fix val4 = (Fix)2L;
			val2 += val4;
			val3 -= val4;
			if (val3 <= val2)
			{
				return;
			}
			Fix val5 = SceneBounds.Camera_YMax - (Fix)2L;
			if (val5 >= SceneBounds.BlastZone_YMax)
			{
				val5 = SceneBounds.BlastZone_YMax - (Fix)2L;
			}
			val5 += Updater.RandomFix((Fix)(-2.4f), (Fix)0.4f);
			if (val5 >= SceneBounds.BlastZone_YMax)
			{
				val5 = SceneBounds.BlastZone_YMax - (Fix)1L;
			}
			Fix val6 = (val3 - val2) / (Fix)6L;
			Fix val7 = val2 + val6 * ((Fix)(long)stream + (Fix)0.5f) + Updater.RandomFix(-val6, val6);
			if (val7 < val2)
			{
				val7 = val2;
			}
			else if (val7 > val3)
			{
				val7 = val3;
			}
			Vec2 val8 = default(Vec2);
			((Vec2)(ref val8))..ctor(val7, val5);
			Vec2 val9 = Vec2.Normalized(new Vec2(Updater.RandomFix((Fix)(-0.22f), (Fix)0.22f), (Fix)(-1L)));
			Fix val10 = Vec2.NormalizedVectorAngle(val9);
			BoplBody val11 = FixTransform.InstantiateFixed<BoplBody>(val, val8, val10);
			if ((Object)(object)val11 == (Object)null)
			{
				return;
			}
			val11.Scale = Fix.One;
			val11.rotation = val10;
			val11.StartVelocity = val9 * LluviaAbility.ArrowSpeed;
			IPlayerIdHolder component = ((Component)val11).GetComponent<IPlayerIdHolder>();
			if (component != null)
			{
				component.SetPlayerId(storm.playerId);
			}
			if ((Object)(object)storm.material != (Object)null)
			{
				SpriteRenderer component2 = ((Component)val11).GetComponent<SpriteRenderer>();
				if ((Object)(object)component2 != (Object)null)
				{
					((Renderer)component2).material = storm.material;
				}
			}
			Projectile component3 = ((Component)val11).GetComponent<Projectile>();
			if ((Object)(object)component3 != (Object)null)
			{
				Fix val12 = Vec2.Magnitude(val11.StartVelocity);
				if (val12 > Fix.Zero)
				{
					component3.DelayedEnableHurtOwner(LluviaAbility.TimeBeforeArrowsHurtOwner / val12);
				}
			}
			storm.shots++;
			if (storm.shots % 8 == 1)
			{
				AudioManager.Get().Play("arrowShoot");
			}
		}
	}
	internal static class ChargeAura
	{
		private static readonly FieldInfo RedGlow = AccessTools.Field(typeof(DarknessAura), "redGlow");

		private static readonly FieldInfo BlackGlow = AccessTools.Field(typeof(DarknessAura), "blackGlow");

		private static readonly FieldInfo BlackStreams = AccessTools.Field(typeof(DarknessAura), "blackStreams");

		private static readonly FieldInfo BlackFade = AccessTools.Field(typeof(DarknessAura), "BlackFade");

		private static readonly FieldInfo OrangeFlare = AccessTools.Field(typeof(DarknessAura), "OrangeFlare");

		private static readonly FieldInfo CharacterField = AccessTools.Field(typeof(DarknessAura), "character");

		private static readonly FieldInfo TargetColorField = AccessTools.Field(typeof(DarknessAura), "TargetColor");

		public static void Apply(DarknessAura aura)
		{
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: 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_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)aura == (Object)null) && LluviaAbility.IsLluvia(((Component)aura).gameObject))
			{
				object? obj = BlackFade?.GetValue(aura);
				Hide((SpriteRenderer)((obj is SpriteRenderer) ? obj : null));
				object? obj2 = OrangeFlare?.GetValue(aura);
				Hide((SpriteRenderer)((obj2 is SpriteRenderer) ? obj2 : null));
				object? obj3 = RedGlow?.GetValue(aura);
				Hide((SpriteRenderer)((obj3 is SpriteRenderer) ? obj3 : null));
				float num = GameAccess.Charge01(((Component)aura).GetComponentInParent<CastSpell>());
				Color val = Color.Lerp(new Color(0.45f, 0.92f, 1f, 0.85f), new Color(0.05f, 0.08f, 0.16f, 0.9f), num);
				Color color = Color.Lerp(new Color(0.9f, 0.97f, 1f, 1f), new Color(0.35f, 0.42f, 0.52f, 1f), num);
				TargetColorField?.SetValue(aura, val);
				object? obj4 = BlackGlow?.GetValue(aura);
				Tint((SpriteRenderer)((obj4 is SpriteRenderer) ? obj4 : null), val);
				object? obj5 = BlackStreams?.GetValue(aura);
				Tint((SpriteRenderer)((obj5 is SpriteRenderer) ? obj5 : null), val);
				object? obj6 = CharacterField?.GetValue(aura);
				SpriteRenderer val2 = (SpriteRenderer)((obj6 is SpriteRenderer) ? obj6 : null);
				if ((Object)(object)val2 != (Object)null)
				{
					val2.color = color;
				}
			}
		}

		public static void ForgetAll()
		{
		}

		private static void Hide(SpriteRenderer renderer)
		{
			if (!((Object)(object)renderer == (Object)null))
			{
				((Renderer)renderer).enabled = false;
			}
		}

		private static void Tint(SpriteRenderer renderer, Color tint)
		{
			//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_001a: 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)
			//IL_0027: 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)
			if (!((Object)(object)renderer == (Object)null))
			{
				((Renderer)renderer).enabled = true;
				Color color = renderer.color;
				tint.a = ((color.a > 0.01f) ? color.a : tint.a);
				renderer.color = tint;
			}
		}
	}
	[HarmonyPatch(typeof(DarknessAura), "AnimateEffects")]
	public static class LluviaAuraPatch
	{
		public static void Postfix(DarknessAura __instance)
		{
			ChargeAura.Apply(__instance);
		}
	}
	internal static class GameAccess
	{
		private static readonly FieldInfo CastSpellAbility = AccessTools.Field(typeof(CastSpell), "ability");

		private static readonly FieldInfo CastSpellPlayerInfo = AccessTools.Field(typeof(CastSpell), "playerInfo");

		private static readonly FieldInfo CastSpellSpell = AccessTools.Field(typeof(CastSpell), "spell");

		private static readonly FieldInfo CastSpellCastTime = AccessTools.Field(typeof(CastSpell), "castTime");

		private static readonly FieldInfo CastSpellOnlyOnce = AccessTools.Field(typeof(CastSpell), "onlyCastableOnce");

		private static readonly FieldInfo CastSpellMuteMusic = AccessTools.Field(typeof(CastSpell), "affectMusicVolume");

		private static readonly FieldInfo CastSpellTime = AccessTools.Field(typeof(CastSpell), "timeSinceActivation");

		private static readonly FieldInfo BowArrow = AccessTools.Field(typeof(BowTransform), "Arrow");

		private static readonly FieldInfo BowArrowSpeed = AccessTools.Field(typeof(BowTransform), "ArrowSpeed");

		private static readonly FieldInfo BowHurtOwnerDelay = AccessTools.Field(typeof(BowTransform), "TimeBeforeArrowsHurtOwner");

		public static PlayerInfo InfoOf(CastSpell cast)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: 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_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			if ((Object)(object)cast == (Object)null)
			{
				return default(PlayerInfo);
			}
			if (CastSpellPlayerInfo != null)
			{
				object value = CastSpellPlayerInfo.GetValue(cast);
				if (value is PlayerInfo)
				{
					return (PlayerInfo)value;
				}
			}
			Ability val = AbilityOf(cast);
			if ((Object)(object)val != (Object)null)
			{
				return val.GetPlayerInfo();
			}
			return default(PlayerInfo);
		}

		public static Ability AbilityOf(CastSpell cast)
		{
			if ((Object)(object)cast == (Object)null)
			{
				return null;
			}
			if (CastSpellAbility != null)
			{
				object? value = CastSpellAbility.GetValue(cast);
				Ability val = (Ability)((value is Ability) ? value : null);
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
			return ((Component)cast).GetComponent<Ability>() ?? ((Component)cast).GetComponentInChildren<Ability>(true);
		}

		public static GameObject SpellOf(CastSpell cast)
		{
			if ((Object)(object)cast == (Object)null || CastSpellSpell == null)
			{
				return null;
			}
			object? value = CastSpellSpell.GetValue(cast);
			return (GameObject)((value is GameObject) ? value : null);
		}

		public static void ConfigureCast(CastSpell cast)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)cast == (Object)null))
			{
				CastSpellCastTime?.SetValue(cast, (Fix)15L);
				CastSpellSpell?.SetValue(cast, null);
				CastSpellOnlyOnce?.SetValue(cast, false);
				CastSpellMuteMusic?.SetValue(cast, false);
			}
		}

		public static float Charge01(CastSpell cast)
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: 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_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)cast == (Object)null || CastSpellTime == null || CastSpellCastTime == null)
			{
				return 0f;
			}
			object value = CastSpellTime.GetValue(cast);
			object value2 = CastSpellCastTime.GetValue(cast);
			if (!(value is Fix val) || !(value2 is Fix val2) || val2 <= Fix.Zero)
			{
				return 0f;
			}
			float num = (float)(val / val2);
			if (num < 0f)
			{
				return 0f;
			}
			if (num > 1f)
			{
				return 1f;
			}
			return num;
		}

		public static BoplBody ArrowOf(BowTransform bow)
		{
			if ((Object)(object)bow == (Object)null || BowArrow == null)
			{
				return null;
			}
			object? value = BowArrow.GetValue(bow);
			return (BoplBody)((value is BoplBody) ? value : null);
		}

		public static Fix ArrowSpeedOf(BowTransform bow, Fix fallback)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: 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_0033: 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_0042: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)bow == (Object)null || BowArrowSpeed == null)
			{
				return fallback;
			}
			if (!(BowArrowSpeed.GetValue(bow) is Fix val) || !(val > Fix.Zero))
			{
				return fallback;
			}
			return val;
		}

		public static Fix HurtOwnerDelayOf(BowTransform bow, Fix fallback)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: 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_0033: 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_0042: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)bow == (Object)null || BowHurtOwnerDelay == null)
			{
				return fallback;
			}
			if (!(BowHurtOwnerDelay.GetValue(bow) is Fix val) || !(val > Fix.Zero))
			{
				return fallback;
			}
			return val;
		}
	}
	public static class LluviaAbility
	{
		public const string AbilityName = "lluvia";

		public const string IconTextureName = "LluviaIcon";

		public const int ChargeSeconds = 15;

		public const int CooldownSeconds = 8;

		public const int TicksPerSecond = 60;

		public const int RainSeconds = 5;

		public const int RainTicks = 300;

		public const int RainStreams = 6;

		public const int ShootSoundEvery = 8;

		public const float IconFill = 0.88f;

		public static readonly Vector4 CircleExtents = new Vector4(0.04882813f, 0.04882813f, 0.08300781f, 0.9287109f);

		public static BoplBody ArrowPrefab;

		public static Fix ArrowSpeed = (Fix)45L;

		public static Fix TimeBeforeArrowsHurtOwner = (Fix)0.35f;

		public static bool IsLluvia(GameObject go)
		{
			Transform val = (((Object)(object)go == (Object)null) ? null : go.transform);
			while ((Object)(object)val != (Object)null)
			{
				if (((Object)val).name != null && ((Object)val).name.ToLower().Contains("lluvia"))
				{
					return true;
				}
				val = val.parent;
			}
			return false;
		}

		public static bool IsLluviaIcon(Sprite sprite)
		{
			if ((Object)(object)sprite != (Object)null && (Object)(object)sprite.texture != (Object)null)
			{
				return ((Object)sprite.texture).name == "LluviaIcon";
			}
			return false;
		}

		public static bool IsTimeStopTemplate(NamedSprite sprite)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)sprite.associatedGameObject == (Object)null)
			{
				return false;
			}
			string text = ((sprite.name == null) ? "" : sprite.name.ToLower());
			if (text.Contains("lluvia"))
			{
				return false;
			}
			if (text.Contains("time") && text.Contains("stop"))
			{
				return true;
			}
			GameObject val = GameAccess.SpellOf(sprite.associatedGameObject.GetComponentInChildren<CastSpell>(true));
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			if (!((Object)(object)val.GetComponent<TimeStop>() != (Object)null))
			{
				return (Object)(object)val.GetComponentInChildren<TimeStop>(true) != (Object)null;
			}
			return true;
		}

		public static void CaptureVanilla(NamedSpriteList icons)
		{
			//IL_0022: 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_0028: 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_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_0064: 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_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)
			if ((Object)(object)icons == (Object)null || icons.sprites == null)
			{
				return;
			}
			foreach (NamedSprite sprite in icons.sprites)
			{
				if (!((Object)(object)sprite.associatedGameObject == (Object)null))
				{
					BowTransform componentInChildren = sprite.associatedGameObject.GetComponentInChildren<BowTransform>(true);
					BoplBody val = GameAccess.ArrowOf(componentInChildren);
					if (!((Object)(object)val == (Object)null))
					{
						ArrowPrefab = val;
						ArrowSpeed = GameAccess.ArrowSpeedOf(componentInChildren, ArrowSpeed);
						TimeBeforeArrowsHurtOwner = GameAccess.HurtOwnerDelayOf(componentInChildren, TimeBeforeArrowsHurtOwner);
						break;
					}
				}
			}
		}

		public static BoplBody ResolveArrowPrefab()
		{
			//IL_0038: 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_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: 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)
			if ((Object)(object)ArrowPrefab != (Object)null)
			{
				return ArrowPrefab;
			}
			BowTransform[] array = Resources.FindObjectsOfTypeAll<BowTransform>();
			foreach (BowTransform bow in array)
			{
				BoplBody val = GameAccess.ArrowOf(bow);
				if (!((Object)(object)val == (Object)null))
				{
					ArrowPrefab = val;
					ArrowSpeed = GameAccess.ArrowSpeedOf(bow, ArrowSpeed);
					TimeBeforeArrowsHurtOwner = GameAccess.HurtOwnerDelayOf(bow, TimeBeforeArrowsHurtOwner);
					return ArrowPrefab;
				}
			}
			return null;
		}

		public static void Configure(GameObject go)
		{
			//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)
			if (!((Object)(object)go == (Object)null))
			{
				((Object)go).name = "lluvia";
				Ability val = go.GetComponent<Ability>() ?? go.GetComponentInChildren<Ability>(true);
				if ((Object)(object)val != (Object)null)
				{
					val.Cooldown = (Fix)8L;
				}
				GameAccess.ConfigureCast(go.GetComponent<CastSpell>() ?? go.GetComponentInChildren<CastSpell>(true));
			}
		}

		public static Sprite LoadIcon(Sprite template)
		{
			//IL_002c: 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_0041: 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)
			Texture2D val = LoadTexture("Lluvia.AbilityIcon.png");
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			int size = 128;
			float pixelsPerUnit = 100f;
			if ((Object)(object)template != (Object)null)
			{
				Rect rect = template.rect;
				if (((Rect)(ref rect)).width > 8f)
				{
					rect = template.rect;
					size = Mathf.RoundToInt(((Rect)(ref rect)).width);
				}
				pixelsPerUnit = template.pixelsPerUnit;
			}
			Texture2D obj = BlitCentered(val, size, 0.88f);
			((Object)obj).name = "LluviaIcon";
			((Texture)obj).filterMode = (FilterMode)1;
			((Texture)obj).wrapMode = (TextureWrapMode)1;
			obj.Apply(false, false);
			Sprite obj2 = Build(obj, pixelsPerUnit);
			((Object)obj2).name = "lluvia";
			return obj2;
		}

		private static Texture2D BlitCentered(Texture2D source, int size, float fill)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Expected O, but got Unknown
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(size, size, (TextureFormat)4, false);
			Color[] pixels = (Color[])(object)new Color[size * size];
			val.SetPixels(pixels);
			int num = Mathf.Max(1, Mathf.RoundToInt((float)size * fill));
			Color[] pixels2 = source.GetPixels();
			int width = ((Texture)source).width;
			int height = ((Texture)source).height;
			float num2 = (float)width / (float)height;
			int num3 = num;
			int num4 = num;
			if (num2 > 1f)
			{
				num4 = Mathf.Max(1, Mathf.RoundToInt((float)num / num2));
			}
			else
			{
				num3 = Mathf.Max(1, Mathf.RoundToInt((float)num * num2));
			}
			int num5 = (size - num3) / 2;
			int num6 = (size - num4) / 2;
			for (int i = 0; i < num4; i++)
			{
				int num7 = Mathf.Clamp(i * height / num4, 0, height - 1);
				for (int j = 0; j < num3; j++)
				{
					int num8 = Mathf.Clamp(j * width / num3, 0, width - 1);
					Color val2 = pixels2[num7 * width + num8];
					if (!(val2.a < 0.05f))
					{
						val.SetPixel(num5 + j, num6 + i, val2);
					}
				}
			}
			return val;
		}

		private static Sprite Build(Texture2D texture, float pixelsPerUnit)
		{
			//IL_0027: 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)
			((Texture)texture).filterMode = (FilterMode)1;
			((Texture)texture).wrapMode = (TextureWrapMode)1;
			return Sprite.Create(texture, new Rect(0f, 0f, (float)((Texture)texture).width, (float)((Texture)texture).height), new Vector2(0.5f, 0.5f), pixelsPerUnit, 0u, (SpriteMeshType)0);
		}

		private static Texture2D LoadTexture(string resourceName)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName);
			if (stream == null)
			{
				Plugin.Log.LogError((object)("Lluvia: embedded resource '" + resourceName + "' not found."));
				return null;
			}
			byte[] array;
			using (MemoryStream memoryStream = new MemoryStream())
			{
				stream.CopyTo(memoryStream);
				array = memoryStream.ToArray();
			}
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
			if (!ImageConversion.LoadImage(val, array))
			{
				Plugin.Log.LogError((object)("Lluvia: '" + resourceName + "' failed to decode as a PNG."));
				return null;
			}
			StripBackground(val);
			val.Apply(false, false);
			return val;
		}

		private static void StripBackground(Texture2D texture)
		{
			//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)
			int w = ((Texture)texture).width;
			int h = ((Texture)texture).height;
			Color[] pixels = texture.GetPixels();
			bool[] seen = new bool[pixels.Length];
			Queue<int> queue = new Queue<int>();
			for (int i = 0; i < w; i++)
			{
				Try(i, 0);
				Try(i, h - 1);
			}
			for (int j = 0; j < h; j++)
			{
				Try(0, j);
				Try(w - 1, j);
			}
			while (queue.Count > 0)
			{
				int num = queue.Dequeue();
				pixels[num] = Color.clear;
				int num2 = num % w;
				int num3 = num / w;
				Try(num2 + 1, num3);
				Try(num2 - 1, num3);
				Try(num2, num3 + 1);
				Try(num2, num3 - 1);
			}
			texture.SetPixels(pixels);
			void Try(int x, int y)
			{
				//IL_0037: Unknown result type (might be due to invalid IL or missing references)
				if (x >= 0 && y >= 0 && x < w && y < h)
				{
					int num4 = y * w + x;
					if (!seen[num4] && IsBackdrop(pixels[num4]))
					{
						seen[num4] = true;
						queue.Enqueue(num4);
					}
				}
			}
		}

		private static bool IsBackdrop(Color color)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: 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_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			if (color.a < 0.08f)
			{
				return true;
			}
			float num = Mathf.Max(color.r, Mathf.Max(color.g, color.b));
			float num2 = Mathf.Min(color.r, Mathf.Min(color.g, color.b));
			if (num - num2 < 0.08f)
			{
				return num2 > 0.62f;
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(AbilityGrid), "Awake")]
	public static class LluviaInjectionPatch
	{
		private static bool hasInjected;

		public static void Prefix(AbilityGrid __instance)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: 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_0058: 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_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: 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)
			if (hasInjected)
			{
				return;
			}
			NamedSpriteList abilityIcons = __instance.abilityIcons;
			if ((Object)(object)abilityIcons == (Object)null || abilityIcons.sprites == null)
			{
				Plugin.Log.LogWarning((object)"Lluvia: AbilityGrid.abilityIcons was empty this Awake; not injecting yet (will retry on the next grid build).");
				return;
			}
			LluviaAbility.CaptureVanilla(abilityIcons);
			NamedSprite val = default(NamedSprite);
			bool flag = false;
			foreach (NamedSprite sprite in abilityIcons.sprites)
			{
				if (LluviaAbility.IsTimeStopTemplate(sprite))
				{
					val = sprite;
					flag = true;
					break;
				}
			}
			if (!flag || (Object)(object)val.associatedGameObject == (Object)null)
			{
				Plugin.Log.LogError((object)"Lluvia: could not find Time Stop to clone, so the ability was not added.");
				return;
			}
			GameObject val2 = Object.Instantiate<GameObject>(val.associatedGameObject);
			Object.DontDestroyOnLoad((Object)(object)val2);
			LluviaAbility.Configure(val2);
			if ((Object)(object)(val2.GetComponent<CastSpell>() ?? val2.GetComponentInChildren<CastSpell>(true)) == (Object)null)
			{
				Plugin.Log.LogError((object)"Lluvia: the cloned Time Stop has no CastSpell component.");
				return;
			}
			Sprite val3 = LluviaAbility.LoadIcon(val.sprite) ?? val.sprite;
			abilityIcons.sprites.Add(new NamedSprite("lluvia", val3, val2, true));
			hasInjected = true;
			Plugin.Log.LogInfo((object)("Lluvia: ability injected (cloned '" + val.name + "', " + $"charge {15}s, cooldown {8}s)."));
		}
	}
	[HarmonyPatch(typeof(AbilityReadyIndicator), "SetSprite")]
	public static class LluviaCirclePatch
	{
		public static void Postfix(AbilityReadyIndicator __instance, Sprite sprite)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			if (LluviaAbility.IsLluviaIcon(sprite))
			{
				SpriteRenderer spriteRen = __instance.GetSpriteRen();
				if (!((Object)(object)spriteRen == (Object)null) && !((Object)(object)((Renderer)spriteRen).material == (Object)null))
				{
					((Renderer)spriteRen).material.SetVector("_CircleExtents", LluviaAbility.CircleExtents);
				}
			}
		}
	}
	[HarmonyPatch(typeof(CastSpell), "Cast")]
	public static class LluviaCastPatch
	{
		public static void Prefix(CastSpell __instance)
		{
			if (LluviaAbility.IsLluvia(((Component)__instance).gameObject))
			{
				ArrowRain.Begin(__instance);
			}
		}
	}
	[HarmonyPatch(typeof(Updater), "TickSimulation")]
	public static class LluviaTickPatch
	{
		public static void Postfix()
		{
			AbilityApiClonesFix.Ensure();
			ArrowRain.Tick();
		}
	}
	[HarmonyPatch(typeof(PlayerHandler), "ResetForNextStage")]
	public static class LluviaResetPatch
	{
		public static void Prefix()
		{
			ArrowRain.ForgetAll();
			ChargeAura.ForgetAll();
		}
	}
	[HarmonyPatch(typeof(Updater), "PreLevelLoad")]
	public static class LluviaLevelLoadPatch
	{
		public static void Prefix()
		{
			ArrowRain.ForgetAll();
			ChargeAura.ForgetAll();
		}
	}
	[BepInPlugin("com.solsticio.boplbattle.lluvia", "Lluvia", "1.0.1")]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.solsticio.boplbattle.lluvia";

		public const string PluginName = "Lluvia";

		public const string PluginVersion = "1.0.1";

		internal static ManualLogSource Log;

		private void Awake()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			Log.LogInfo((object)"Lluvia: loading...");
			new Harmony("com.solsticio.boplbattle.lluvia").PatchAll();
			Log.LogInfo((object)($"Lluvia: loaded (charge {15}s, " + $"cooldown {8}s after it ends)."));
		}
	}
	internal static class UniqueLluviaSlots
	{
		public static void Ensure(SlimeController slime)
		{
			if ((Object)(object)slime == (Object)null || slime.abilities == null)
			{
				return;
			}
			HashSet<int> hashSet = new HashSet<int>();
			for (int i = 0; i < slime.abilities.Count; i++)
			{
				AbilityMonoBehaviour val = slime.abilities[i];
				if ((Object)(object)val == (Object)null || !LluviaAbility.IsLluvia(((Component)val).gameObject))
				{
					continue;
				}
				int instanceID = ((Object)val).GetInstanceID();
				if (!hashSet.Add(instanceID))
				{
					Ability val2 = Clone(val);
					if ((Object)(object)val2 != (Object)null)
					{
						slime.abilities[i] = (AbilityMonoBehaviour)(object)val2;
					}
				}
			}
		}

		public static AbilityMonoBehaviour CloneIfLluvia(AbilityMonoBehaviour ability)
		{
			if ((Object)(object)ability == (Object)null || !LluviaAbility.IsLluvia(((Component)ability).gameObject))
			{
				return ability;
			}
			return (AbilityMonoBehaviour)(((object)Clone(ability)) ?? ((object)ability));
		}

		private static Ability Clone(AbilityMonoBehaviour ability)
		{
			GameObject val = Object.Instantiate<GameObject>(((Component)ability).gameObject);
			Object.DontDestroyOnLoad((Object)(object)val);
			LluviaAbility.Configure(val);
			return val.GetComponent<Ability>() ?? val.GetComponentInChildren<Ability>(true);
		}
	}
	[HarmonyPatch(typeof(SlimeController), "AddAbility")]
	public static class LluviaAddAbilityPatch
	{
		public static void Prefix(ref AbilityMonoBehaviour ability)
		{
			ability = UniqueLluviaSlots.CloneIfLluvia(ability);
		}
	}
	[HarmonyPatch(typeof(SlimeController), "AddAdditionalAbility")]
	public static class LluviaAddAdditionalAbilityPatch
	{
		public static void Prefix(ref AbilityMonoBehaviour ability)
		{
			ability = UniqueLluviaSlots.CloneIfLluvia(ability);
		}
	}
	[HarmonyPatch(typeof(SlimeController), "OldUpdate")]
	public static class LluviaUniqueSlotsPatch
	{
		public static void Postfix(SlimeController __instance)
		{
			UniqueLluviaSlots.Ensure(__instance);
		}
	}
}