Decompiled source of ArenMod v0.1.1

plugins\ArenMod.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnboundLib.Cards;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("ArenMod")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ArenMod")]
[assembly: AssemblyTitle("ArenMod")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ArenMod
{
	public class AirSupportBarrageProjectile : MonoBehaviour
	{
		private Player owner;

		private float damage;

		private bool dealDamage;

		private static Sprite cachedFlashSprite;

		public void Initialize(Player newOwner, float newDamage, bool shouldDealDamage)
		{
			owner = newOwner;
			damage = newDamage;
			dealDamage = shouldDealDamage;
		}

		private void OnTriggerEnter2D(Collider2D other)
		{
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: 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)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: 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_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)other == (Object)null)
			{
				return;
			}
			Player componentInParent = ((Component)other).GetComponentInParent<Player>();
			if ((Object)(object)componentInParent != (Object)null && (Object)(object)owner != (Object)null)
			{
				if (dealDamage && (Object)(object)componentInParent.data != (Object)null && (Object)(object)componentInParent.data.healthHandler != (Object)null)
				{
					Vector2 val = Vector2.op_Implicit(((Component)componentInParent).transform.position - ((Component)this).transform.position);
					Vector2 normalized = ((Vector2)(ref val)).normalized;
					((Damagable)componentInParent.data.healthHandler).CallTakeDamage(normalized * damage, Vector2.op_Implicit(((Component)this).transform.position), ((Component)owner).gameObject, owner, true);
					SpawnHitFlash(((Component)this).transform.position);
					ManualLogSource log = Plugin.Log;
					if (log != null)
					{
						log.LogInfo((object)$"Air Support: barrage hit player {componentInParent.playerID}");
					}
				}
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
			else if (!other.isTrigger)
			{
				SpawnHitFlash(((Component)this).transform.position);
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
		}

		private void SpawnHitFlash(Vector3 pos)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: 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_0016: 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_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Expected O, but got Unknown
			GameObject val = new GameObject("AirSupport_HitFlash");
			val.transform.position = pos;
			SpriteRenderer obj = val.AddComponent<SpriteRenderer>();
			obj.sprite = CreateFlashSprite();
			obj.color = new Color(1f, 0.85f, 0.35f, 0.9f);
			((Renderer)obj).sortingOrder = 130;
			val.transform.localScale = new Vector3(0.5f, 0.5f, 1f);
			val.AddComponent<AirSupportHitFlash>();
			Object.Destroy((Object)val, 0.2f);
		}

		private Sprite CreateFlashSprite()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: 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_007f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)cachedFlashSprite != (Object)null)
			{
				return cachedFlashSprite;
			}
			int num = 16;
			Texture2D val = new Texture2D(num, num, (TextureFormat)5, false);
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor((float)num / 2f, (float)num / 2f);
			for (int i = 0; i < num; i++)
			{
				for (int j = 0; j < num; j++)
				{
					float num2 = Vector2.Distance(new Vector2((float)j, (float)i), val2);
					float num3 = Mathf.Clamp01(1f - num2 / ((float)num * 0.5f));
					val.SetPixel(j, i, new Color(1f, 1f, 1f, num3));
				}
			}
			val.Apply();
			cachedFlashSprite = Sprite.Create(val, new Rect(0f, 0f, (float)num, (float)num), new Vector2(0.5f, 0.5f), (float)num);
			return cachedFlashSprite;
		}
	}
	public class AirSupportCard : CustomCard
	{
		public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block)
		{
			gun.reloadTimeAdd += 0.75f;
		}

		public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats)
		{
			AirSupportPlayerController airSupportPlayerController = ((Component)player).gameObject.GetComponent<AirSupportPlayerController>();
			if ((Object)(object)airSupportPlayerController == (Object)null)
			{
				airSupportPlayerController = ((Component)player).gameObject.AddComponent<AirSupportPlayerController>();
			}
			airSupportPlayerController.SetActive(value: true);
			AirSupportProjectileHook.EnsureAddedToGun(gun, player);
		}

		public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats)
		{
			AirSupportPlayerController component = ((Component)player).gameObject.GetComponent<AirSupportPlayerController>();
			if ((Object)(object)component != (Object)null)
			{
				component.SetActive(value: false);
			}
		}

		protected override string GetTitle()
		{
			return "Air Support";
		}

		protected override string GetDescription()
		{
			return "Your shots call in a delayed strafing run where they land.";
		}

		protected override CardInfoStat[] GetStats()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//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_0039: 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_0050: Expected O, but got Unknown
			return (CardInfoStat[])(object)new CardInfoStat[2]
			{
				new CardInfoStat
				{
					positive = true,
					stat = "Signal shot",
					amount = "Calls barrage"
				},
				new CardInfoStat
				{
					positive = false,
					stat = "Reload time",
					amount = "+0.75s"
				}
			};
		}

		protected override GameObject GetCardArt()
		{
			return null;
		}

		protected override Rarity GetRarity()
		{
			return (Rarity)2;
		}

		protected override CardThemeColorType GetTheme()
		{
			return (CardThemeColorType)0;
		}

		public override string GetModName()
		{
			return "Aren Mod";
		}
	}
	public class AirSupportHitFlash : MonoBehaviour
	{
		private SpriteRenderer sr;

		private float age;

		private void Start()
		{
			sr = ((Component)this).GetComponent<SpriteRenderer>();
		}

		private void Update()
		{
			//IL_003b: 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_0087: Unknown result type (might be due to invalid IL or missing references)
			age += Time.deltaTime;
			float num = Mathf.Lerp(0.5f, 1.1f, age / 0.2f);
			((Component)this).transform.localScale = new Vector3(num, num, 1f);
			if ((Object)(object)sr != (Object)null)
			{
				Color color = sr.color;
				color.a = Mathf.Lerp(0.9f, 0f, age / 0.2f);
				sr.color = color;
			}
		}
	}
	public class AirSupportPlayerController : MonoBehaviour
	{
		private static readonly Dictionary<string, float> RecentAirSupportEvents = new Dictionary<string, float>();

		private Player player;

		private bool active;

		private static Sprite cachedTracerSprite;

		private static Sprite cachedCircleSprite;

		private void Awake()
		{
			player = ((Component)this).GetComponent<Player>();
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				log.LogInfo((object)"Air Support: player controller awake.");
			}
		}

		public void SetActive(bool value)
		{
			active = value;
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				log.LogInfo((object)$"Air Support: controller active set to {active}");
			}
		}

		public bool IsActive()
		{
			return active;
		}

		public void CallAirSupport(Vector3 targetPoint)
		{
			//IL_0010: 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_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				log.LogInfo((object)$"Air Support: CallAirSupport received at {targetPoint}");
			}
			if (!active || (Object)(object)player == (Object)null || (Object)(object)player.data == (Object)null || player.data.dead)
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogWarning((object)"Air Support: CallAirSupport aborted due to inactive/dead/null state.");
				}
			}
			else
			{
				if ((Object)(object)player.data.view == (Object)null || !player.data.view.IsMine)
				{
					return;
				}
				int num = Random.Range(int.MinValue, int.MaxValue);
				HandleNetworkedAirSupport(player.playerID, targetPoint, num);
				if (!Plugin.RaiseNetworkEvent("ArenMod_AirSupportCallEvent", player.playerID, targetPoint.x, targetPoint.y, num))
				{
					ManualLogSource log3 = Plugin.Log;
					if (log3 != null)
					{
						log3.LogWarning((object)"Air Support: failed to raise networked air support event. Local barrage still succeeded.");
					}
				}
			}
		}

		public static void HandleNetworkedAirSupport(int ownerPlayerID, Vector3 targetPoint, int seed)
		{
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			string key = $"{ownerPlayerID}:{seed}";
			if (RecentAirSupportEvents.TryGetValue(key, out var value) && Time.time - value < 0.5f)
			{
				return;
			}
			RecentAirSupportEvents[key] = Time.time;
			CleanupRecentEvents();
			Player[] array = Object.FindObjectsOfType<Player>();
			Player val = null;
			for (int i = 0; i < array.Length; i++)
			{
				if ((Object)(object)array[i] != (Object)null && array[i].playerID == ownerPlayerID)
				{
					val = array[i];
					break;
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogWarning((object)$"Air Support: could not resolve owner for networked barrage. playerID={ownerPlayerID}");
				}
				return;
			}
			AirSupportPlayerController airSupportPlayerController = ((Component)val).GetComponent<AirSupportPlayerController>();
			if ((Object)(object)airSupportPlayerController == (Object)null)
			{
				airSupportPlayerController = ((Component)val).gameObject.AddComponent<AirSupportPlayerController>();
			}
			if (!airSupportPlayerController.IsActive())
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogWarning((object)$"Air Support: controller inactive for networked barrage. playerID={ownerPlayerID}");
				}
			}
			else
			{
				bool dealDamage = (Object)(object)val.data != (Object)null && (Object)(object)val.data.view != (Object)null && val.data.view.IsMine;
				((MonoBehaviour)airSupportPlayerController).StartCoroutine(airSupportPlayerController.AirSupportRoutine(targetPoint, seed, dealDamage));
			}
		}

		private static void CleanupRecentEvents()
		{
			List<string> list = null;
			foreach (KeyValuePair<string, float> recentAirSupportEvent in RecentAirSupportEvents)
			{
				if (Time.time - recentAirSupportEvent.Value > 2f)
				{
					if (list == null)
					{
						list = new List<string>();
					}
					list.Add(recentAirSupportEvent.Key);
				}
			}
			if (list != null)
			{
				for (int i = 0; i < list.Count; i++)
				{
					RecentAirSupportEvents.Remove(list[i]);
				}
			}
		}

		private IEnumerator AirSupportRoutine(Vector3 targetPoint, int seed, bool dealDamage)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				log.LogInfo((object)"Air Support: barrage routine started.");
			}
			SpawnTargetMarker(targetPoint);
			yield return (object)new WaitForSeconds(0.8f);
			Camera main = Camera.main;
			if ((Object)(object)main == (Object)null)
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogError((object)"Air Support: Camera.main was null.");
				}
				yield break;
			}
			Vector3 val = main.ViewportToWorldPoint(new Vector3(0f, 1f, 0f));
			Vector3 val2 = main.ViewportToWorldPoint(new Vector3(1f, 1f, 0f));
			float topY = Mathf.Max(val.y, val2.y) + 2.5f;
			float num = 5.5f;
			int bulletsToSpawn = 12;
			float timeBetweenBullets = 0.04f;
			Random random = new Random(seed);
			bool startFromLeft = random.NextDouble() > 0.5;
			float startX = (startFromLeft ? (targetPoint.x - num * 0.5f) : (targetPoint.x + num * 0.5f));
			float endX = (startFromLeft ? (targetPoint.x + num * 0.5f) : (targetPoint.x - num * 0.5f));
			ManualLogSource log3 = Plugin.Log;
			if (log3 != null)
			{
				log3.LogInfo((object)$"Air Support: barrage spawning. startFromLeft={startFromLeft}, startX={startX}, endX={endX}, topY={topY}");
			}
			Vector3 spawnPos = default(Vector3);
			for (int i = 0; i < bulletsToSpawn; i++)
			{
				if ((Object)(object)player == (Object)null || (Object)(object)player.data == (Object)null || player.data.dead)
				{
					ManualLogSource log4 = Plugin.Log;
					if (log4 != null)
					{
						log4.LogWarning((object)"Air Support: barrage cancelled because player died/null.");
					}
					break;
				}
				float num2 = ((bulletsToSpawn == 1) ? 0f : ((float)i / (float)(bulletsToSpawn - 1)));
				float num3 = Mathf.Lerp(startX, endX, num2);
				((Vector3)(ref spawnPos))..ctor(num3, topY, 0f);
				Vector2 val3;
				Vector2 normalized;
				if (!startFromLeft)
				{
					val3 = new Vector2(-0.25f, -1f);
					normalized = ((Vector2)(ref val3)).normalized;
				}
				else
				{
					val3 = new Vector2(0.25f, -1f);
					normalized = ((Vector2)(ref val3)).normalized;
				}
				Vector2 direction = normalized;
				SpawnAirSupportProjectile(spawnPos, direction, dealDamage);
				yield return (object)new WaitForSeconds(timeBetweenBullets);
			}
		}

		private void SpawnTargetMarker(Vector3 targetPoint)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: 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_0016: 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_004e: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Expected O, but got Unknown
			GameObject val = new GameObject("AirSupport_TargetMarker");
			val.transform.position = targetPoint;
			SpriteRenderer obj = val.AddComponent<SpriteRenderer>();
			obj.sprite = CreateCircleSprite();
			obj.color = new Color(1f, 0.3f, 0.15f, 0.65f);
			((Renderer)obj).sortingOrder = 100;
			val.transform.localScale = new Vector3(0.7f, 0.7f, 1f);
			val.AddComponent<AirSupportTargetMarker>();
			Object.Destroy((Object)val, 1.2f);
		}

		private void SpawnAirSupportProjectile(Vector3 spawnPos, Vector2 direction, bool dealDamage)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: 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_0016: 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_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: 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_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Expected O, but got Unknown
			GameObject val = new GameObject("AirSupport_Bullet");
			val.transform.position = spawnPos;
			float num = Mathf.Atan2(direction.y, direction.x) * 57.29578f;
			val.transform.rotation = Quaternion.Euler(0f, 0f, num);
			Rigidbody2D obj = val.AddComponent<Rigidbody2D>();
			obj.gravityScale = 0f;
			obj.collisionDetectionMode = (CollisionDetectionMode2D)1;
			obj.velocity = direction * 35f;
			CircleCollider2D obj2 = val.AddComponent<CircleCollider2D>();
			((Collider2D)obj2).isTrigger = true;
			obj2.radius = 0.16f;
			SpriteRenderer val2 = val.AddComponent<SpriteRenderer>();
			val2.sprite = CreateTracerSprite();
			val2.color = new Color(1f, 0.95f, 0.65f, 1f);
			((Renderer)val2).sortingOrder = 120;
			val.transform.localScale = new Vector3(0.9f, 0.2f, 1f);
			val.AddComponent<AirSupportTracerVisual>().SetRenderer(val2);
			val.AddComponent<AirSupportBarrageProjectile>().Initialize(player, 1.5f, dealDamage);
			Object.Destroy((Object)val, 4f);
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				log.LogInfo((object)"Air Support: spawned custom barrage projectile.");
			}
		}

		private Sprite CreateTracerSprite()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_0044: 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_00f8: 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_009d: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)cachedTracerSprite != (Object)null)
			{
				return cachedTracerSprite;
			}
			Texture2D val = new Texture2D(16, 4, (TextureFormat)5, false);
			Color val2 = default(Color);
			((Color)(ref val2))..ctor(0f, 0f, 0f, 0f);
			for (int i = 0; i < 4; i++)
			{
				for (int j = 0; j < 16; j++)
				{
					val.SetPixel(j, i, val2);
				}
			}
			for (int k = 1; k <= 2; k++)
			{
				for (int l = 0; l < 16; l++)
				{
					float num = (float)l / 15f;
					Color val3 = Color.Lerp(new Color(1f, 0.45f, 0.1f, 0.2f), new Color(1f, 1f, 0.9f, 1f), num);
					val.SetPixel(l, k, val3);
				}
			}
			val.Apply();
			cachedTracerSprite = Sprite.Create(val, new Rect(0f, 0f, 16f, 4f), new Vector2(0.5f, 0.5f), 16f);
			return cachedTracerSprite;
		}

		private Sprite CreateCircleSprite()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: 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_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)cachedCircleSprite != (Object)null)
			{
				return cachedCircleSprite;
			}
			int num = 32;
			Texture2D val = new Texture2D(num, num, (TextureFormat)5, false);
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor((float)num / 2f, (float)num / 2f);
			for (int i = 0; i < num; i++)
			{
				for (int j = 0; j < num; j++)
				{
					float num2 = Vector2.Distance(new Vector2((float)j, (float)i), val2);
					float num3 = (float)num * 0.38f;
					float num4 = (float)num * 0.08f;
					if (num2 <= num3 && num2 >= num3 - num4)
					{
						val.SetPixel(j, i, Color.white);
					}
					else
					{
						val.SetPixel(j, i, new Color(0f, 0f, 0f, 0f));
					}
				}
			}
			val.Apply();
			cachedCircleSprite = Sprite.Create(val, new Rect(0f, 0f, (float)num, (float)num), new Vector2(0.5f, 0.5f), (float)num);
			return cachedCircleSprite;
		}
	}
	public static class AirSupportProjectileHook
	{
		public static void EnsureAddedToGun(Gun gun, Player owner)
		{
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Expected O, but got Unknown
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Expected O, but got Unknown
			if ((Object)(object)gun == (Object)null)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogError((object)"Air Support: gun was null in EnsureAddedToGun.");
				}
				return;
			}
			if ((Object)(object)owner == (Object)null)
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogError((object)"Air Support: owner was null in EnsureAddedToGun.");
				}
				return;
			}
			if (gun.objectsToSpawn == null)
			{
				gun.objectsToSpawn = (ObjectsToSpawn[])(object)new ObjectsToSpawn[0];
				ManualLogSource log3 = Plugin.Log;
				if (log3 != null)
				{
					log3.LogInfo((object)"Air Support: initialized gun.objectsToSpawn.");
				}
			}
			if (gun.objectsToSpawn.Any((ObjectsToSpawn o) => o != null && (Object)(object)o.AddToProjectile != (Object)null && (Object)(object)o.AddToProjectile.GetComponent<AirSupportSignalProjectile>() != (Object)null))
			{
				ManualLogSource log4 = Plugin.Log;
				if (log4 != null)
				{
					log4.LogInfo((object)"Air Support: signal hook already on gun.");
				}
				return;
			}
			GameObject val = new GameObject("AirSupportSignalHook");
			((Object)val).hideFlags = (HideFlags)61;
			val.AddComponent<AirSupportSignalProjectile>().SetOwner(owner);
			ObjectsToSpawn item = new ObjectsToSpawn
			{
				AddToProjectile = val
			};
			List<ObjectsToSpawn> list = gun.objectsToSpawn.ToList();
			list.Add(item);
			gun.objectsToSpawn = list.ToArray();
			ManualLogSource log5 = Plugin.Log;
			if (log5 != null)
			{
				log5.LogInfo((object)$"Air Support: added signal hook to gun for player {owner.playerID}. objectsToSpawn count = {gun.objectsToSpawn.Length}");
			}
		}
	}
	public class AirSupportSignalProjectile : MonoBehaviour
	{
		private bool triggered;

		[SerializeField]
		private int ownerPlayerID = -1;

		private Player owner;

		public void SetOwner(Player newOwner)
		{
			owner = newOwner;
			if ((Object)(object)newOwner != (Object)null)
			{
				ownerPlayerID = newOwner.playerID;
			}
		}

		private void Start()
		{
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				log.LogInfo((object)"Air Support: signal projectile component started on projectile.");
			}
			ResolveOwner();
		}

		private void OnCollisionEnter2D(Collision2D collision)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				log.LogInfo((object)"Air Support: projectile collision detected.");
			}
			TryTrigger(((Component)this).transform.position);
		}

		private void OnTriggerEnter2D(Collider2D other)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				log.LogInfo((object)"Air Support: projectile trigger detected.");
			}
			TryTrigger(((Component)this).transform.position);
		}

		private void OnDisable()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			if (!triggered)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogInfo((object)"Air Support: projectile disabled before trigger, using fallback.");
				}
				TryTrigger(((Component)this).transform.position);
			}
		}

		private void TryTrigger(Vector3 point)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			if (triggered)
			{
				return;
			}
			triggered = true;
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				log.LogInfo((object)$"Air Support: TryTrigger at {point}");
			}
			ResolveOwner();
			if ((Object)(object)owner == (Object)null)
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogWarning((object)$"Air Support: TryTrigger failed because owner is null. ownerPlayerID={ownerPlayerID}");
				}
				return;
			}
			AirSupportPlayerController component = ((Component)owner).GetComponent<AirSupportPlayerController>();
			if ((Object)(object)component == (Object)null)
			{
				ManualLogSource log3 = Plugin.Log;
				if (log3 != null)
				{
					log3.LogWarning((object)"Air Support: owner had no AirSupportPlayerController.");
				}
			}
			else if (!component.IsActive())
			{
				ManualLogSource log4 = Plugin.Log;
				if (log4 != null)
				{
					log4.LogWarning((object)"Air Support: controller exists but is not active.");
				}
			}
			else if (!((Object)(object)owner.data == (Object)null) && !((Object)(object)owner.data.view == (Object)null) && owner.data.view.IsMine)
			{
				ManualLogSource log5 = Plugin.Log;
				if (log5 != null)
				{
					log5.LogInfo((object)$"Air Support: calling air support for playerID={owner.playerID}");
				}
				component.CallAirSupport(point);
			}
		}

		private void ResolveOwner()
		{
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)owner != (Object)null)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogInfo((object)$"Air Support: owner already assigned on projectile start. playerID={owner.playerID}");
				}
				return;
			}
			if (ownerPlayerID != -1)
			{
				Player[] array = Object.FindObjectsOfType<Player>();
				foreach (Player val in array)
				{
					if ((Object)(object)val != (Object)null && val.playerID == ownerPlayerID)
					{
						owner = val;
						ManualLogSource log2 = Plugin.Log;
						if (log2 != null)
						{
							log2.LogInfo((object)$"Air Support: owner resolved by playerID. playerID={owner.playerID}");
						}
						return;
					}
				}
			}
			AirSupportPlayerController[] array2 = Object.FindObjectsOfType<AirSupportPlayerController>();
			AirSupportPlayerController airSupportPlayerController = null;
			int num = 0;
			AirSupportPlayerController[] array3 = array2;
			foreach (AirSupportPlayerController airSupportPlayerController2 in array3)
			{
				if ((Object)(object)airSupportPlayerController2 != (Object)null && airSupportPlayerController2.IsActive())
				{
					airSupportPlayerController = airSupportPlayerController2;
					num++;
				}
			}
			if (num == 1 && (Object)(object)airSupportPlayerController != (Object)null)
			{
				owner = ((Component)airSupportPlayerController).GetComponent<Player>();
				if ((Object)(object)owner != (Object)null)
				{
					ownerPlayerID = owner.playerID;
					ManualLogSource log3 = Plugin.Log;
					if (log3 != null)
					{
						log3.LogInfo((object)$"Air Support: owner resolved by active controller fallback. playerID={owner.playerID}");
					}
					return;
				}
			}
			if (num > 1)
			{
				float num2 = float.MaxValue;
				Player val2 = null;
				array3 = array2;
				foreach (AirSupportPlayerController airSupportPlayerController3 in array3)
				{
					if ((Object)(object)airSupportPlayerController3 == (Object)null || !airSupportPlayerController3.IsActive())
					{
						continue;
					}
					Player component = ((Component)airSupportPlayerController3).GetComponent<Player>();
					if (!((Object)(object)component == (Object)null))
					{
						float num3 = Vector3.Distance(((Component)this).transform.position, ((Component)component).transform.position);
						if (num3 < num2)
						{
							num2 = num3;
							val2 = component;
						}
					}
				}
				if ((Object)(object)val2 != (Object)null)
				{
					owner = val2;
					ownerPlayerID = owner.playerID;
					ManualLogSource log4 = Plugin.Log;
					if (log4 != null)
					{
						log4.LogInfo((object)$"Air Support: owner resolved by nearest active player fallback. playerID={owner.playerID}");
					}
					return;
				}
			}
			ManualLogSource log5 = Plugin.Log;
			if (log5 != null)
			{
				log5.LogWarning((object)$"Air Support: owner unresolved. ownerPlayerID={ownerPlayerID}, activeControllers={num}");
			}
		}
	}
	public class AirSupportTargetMarker : MonoBehaviour
	{
		private SpriteRenderer sr;

		private float age;

		private void Start()
		{
			sr = ((Component)this).GetComponent<SpriteRenderer>();
		}

		private void Update()
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			age += Time.deltaTime;
			float num = 1f + Mathf.Sin(age * 18f) * 0.12f;
			((Component)this).transform.localScale = new Vector3(0.7f * num, 0.7f * num, 1f);
			if ((Object)(object)sr != (Object)null)
			{
				Color color = sr.color;
				color.a = Mathf.Lerp(0.75f, 0.15f, age / 1.2f);
				sr.color = color;
			}
		}
	}
	public class AirSupportTracerVisual : MonoBehaviour
	{
		private SpriteRenderer sr;

		private float age;

		private Vector3 baseScale;

		public void SetRenderer(SpriteRenderer rendererToUse)
		{
			sr = rendererToUse;
		}

		private void Start()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			baseScale = ((Component)this).transform.localScale;
		}

		private void Update()
		{
			//IL_0059: 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_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			age += Time.deltaTime;
			float num = 1f + Mathf.Sin(age * 40f) * 0.08f;
			((Component)this).transform.localScale = new Vector3(baseScale.x * num, baseScale.y, baseScale.z);
			if ((Object)(object)sr != (Object)null)
			{
				float a = Mathf.Clamp01(1f - age / 4f);
				Color color = sr.color;
				color.a = a;
				sr.color = color;
			}
		}
	}
	public class FountainBulletProjectile : MonoBehaviour
	{
		private Player owner;

		private float damage;

		public void Initialize(Player newOwner, float newDamage)
		{
			owner = newOwner;
			damage = newDamage;
		}

		private void OnTriggerEnter2D(Collider2D other)
		{
			//IL_0055: 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_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: 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_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: 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_0095: 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)
			if ((Object)(object)other == (Object)null)
			{
				return;
			}
			Player componentInParent = ((Component)other).GetComponentInParent<Player>();
			if ((Object)(object)componentInParent != (Object)null && (Object)(object)owner != (Object)null)
			{
				if ((Object)(object)componentInParent.data != (Object)null && (Object)(object)componentInParent.data.healthHandler != (Object)null)
				{
					Vector2 val = Vector2.op_Implicit(((Component)componentInParent).transform.position - ((Component)this).transform.position);
					Vector2 normalized = ((Vector2)(ref val)).normalized;
					((Damagable)componentInParent.data.healthHandler).CallTakeDamage(normalized * damage, Vector2.op_Implicit(((Component)this).transform.position), ((Component)owner).gameObject, owner, true);
				}
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
			else if (!other.isTrigger)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
		}
	}
	public class FountainBulletVisual : MonoBehaviour
	{
		private SpriteRenderer sr;

		private float age;

		private Vector3 baseScale;

		public void SetRenderer(SpriteRenderer rendererToUse)
		{
			sr = rendererToUse;
		}

		private void Start()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			baseScale = ((Component)this).transform.localScale;
		}

		private void Update()
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			age += Time.deltaTime;
			float num = 1f + Mathf.Sin(age * 30f) * 0.06f;
			((Component)this).transform.localScale = new Vector3(baseScale.x * num, baseScale.y, baseScale.z);
			if ((Object)(object)sr != (Object)null)
			{
				Color color = sr.color;
				color.a = Mathf.Clamp01(1f - age / 3f);
				sr.color = color;
			}
		}
	}
	public class FountainCard : CustomCard
	{
		public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block)
		{
			gun.damage *= 0.7f;
		}

		public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats)
		{
			FountainPlayerController fountainPlayerController = ((Component)player).gameObject.GetComponent<FountainPlayerController>();
			if ((Object)(object)fountainPlayerController == (Object)null)
			{
				fountainPlayerController = ((Component)player).gameObject.AddComponent<FountainPlayerController>();
			}
			fountainPlayerController.SetActive(value: true);
			FountainProjectileHook.EnsureAddedToGun(gun, player);
		}

		public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats)
		{
			FountainPlayerController component = ((Component)player).gameObject.GetComponent<FountainPlayerController>();
			if ((Object)(object)component != (Object)null)
			{
				component.SetActive(value: false);
			}
		}

		protected override string GetTitle()
		{
			return "Fountain";
		}

		protected override string GetDescription()
		{
			return "Each impact spawns a bullet fountain.";
		}

		protected override CardInfoStat[] GetStats()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//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_0039: 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_0050: Expected O, but got Unknown
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: 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_0075: Expected O, but got Unknown
			return (CardInfoStat[])(object)new CardInfoStat[3]
			{
				new CardInfoStat
				{
					positive = true,
					stat = "On impact",
					amount = "Spawn fountain"
				},
				new CardInfoStat
				{
					positive = true,
					stat = "Bounces",
					amount = "More fountains"
				},
				new CardInfoStat
				{
					positive = false,
					stat = "Damage",
					amount = "-30%"
				}
			};
		}

		protected override GameObject GetCardArt()
		{
			return null;
		}

		protected override Rarity GetRarity()
		{
			return (Rarity)1;
		}

		protected override CardThemeColorType GetTheme()
		{
			return (CardThemeColorType)3;
		}

		public override string GetModName()
		{
			return "Aren Mod";
		}
	}
	public class FountainMarkerVisual : MonoBehaviour
	{
		private SpriteRenderer sr;

		private float age;

		private void Start()
		{
			sr = ((Component)this).GetComponent<SpriteRenderer>();
		}

		private void Update()
		{
			//IL_003b: 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_0087: Unknown result type (might be due to invalid IL or missing references)
			age += Time.deltaTime;
			float num = Mathf.Lerp(0.45f, 0.8f, age / 0.6f);
			((Component)this).transform.localScale = new Vector3(num, num, 1f);
			if ((Object)(object)sr != (Object)null)
			{
				Color color = sr.color;
				color.a = Mathf.Lerp(0.55f, 0f, age / 0.6f);
				sr.color = color;
			}
		}
	}
	public class FountainPlayerController : MonoBehaviour
	{
		private static readonly Dictionary<string, float> RecentFountainEvents = new Dictionary<string, float>();

		private Player player;

		private bool active;

		private static Sprite cachedBulletSprite;

		private static Sprite cachedCircleSprite;

		private void Awake()
		{
			player = ((Component)this).GetComponent<Player>();
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				log.LogInfo((object)"Fountain: player controller awake.");
			}
		}

		public void SetActive(bool value)
		{
			active = value;
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				log.LogInfo((object)$"Fountain: controller active set to {active}");
			}
		}

		public bool IsActive()
		{
			return active;
		}

		public void SpawnFountain(Vector3 point)
		{
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			if (!active || (Object)(object)player == (Object)null || (Object)(object)player.data == (Object)null || player.data.dead)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogWarning((object)"Fountain: SpawnFountain aborted due to inactive/dead/null state.");
				}
			}
			else
			{
				if ((Object)(object)player.data.view == (Object)null || !player.data.view.IsMine)
				{
					return;
				}
				int num = Random.Range(int.MinValue, int.MaxValue);
				HandleNetworkedFountain(player.playerID, point, num);
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogInfo((object)$"Fountain: raising networked fountain event at {point} with seed {num}");
				}
				if (!Plugin.RaiseNetworkEvent("ArenMod_FountainSpawnEvent", player.playerID, point.x, point.y, num))
				{
					ManualLogSource log3 = Plugin.Log;
					if (log3 != null)
					{
						log3.LogError((object)"Fountain: failed to raise networked fountain event.");
					}
				}
			}
		}

		public static void HandleNetworkedFountain(int ownerPlayerID, Vector3 point, int seed)
		{
			//IL_0153: 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)
			string text = $"{ownerPlayerID}:{seed}";
			if (RecentFountainEvents.TryGetValue(text, out var value) && Time.time - value < 0.35f)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogInfo((object)("Fountain: duplicate networked fountain ignored for key=" + text));
				}
				return;
			}
			RecentFountainEvents[text] = Time.time;
			CleanupRecentEvents();
			Player[] array = Object.FindObjectsOfType<Player>();
			Player val = null;
			Player[] array2 = array;
			foreach (Player val2 in array2)
			{
				if ((Object)(object)val2 != (Object)null && val2.playerID == ownerPlayerID)
				{
					val = val2;
					break;
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogWarning((object)$"Fountain: could not resolve owner for networked fountain. playerID={ownerPlayerID}");
				}
				return;
			}
			FountainPlayerController fountainPlayerController = ((Component)val).GetComponent<FountainPlayerController>();
			if ((Object)(object)fountainPlayerController == (Object)null)
			{
				fountainPlayerController = ((Component)val).gameObject.AddComponent<FountainPlayerController>();
			}
			if (!fountainPlayerController.IsActive())
			{
				ManualLogSource log3 = Plugin.Log;
				if (log3 != null)
				{
					log3.LogWarning((object)$"Fountain: controller inactive for networked fountain. playerID={ownerPlayerID}");
				}
				return;
			}
			bool flag = (Object)(object)val.data != (Object)null && (Object)(object)val.data.view != (Object)null && val.data.view.IsMine;
			ManualLogSource log4 = Plugin.Log;
			if (log4 != null)
			{
				log4.LogInfo((object)$"Fountain: received networked fountain at {point}, owner={ownerPlayerID}, damageAuthority={flag}");
			}
			((MonoBehaviour)fountainPlayerController).StartCoroutine(fountainPlayerController.FountainRoutine(point, seed, flag));
		}

		private static void CleanupRecentEvents()
		{
			List<string> list = null;
			foreach (KeyValuePair<string, float> recentFountainEvent in RecentFountainEvents)
			{
				if (Time.time - recentFountainEvent.Value > 2f)
				{
					if (list == null)
					{
						list = new List<string>();
					}
					list.Add(recentFountainEvent.Key);
				}
			}
			if (list != null)
			{
				for (int i = 0; i < list.Count; i++)
				{
					RecentFountainEvents.Remove(list[i]);
				}
			}
		}

		private IEnumerator FountainRoutine(Vector3 point, int seed, bool dealDamage)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			SpawnMarker(point);
			int bulletCount = 10;
			float timeBetween = 0.06f;
			Gun val = (((Object)(object)player != (Object)null && (Object)(object)player.data != (Object)null && (Object)(object)player.data.weaponHandler != (Object)null) ? player.data.weaponHandler.gun : null);
			float bulletDamage = 0.8f;
			float bulletSpeed = 18f;
			if ((Object)(object)val != (Object)null)
			{
				bulletDamage = Mathf.Max(0.7f, val.damage * 0.85f);
				bulletSpeed = Mathf.Max(16f, val.projectileSpeed * 0.5f);
			}
			Random rng = new Random(seed);
			for (int i = 0; i < bulletCount; i++)
			{
				float num = Lerp(-0.38f, 0.38f, (float)rng.NextDouble());
				float num2 = Lerp(1.15f, 1.55f, (float)rng.NextDouble());
				Vector2 val2 = new Vector2(num, num2);
				Vector2 normalized = ((Vector2)(ref val2)).normalized;
				float speed = Lerp(bulletSpeed * 0.9f, bulletSpeed * 1.15f, (float)rng.NextDouble());
				SpawnFountainBullet(point, normalized, speed, bulletDamage, dealDamage);
				yield return (object)new WaitForSeconds(timeBetween);
			}
		}

		private void SpawnMarker(Vector3 point)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: 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_0016: 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_004e: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Expected O, but got Unknown
			GameObject val = new GameObject("FountainMarker");
			val.transform.position = point;
			SpriteRenderer obj = val.AddComponent<SpriteRenderer>();
			obj.sprite = CreateCircleSprite();
			obj.color = new Color(0.35f, 0.85f, 1f, 0.55f);
			((Renderer)obj).sortingOrder = 110;
			val.transform.localScale = new Vector3(0.55f, 0.55f, 1f);
			val.AddComponent<FountainMarkerVisual>();
			Object.Destroy((Object)val, 0.6f);
		}

		private void SpawnFountainBullet(Vector3 point, Vector2 dir, float speed, float damage, bool dealDamage)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_000b: 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_0020: 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_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("FountainBullet");
			Vector3 position = point + new Vector3(0f, 0.38f, 0f);
			val.transform.position = position;
			float num = Mathf.Atan2(dir.y, dir.x) * 57.29578f;
			val.transform.rotation = Quaternion.Euler(0f, 0f, num);
			Rigidbody2D obj = val.AddComponent<Rigidbody2D>();
			obj.gravityScale = 1.25f;
			obj.collisionDetectionMode = (CollisionDetectionMode2D)1;
			obj.drag = 0f;
			obj.angularDrag = 0f;
			obj.velocity = dir * speed;
			CircleCollider2D obj2 = val.AddComponent<CircleCollider2D>();
			((Collider2D)obj2).isTrigger = true;
			obj2.radius = 0.14f;
			SpriteRenderer val2 = val.AddComponent<SpriteRenderer>();
			val2.sprite = CreateBulletSprite();
			val2.color = new Color(0.55f, 0.95f, 1f, 1f);
			((Renderer)val2).sortingOrder = 120;
			val.transform.localScale = new Vector3(0.5f, 0.16f, 1f);
			val.AddComponent<FountainBulletVisual>().SetRenderer(val2);
			if (dealDamage)
			{
				val.AddComponent<FountainBulletProjectile>().Initialize(player, damage);
			}
			Object.Destroy((Object)(object)val, 4f);
		}

		private static float Lerp(float a, float b, float t)
		{
			return a + (b - a) * t;
		}

		private Sprite CreateBulletSprite()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_0044: 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_00f8: 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_009d: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)cachedBulletSprite != (Object)null)
			{
				return cachedBulletSprite;
			}
			Texture2D val = new Texture2D(16, 4, (TextureFormat)5, false);
			Color val2 = default(Color);
			((Color)(ref val2))..ctor(0f, 0f, 0f, 0f);
			for (int i = 0; i < 4; i++)
			{
				for (int j = 0; j < 16; j++)
				{
					val.SetPixel(j, i, val2);
				}
			}
			for (int k = 1; k <= 2; k++)
			{
				for (int l = 0; l < 16; l++)
				{
					float num = (float)l / 15f;
					Color val3 = Color.Lerp(new Color(0.2f, 0.7f, 1f, 0.15f), new Color(0.9f, 1f, 1f, 1f), num);
					val.SetPixel(l, k, val3);
				}
			}
			val.Apply();
			cachedBulletSprite = Sprite.Create(val, new Rect(0f, 0f, 16f, 4f), new Vector2(0.5f, 0.5f), 16f);
			return cachedBulletSprite;
		}

		private Sprite CreateCircleSprite()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: 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_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)cachedCircleSprite != (Object)null)
			{
				return cachedCircleSprite;
			}
			int num = 32;
			Texture2D val = new Texture2D(num, num, (TextureFormat)5, false);
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor((float)num / 2f, (float)num / 2f);
			for (int i = 0; i < num; i++)
			{
				for (int j = 0; j < num; j++)
				{
					float num2 = Vector2.Distance(new Vector2((float)j, (float)i), val2);
					float num3 = (float)num * 0.36f;
					float num4 = (float)num * 0.1f;
					if (num2 <= num3 && num2 >= num3 - num4)
					{
						val.SetPixel(j, i, Color.white);
					}
					else
					{
						val.SetPixel(j, i, new Color(0f, 0f, 0f, 0f));
					}
				}
			}
			val.Apply();
			cachedCircleSprite = Sprite.Create(val, new Rect(0f, 0f, (float)num, (float)num), new Vector2(0.5f, 0.5f), (float)num);
			return cachedCircleSprite;
		}
	}
	public static class FountainProjectileHook
	{
		public static void EnsureAddedToGun(Gun gun, Player owner)
		{
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Expected O, but got Unknown
			//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)
			//IL_00bd: Expected O, but got Unknown
			if ((Object)(object)gun == (Object)null)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogError((object)"Fountain: gun was null in EnsureAddedToGun.");
				}
				return;
			}
			if ((Object)(object)owner == (Object)null)
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogError((object)"Fountain: owner was null in EnsureAddedToGun.");
				}
				return;
			}
			if (gun.objectsToSpawn == null)
			{
				gun.objectsToSpawn = (ObjectsToSpawn[])(object)new ObjectsToSpawn[0];
			}
			if (gun.objectsToSpawn.Any((ObjectsToSpawn o) => o != null && (Object)(object)o.AddToProjectile != (Object)null && (Object)(object)o.AddToProjectile.GetComponent<FountainSignalProjectile>() != (Object)null))
			{
				ManualLogSource log3 = Plugin.Log;
				if (log3 != null)
				{
					log3.LogInfo((object)"Fountain: signal hook already on gun.");
				}
				return;
			}
			GameObject val = new GameObject("FountainSignalHook");
			((Object)val).hideFlags = (HideFlags)61;
			val.AddComponent<FountainSignalProjectile>().SetOwner(owner);
			ObjectsToSpawn item = new ObjectsToSpawn
			{
				AddToProjectile = val
			};
			List<ObjectsToSpawn> list = gun.objectsToSpawn.ToList();
			list.Add(item);
			gun.objectsToSpawn = list.ToArray();
			ManualLogSource log4 = Plugin.Log;
			if (log4 != null)
			{
				log4.LogInfo((object)$"Fountain: added signal hook to gun for player {owner.playerID}. objectsToSpawn count = {gun.objectsToSpawn.Length}");
			}
		}
	}
	public class FountainSignalProjectile : MonoBehaviour
	{
		[SerializeField]
		private int ownerPlayerID = -1;

		private Player owner;

		private float lastSpawnTime = -999f;

		private Vector3 lastSpawnPos = new Vector3(9999f, 9999f, 9999f);

		private Vector3 previousPosition;

		private Vector3 previousVelocityLike;

		private bool hasPreviousSample;

		public void SetOwner(Player newOwner)
		{
			owner = newOwner;
			if ((Object)(object)newOwner != (Object)null)
			{
				ownerPlayerID = newOwner.playerID;
			}
		}

		private void Start()
		{
			//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_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)
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				log.LogInfo((object)"Fountain: signal projectile started.");
			}
			ResolveOwner();
			previousPosition = ((Component)this).transform.position;
			previousVelocityLike = Vector3.zero;
			hasPreviousSample = false;
		}

		private void Update()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: 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_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: 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_0126: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ((Component)this).transform.position;
			Vector3 val = position - previousPosition;
			if (hasPreviousSample)
			{
				float magnitude = ((Vector3)(ref val)).magnitude;
				float magnitude2 = ((Vector3)(ref previousVelocityLike)).magnitude;
				if (magnitude > 0.01f && magnitude2 > 0.01f)
				{
					Vector2 val2 = new Vector2(previousVelocityLike.x, previousVelocityLike.y);
					Vector2 val3 = default(Vector2);
					((Vector2)(ref val3))..ctor(val.x, val.y);
					float num = Vector2.Angle(val2, val3);
					bool num2 = num > 28f;
					bool flag = Mathf.Sign(previousVelocityLike.y) != Mathf.Sign(val.y) && Mathf.Abs(previousVelocityLike.y) > 0.015f && Mathf.Abs(val.y) > 0.015f;
					bool flag2 = Mathf.Abs(magnitude2 - magnitude) > 0.08f && num > 16f;
					if (num2 || flag || flag2)
					{
						ManualLogSource log = Plugin.Log;
						if (log != null)
						{
							log.LogInfo((object)$"Fountain: bounce-like direction change detected at {position}, angle={num}");
						}
						TrySpawnFountain(position, "direction-change");
					}
				}
			}
			previousVelocityLike = val;
			previousPosition = position;
			hasPreviousSample = true;
		}

		private void OnCollisionEnter2D(Collision2D collision)
		{
			//IL_0016: 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)
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				log.LogInfo((object)$"Fountain: OnCollisionEnter2D at {((Component)this).transform.position}");
			}
			TrySpawnFountain(((Component)this).transform.position, "collision");
		}

		private void OnTriggerEnter2D(Collider2D other)
		{
			//IL_0016: 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)
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				log.LogInfo((object)$"Fountain: OnTriggerEnter2D at {((Component)this).transform.position}");
			}
			TrySpawnFountain(((Component)this).transform.position, "trigger");
		}

		private void OnDisable()
		{
			//IL_0016: 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)
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				log.LogInfo((object)$"Fountain: OnDisable at {((Component)this).transform.position}");
			}
			TrySpawnFountain(((Component)this).transform.position, "disable");
		}

		private void TrySpawnFountain(Vector3 point, string source)
		{
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: 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_010b: 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)
			ResolveOwner();
			if ((Object)(object)owner == (Object)null)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogWarning((object)$"Fountain: owner unresolved during {source}. ownerPlayerID={ownerPlayerID}");
				}
				return;
			}
			FountainPlayerController component = ((Component)owner).GetComponent<FountainPlayerController>();
			if ((Object)(object)component == (Object)null)
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogWarning((object)("Fountain: no controller during " + source + "."));
				}
				return;
			}
			if (!component.IsActive())
			{
				ManualLogSource log3 = Plugin.Log;
				if (log3 != null)
				{
					log3.LogWarning((object)("Fountain: controller inactive during " + source + "."));
				}
				return;
			}
			float num = Time.time - lastSpawnTime;
			float num2 = Vector3.Distance(point, lastSpawnPos);
			if (num < 0.04f && num2 < 0.28f)
			{
				ManualLogSource log4 = Plugin.Log;
				if (log4 != null)
				{
					log4.LogInfo((object)$"Fountain: duplicate suppressed from {source}. dt={num:F3}, dist={num2:F3}");
				}
				return;
			}
			lastSpawnTime = Time.time;
			lastSpawnPos = point;
			ManualLogSource log5 = Plugin.Log;
			if (log5 != null)
			{
				log5.LogInfo((object)$"Fountain: spawning fountain from {source} at {point} for playerID={owner.playerID}");
			}
			component.SpawnFountain(point);
		}

		private void ResolveOwner()
		{
			if ((Object)(object)owner != (Object)null)
			{
				return;
			}
			if (ownerPlayerID != -1)
			{
				Player[] array = Object.FindObjectsOfType<Player>();
				foreach (Player val in array)
				{
					if ((Object)(object)val != (Object)null && val.playerID == ownerPlayerID)
					{
						owner = val;
						ManualLogSource log = Plugin.Log;
						if (log != null)
						{
							log.LogInfo((object)$"Fountain: owner resolved by playerID={owner.playerID}");
						}
						return;
					}
				}
			}
			FountainPlayerController[] array2 = Object.FindObjectsOfType<FountainPlayerController>();
			FountainPlayerController fountainPlayerController = null;
			int num = 0;
			FountainPlayerController[] array3 = array2;
			foreach (FountainPlayerController fountainPlayerController2 in array3)
			{
				if ((Object)(object)fountainPlayerController2 != (Object)null && fountainPlayerController2.IsActive())
				{
					fountainPlayerController = fountainPlayerController2;
					num++;
				}
			}
			if (num == 1 && (Object)(object)fountainPlayerController != (Object)null)
			{
				owner = ((Component)fountainPlayerController).GetComponent<Player>();
				if ((Object)(object)owner != (Object)null)
				{
					ownerPlayerID = owner.playerID;
					ManualLogSource log2 = Plugin.Log;
					if (log2 != null)
					{
						log2.LogInfo((object)$"Fountain: owner resolved by active controller fallback. playerID={owner.playerID}");
					}
					return;
				}
			}
			ManualLogSource log3 = Plugin.Log;
			if (log3 != null)
			{
				log3.LogWarning((object)$"Fountain: ResolveOwner failed. ownerPlayerID={ownerPlayerID}, activeControllers={num}");
			}
		}
	}
	public class GlideCard : CustomCard
	{
		public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block)
		{
			statModifiers.movementSpeed *= 0.95f;
		}

		public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats)
		{
			if ((Object)(object)((Component)player).gameObject.GetComponent<UtilityInputController>() == (Object)null)
			{
				((Component)player).gameObject.AddComponent<UtilityInputController>();
			}
			GlideUtility glideUtility = ((Component)player).gameObject.GetComponent<GlideUtility>();
			if ((Object)(object)glideUtility == (Object)null)
			{
				glideUtility = ((Component)player).gameObject.AddComponent<GlideUtility>();
			}
			glideUtility.SetUtilityActive(value: true);
		}

		public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats)
		{
			GlideUtility component = ((Component)player).gameObject.GetComponent<GlideUtility>();
			if ((Object)(object)component != (Object)null)
			{
				component.SetUtilityActive(value: false);
			}
		}

		protected override string GetTitle()
		{
			return "Glide";
		}

		protected override string GetDescription()
		{
			return "Hold Alt in the air to slow your fall.";
		}

		protected override CardInfoStat[] GetStats()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//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_0039: 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_0050: Expected O, but got Unknown
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: 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_0075: Expected O, but got Unknown
			return (CardInfoStat[])(object)new CardInfoStat[3]
			{
				new CardInfoStat
				{
					positive = true,
					stat = "Utility",
					amount = "Alt to glide"
				},
				new CardInfoStat
				{
					positive = true,
					stat = "Glide meter",
					amount = "Shown above health"
				},
				new CardInfoStat
				{
					positive = false,
					stat = "Move speed",
					amount = "-5%"
				}
			};
		}

		protected override GameObject GetCardArt()
		{
			return null;
		}

		protected override Rarity GetRarity()
		{
			return (Rarity)1;
		}

		protected override CardThemeColorType GetTheme()
		{
			return (CardThemeColorType)3;
		}

		public override string GetModName()
		{
			return "Aren Mod";
		}
	}
	public class GlideMeterVisual : MonoBehaviour
	{
		private static readonly Vector3 MeterLocalPosition = new Vector3(0f, 1.22f, 0f);

		private static Sprite barSprite;

		private GameObject root;

		private Transform fillTransform;

		private Transform backgroundTransform;

		private SpriteRenderer backgroundRenderer;

		private SpriteRenderer fillRenderer;

		private void Awake()
		{
			EnsureVisuals();
			SetMeter(1f, visible: false);
		}

		private void LateUpdate()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)root != (Object)null)
			{
				root.transform.localPosition = MeterLocalPosition;
				root.transform.localRotation = Quaternion.identity;
			}
		}

		public void SetMeter(float normalized, bool visible)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			EnsureVisuals();
			normalized = Mathf.Clamp01(normalized);
			if ((Object)(object)root != (Object)null && root.activeSelf != visible)
			{
				root.SetActive(visible);
			}
			if ((Object)(object)fillTransform != (Object)null)
			{
				fillTransform.localScale = new Vector3(normalized, 1f, 1f);
				fillTransform.localPosition = Vector3.zero;
			}
			if ((Object)(object)fillRenderer != (Object)null)
			{
				fillRenderer.color = Color.Lerp(new Color(1f, 0.25f, 0.12f, 0.95f), new Color(0.25f, 0.9f, 1f, 0.95f), normalized);
			}
		}

		private void EnsureVisuals()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Expected O, but got Unknown
			//IL_0097: 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_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Expected O, but got Unknown
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)root != (Object)null))
			{
				root = new GameObject("GlideMeter");
				root.transform.SetParent(((Component)this).transform, false);
				root.transform.localPosition = MeterLocalPosition;
				root.transform.localScale = new Vector3(0.85f, 0.08f, 1f);
				GameObject val = new GameObject("Background");
				val.transform.SetParent(root.transform, false);
				val.transform.localPosition = Vector3.zero;
				val.transform.localScale = Vector3.one;
				backgroundTransform = val.transform;
				backgroundRenderer = val.AddComponent<SpriteRenderer>();
				backgroundRenderer.sprite = GetBarSprite();
				backgroundRenderer.color = new Color(0.02f, 0.08f, 0.1f, 0.75f);
				((Renderer)backgroundRenderer).sortingOrder = 151;
				GameObject val2 = new GameObject("Fill");
				val2.transform.SetParent(root.transform, false);
				val2.transform.localPosition = Vector3.zero;
				val2.transform.localScale = Vector3.one;
				fillTransform = val2.transform;
				fillRenderer = val2.AddComponent<SpriteRenderer>();
				fillRenderer.sprite = GetBarSprite();
				fillRenderer.color = new Color(0.25f, 0.9f, 1f, 0.95f);
				((Renderer)fillRenderer).sortingOrder = 152;
			}
		}

		private static Sprite GetBarSprite()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: 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_0061: Expected O, but got Unknown
			if ((Object)(object)barSprite != (Object)null)
			{
				return barSprite;
			}
			Texture2D val = new Texture2D(1, 1, (TextureFormat)5, false);
			val.SetPixel(0, 0, Color.white);
			val.Apply();
			barSprite = Sprite.Create(val, new Rect(0f, 0f, 1f, 1f), new Vector2(0.5f, 0.5f), 1f);
			return barSprite;
		}
	}
	public class GlideUtility : UtilityAbility
	{
		private static readonly FieldInfo PlayerVelocityField = typeof(PlayerVelocity).GetField("velocity", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly FieldInfo GravityForceField = typeof(Gravity).GetField("gravityForce", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private const float MaxGlideCharge = 2.75f;

		private const float GlideDrainPerSecond = 1f;

		private const float GlideRechargePerSecond = 1.35f;

		private const float GroundedRechargeDelay = 0.25f;

		private const float MaxFallSpeedWhileGliding = -3.15f;

		private const float MaxFallSpeedAfterGlide = -5.25f;

		private const float GlideReleaseClampTime = 0.55f;

		private const float GlideGravityMultiplier = 0.08f;

		private float glideCharge = 2.75f;

		private float lastAirborneTime;

		private GlideMeterVisual meterVisual;

		private Rigidbody2D cachedBody;

		private Gravity cachedGravity;

		private float originalGravityForce;

		private bool hasOriginalGravityForce;

		private bool wasGliding;

		private float releaseClampUntil;

		public override int Priority => 20;

		protected override void Awake()
		{
			base.Awake();
			meterVisual = ((Component)this).GetComponent<GlideMeterVisual>();
			if ((Object)(object)meterVisual == (Object)null)
			{
				meterVisual = ((Component)this).gameObject.AddComponent<GlideMeterVisual>();
			}
		}

		private void Update()
		{
			if (!IsUtilityActive() || (Object)(object)player == (Object)null || (Object)(object)player.data == (Object)null)
			{
				StopGlideGravity();
				SetMeterVisible(visible: false);
				return;
			}
			UpdateCharge();
			UpdateMeter();
			if (!ShouldGlide())
			{
				StopGlideGravity();
				ApplyReleaseClamp();
			}
			else
			{
				StartGlideGravity();
				ApplyGlide();
				glideCharge = Mathf.Max(0f, glideCharge - 1f * Time.deltaTime);
			}
		}

		private void FixedUpdate()
		{
			if (!ShouldGlide())
			{
				ApplyReleaseClamp();
				return;
			}
			StartGlideGravity();
			ApplyGlide();
		}

		private void LateUpdate()
		{
			if (!ShouldGlide())
			{
				ApplyReleaseClamp();
			}
			else
			{
				ApplyGlide();
			}
		}

		private void OnDisable()
		{
			StopGlideGravity();
		}

		private void OnDestroy()
		{
			StopGlideGravity();
		}

		protected override void UseAbility()
		{
		}

		private void UpdateCharge()
		{
			if (player.data.isGrounded)
			{
				if (Time.time >= lastAirborneTime + 0.25f)
				{
					glideCharge = Mathf.Min(2.75f, glideCharge + 1.35f * Time.deltaTime);
				}
			}
			else
			{
				lastAirborneTime = Time.time;
			}
		}

		private void ApplyGlide()
		{
			ClampFallSpeed(-3.15f);
		}

		private void StartGlideGravity()
		{
			Gravity val = GetCachedGravity();
			if ((Object)(object)val != (Object)null && GravityForceField != null)
			{
				if (!hasOriginalGravityForce)
				{
					originalGravityForce = (float)GravityForceField.GetValue(val);
					hasOriginalGravityForce = true;
				}
				GravityForceField.SetValue(val, originalGravityForce * 0.08f);
			}
			wasGliding = true;
		}

		private void StopGlideGravity()
		{
			Gravity val = GetCachedGravity();
			if ((Object)(object)val != (Object)null && GravityForceField != null && hasOriginalGravityForce)
			{
				GravityForceField.SetValue(val, originalGravityForce);
			}
			if (wasGliding)
			{
				ApplyGlide();
				releaseClampUntil = Time.time + 0.55f;
				wasGliding = false;
			}
		}

		private void ApplyReleaseClamp()
		{
			if (!(Time.time > releaseClampUntil))
			{
				ClampFallSpeed(-5.25f);
			}
		}

		private bool ShouldGlide()
		{
			if (CanUse() && IsAltHeld() && glideCharge > 0f && (Object)(object)player.data != (Object)null)
			{
				return !player.data.isGrounded;
			}
			return false;
		}

		private void ClampFallSpeed(float maxFallSpeed)
		{
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: 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_006d: 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_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_009f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player != (Object)null && (Object)(object)player.data != (Object)null && (Object)(object)player.data.playerVel != (Object)null)
			{
				Vector2 val = (Vector2)((PlayerVelocityField != null) ? ((Vector2)PlayerVelocityField.GetValue(player.data.playerVel)) : Vector2.zero);
				if (val.y < maxFallSpeed)
				{
					val.y = maxFallSpeed;
					PlayerVelocityField?.SetValue(player.data.playerVel, val);
				}
			}
			Rigidbody2D val2 = GetCachedBody();
			if ((Object)(object)val2 != (Object)null && val2.velocity.y < maxFallSpeed)
			{
				val2.velocity = new Vector2(val2.velocity.x, maxFallSpeed);
			}
		}

		private Rigidbody2D GetCachedBody()
		{
			if ((Object)(object)cachedBody == (Object)null)
			{
				if ((Object)(object)player != (Object)null && (Object)(object)player.data != (Object)null && (Object)(object)player.data.playerVel != (Object)null)
				{
					cachedBody = ((Component)player.data.playerVel).GetComponent<Rigidbody2D>();
				}
				if ((Object)(object)cachedBody == (Object)null)
				{
					cachedBody = ((Component)this).GetComponent<Rigidbody2D>();
				}
				if ((Object)(object)cachedBody == (Object)null)
				{
					cachedBody = ((Component)this).GetComponentInChildren<Rigidbody2D>();
				}
			}
			return cachedBody;
		}

		private Gravity GetCachedGravity()
		{
			if ((Object)(object)cachedGravity == (Object)null)
			{
				cachedGravity = ((Component)this).GetComponent<Gravity>();
				if ((Object)(object)cachedGravity == (Object)null)
				{
					cachedGravity = ((Component)this).GetComponentInChildren<Gravity>();
				}
			}
			return cachedGravity;
		}

		private void UpdateMeter()
		{
			if (!((Object)(object)meterVisual == (Object)null))
			{
				float num = glideCharge / 2.75f;
				bool visible = IsUtilityActive() && num < 0.999f;
				meterVisual.SetMeter(num, visible);
			}
		}

		private void SetMeterVisible(bool visible)
		{
			if ((Object)(object)meterVisual != (Object)null)
			{
				meterVisual.SetMeter(glideCharge / 2.75f, visible);
			}
		}

		private static bool IsAltHeld()
		{
			if (!Input.GetKey((KeyCode)308))
			{
				return Input.GetKey((KeyCode)307);
			}
			return true;
		}
	}
	public class GrenadeCard : CustomCard
	{
		public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block)
		{
			gun.attackSpeed *= 0.95f;
		}

		public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats)
		{
			if ((Object)(object)((Component)player).gameObject.GetComponent<UtilityInputController>() == (Object)null)
			{
				((Component)player).gameObject.AddComponent<UtilityInputController>();
			}
			GrenadeUtility grenadeUtility = ((Component)player).gameObject.GetComponent<GrenadeUtility>();
			if ((Object)(object)grenadeUtility == (Object)null)
			{
				grenadeUtility = ((Component)player).gameObject.AddComponent<GrenadeUtility>();
			}
			grenadeUtility.SetUtilityActive(value: true);
		}

		public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats)
		{
			GrenadeUtility component = ((Component)player).gameObject.GetComponent<GrenadeUtility>();
			if ((Object)(object)component != (Object)null)
			{
				component.SetUtilityActive(value: false);
			}
		}

		protected override string GetTitle()
		{
			return "Grenade";
		}

		protected override string GetDescription()
		{
			return "Alt throws a grenade utility.";
		}

		protected override CardInfoStat[] GetStats()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//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_0039: 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_0050: Expected O, but got Unknown
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: 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_0075: Expected O, but got Unknown
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Expected O, but got Unknown
			return (CardInfoStat[])(object)new CardInfoStat[4]
			{
				new CardInfoStat
				{
					positive = true,
					stat = "Utility",
					amount = "Alt throws grenade"
				},
				new CardInfoStat
				{
					positive = true,
					stat = "Explosion",
					amount = "Area damage"
				},
				new CardInfoStat
				{
					positive = false,
					stat = "Utility cooldown",
					amount = "8s"
				},
				new CardInfoStat
				{
					positive = false,
					stat = "Attack speed",
					amount = "-5%"
				}
			};
		}

		protected override GameObject GetCardArt()
		{
			return null;
		}

		protected override Rarity GetRarity()
		{
			return (Rarity)2;
		}

		protected override CardThemeColorType GetTheme()
		{
			return (CardThemeColorType)0;
		}

		public override string GetModName()
		{
			return "Aren Mod";
		}
	}
	public class GrenadeProjectile : MonoBehaviour
	{
		private static readonly FieldInfo ExplosionSpawnedField = typeof(Explosion).GetField("spawned", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly FieldInfo ExplosionSoundDamageField = typeof(Explosion).GetField("soundDamage", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private const float FuseTime = 1.65f;

		private const float ExplosionRadius = 3.15f;

		private const float ExplosionDamage = 35f;

		private const float ExplosionForce = 115f;

		private const float ExplosionImmunity = 0.15f;

		private static Sprite cachedGrenadeSprite;

		private static GameObject cachedExplosionEffectTemplate;

		private static ObjectsToSpawn cachedExplosionObjectsToSpawn;

		private static object cachedExplosionSoundDamage;

		private Player owner;

		private bool dealDamage;

		private float spawnTime;

		private bool exploded;

		private SpriteRenderer bodyRenderer;

		private SpriteRenderer indicatorRenderer;

		private SpawnedAttack spawnedAttack;

		private Explosion builtInExplosion;

		public void Initialize(Player grenadeOwner, bool shouldDealDamage)
		{
			owner = grenadeOwner;
			dealDamage = shouldDealDamage;
			spawnTime = Time.time;
			bodyRenderer = ((Component)this).GetComponent<SpriteRenderer>();
			Transform obj = ((Component)this).transform.Find("Indicator");
			indicatorRenderer = ((obj != null) ? ((Component)obj).GetComponent<SpriteRenderer>() : null);
			ConfigureBuiltInExplosion();
		}

		private void Update()
		{
			UpdateIndicatorFlash();
			if (!exploded && Time.time >= spawnTime + 1.65f)
			{
				Explode();
			}
		}

		private void OnCollisionEnter2D(Collision2D collision)
		{
			//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_0043: 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)
			if (exploded || Time.time < spawnTime + 0.12f)
			{
				return;
			}
			Rigidbody2D component = ((Component)this).GetComponent<Rigidbody2D>();
			if ((Object)(object)component != (Object)null)
			{
				Vector2 velocity = component.velocity;
				if (((Vector2)(ref velocity)).magnitude < 1.2f)
				{
					component.velocity *= 0.65f;
				}
			}
		}

		private void Explode()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			if (!exploded)
			{
				exploded = true;
				TriggerBuiltInExplosion(((Component)this).transform.position);
				Object.Destroy((Object)(object)((Component)this).gameObject, 0.1f);
			}
		}

		private void UpdateIndicatorFlash()
		{
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: 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_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)indicatorRenderer == (Object)null))
			{
				float num = Time.time - spawnTime;
				float num2 = Mathf.Max(0.01f, 1.65f - num);
				float num3 = Mathf.Lerp(5f, 14f, 1f - Mathf.Clamp01(num2 / 1.65f));
				float num4 = 0.5f + 0.5f * Mathf.Sin(Time.time * num3 * MathF.PI * 2f);
				indicatorRenderer.color = Color.Lerp(new Color(0.4f, 0.05f, 0.05f, 0.65f), new Color(1f, 0.1f, 0.1f, 1f), num4);
				if ((Object)(object)bodyRenderer != (Object)null)
				{
					bodyRenderer.color = Color.Lerp(new Color(0.24f, 0.72f, 0.32f, 1f), new Color(0.32f, 0.9f, 0.42f, 1f), num4 * 0.18f);
				}
			}
		}

		private void TriggerBuiltInExplosion(Vector3 position)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			((Component)this).transform.position = position;
			if ((Object)(object)builtInExplosion == (Object)null)
			{
				ConfigureBuiltInExplosion();
			}
			SpawnBuiltInExplosionVisual(position);
			Explosion obj = builtInExplosion;
			if (obj != null)
			{
				obj.Explode();
			}
			ApplyFallbackPhysicsPush(position);
		}

		private void ConfigureBuiltInExplosion()
		{
			if ((Object)(object)spawnedAttack == (Object)null)
			{
				spawnedAttack = ((Component)this).gameObject.GetComponent<SpawnedAttack>();
				if ((Object)(object)spawnedAttack == (Object)null)
				{
					spawnedAttack = ((Component)this).gameObject.AddComponent<SpawnedAttack>();
				}
			}
			spawnedAttack.spawner = owner;
			spawnedAttack.attackID = Random.Range(int.MinValue, int.MaxValue);
			spawnedAttack.attackLevel = 0;
			if ((Object)(object)builtInExplosion == (Object)null)
			{
				builtInExplosion = ((Component)this).gameObject.GetComponent<Explosion>();
				if ((Object)(object)builtInExplosion == (Object)null)
				{
					builtInExplosion = ((Component)this).gameObject.AddComponent<Explosion>();
				}
			}
			builtInExplosion.range = 3.15f;
			builtInExplosion.damage = (dealDamage ? 35f : 0f);
			builtInExplosion.force = (dealDamage ? 115f : 0f);
			builtInExplosion.objectForceMultiplier = (dealDamage ? 2f : 0f);
			builtInExplosion.forceIgnoreMass = true;
			builtInExplosion.ignoreWalls = false;
			builtInExplosion.ignoreTeam = false;
			builtInExplosion.staticRangeMultiplier = false;
			builtInExplosion.scaleDmg = false;
			builtInExplosion.scaleForce = false;
			builtInExplosion.scaleRadius = false;
			builtInExplosion.scaleSlow = false;
			builtInExplosion.scaleSilence = false;
			builtInExplosion.scaleStun = false;
			builtInExplosion.slow = 0f;
			builtInExplosion.silence = 0f;
			builtInExplosion.stun = 0f;
			builtInExplosion.fastSlow = false;
			builtInExplosion.immunity = 0.15f;
			builtInExplosion.flyingFor = 0f;
			builtInExplosion.auto = false;
			builtInExplosion.locallySimulated = true;
			ExplosionSpawnedField?.SetValue(builtInExplosion, spawnedAttack);
			CopyBuiltInExplosionSound(builtInExplosion);
		}

		private static void CopyBuiltInExplosionSound(Explosion target)
		{
			if (ExplosionSoundDamageField == null || (Object)(object)target == (Object)null)
			{
				return;
			}
			if (cachedExplosionSoundDamage == null)
			{
				Explosion[] array = Resources.FindObjectsOfTypeAll<Explosion>();
				for (int i = 0; i < array.Length; i++)
				{
					if (!((Object)(object)array[i] == (Object)null) && !((Object)(object)array[i] == (Object)(object)target))
					{
						object value = ExplosionSoundDamageField.GetValue(array[i]);
						if (value != null)
						{
							cachedExplosionSoundDamage = value;
							break;
						}
					}
				}
			}
			if (cachedExplosionSoundDamage != null)
			{
				ExplosionSoundDamageField.SetValue(target, cachedExplosionSoundDamage);
			}
		}

		private static void SpawnBuiltInExplosionVisual(Vector3 position)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: 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)
			ObjectsToSpawn val = FindExplosiveShotObjectsToSpawn();
			if (val != null)
			{
				ObjectsToSpawn.SpawnObject(val, position, Quaternion.identity);
				return;
			}
			GameObject val2 = FindBuiltInExplosionEffectTemplate();
			if (!((Object)(object)val2 == (Object)null))
			{
				GameObject val3 = Object.Instantiate<GameObject>(val2, position, Quaternion.identity);
				val3.SetActive(true);
				GeneralParticleSystem componentInChildren = val3.GetComponentInChildren<GeneralParticleSystem>(true);
				if ((Object)(object)componentInChildren != (Object)null)
				{
					componentInChildren.Play();
				}
				LineEffect componentInChildren2 = val3.GetComponentInChildren<LineEffect>(true);
				if ((Object)(object)componentInChildren2 != (Object)null)
				{
					componentInChildren2.Play(val3.transform);
				}
				Object.Destroy((Object)(object)val3, 3f);
			}
		}

		private static ObjectsToSpawn FindExplosiveShotObjectsToSpawn()
		{
			if (cachedExplosionObjectsToSpawn != null)
			{
				return cachedExplosionObjectsToSpawn;
			}
			CardInfo[] array = Resources.FindObjectsOfTypeAll<CardInfo>();
			foreach (CardInfo val in array)
			{
				if ((Object)(object)val == (Object)null || string.IsNullOrEmpty(val.cardName))
				{
					continue;
				}
				string text = val.cardName.ToLowerInvariant();
				if (!text.Contains("explosive") && !text.Contains("bomb"))
				{
					continue;
				}
				Gun componentInChildren = ((Component)val).GetComponentInChildren<Gun>(true);
				if ((Object)(object)componentInChildren == (Object)null || componentInChildren.objectsToSpawn == null)
				{
					continue;
				}
				for (int j = 0; j < componentInChildren.objectsToSpawn.Length; j++)
				{
					ObjectsToSpawn val2 = componentInChildren.objectsToSpawn[j];
					if (val2 != null && !((Object)(object)val2.effect == (Object)null))
					{
						cachedExplosionObjectsToSpawn = val2;
						ManualLogSource log = Plugin.Log;
						if (log != null)
						{
							log.LogInfo((object)("Grenade: using built-in explosion effect from card '" + val.cardName + "' object '" + ((Object)val2.effect).name + "'."));
						}
						return cachedExplosionObjectsToSpawn;
					}
				}
			}
			return null;
		}

		private static GameObject FindBuiltInExplosionEffectTemplate()
		{
			if ((Object)(object)cachedExplosionEffectTemplate != (Object)null)
			{
				return cachedExplosionEffectTemplate;
			}
			GeneralParticleSystem[] array = Resources.FindObjectsOfTypeAll<GeneralParticleSystem>();
			foreach (GeneralParticleSystem val in array)
			{
				if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).gameObject == (Object)null))
				{
					string text = ((Object)((Component)val).gameObject).name.ToLowerInvariant();
					string text2 = (((Object)(object)((Component)val).transform.parent != (Object)null) ? ((Object)((Component)val).transform.parent).name.ToLowerInvariant() : string.Empty);
					if (text.Contains("explosion") || text2.Contains("explosion"))
					{
						cachedExplosionEffectTemplate = (((Object)(object)((Component)val).transform.root != (Object)null) ? ((Component)((Component)val).transform.root).gameObject : ((Component)val).gameObject);
						return cachedExplosionEffectTemplate;
					}
				}
			}
			return null;
		}

		private static void ApplyFallbackPhysicsPush(Vector3 position)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: 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_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: 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_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			Collider2D[] array = Physics2D.OverlapCircleAll(Vector2.op_Implicit(position), 3.15f);
			HashSet<Rigidbody2D> hashSet = new HashSet<Rigidbody2D>();
			foreach (Collider2D val in array)
			{
				if ((Object)(object)val == (Object)null || val.isTrigger)
				{
					continue;
				}
				Rigidbody2D attachedRigidbody = val.attachedRigidbody;
				if (!((Object)(object)attachedRigidbody == (Object)null) && !hashSet.Contains(attachedRigidbody) && !((Object)(object)((Component)attachedRigidbody).GetComponentInParent<CharacterData>() != (Object)null))
				{
					Bounds bounds = val.bounds;
					Vector2 val2 = Vector2.op_Implicit(((Bounds)(ref bounds)).ClosestPoint(position)) - Vector2.op_Implicit(position);
					float num = Mathf.Max(0.1f, ((Vector2)(ref val2)).magnitude);
					float num2 = Mathf.Clamp01(1f - num / 3.15f);
					if (((Vector2)(ref val2)).sqrMagnitude < 0.001f)
					{
						val2 = Vector2.up;
					}
					attachedRigidbody.AddForce(((Vector2)(ref val2)).normalized * 115f * 0.75f * num2, (ForceMode2D)1);
					hashSet.Add(attachedRigidbody);
				}
			}
		}

		public static Sprite CreateGrenadeSprite()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_00af: 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_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_007d: 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)
			if ((Object)(object)cachedGrenadeSprite != (Object)null)
			{
				return cachedGrenadeSprite;
			}
			int num = 16;
			Texture2D val = new Texture2D(num, num, (TextureFormat)5, false);
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor((float)num / 2f, (float)num / 2f);
			for (int i = 0; i < num; i++)
			{
				for (int j = 0; j < num; j++)
				{
					float num2 = Vector2.Distance(new Vector2((float)j, (float)i), val2);
					val.SetPixel(j, i, (Color)((num2 <= (float)num * 0.35f) ? Color.white : new Color(0f, 0f, 0f, 0f)));
				}
			}
			val.Apply();
			cachedGrenadeSprite = Sprite.Create(val, new Rect(0f, 0f, (float)num, (float)num), new Vector2(0.5f, 0.5f), (float)num);
			return cachedGrenadeSprite;
		}
	}
	public class GrenadeUtility : UtilityAbility
	{
		private const float UtilityCooldown = 8f;

		private const float ThrowSpeed = 16f;

		private const float UpwardBoost = 2.5f;

		private static readonly Dictionary<string, float> RecentGrenadeEvents = new Dictionary<string, float>();

		private float nextUseTime;

		public override int Priority => 10;

		public static void HandleNetworkedGrenade(int ownerPlayerID, Vector3 spawnPosition, Vector2 velocity, int throwId)
		{
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			string key = $"{ownerPlayerID}:{throwId}";
			if (RecentGrenadeEvents.TryGetValue(key, out var value) && Time.time - value < 0.4f)
			{
				return;
			}
			RecentGrenadeEvents[key] = Time.time;
			CleanupRecentEvents();
			Player[] array = Object.FindObjectsOfType<Player>();
			Player val = null;
			for (int i = 0; i < array.Length; i++)
			{
				if ((Object)(object)array[i] != (Object)null && array[i].playerID == ownerPlayerID)
				{
					val = array[i];
					break;
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogWarning((object)$"Grenade: could not resolve owner for throw. playerID={ownerPlayerID}");
				}
			}
			else
			{
				bool dealDamage = (Object)(object)val.data != (Object)null && (Object)(object)val.data.view != (Object)null && val.data.view.IsMine;
				SpawnGrenadeObject(val, spawnPosition, velocity, dealDamage);
			}
		}

		protected override bool CanUse()
		{
			if (base.CanUse())
			{
				return Time.time >= nextUseTime;
			}
			return false;
		}

		protected override void UseAbility()
		{
			//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)
			//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_001d: Unknown result typ