Decompiled source of CustomCardPack v1.4.11

CustomCardPack.dll

Decompiled 3 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using CardChoiceSpawnUniqueCardPatch.CustomCategories;
using CustomCardPack.Cards;
using CustomCardPack.Components;
using CustomCardPack.Patches;
using CustomCardPack.Utils;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using ModdingUtils.MonoBehaviours;
using ModdingUtils.Utils;
using Photon.Pun;
using RarityLib.Utils;
using UnboundLib;
using UnboundLib.Cards;
using UnboundLib.GameModes;
using UnityEngine;
using UnityEngine.UI;
using WillsWackyManagers.Utils;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace CustomCardPack
{
	[BepInPlugin("com.korosaki.CustomCardPack", "CustomCardPack", "1.4.11")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInProcess("Rounds.exe")]
	public class Plugin : BaseUnityPlugin
	{
		public const string ModId = "com.korosaki.CustomCardPack";

		public const string ModName = "CustomCardPack";

		public const string ModVersion = "1.4.11";

		public const string ModInitials = "CustomCardPack";

		internal static void DiagLog(string message)
		{
			try
			{
				string path = Path.Combine(Path.GetTempPath(), "CustomCardPack_diag.txt");
				File.AppendAllText(path, $"{DateTime.Now:HH:mm:ss.fff} {message}{Environment.NewLine}");
			}
			catch
			{
			}
		}

		private void Awake()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			DiagLog("Plugin.Awake starting");
			Debug.Log("[CustomCardPack] Plugin.Awake starting");
			Harmony val = new Harmony("com.korosaki.CustomCardPack");
			try
			{
				val.PatchAll();
				DiagLog("harmony.PatchAll() completed");
				Debug.Log("[CustomCardPack] Plugin.Awake: harmony.PatchAll() completed");
			}
			catch (Exception ex)
			{
				DiagLog("harmony.PatchAll() threw - " + ex);
				Debug.LogError("[CustomCardPack] Plugin.Awake: harmony.PatchAll() threw - " + ex);
			}
			MirroredSwordPatch.TryApply(val);
			DiagLog("MirroredSwordPatch.TryApply returned");
			Debug.Log("[CustomCardPack] Plugin.Awake finished");
		}

		private void Start()
		{
			CustomCard.BuildCard<EdenCard>();
			CustomCard.BuildCard<TrainingMontageCard>();
			CustomCard.BuildCard<LeoArmadaCard>();
			CustomCard.BuildCard<DanielsCookingCard>();
			CustomCard.BuildCard<AlessioCard>();
			CustomCard.BuildCard<AlladarCard>();
			CustomCard.BuildCard<HexCard>((Action<CardInfo>)delegate(CardInfo cardInfo)
			{
				HexCard.RegisteredCardInfo = cardInfo;
			});
			CustomCard.BuildCard<QueerEstateCard>();
			CustomCard.BuildCard<CursedGiftCard>();
			CustomCard.BuildCard<TaumanCard>((Action<CardInfo>)delegate(CardInfo cardInfo)
			{
				TaumanCard.RegisteredCardInfo = cardInfo;
			});
			CustomCard.BuildCard<KachowCard>();
			CustomCard.BuildCard<MonkModeCard>();
			CustomCard.BuildCard<FurryTransformationCard>();
			CustomCard.BuildCard<MultiversalDwarfCard>();
			CustomCard.BuildCard<StrengthGauntletsCard>();
			CustomCard.BuildCard<EvilAssArmorCard>();
			CustomCard.BuildCard<CoolStickCard>();
			CustomCard.BuildCard<CauldronCard>();
			CustomCard.BuildCard<OrbitalStrikeCard>();
			CustomCard.BuildCard<KonCard>();
			CustomCard.BuildCard<DragonCard>();
			CustomCard.BuildCard<PassiveAggressiveCard>();
			CustomCard.BuildCard<BigFuckingSwordCard>((Action<CardInfo>)delegate(CardInfo cardInfo)
			{
				CustomCategories.AddCategory(cardInfo, CustomCategories.ClassGated);
			});
			CustomCard.BuildCard<EchoKnightCard>();
			CustomCard.BuildCard<EchoTeleportCard>((Action<CardInfo>)delegate(CardInfo cardInfo)
			{
				CustomCategories.AddCategory(cardInfo, CustomCategories.ClassGated);
			});
			CustomCard.BuildCard<MultiattackCard>();
			CustomCard.BuildCard<TarotDeckCard>((Action<CardInfo>)delegate(CardInfo cardInfo)
			{
				CustomCategories.AddCategory(cardInfo, CustomCategories.Tarot);
			});
			CustomCard.BuildCard<TheFoolCard>((Action<CardInfo>)delegate(CardInfo cardInfo)
			{
				CustomCategories.AddCategory(cardInfo, CustomCategories.Tarot);
				TarotUtils.RegisterCard(cardInfo);
			});
			CustomCard.BuildCard<TheMagicianCard>((Action<CardInfo>)delegate(CardInfo cardInfo)
			{
				CustomCategories.AddCategory(cardInfo, CustomCategories.Tarot);
				TarotUtils.RegisterCard(cardInfo);
			});
			CustomCard.BuildCard<TheHighPriestessCard>((Action<CardInfo>)delegate(CardInfo cardInfo)
			{
				CustomCategories.AddCategory(cardInfo, CustomCategories.Tarot);
				TarotUtils.RegisterCard(cardInfo);
			});
			CustomCard.BuildCard<TheEmpressCard>((Action<CardInfo>)delegate(CardInfo cardInfo)
			{
				CustomCategories.AddCategory(cardInfo, CustomCategories.Tarot);
				TarotUtils.RegisterCard(cardInfo);
			});
			CustomCard.BuildCard<TheEmperorCard>((Action<CardInfo>)delegate(CardInfo cardInfo)
			{
				CustomCategories.AddCategory(cardInfo, CustomCategories.Tarot);
				TarotUtils.RegisterCard(cardInfo);
			});
			CustomCard.BuildCard<TheLoversCard>((Action<CardInfo>)delegate(CardInfo cardInfo)
			{
				CustomCategories.AddCategory(cardInfo, CustomCategories.Tarot);
				TarotUtils.RegisterCard(cardInfo);
			});
			CustomCard.BuildCard<TheChariotCard>((Action<CardInfo>)delegate(CardInfo cardInfo)
			{
				CustomCategories.AddCategory(cardInfo, CustomCategories.Tarot);
				TarotUtils.RegisterCard(cardInfo);
			});
			CustomCard.BuildCard<TheHermitCard>((Action<CardInfo>)delegate(CardInfo cardInfo)
			{
				CustomCategories.AddCategory(cardInfo, CustomCategories.Tarot);
				TarotUtils.RegisterCard(cardInfo);
			});
			CustomCard.BuildCard<TheDevilCard>((Action<CardInfo>)delegate(CardInfo cardInfo)
			{
				CustomCategories.AddCategory(cardInfo, CustomCategories.Tarot);
				TarotUtils.RegisterCard(cardInfo);
			});
			CustomCard.BuildCard<TheTowerCard>((Action<CardInfo>)delegate(CardInfo cardInfo)
			{
				CustomCategories.AddCategory(cardInfo, CustomCategories.Tarot);
				TarotUtils.RegisterCard(cardInfo);
			});
			CustomCard.BuildCard<TemperanceCard>((Action<CardInfo>)delegate(CardInfo cardInfo)
			{
				CustomCategories.AddCategory(cardInfo, CustomCategories.Tarot);
				TarotUtils.RegisterCard(cardInfo);
			});
			CustomCard.BuildCard<DeathCard>((Action<CardInfo>)delegate(CardInfo cardInfo)
			{
				CustomCategories.AddCategory(cardInfo, CustomCategories.Tarot);
				TarotUtils.RegisterCard(cardInfo);
			});
			CustomCard.BuildCard<TheSunCard>((Action<CardInfo>)delegate(CardInfo cardInfo)
			{
				CustomCategories.AddCategory(cardInfo, CustomCategories.Tarot);
				TarotUtils.RegisterCard(cardInfo);
			});
			CustomCard.BuildCard<TheWorldCard>((Action<CardInfo>)delegate(CardInfo cardInfo)
			{
				CustomCategories.AddCategory(cardInfo, CustomCategories.Tarot);
				TarotUtils.RegisterCard(cardInfo);
			});
			CustomCard.BuildCard<HappyBirthdayDanielCard>((Action<CardInfo>)delegate(CardInfo cardInfo)
			{
				CurseManager.instance.RegisterCurse(cardInfo);
			});
			CustomCard.BuildCard<CatAllergyCard>((Action<CardInfo>)delegate(CardInfo cardInfo)
			{
				CurseManager.instance.RegisterCurse(cardInfo);
			});
			CustomCard.BuildCard<CheddaCard>();
			CustomCard.BuildCard<DenverCard>();
			CatUtils.RegisterPickCondition();
			CardGateUtils.RegisterPickConditions();
			GameModeManager.AddHook("GameStart", (Func<IGameModeHandler, IEnumerator>)((IGameModeHandler gm) => ResetPerGameState()), 100);
			GameModeManager.AddHook("RoundStart", (Func<IGameModeHandler, IEnumerator>)((IGameModeHandler gm) => TarotUtils.DealForAllHolders()), 100);
			GameModeManager.AddHook("RoundEnd", (Func<IGameModeHandler, IEnumerator>)LockInTarot, 100);
		}

		private static IEnumerator ResetPerGameState()
		{
			CatUtils.ResetUnlocks();
			TarotUtils.ResetForNewGame();
			yield break;
		}

		private static IEnumerator LockInTarot(IGameModeHandler gameModeHandler)
		{
			if (gameModeHandler != null)
			{
				TarotUtils.MarkWorldPermanentForWinners(gameModeHandler.GetRoundWinners());
			}
			yield break;
		}
	}
}
namespace CustomCardPack.Utils
{
	internal static class CardArtUtils
	{
		private static readonly Dictionary<string, Sprite> SpriteCache = new Dictionary<string, Sprite>();

		private static readonly Dictionary<string, Sprite> PivotedSpriteCache = new Dictionary<string, Sprite>();

		public static Sprite LoadSprite(string relativePath)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			if (SpriteCache.TryGetValue(relativePath, out var value))
			{
				return value;
			}
			Texture2D val = LoadTexture(relativePath);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			Sprite val2 = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
			SpriteCache[relativePath] = val2;
			return val2;
		}

		public static Sprite LoadSpriteWithPivot(string relativePath, Vector2 pivot)
		{
			//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)
			string key = relativePath + "|" + pivot.x.ToString("F4") + "," + pivot.y.ToString("F4");
			if (PivotedSpriteCache.TryGetValue(key, out var value))
			{
				return value;
			}
			Texture2D val = LoadTexture(relativePath);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			Sprite val2 = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), pivot);
			PivotedSpriteCache[key] = val2;
			return val2;
		}

		public static GameObject LoadCoverArt(Transform cardRoot, string relativePath, string objectName)
		{
			//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_0059: 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)
			Texture2D val = LoadTexture(relativePath);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			float targetAspect = FindArtAspect(cardRoot) ?? ((float)((Texture)val).width / (float)((Texture)val).height);
			Rect val2 = CenteredCropRect(((Texture)val).width, ((Texture)val).height, targetAspect);
			Sprite sprite = Sprite.Create(val, val2, new Vector2(0.5f, 0.5f));
			return BuildArtObject(sprite, objectName, stretchToFill: true);
		}

		public static GameObject LoadStretchedArt(string relativePath, string objectName)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = LoadTexture(relativePath);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			Sprite sprite = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
			return BuildArtObject(sprite, objectName, stretchToFill: false);
		}

		private static Texture2D LoadTexture(string relativePath)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			byte[] array = EmbeddedResourceUtils.ReadBytes("Art\\" + relativePath);
			if (array == null)
			{
				return null;
			}
			Texture2D val = new Texture2D(2, 2);
			return ImageConversion.LoadImage(val, array) ? val : null;
		}

		private static float? FindArtAspect(Transform cardRoot)
		{
			//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_0090: 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_009f: 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)
			if ((Object)(object)cardRoot == (Object)null)
			{
				return null;
			}
			CardVisuals componentInChildren = ((Component)cardRoot).GetComponentInChildren<CardVisuals>(true);
			if ((Object)(object)componentInChildren == (Object)null)
			{
				return null;
			}
			Transform obj = ((Component)componentInChildren).transform.Find("Canvas/Front/Background/Art");
			RectTransform val = (RectTransform)(object)((obj is RectTransform) ? obj : null);
			if (!((Object)(object)val == (Object)null))
			{
				Rect rect = val.rect;
				if (!(((Rect)(ref rect)).height <= 0f))
				{
					rect = val.rect;
					float width = ((Rect)(ref rect)).width;
					rect = val.rect;
					return width / ((Rect)(ref rect)).height;
				}
			}
			return null;
		}

		private static Rect CenteredCropRect(int width, int height, float targetAspect)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: 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_005a: Unknown result type (might be due to invalid IL or missing references)
			float num = (float)width / (float)height;
			if (num > targetAspect)
			{
				float num2 = (float)height * targetAspect;
				float num3 = ((float)width - num2) / 2f;
				return new Rect(num3, 0f, num2, (float)height);
			}
			float num4 = (float)width / targetAspect;
			float num5 = ((float)height - num4) / 2f;
			return new Rect(0f, num5, (float)width, num4);
		}

		private static GameObject BuildArtObject(Sprite sprite, string objectName, bool stretchToFill)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(objectName);
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.anchorMin = Vector2.zero;
			val2.anchorMax = Vector2.one;
			val2.offsetMin = Vector2.zero;
			val2.offsetMax = Vector2.zero;
			Image val3 = val.AddComponent<Image>();
			val3.sprite = sprite;
			val3.preserveAspect = !stretchToFill;
			Object.DontDestroyOnLoad((Object)(object)val);
			return val;
		}
	}
	internal static class CustomCategories
	{
		public static CardCategory Curse => CurseManager.instance.curseCategory;

		public static CardCategory CurseSpawner => CurseManager.instance.curseSpawnerCategory;

		public static CardCategory Tarot => CustomCardCategories.instance.CardCategory("Tarot");

		public static CardCategory ClassGated => CustomCardCategories.instance.CardCategory("ClassGated");

		public static void AddCategory(CardInfo cardInfo, CardCategory category)
		{
			cardInfo.categories = (CardCategory[])((cardInfo.categories != null) ? ((Array)cardInfo.categories.Append(category).ToArray()) : ((Array)new CardCategory[1] { category }));
		}
	}
	internal static class CardGateUtils
	{
		private static readonly Dictionary<string, string> RequiresCard = new Dictionary<string, string>
		{
			{ "Big Fucking Sword", "Knight" },
			{ "Echo Teleport", "Echo Knight" }
		};

		private static readonly (string, string)[] MutuallyExclusiveCards = new(string, string)[1] { ("Dragon", "Knight") };

		public static void RegisterPickConditions()
		{
			Cards.instance.AddCardValidationFunction((Func<Player, CardInfo, bool>)IsAllowed);
		}

		private static bool IsAllowed(Player player, CardInfo card)
		{
			if ((Object)(object)card == (Object)null)
			{
				return true;
			}
			if (TarotUtils.IsTarotCard(card))
			{
				return false;
			}
			(string, string)[] mutuallyExclusiveCards = MutuallyExclusiveCards;
			for (int i = 0; i < mutuallyExclusiveCards.Length; i++)
			{
				(string, string) tuple = mutuallyExclusiveCards[i];
				if (card.cardName == tuple.Item1 && HasCard(player, tuple.Item2))
				{
					return false;
				}
				if (card.cardName == tuple.Item2 && HasCard(player, tuple.Item1))
				{
					return false;
				}
			}
			if (!RequiresCard.TryGetValue(card.cardName, out var value))
			{
				return true;
			}
			return HasCard(player, value);
		}

		public static bool HasCard(Player player, string cardName)
		{
			if ((Object)(object)player == (Object)null || (Object)(object)player.data == (Object)null || player.data.currentCards == null)
			{
				return false;
			}
			List<CardInfo> currentCards = player.data.currentCards;
			for (int i = 0; i < currentCards.Count; i++)
			{
				if ((Object)(object)currentCards[i] != (Object)null && currentCards[i].cardName == cardName)
				{
					return true;
				}
			}
			return false;
		}
	}
	internal static class CatUtils
	{
		private static readonly HashSet<string> CatCardTitles = new HashSet<string> { "Chedda", "Denver", "Furry transformation" };

		private static readonly HashSet<string> LockedCatCardTitles = new HashSet<string> { "Chedda", "Denver" };

		private static readonly HashSet<int> PlayersWithCatsUnlocked = new HashSet<int>();

		public static bool IsCatCard(CardInfo card)
		{
			return (Object)(object)card != (Object)null && CatCardTitles.Contains(card.cardName);
		}

		public static int CountCats(CharacterData data)
		{
			if ((Object)(object)data == (Object)null || data.currentCards == null)
			{
				return 0;
			}
			int num = 0;
			for (int i = 0; i < data.currentCards.Count; i++)
			{
				if (IsCatCard(data.currentCards[i]))
				{
					num++;
				}
			}
			return num;
		}

		public static void RegisterPickCondition()
		{
			Cards.instance.AddCardValidationFunction((Func<Player, CardInfo, bool>)((Player player, CardInfo card) => !LockedCatCardTitles.Contains(card.cardName) || HasUnlockedCats(player)));
		}

		public static bool HasUnlockedCats(Player player)
		{
			return (Object)(object)player != (Object)null && PlayersWithCatsUnlocked.Contains(player.playerID);
		}

		public static void UnlockCatsFor(Player player)
		{
			if ((Object)(object)player != (Object)null)
			{
				PlayersWithCatsUnlocked.Add(player.playerID);
			}
		}

		public static void LockCatsFor(Player player)
		{
			if ((Object)(object)player != (Object)null)
			{
				PlayersWithCatsUnlocked.Remove(player.playerID);
			}
		}

		public static void ResetUnlocks()
		{
			PlayersWithCatsUnlocked.Clear();
		}
	}
	internal static class CharacterStatUtils
	{
		public static void ConfigureMassAndSize(CharacterStatModifiers stats)
		{
			Traverse.Create((object)stats).Method("ConfigureMassAndSize", Array.Empty<object>()).GetValue();
		}
	}
	internal static class EffectMaterials
	{
		private static Material spritesDefault;

		public static Material SpritesDefault
		{
			get
			{
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0025: Expected O, but got Unknown
				if ((Object)(object)spritesDefault == (Object)null)
				{
					spritesDefault = new Material(Shader.Find("Sprites/Default"));
				}
				return spritesDefault;
			}
		}
	}
	internal static class EmbeddedResourceUtils
	{
		public static byte[] ReadBytes(string logicalName)
		{
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			using Stream stream = executingAssembly.GetManifestResourceStream(logicalName);
			if (stream == null)
			{
				return null;
			}
			byte[] array = new byte[stream.Length];
			int num;
			for (int i = 0; i < array.Length; i += num)
			{
				num = stream.Read(array, i, array.Length - i);
				if (num <= 0)
				{
					break;
				}
			}
			return array;
		}
	}
	internal static class ExternalCardUtils
	{
		public static void GrantCard(Player player, string cardName, string grantedBy)
		{
			if (!((Object)(object)player == (Object)null) && !string.IsNullOrEmpty(cardName) && (PhotonNetwork.OfflineMode || PhotonNetwork.IsMasterClient))
			{
				((MonoBehaviour)Unbound.Instance).StartCoroutine(GrantNextFrame(player, cardName, grantedBy));
			}
		}

		private static IEnumerator GrantNextFrame(Player player, string cardName, string grantedBy)
		{
			yield return null;
			if (!((Object)(object)player == (Object)null) && !((Object)(object)player.data == (Object)null) && player.data.currentCards != null && !player.data.currentCards.Any((CardInfo c) => (Object)(object)c != (Object)null && c.cardName == cardName))
			{
				CardInfo card = FindCard(cardName);
				if ((Object)(object)card == (Object)null)
				{
					Debug.LogWarning("[CustomCardPack] " + grantedBy + " wanted to grant the card \"" + cardName + "\", but no card by that name is registered - is the mod that provides it installed in this profile? Skipping the grant; the card's own stats still apply.");
				}
				else
				{
					Cards.instance.AddCardToPlayer(player, card, false, "", 2f, 2f, true);
				}
			}
		}

		public static CardInfo FindCard(string cardName)
		{
			List<CardInfo> all = Cards.all;
			if (all == null)
			{
				return null;
			}
			for (int i = 0; i < all.Count; i++)
			{
				CardInfo val = all[i];
				if (!((Object)(object)val == (Object)null) && string.Equals(val.cardName, cardName, StringComparison.OrdinalIgnoreCase))
				{
					return val;
				}
			}
			for (int j = 0; j < all.Count; j++)
			{
				CardInfo val2 = all[j];
				if ((Object)(object)val2 != (Object)null && string.Equals(((Object)val2).name, cardName, StringComparison.OrdinalIgnoreCase))
				{
					return val2;
				}
			}
			return null;
		}
	}
	internal static class SoundUtils
	{
		private static readonly Dictionary<string, AudioClip> ClipCache = new Dictionary<string, AudioClip>();

		public static AudioClip LoadClip(string relativePath)
		{
			if (ClipCache.TryGetValue(relativePath, out var value))
			{
				return value;
			}
			byte[] array = EmbeddedResourceUtils.ReadBytes("Sound\\" + relativePath);
			if (array == null)
			{
				return null;
			}
			AudioClip val;
			try
			{
				val = ParseWav(array, Path.GetFileNameWithoutExtension(relativePath));
			}
			catch (Exception)
			{
				return null;
			}
			ClipCache[relativePath] = val;
			return val;
		}

		public static void PlayOneShot(AudioClip clip, Vector3 position, float volume = 1f)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)clip == (Object)null))
			{
				GameObject val = new GameObject("OneShotAudio");
				val.transform.position = position;
				AudioSource val2 = val.AddComponent<AudioSource>();
				val2.spatialBlend = 0f;
				val2.volume = volume;
				val2.clip = clip;
				val2.Play();
				Object.Destroy((Object)(object)val, clip.length);
			}
		}

		private static AudioClip ParseWav(byte[] data, string clipName)
		{
			if (data.Length < 12 || data[0] != 82 || data[1] != 73 || data[2] != 70 || data[3] != 70 || data[8] != 87 || data[9] != 65 || data[10] != 86 || data[11] != 69)
			{
				throw new InvalidDataException("Not a RIFF/WAVE file");
			}
			short audioFormat = 0;
			short num = 0;
			short num2 = 0;
			int num3 = 0;
			byte[] array = null;
			int num4 = 12;
			while (num4 + 8 <= data.Length)
			{
				string text = Encoding.ASCII.GetString(data, num4, 4);
				int num5 = BitConverter.ToInt32(data, num4 + 4);
				int num6 = num4 + 8;
				if (text == "fmt ")
				{
					audioFormat = BitConverter.ToInt16(data, num6);
					num = BitConverter.ToInt16(data, num6 + 2);
					num3 = BitConverter.ToInt32(data, num6 + 4);
					num2 = BitConverter.ToInt16(data, num6 + 14);
				}
				else if (text == "data")
				{
					array = new byte[num5];
					Array.Copy(data, num6, array, 0, num5);
				}
				num4 = num6 + num5 + num5 % 2;
			}
			if (array == null || num == 0 || num3 == 0 || num2 == 0)
			{
				throw new InvalidDataException("Missing fmt/data chunk");
			}
			float[] array2 = ToFloatSamples(array, num2, audioFormat);
			int num7 = array2.Length / num;
			AudioClip val = AudioClip.Create(clipName, num7, (int)num, num3, false);
			val.SetData(array2, 0);
			return val;
		}

		private static float[] ToFloatSamples(byte[] pcmData, int bitsPerSample, short audioFormat)
		{
			switch (bitsPerSample)
			{
			case 8:
			{
				float[] array5 = new float[pcmData.Length];
				for (int m = 0; m < array5.Length; m++)
				{
					array5[m] = (float)(pcmData[m] - 128) / 128f;
				}
				return array5;
			}
			case 16:
			{
				float[] array4 = new float[pcmData.Length / 2];
				for (int l = 0; l < array4.Length; l++)
				{
					array4[l] = (float)BitConverter.ToInt16(pcmData, l * 2) / 32768f;
				}
				return array4;
			}
			case 24:
			{
				float[] array3 = new float[pcmData.Length / 3];
				for (int k = 0; k < array3.Length; k++)
				{
					int num = k * 3;
					int num2 = pcmData[num] | (pcmData[num + 1] << 8) | (pcmData[num + 2] << 16);
					if ((num2 & 0x800000) != 0)
					{
						num2 |= -16777216;
					}
					array3[k] = (float)num2 / 8388608f;
				}
				return array3;
			}
			case 32:
				switch (audioFormat)
				{
				case 3:
				{
					float[] array2 = new float[pcmData.Length / 4];
					for (int j = 0; j < array2.Length; j++)
					{
						array2[j] = BitConverter.ToSingle(pcmData, j * 4);
					}
					return array2;
				}
				case 1:
				{
					float[] array = new float[pcmData.Length / 4];
					for (int i = 0; i < array.Length; i++)
					{
						array[i] = (float)BitConverter.ToInt32(pcmData, i * 4) / 2.1474836E+09f;
					}
					return array;
				}
				}
				break;
			}
			throw new InvalidDataException($"Unsupported wav format: {bitsPerSample}-bit, format tag {audioFormat}");
		}
	}
	internal static class TarotUtils
	{
		public const string DeckCardName = "Tarot Deck";

		public const string WorldCardName = "The World";

		public static readonly string[] TarotCardNames = new string[14]
		{
			"The Fool", "The Magician", "The High Priestess", "The Empress", "The Emperor", "The Lovers", "The Chariot", "The Hermit", "The Devil", "The Tower",
			"Temperance", "Death", "The Sun", "The World"
		};

		private static readonly Dictionary<string, CardInfo> RegisteredCards = new Dictionary<string, CardInfo>(StringComparer.OrdinalIgnoreCase);

		private static readonly Dictionary<int, HashSet<string>> PermanentByPlayer = new Dictionary<int, HashSet<string>>();

		private static bool dealing;

		public static void RegisterCard(CardInfo cardInfo)
		{
			if (!((Object)(object)cardInfo == (Object)null))
			{
				RegisteredCards[cardInfo.cardName] = cardInfo;
			}
		}

		public static bool IsTarotCard(CardInfo card)
		{
			CardInfo value;
			return (Object)(object)card != (Object)null && RegisteredCards.TryGetValue(card.cardName, out value) && (Object)(object)value == (Object)(object)card;
		}

		public static void ResetForNewGame()
		{
			PermanentByPlayer.Clear();
		}

		public static IEnumerator DealForAllHolders()
		{
			if (!PhotonNetwork.IsMasterClient || dealing)
			{
				yield break;
			}
			List<Player> players = (((Object)(object)PlayerManager.instance != (Object)null) ? PlayerManager.instance.players : null);
			if (players == null)
			{
				yield break;
			}
			dealing = true;
			try
			{
				for (int i = 0; i < players.Count; i++)
				{
					Player player = players[i];
					if (CardGateUtils.HasCard(player, "Tarot Deck"))
					{
						yield return DealFor(player);
					}
				}
			}
			finally
			{
				dealing = false;
			}
		}

		public static void EnsureFirstDeal(Player player)
		{
			if (PhotonNetwork.IsMasterClient && !((Object)(object)player == (Object)null))
			{
				((MonoBehaviour)Unbound.Instance).StartCoroutine(FirstDealRoutine(player));
			}
		}

		private static IEnumerator FirstDealRoutine(Player player)
		{
			yield return null;
			if (!dealing && !((Object)(object)player == (Object)null) && !((Object)(object)player.data == (Object)null) && player.data.currentCards != null && CardGateUtils.HasCard(player, "Tarot Deck") && !HasAnyTarotCard(player))
			{
				dealing = true;
				try
				{
					yield return DealFor(player);
				}
				finally
				{
					dealing = false;
				}
			}
		}

		private static IEnumerator DealFor(Player player)
		{
			if ((Object)(object)player == (Object)null || (Object)(object)player.data == (Object)null || player.data.currentCards == null)
			{
				yield break;
			}
			HashSet<string> permanent = GetPermanent(player.playerID);
			string pick = ChooseCardName(permanent);
			if (pick == null)
			{
				yield break;
			}
			if (!RegisteredCards.TryGetValue(pick, out var newCard) || (Object)(object)newCard == (Object)null)
			{
				Debug.LogWarning("[CustomCardPack] Tarot Deck tried to deal \"" + pick + "\" but this pack's own card by that name hasn't registered yet - skipping this draw.");
				yield break;
			}
			CardInfo current = FindCurrentDraw(player, permanent);
			if ((Object)(object)current != (Object)null)
			{
				yield return Cards.instance.ReplaceCard(player, current, newCard, "", 2f, 2f, (SelectionType)2);
				yield break;
			}
			Cards.instance.AddCardToPlayer(player, newCard, false, "", 2f, 2f, true);
			yield return null;
		}

		private static CardInfo FindCurrentDraw(Player player, HashSet<string> permanent)
		{
			List<CardInfo> currentCards = player.data.currentCards;
			for (int i = 0; i < currentCards.Count; i++)
			{
				if (IsTarotCard(currentCards[i]) && !permanent.Contains(currentCards[i].cardName))
				{
					return currentCards[i];
				}
			}
			return null;
		}

		private static bool HasAnyTarotCard(Player player)
		{
			List<CardInfo> currentCards = player.data.currentCards;
			for (int i = 0; i < currentCards.Count; i++)
			{
				if (IsTarotCard(currentCards[i]))
				{
					return true;
				}
			}
			return false;
		}

		private static string ChooseCardName(HashSet<string> permanent)
		{
			List<string> list = new List<string>();
			for (int i = 0; i < TarotCardNames.Length; i++)
			{
				if (!permanent.Contains(TarotCardNames[i]))
				{
					list.Add(TarotCardNames[i]);
				}
			}
			return (list.Count == 0) ? null : list[Random.Range(0, list.Count)];
		}

		public static void MarkWorldPermanentForWinners(int[] winningTeamIDs)
		{
			if (winningTeamIDs == null || winningTeamIDs.Length == 0 || (Object)(object)PlayerManager.instance == (Object)null)
			{
				return;
			}
			List<Player> players = PlayerManager.instance.players;
			for (int i = 0; i < players.Count; i++)
			{
				Player val = players[i];
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				bool flag = false;
				for (int j = 0; j < winningTeamIDs.Length; j++)
				{
					if (winningTeamIDs[j] == val.teamID)
					{
						flag = true;
						break;
					}
				}
				if (flag && CardGateUtils.HasCard(val, "The World"))
				{
					GetPermanent(val.playerID).Add("The World");
				}
			}
		}

		private static HashSet<string> GetPermanent(int playerID)
		{
			if (!PermanentByPlayer.TryGetValue(playerID, out var value))
			{
				value = new HashSet<string>();
				PermanentByPlayer[playerID] = value;
			}
			return value;
		}
	}
}
namespace CustomCardPack.Patches
{
	[HarmonyPatch(typeof(HealthHandler), "DoDamage")]
	internal static class HexNearSightPatch
	{
		private const float NearSightSeconds = 3f;

		private static void Postfix(Player damagingPlayer, Player ___player)
		{
			if (!((Object)(object)damagingPlayer == (Object)null) && !((Object)(object)___player == (Object)null) && !((Object)(object)damagingPlayer == (Object)(object)___player) && damagingPlayer.teamID != ___player.teamID && HasHex(damagingPlayer))
			{
				NearSightOverlay.Apply(___player, 3f);
			}
		}

		private static bool HasHex(Player player)
		{
			if ((Object)(object)player.data == (Object)null || player.data.currentCards == null || (Object)(object)HexCard.RegisteredCardInfo == (Object)null)
			{
				return false;
			}
			List<CardInfo> currentCards = player.data.currentCards;
			for (int i = 0; i < currentCards.Count; i++)
			{
				if ((Object)(object)currentCards[i] == (Object)(object)HexCard.RegisteredCardInfo)
				{
					return true;
				}
			}
			return false;
		}
	}
	internal static class IncomingEffectTuning
	{
		public const float LoversDamageTakenMultiplier = 1.5f;

		public const float EmperorDamageTakenMultiplier = 0.75f;

		public const float PassiveAggressiveDamageTakenMultiplier = 1.25f;

		public const float ChariotKnockbackMultiplier = 0.6f;

		public static float GetMultiplier(Player victim, string cardName, float perCopy)
		{
			if ((Object)(object)victim == (Object)null || (Object)(object)victim.data == (Object)null || victim.data.currentCards == null)
			{
				return 1f;
			}
			float num = 1f;
			List<CardInfo> currentCards = victim.data.currentCards;
			for (int i = 0; i < currentCards.Count; i++)
			{
				if ((Object)(object)currentCards[i] != (Object)null && currentCards[i].cardName == cardName)
				{
					num *= perCopy;
				}
			}
			return num;
		}

		public static float GetDamageTakenMultiplier(Player victim)
		{
			if ((Object)(object)victim == (Object)null || (Object)(object)victim.data == (Object)null || victim.data.currentCards == null)
			{
				return 1f;
			}
			float num = 1f;
			List<CardInfo> currentCards = victim.data.currentCards;
			for (int i = 0; i < currentCards.Count; i++)
			{
				CardInfo val = currentCards[i];
				if (!((Object)(object)val == (Object)null))
				{
					if (val.cardName == "The Lovers")
					{
						num *= 1.5f;
					}
					else if (val.cardName == "The Emperor")
					{
						num *= 0.75f;
					}
					else if (val.cardName == "Passive Aggressive")
					{
						num *= 1.25f;
					}
				}
			}
			return num;
		}
	}
	[HarmonyPatch(typeof(HealthHandler), "DoDamage")]
	internal static class IncomingDamagePatch
	{
		private static void Prefix(ref Vector2 damage, Player ___player)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)___player == (Object)null))
			{
				float damageTakenMultiplier = IncomingEffectTuning.GetDamageTakenMultiplier(___player);
				if (damageTakenMultiplier != 1f)
				{
					damage *= damageTakenMultiplier;
				}
			}
		}
	}
	[HarmonyPatch(typeof(HealthHandler), "TakeForce")]
	internal static class IncomingForcePatch
	{
		private static void Prefix(ref Vector2 force, Player ___player)
		{
			//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_003d: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)___player == (Object)null))
			{
				float multiplier = IncomingEffectTuning.GetMultiplier(___player, "The Chariot", 0.6f);
				if (multiplier != 1f)
				{
					force *= multiplier;
				}
			}
		}
	}
	internal static class MirroredSwordPatch
	{
		private sealed class SwapState
		{
			public Gun Gun;

			public Transform OriginalShootPosition;

			public Vector3 OriginalOwnWeaponPosition;
		}

		private const float MirrorAxisX = 0f;

		private static Transform mirrorAnchor;

		public static void TryApply(Harmony harmony)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			try
			{
				Type type = AccessTools.TypeByName("RSClasses.SwordSlash");
				if (type == null)
				{
					Plugin.DiagLog("MirroredSwordPatch: RSClasses.SwordSlash not found - the mirrored-sword fix is not applied.");
					return;
				}
				HarmonyMethod val = new HarmonyMethod(typeof(MirroredSwordPatch).GetMethod("Prefix", BindingFlags.Static | BindingFlags.NonPublic));
				HarmonyMethod val2 = new HarmonyMethod(typeof(MirroredSwordPatch).GetMethod("Postfix", BindingFlags.Static | BindingFlags.NonPublic));
				MethodInfo methodInfo = AccessTools.Method(type, "FixedUpdate", (Type[])null, (Type[])null);
				if (methodInfo == null)
				{
					Plugin.DiagLog("MirroredSwordPatch: found RSClasses.SwordSlash but not its FixedUpdate - the mirrored-sword fix is not applied.");
					return;
				}
				harmony.Patch((MethodBase)methodInfo, val, val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				MethodInfo methodInfo2 = AccessTools.Method(type, "Start", (Type[])null, (Type[])null);
				if (methodInfo2 == null)
				{
					Plugin.DiagLog("MirroredSwordPatch: found RSClasses.SwordSlash but not its Start - mirrored swings will hit correctly but show no blade visual.");
				}
				else
				{
					harmony.Patch((MethodBase)methodInfo2, val, val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
			}
			catch (Exception ex)
			{
				Plugin.DiagLog("MirroredSwordPatch: TryApply threw - the mirrored-sword fix is not applied. " + ex);
			}
		}

		private static Vector3 Mirror(Vector3 point)
		{
			//IL_0005: 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_0012: 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)
			return new Vector3(0f - point.x, point.y, point.z);
		}

		private static Quaternion MirrorRotation(Quaternion rotation)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			Vector3 eulerAngles = ((Quaternion)(ref rotation)).eulerAngles;
			return Quaternion.Euler(eulerAngles.x, eulerAngles.y, 0f - eulerAngles.z);
		}

		private static void StartMirroredBladeTracking(Gun realGun)
		{
			try
			{
				Type type = AccessTools.TypeByName("RSClasses.SwordLength_Mono");
				if (type == null)
				{
					return;
				}
				Component component = ((Component)realGun).GetComponent(type);
				if (!((Object)(object)component == (Object)null))
				{
					FieldInfo fieldInfo = AccessTools.Field(type, "blade");
					Transform val = (Transform)((fieldInfo != null) ? /*isinst with value type is only supported in some contexts*/: null);
					if (!((Object)(object)val == (Object)null))
					{
						Transform realSpring = (((Object)(object)val.parent != (Object)null) ? val.parent : val);
						((MonoBehaviour)Unbound.Instance).StartCoroutine(TrackMirroredBlade(realSpring));
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.DiagLog("StartMirroredBladeTracking threw - " + ex);
			}
		}

		private static IEnumerator TrackMirroredBlade(Transform realSpring)
		{
			GameObject clone = Object.Instantiate<GameObject>(((Component)realSpring).gameObject);
			((Object)clone).name = "CustomCardPack_MirroredBlade";
			float elapsed = 0f;
			while (elapsed < 0.6f && (Object)(object)realSpring != (Object)null)
			{
				clone.transform.position = Mirror(realSpring.position);
				clone.transform.rotation = MirrorRotation(realSpring.rotation);
				Vector3 realScale = realSpring.lossyScale;
				clone.transform.localScale = new Vector3(0f - realScale.x, realScale.y, realScale.z);
				elapsed += Time.deltaTime;
				yield return null;
			}
			Object.Destroy((Object)(object)clone);
		}

		private static void Prefix(object __instance, ref SwapState __state, MethodBase __originalMethod)
		{
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: 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)
			__state = null;
			bool flag = __originalMethod != null && __originalMethod.Name == "Start";
			Component val = (Component)((__instance is Component) ? __instance : null);
			ProjectileHit val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<ProjectileHit>() : null);
			if ((Object)(object)val2 == (Object)null || (Object)(object)val2.ownWeapon == (Object)null || (Object)(object)val2.ownPlayer == (Object)null)
			{
				return;
			}
			Gun component = val2.ownWeapon.GetComponent<Gun>();
			if ((Object)(object)component == (Object)null || (Object)(object)component.shootPosition == (Object)null || ((object)component).GetType().Name != "SimulatedGun")
			{
				return;
			}
			Gun val3 = ((!((Object)(object)val2.ownPlayer.data != (Object)null)) ? null : val2.ownPlayer.data.weaponHandler?.gun);
			if (!((Object)(object)val3 == (Object)null) && !((Object)(object)val3.shootPosition == (Object)null))
			{
				Vector3 position = Mirror(((Component)val3).transform.position);
				Vector3 position2 = Mirror(val3.shootPosition.position);
				if (flag)
				{
					StartMirroredBladeTracking(val3);
				}
				Transform val4 = GetMirrorAnchor();
				val4.position = position2;
				__state = new SwapState
				{
					Gun = component,
					OriginalShootPosition = component.shootPosition,
					OriginalOwnWeaponPosition = ((Component)component).transform.position
				};
				((Component)component).transform.position = position;
				component.shootPosition = val4;
			}
		}

		private static void Postfix(SwapState __state)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			if (__state != null && !((Object)(object)__state.Gun == (Object)null))
			{
				__state.Gun.shootPosition = __state.OriginalShootPosition;
				((Component)__state.Gun).transform.position = __state.OriginalOwnWeaponPosition;
			}
		}

		private static Transform GetMirrorAnchor()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			if ((Object)(object)mirrorAnchor == (Object)null)
			{
				GameObject val = new GameObject("CustomCardPack_MirrorShootAnchor");
				Object.DontDestroyOnLoad((Object)(object)val);
				mirrorAnchor = val.transform;
			}
			return mirrorAnchor;
		}
	}
	[HarmonyPatch(typeof(Gun), "Attack")]
	internal static class MirrorMageRehookPatch
	{
		private static Type mirrorMonoType;

		private static FieldInfo gunField;

		private static MethodInfo onShootMethod;

		private static bool reflectionResolved;

		private static void Prefix(Gun __instance)
		{
			try
			{
				Player val = (((Object)(object)__instance != (Object)null) ? __instance.player : null);
				if ((Object)(object)val == (Object)null || !HasMirrorMage(val) || !ResolveReflectedMembers())
				{
					return;
				}
				Component componentInChildren = ((Component)val).GetComponentInChildren(mirrorMonoType);
				if ((Object)(object)componentInChildren == (Object)null)
				{
					return;
				}
				object? value = gunField.GetValue(componentInChildren);
				Gun val2 = (Gun)((value is Gun) ? value : null);
				if (!((Object)(object)val2 == (Object)(object)__instance))
				{
					Action<GameObject> action = (Action<GameObject>)Delegate.CreateDelegate(typeof(Action<GameObject>), componentInChildren, onShootMethod);
					if ((Object)(object)val2 != (Object)null)
					{
						val2.ShootPojectileAction = (Action<GameObject>)Delegate.Remove(val2.ShootPojectileAction, action);
					}
					__instance.ShootPojectileAction = (Action<GameObject>)Delegate.Combine(__instance.ShootPojectileAction, action);
					gunField.SetValue(componentInChildren, __instance);
					Plugin.DiagLog("MirrorMageRehookPatch: re-pointed Mirror_Mono from stale gun '" + (((Object)(object)val2 != (Object)null) ? ((Object)val2).name : "<null>") + "' to current gun '" + ((Object)__instance).name + "'");
				}
			}
			catch (Exception ex)
			{
				Plugin.DiagLog("MirrorMageRehookPatch.Prefix threw - " + ex);
			}
		}

		private static bool HasMirrorMage(Player player)
		{
			return (Object)(object)player.data != (Object)null && player.data.currentCards != null && player.data.currentCards.Any((CardInfo c) => (Object)(object)c != (Object)null && c.cardName == "Mirror Mage");
		}

		private static bool ResolveReflectedMembers()
		{
			if (reflectionResolved)
			{
				return mirrorMonoType != null;
			}
			reflectionResolved = true;
			mirrorMonoType = AccessTools.TypeByName("RSClasses.MonoBehaviours.Mirror_Mono");
			if (mirrorMonoType == null)
			{
				return false;
			}
			gunField = AccessTools.Field(mirrorMonoType, "gun");
			onShootMethod = AccessTools.Method(mirrorMonoType, "OnShootProjectileAction", (Type[])null, (Type[])null);
			if (gunField == null || onShootMethod == null)
			{
				mirrorMonoType = null;
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(Gun), "Attack")]
	internal static class MonkModeNoFirePatch
	{
		private static bool Prefix(Gun __instance)
		{
			if ((Object)(object)__instance.player == (Object)null)
			{
				return true;
			}
			return (Object)(object)((Component)__instance.player).GetComponent<MonkModeController>() == (Object)null;
		}
	}
	[HarmonyPatch(typeof(ProjectileHit), "RPCA_DoHit")]
	internal static class OrbitalStrikePatch
	{
		private static void Postfix(ProjectileHit __instance, Vector2 hitPoint, bool wasBlocked)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			if (!wasBlocked && !((Object)(object)__instance.ownPlayer == (Object)null))
			{
				OrbitalStrikeController component = ((Component)__instance.ownPlayer).GetComponent<OrbitalStrikeController>();
				if (!((Object)(object)component == (Object)null) && component.TryConsumeCooldown())
				{
					OrbitalStrikeWatcher orbitalStrikeWatcher = new GameObject("OrbitalStrikeWatcher").AddComponent<OrbitalStrikeWatcher>();
					orbitalStrikeWatcher.Init(__instance.ownPlayer, Vector2.op_Implicit(hitPoint), __instance.damage * 10f);
				}
			}
		}
	}
	[HarmonyPatch(typeof(HealthHandler), "DoDamage")]
	internal static class TaumanDamagePatch
	{
		private const float BonusMultiplier = 1.5f;

		private static void Prefix(ref Vector2 damage, Player damagingPlayer, Player ___player)
		{
			//IL_0044: 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_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: 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)
			if (!((Object)(object)damagingPlayer == (Object)null) && !((Object)(object)___player == (Object)null) && !((Object)(object)damagingPlayer == (Object)(object)___player) && HasTauman(damagingPlayer))
			{
				Color color = PlayerManager.instance.GetColorFromPlayer(damagingPlayer.playerID).color;
				Color color2 = PlayerManager.instance.GetColorFromPlayer(___player.playerID).color;
				if (((Color)(ref color2)).grayscale < ((Color)(ref color)).grayscale)
				{
					damage *= 1.5f;
				}
			}
		}

		private static bool HasTauman(Player player)
		{
			if ((Object)(object)player.data == (Object)null || player.data.currentCards == null || (Object)(object)TaumanCard.RegisteredCardInfo == (Object)null)
			{
				return false;
			}
			List<CardInfo> currentCards = player.data.currentCards;
			for (int i = 0; i < currentCards.Count; i++)
			{
				if ((Object)(object)currentCards[i] == (Object)(object)TaumanCard.RegisteredCardInfo)
				{
					return true;
				}
			}
			return false;
		}
	}
}
namespace CustomCardPack.Components
{
	internal sealed class AlladarShockwaveController : MonoBehaviour
	{
		private const float ShockwaveRadius = 8f;

		private const float StunSecondsPerStack = 1f;

		private const float DamagePercentOfCurrentHealth = 0.15f;

		private const float VisualLifetime = 0.45f;

		private const float ChordVolume = 0.45f;

		private Player ownerPlayer;

		private Block ownerBlock;

		public int StackCount;

		public void Init(Player player, Block block)
		{
			ownerPlayer = player;
			ownerBlock = block;
			block.BlockAction = (Action<BlockTriggerType>)Delegate.Combine(block.BlockAction, new Action<BlockTriggerType>(OnBlock));
		}

		private void OnDestroy()
		{
			if ((Object)(object)ownerBlock != (Object)null)
			{
				Block obj = ownerBlock;
				obj.BlockAction = (Action<BlockTriggerType>)Delegate.Remove(obj.BlockAction, new Action<BlockTriggerType>(OnBlock));
			}
		}

		private void OnBlock(BlockTriggerType triggerType)
		{
			//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_0037: 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_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ownerPlayer == (Object)null)
			{
				return;
			}
			Vector3 position = ((Component)ownerPlayer).transform.position;
			float num = 1f * (float)StackCount;
			SpawnShockwaveVisual(position);
			PlayShockwaveSound(position);
			List<Player> players = PlayerManager.instance.players;
			for (int i = 0; i < players.Count; i++)
			{
				Player val = players[i];
				if (!((Object)(object)val == (Object)(object)ownerPlayer) && !((Object)(object)val.data == (Object)null) && !val.data.dead && val.teamID != ownerPlayer.teamID && !(Vector3.Distance(((Component)val).transform.position, position) > 8f))
				{
					CharacterData data = val.data;
					HealthHandler component = ((Component)val).GetComponent<HealthHandler>();
					data.stunHandler.AddStun(num);
					float num2 = data.health * 0.15f;
					((Damagable)component).TakeDamage(new Vector2(num2, 0f), Vector2.op_Implicit(position), (GameObject)null, (Player)null, true, true);
				}
			}
		}

		private void SpawnShockwaveVisual(Vector3 origin)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("AlladarShockwave");
			val.transform.position = origin;
			ShockwaveRing shockwaveRing = val.AddComponent<ShockwaveRing>();
			shockwaveRing.Initialize(8f, 0.45f);
		}

		private void PlayShockwaveSound(Vector3 origin)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("AlladarShockwaveSound");
			val.transform.position = origin;
			AudioSource val2 = val.AddComponent<AudioSource>();
			val2.spatialBlend = 0f;
			val2.volume = 0.45f;
			val2.clip = GuitarChord.Create();
			val2.Play();
			Object.Destroy((Object)(object)val, val2.clip.length);
		}
	}
	internal sealed class ShockwaveRing : MonoBehaviour
	{
		private LineRenderer line;

		private float radius;

		private float lifetime;

		private float elapsed;

		public void Initialize(float targetRadius, float duration)
		{
			//IL_0084: 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)
			radius = targetRadius;
			lifetime = duration;
			line = ((Component)this).gameObject.AddComponent<LineRenderer>();
			line.loop = true;
			line.useWorldSpace = false;
			line.positionCount = 48;
			line.startWidth = 0.16f;
			line.endWidth = 0.16f;
			line.startColor = new Color(1f, 0.25f, 0.1f, 0.9f);
			line.endColor = new Color(1f, 0.75f, 0.2f, 0.1f);
			((Renderer)line).material = EffectMaterials.SpritesDefault;
		}

		private void Update()
		{
			//IL_0078: 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_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			elapsed += Time.deltaTime;
			float num = Mathf.Clamp01(elapsed / lifetime);
			float num2 = Mathf.Lerp(0.25f, radius, num);
			for (int i = 0; i < line.positionCount; i++)
			{
				float num3 = (float)i * MathF.PI * 2f / (float)line.positionCount;
				line.SetPosition(i, new Vector3(Mathf.Cos(num3) * num2, Mathf.Sin(num3) * num2, 0f));
			}
			Color val = Color.Lerp(new Color(1f, 0.25f, 0.1f, 0.9f), new Color(1f, 0.25f, 0.1f, 0f), num);
			line.startColor = val;
			line.endColor = val;
			if (num >= 1f)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
		}
	}
	internal static class GuitarChord
	{
		private const int SampleRate = 44100;

		private const float Duration = 0.8f;

		private static AudioClip cached;

		public static AudioClip Create()
		{
			if ((Object)(object)cached != (Object)null)
			{
				return cached;
			}
			int num = Mathf.CeilToInt(35280f);
			AudioClip val = AudioClip.Create("AlladarGuitarChord", num, 1, 44100, false);
			float[] array = new float[num];
			float[] array2 = new float[4] { 164.81f, 246.94f, 329.63f, 415.3f };
			for (int i = 0; i < num; i++)
			{
				float num2 = (float)i / 44100f;
				float num3 = Mathf.Exp(-4.8f * num2) * Mathf.Clamp01(num2 * 220f);
				float num4 = 0f;
				foreach (float num5 in array2)
				{
					float num6 = num2 * num5 * MathF.PI * 2f;
					num4 += Mathf.Sin(num6) + 0.35f * Mathf.Sin(num6 * 2f) + 0.15f * Mathf.Sin(num6 * 3f);
				}
				array[i] = num4 / (float)array2.Length * num3;
			}
			val.SetData(array, 0);
			cached = val;
			return val;
		}
	}
	internal class CatAllergyWatcher : MonoBehaviour
	{
		private const float Range = 5f;

		private const float DamagePerCatPerSecond = 3f;

		private Player ownerPlayer;

		private CharacterData ownerData;

		public void Init(Player owner)
		{
			ownerPlayer = owner;
			ownerData = owner.data;
		}

		private void Update()
		{
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ownerPlayer == (Object)null || (Object)(object)ownerData == (Object)null || ownerData.dead)
			{
				return;
			}
			int num = 0;
			List<Player> players = PlayerManager.instance.players;
			for (int i = 0; i < players.Count; i++)
			{
				Player val = players[i];
				if (!((Object)(object)val == (Object)(object)ownerPlayer) && !((Object)(object)val.data == (Object)null) && !(Vector3.Distance(((Component)val).transform.position, ((Component)ownerPlayer).transform.position) > 5f))
				{
					num += CatUtils.CountCats(val.data);
				}
			}
			if (num > 0)
			{
				float num2 = (float)num * 3f * TimeHandler.deltaTime;
				ownerData.health = Mathf.Max(1f, ownerData.health - num2);
			}
		}
	}
	internal sealed class EchoTeleportController : MonoBehaviour
	{
		private const float EchoLifetime = 1f;

		private const float TrailDuration = 1f;

		private const int WallIgnoreFrames = 5;

		public int StackCount;

		private Player ownerPlayer;

		private Block ownerBlock;

		private PlayerCollision ownerCollision;

		private Traverse lastPosField;

		private const float MirrorAxisX = 0f;

		public void Init(Player player, Block block)
		{
			ownerPlayer = player;
			ownerBlock = block;
			ownerCollision = FindCollision(player);
			if ((Object)(object)ownerCollision != (Object)null)
			{
				lastPosField = Traverse.Create((object)ownerCollision).Field("lastPos");
			}
			else
			{
				Debug.LogWarning("[CustomCardPack] Echo Teleport could not find this player's PlayerCollision - the blink will be resolved by swept collision and fling the player. Please report this.");
			}
			block.BlockAction = (Action<BlockTriggerType>)Delegate.Combine(block.BlockAction, new Action<BlockTriggerType>(OnBlock));
		}

		private void OnDestroy()
		{
			if ((Object)(object)ownerBlock != (Object)null)
			{
				Block obj = ownerBlock;
				obj.BlockAction = (Action<BlockTriggerType>)Delegate.Remove(obj.BlockAction, new Action<BlockTriggerType>(OnBlock));
			}
		}

		private void OnBlock(BlockTriggerType triggerType)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)ownerPlayer == (Object)null) && StackCount > 0)
			{
				Vector3 position = ((Component)ownerPlayer).transform.position;
				EchoGhost.Spawn(position, 1f);
				EchoTrail.Attach(ownerPlayer, 1f);
				PhotonView val = (((Object)(object)ownerPlayer.data != (Object)null) ? ownerPlayer.data.view : null);
				if (!((Object)(object)val != (Object)null) || val.IsMine)
				{
					Blink(GetMirrorTarget());
				}
			}
		}

		private void Blink(Vector2 target)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: 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_006b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ownerCollision != (Object)null)
			{
				ownerCollision.IgnoreWallForFrames(5);
			}
			((Component)ownerPlayer).transform.position = new Vector3(target.x, target.y, ((Component)ownerPlayer).transform.position.z);
			if (lastPosField != null)
			{
				lastPosField.SetValue((object)target);
			}
		}

		private Vector2 GetMirrorTarget()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ((Component)ownerPlayer).transform.position;
			float mirrorAxisX = GetMirrorAxisX();
			return new Vector2(2f * mirrorAxisX - position.x, position.y);
		}

		private static float GetMirrorAxisX()
		{
			return 0f;
		}

		private static PlayerCollision FindCollision(Player player)
		{
			PlayerCollision componentInChildren = ((Component)player).GetComponentInChildren<PlayerCollision>(true);
			if ((Object)(object)componentInChildren == (Object)null && (Object)(object)player.data != (Object)null)
			{
				componentInChildren = ((Component)player.data).GetComponentInChildren<PlayerCollision>(true);
			}
			if ((Object)(object)componentInChildren == (Object)null && (Object)(object)((Component)player).transform != (Object)null && (Object)(object)((Component)player).transform.root != (Object)null)
			{
				componentInChildren = ((Component)((Component)player).transform.root).GetComponentInChildren<PlayerCollision>(true);
			}
			return componentInChildren;
		}
	}
	internal sealed class EchoGhost : MonoBehaviour
	{
		private static readonly Color EchoColor = new Color(0.35f, 0.75f, 1f, 0.85f);

		private const int Segments = 32;

		private const int SortingOrder = 1000;

		private float lifetime;

		private float elapsed;

		private float radius;

		private LineRenderer line;

		public static EchoGhost Spawn(Vector3 position, float lifetime, float radius = 0.45f)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("EchoGhost");
			val.transform.position = position;
			EchoGhost echoGhost = val.AddComponent<EchoGhost>();
			echoGhost.lifetime = Mathf.Max(0.01f, lifetime);
			echoGhost.radius = radius;
			return echoGhost;
		}

		private void Start()
		{
			//IL_0092: 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)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			line = ((Component)this).gameObject.AddComponent<LineRenderer>();
			line.loop = true;
			line.useWorldSpace = false;
			line.positionCount = 32;
			line.startWidth = radius * 2f;
			line.endWidth = radius * 2f;
			((Renderer)line).material = EffectMaterials.SpritesDefault;
			((Renderer)line).sortingOrder = 1000;
			line.startColor = EchoColor;
			line.endColor = EchoColor;
			for (int i = 0; i < 32; i++)
			{
				float num = (float)i * MathF.PI * 2f / 32f;
				line.SetPosition(i, new Vector3(Mathf.Cos(num) * radius, Mathf.Sin(num) * radius, 0f));
			}
		}

		private void Update()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			elapsed += Time.deltaTime;
			float num = Mathf.Clamp01(elapsed / lifetime);
			if ((Object)(object)line != (Object)null)
			{
				Color echoColor = EchoColor;
				echoColor.a *= 1f - num;
				line.startColor = echoColor;
				line.endColor = echoColor;
			}
			if (num >= 1f)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
		}
	}
	internal sealed class EchoTrail : MonoBehaviour
	{
		private const float SampleInterval = 0.04f;

		private const float SampleLifetime = 0.35f;

		private const float SampleRadius = 0.22f;

		private float remaining;

		private float sinceSample;

		public static void Attach(Player player, float duration)
		{
			if (!((Object)(object)player == (Object)null))
			{
				EchoTrail echoTrail = ((Component)player).gameObject.GetComponent<EchoTrail>();
				if ((Object)(object)echoTrail == (Object)null)
				{
					echoTrail = ((Component)player).gameObject.AddComponent<EchoTrail>();
				}
				echoTrail.remaining = Mathf.Max(echoTrail.remaining, duration);
			}
		}

		private void Update()
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			if (!(remaining <= 0f))
			{
				remaining -= Time.deltaTime;
				sinceSample += Time.deltaTime;
				if (!(sinceSample < 0.04f))
				{
					sinceSample = 0f;
					EchoGhost.Spawn(((Component)this).transform.position, 0.35f, 0.22f);
				}
			}
		}
	}
	internal sealed class HealthDrainWatcher : MonoBehaviour
	{
		public const float DrainFractionPerSecond = 0.015f;

		private static readonly bool Lethal = true;

		private const float TickInterval = 1f;

		public int Stacks;

		private Player ownerPlayer;

		private CharacterData ownerData;

		private HealthHandler ownerHealth;

		private float sinceLastTick;

		public void Init(Player owner)
		{
			ownerPlayer = owner;
			ownerData = owner.data;
			ownerHealth = ((Component)owner).GetComponent<HealthHandler>();
		}

		private void Update()
		{
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ownerPlayer == (Object)null || (Object)(object)ownerData == (Object)null || ownerData.dead || Stacks <= 0)
			{
				return;
			}
			sinceLastTick += TimeHandler.deltaTime;
			if (sinceLastTick < 1f)
			{
				return;
			}
			sinceLastTick -= 1f;
			float num = ownerData.maxHealth * 0.015f * (float)Stacks;
			if (!(num <= 0f))
			{
				if (!Lethal)
				{
					ownerData.health = Mathf.Max(1f, ownerData.health - num);
				}
				else if (!((Object)(object)ownerHealth == (Object)null))
				{
					((Damagable)ownerHealth).TakeDamage(new Vector2(0f, num), Vector2.op_Implicit(((Component)ownerPlayer).transform.position), (GameObject)null, (Player)null, true, true);
				}
			}
		}
	}
	internal sealed class HexBlockFreezeController : MonoBehaviour
	{
		private const float FreezeRadius = 8f;

		private const float FreezeSecondsPerStack = 1.5f;

		public int StackCount;

		private Player ownerPlayer;

		private Block ownerBlock;

		public void Init(Player player, Block block)
		{
			ownerPlayer = player;
			ownerBlock = block;
			block.BlockAction = (Action<BlockTriggerType>)Delegate.Combine(block.BlockAction, new Action<BlockTriggerType>(OnBlock));
		}

		private void OnDestroy()
		{
			if ((Object)(object)ownerBlock != (Object)null)
			{
				Block obj = ownerBlock;
				obj.BlockAction = (Action<BlockTriggerType>)Delegate.Remove(obj.BlockAction, new Action<BlockTriggerType>(OnBlock));
			}
		}

		private void OnBlock(BlockTriggerType triggerType)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ownerPlayer == (Object)null || StackCount <= 0)
			{
				return;
			}
			Vector3 position = ((Component)ownerPlayer).transform.position;
			float num = 1.5f * (float)StackCount;
			List<Player> players = PlayerManager.instance.players;
			for (int i = 0; i < players.Count; i++)
			{
				Player val = players[i];
				if (!((Object)(object)val == (Object)(object)ownerPlayer) && !((Object)(object)val.data == (Object)null) && !val.data.dead && val.teamID != ownerPlayer.teamID && !(Vector3.Distance(((Component)val).transform.position, position) > 8f))
				{
					val.data.stunHandler.AddStun(num);
				}
			}
		}
	}
	internal sealed class KachowBlockController : MonoBehaviour
	{
		private const float SearchRadius = 20f;

		private const float CarSpeed = 15f;

		private const float CarHitRadius = 1.3f;

		private const float KnockbackForce = 30000f;

		private const float FlyingDuration = 1f;

		private const float CarMaxLifetime = 1f;

		private const float SummonCooldownSeconds = 1f;

		public int StackCount;

		private Player ownerPlayer;

		private Block ownerBlock;

		private Sprite carSprite;

		private AudioClip summonSound;

		private AudioClip hitSound;

		private float cooldownRemaining;

		public void Init(Player player, Block block, Sprite carSprite, AudioClip summonSound, AudioClip hitSound)
		{
			ownerPlayer = player;
			ownerBlock = block;
			this.carSprite = carSprite;
			this.summonSound = summonSound;
			this.hitSound = hitSound;
			block.BlockAction = (Action<BlockTriggerType>)Delegate.Combine(block.BlockAction, new Action<BlockTriggerType>(OnBlock));
		}

		private void OnDestroy()
		{
			if ((Object)(object)ownerBlock != (Object)null)
			{
				Block obj = ownerBlock;
				obj.BlockAction = (Action<BlockTriggerType>)Delegate.Remove(obj.BlockAction, new Action<BlockTriggerType>(OnBlock));
			}
		}

		private void Update()
		{
			if (cooldownRemaining > 0f)
			{
				cooldownRemaining -= TimeHandler.deltaTime;
			}
		}

		private void OnBlock(BlockTriggerType triggerType)
		{
			//IL_003f: 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_0046: 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_0073: Expected O, but got Unknown
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)ownerPlayer == (Object)null) && StackCount > 0 && !(cooldownRemaining > 0f))
			{
				Vector3 position = ((Component)ownerPlayer).transform.position;
				Player val = FindNearestEnemy(position);
				if (!((Object)(object)val == (Object)null))
				{
					cooldownRemaining = 1f;
					GameObject val2 = new GameObject("KachowCar");
					KachowCarController kachowCarController = val2.AddComponent<KachowCarController>();
					kachowCarController.Initialize(ownerPlayer, position, val, 15f, 1.3f, 30000f, 1f, 1f, carSprite, summonSound, hitSound);
				}
			}
		}

		private Player FindNearestEnemy(Vector3 originPos)
		{
			//IL_007f: 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)
			Player result = null;
			float num = 20f;
			List<Player> players = PlayerManager.instance.players;
			for (int i = 0; i < players.Count; i++)
			{
				Player val = players[i];
				if (!((Object)(object)val == (Object)(object)ownerPlayer) && !((Object)(object)val.data == (Object)null) && !val.data.dead && val.teamID != ownerPlayer.teamID)
				{
					float num2 = Vector3.Distance(((Component)val).transform.position, originPos);
					if (!(num2 > num))
					{
						result = val;
						num = num2;
					}
				}
			}
			return result;
		}
	}
	internal sealed class KachowCarController : MonoBehaviour
	{
		private const float ArrivalThreshold = 0.05f;

		private const float VisualSizeMultiplier = 2.2f;

		private const float HitSoundVolume = 0.7f;

		private const float SummonSoundVolume = 0.6f;

		private Player ownerPlayer;

		private Player target;

		private Vector2 direction;

		private float speed;

		private float hitRadius;

		private float knockbackForce;

		private float flyingDuration;

		private float maxLifetime;

		private Vector3 lastKnownTargetPosition;

		private float elapsed;

		private AudioClip hitSound;

		private Transform visualTransform;

		private SpriteRenderer visualRenderer;

		private readonly HashSet<Player> hitPlayers = new HashSet<Player>();

		public void Initialize(Player owner, Vector3 origin, Player targetPlayer, float carSpeed, float carHitRadius, float carKnockbackForce, float carFlyingDuration, float carMaxLifetime, Sprite carSprite, AudioClip carSummonSound, AudioClip carHitSound)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: 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_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_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Expected O, but got Unknown
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: 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_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			ownerPlayer = owner;
			target = targetPlayer;
			speed = carSpeed;
			hitRadius = carHitRadius;
			knockbackForce = carKnockbackForce;
			flyingDuration = carFlyingDuration;
			maxLifetime = carMaxLifetime;
			hitSound = carHitSound;
			lastKnownTargetPosition = ((Component)targetPlayer).transform.position;
			Vector2 val = Vector2.op_Implicit(lastKnownTargetPosition) - Vector2.op_Implicit(origin);
			direction = ((Vector2)(ref val)).normalized;
			if (direction == Vector2.zero)
			{
				direction = Vector2.up;
			}
			((Component)this).transform.position = origin;
			if ((Object)(object)carSprite != (Object)null)
			{
				GameObject val2 = new GameObject("KachowCarVisual");
				val2.transform.SetParent(((Component)this).transform, false);
				visualTransform = val2.transform;
				visualRenderer = val2.AddComponent<SpriteRenderer>();
				visualRenderer.sprite = carSprite;
				((Renderer)visualRenderer).sortingOrder = 10;
				float num = hitRadius * 2f * 2.2f;
				Bounds bounds = carSprite.bounds;
				Vector3 size = ((Bounds)(ref bounds)).size;
				float num2 = num / Mathf.Max(size.x, size.y);
				val2.transform.localScale = Vector3.one * num2;
				UpdateVisualOrientation();
			}
			if ((Object)(object)carSummonSound != (Object)null)
			{
				AudioSource val3 = ((Component)this).gameObject.AddComponent<AudioSource>();
				val3.spatialBlend = 0f;
				val3.volume = 0.6f;
				val3.clip = carSummonSound;
				val3.Play();
			}
		}

		private void Update()
		{
			//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_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_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: 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_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: 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)
			//IL_00f9: 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_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			elapsed += Time.deltaTime;
			if ((Object)(object)target != (Object)null && (Object)(object)target.data != (Object)null && !target.data.dead)
			{
				lastKnownTargetPosition = ((Component)target).transform.position;
			}
			Vector2 val = Vector2.op_Implicit(lastKnownTargetPosition) - Vector2.op_Implicit(((Component)this).transform.position);
			if (val != Vector2.zero)
			{
				direction = ((Vector2)(ref val)).normalized;
				UpdateVisualOrientation();
			}
			Vector3 val2 = Vector2.op_Implicit(direction) * speed * Time.deltaTime;
			((Component)this).transform.position = ((((Vector3)(ref val2)).magnitude >= ((Vector2)(ref val)).magnitude) ? lastKnownTargetPosition : (((Component)this).transform.position + val2));
			CheckForHits();
			if (Vector3.Distance(((Component)this).transform.position, lastKnownTargetPosition) <= 0.05f || elapsed >= maxLifetime)
			{
				Crash();
			}
		}

		private void UpdateVisualOrientation()
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)visualTransform == (Object)null))
			{
				float num = Mathf.Atan2(direction.y, direction.x) * 57.29578f;
				bool flag = num > 90f || num < -90f;
				visualRenderer.flipX = flag;
				float num2 = (flag ? (num - Mathf.Sign(num) * 180f) : num);
				visualTransform.localRotation = Quaternion.Euler(0f, 0f, num2);
			}
		}

		private void CheckForHits()
		{
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: 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_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: 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_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			List<Player> players = PlayerManager.instance.players;
			for (int i = 0; i < players.Count; i++)
			{
				Player val = players[i];
				if (!((Object)(object)val == (Object)(object)ownerPlayer) && !((Object)(object)val.data == (Object)null) && !val.data.dead && val.teamID != ownerPlayer.teamID && !hitPlayers.Contains(val) && !(Vector3.Distance(((Component)val).transform.position, ((Component)this).transform.position) > hitRadius))
				{
					hitPlayers.Add(val);
					Vector2 val2 = Vector2.op_Implicit(((Component)val).transform.position) - Vector2.op_Implicit(((Component)this).transform.position);
					Vector2 normalized = ((Vector2)(ref val2)).normalized;
					if (normalized == Vector2.zero)
					{
						normalized = direction;
					}
					HealthHandler component = ((Component)val).GetComponent<HealthHandler>();
					component.CallTakeForce(normalized * knockbackForce, (ForceMode2D)1, true, true, flyingDuration);
					SoundUtils.PlayOneShot(hitSound, ((Component)this).transform.position, 0.7f);
				}
			}
		}

		private void Crash()
		{
			Object.Destroy((Object)(object)((Component)this).gameObject);
		}
	}
	internal sealed class KonBiteWatcher : MonoBehaviour
	{
		private const float HoldSeconds = 1.5f;

		private const float BiteDuration = 1.5f;

		private const float OpenRadius = 7f;

		private const float ClosedRadius = 0.6f;

		private const int AttackStartFrameIndex = 5;

		private const float PullTickInterval = 0.1f;

		private const float PullForceStart = 8000f;

		private const float PullForceEnd = 40000f;

		private const float BiteDamageBaseline = 40f;

		private const float BiteDamageMultiplier = 2f;

		private const int HoleIgnoreWallFrames = 40;

		private static readonly Color MouthColor = new Color(0.5f, 0.03f, 0.03f, 0.85f);

		private Player ownerPlayer;

		private Player targetPlayer;

		private Vector3 strikeCenter;

		private float elapsed;

		private float sinceHold;

		private float sincePull;

		private float attackStartElapsed;

		private float preAttackDuration;

		private float holdSecondsUsed;

		private bool holding = true;

		private bool detonated;

		private bool konSoundPlayed;

		private float sinceInit;

		private KonMouthVisual visual;

		private AudioClip konSound;

		private const float KonSoundDelaySeconds = 1f;

		public void Init(Player owner, Player target, Sprite grabSprite, Sprite[] animationFrames, AudioClip konSound)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			ownerPlayer = owner;
			targetPlayer = target;
			strikeCenter = ((Component)target).transform.position;
			this.konSound = konSound;
			int num = ((animationFrames != null) ? animationFrames.Length : 0);
			float num2;
			if (num > 0)
			{
				num2 = 1.5f / (float)num;
				attackStartElapsed = Mathf.Min(1.5f, 5f * num2);
			}
			else
			{
				num2 = 0f;
				attackStartElapsed = 1.5f;
				holding = false;
			}
			holdSecondsUsed = (holding ? 1.5f : 0f);
			preAttackDuration = holdSecondsUsed + attackStartElapsed;
			visual = new GameObject("KonMouth").AddComponent<KonMouthVisual>();
			visual.Initialize(strikeCenter, 7f, 0.6f, 1.5f, MouthColor, grabSprite, animationFrames, num2);
			if (!holding)
			{
				visual.CommitAndStartAnimating(strikeCenter);
			}
		}

		private void Update()
		{
			sinceInit += TimeHandler.deltaTime;
			if (!konSoundPlayed && sinceInit >= 1f)
			{
				konSoundPlayed = true;
				PlayKonSound();
			}
			if (holding)
			{
				UpdateHold();
				return;
			}
			elapsed += TimeHandler.deltaTime;
			float num = Mathf.Clamp01(elapsed / 1.5f);
			float num2 = Mathf.Lerp(7f, 0.6f, num);
			if (!detonated)
			{
				if (elapsed >= attackStartElapsed)
				{
					detonated = true;
					if ((Object)(object)visual != (Object)null)
					{
						visual.RevertToStandardScale();
					}
					Detonate(num2);
				}
				else
				{
					TickPull(num2, holdSecondsUsed + elapsed);
				}
			}
			if (elapsed >= 1.5f)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
		}

		private void UpdateHold()
		{
			//IL_0049: 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_0090: 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)
			if ((Object)(object)targetPlayer != (Object)null && (Object)(object)targetPlayer.data != (Object)null && !targetPlayer.data.dead)
			{
				strikeCenter = ((Component)targetPlayer).transform.position;
			}
			sinceHold += TimeHandler.deltaTime;
			float holdProgress = Mathf.Clamp01(sinceHold / 1.5f);
			if ((Object)(object)visual != (Object)null)
			{
				visual.SetTrackedPosition(strikeCenter, holdProgress);
			}
			TickPull(7f, sinceHold);
			if (!(sinceHold < 1.5f))
			{
				holding = false;
				if ((Object)(object)visual != (Object)null)
				{
					visual.CommitAndStartAnimating(strikeCenter);
				}
			}
		}

		private void PlayKonSound()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			SoundUtils.PlayOneShot(konSound, strikeCenter);
		}

		private void TickPull(float captureRadius, float continuousElapsedForRamp)
		{
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			sincePull += TimeHandler.deltaTime;
			bool flag = sincePull >= 0.1f;
			if (flag)
			{
				sincePull = 0f;
			}
			float num = ((preAttackDuration > 0f) ? Mathf.Clamp01(continuousElapsedForRamp / preAttackDuration) : 1f);
			float force = Mathf.Lerp(8000f, 40000f, num);
			List<Player> players = PlayerManager.instance.players;
			for (int i = 0; i < players.Count; i++)
			{
				Player val = players[i];
				if (!((Object)(object)val == (Object)(object)ownerPlayer) && !((Object)(object)val.data == (Object)null) && !val.data.dead && (!((Object)(object)ownerPlayer != (Object)null) || val.teamID != ownerPlayer.teamID) && !(Vector3.Distance(((Component)val).transform.position, strikeCenter) > captureRadius) && flag)
				{
					PullToward(val, force, captureRadius);
				}
			}
		}

		private void PullToward(Player target, float force, float captureRadius)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = Vector2.op_Implicit(strikeCenter) - Vector2.op_Implicit(((Component)target).transform.position);
			float magnitude = ((Vector2)(ref val)).magnitude;
			if (!(magnitude <= 0.0001f))
			{
				float num = Mathf.Clamp01(magnitude / captureRadius);
				float num2 = force * num;
				HealthHandler component = ((Component)target).GetComponent<HealthHandler>();
				component.CallTakeForce(((Vector2)(ref val)).normalized * num2, (ForceMode2D)1, true, true, 0f);
			}
		}

		private void Detonate(float finalRadius)
		{
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: 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)
			Gun val = (((Object)(object)ownerPlayer != (Object)null && (Object)(object)ownerPlayer.data != (Object)null && (Object)(object)ownerPlayer.data.weaponHandler != (Object)null) ? ownerPlayer.data.weaponHandler.gun : null);
			float num = 80f * (((Object)(object)val != (Object)null) ? val.damage : 1f);
			List<Player> players = PlayerManager.instance.players;
			for (int i = 0; i < players.Count; i++)
			{
				Player val2 = players[i];
				if (!((Object)(object)val2 == (Object)(object)ownerPlayer) && !((Object)(object)val2.data == (Object)null) && !val2.data.dead && (!((Object)(object)ownerPlayer != (Object)null) || val2.teamID != ownerPlayer.teamID) && !(Vector3.Distance(((Component)val2).transform.position, strikeCenter) > finalRadius))
				{
					HealthHandler component = ((Component)val2).GetComponent<HealthHandler>();
					((Damagable)component).TakeDamage(new Vector2(num, 0f), Vector2.op_Implicit(strikeCenter), (GameObject)null, ownerPlayer, true, true);
					PlayerCollision val3 = FindCollision(val2);
					if ((Object)(object)val3 != (Object)null)
					{
						val3.IgnoreWallForFrames(40);
					}
				}
			}
		}

		private static PlayerCollision FindCollision(Player player)
		{
			PlayerCollision componentInChildren = ((Component)player).GetComponentInChildren<PlayerCollision>(true);
			if ((Object)(object)componentInChildren == (Object)null && (Object)(object)player.data != (Object)null)
			{
				componentInChildren = ((Component)player.data).GetComponentInChildren<PlayerCollision>(true);
			}
			if ((Object)(object)componentInChildren == (Object)null && (Object)(object)((Component)player).transform != (Object)null && (Object)(object)((Component)player).transform.root != (Object)null)
			{
				componentInChildren = ((Component)((Component)player).transform.root).GetComponentInChildren<PlayerCollision>(true);
			}
			return componentInChildren;
		}
	}
	internal sealed class KonMouthVisual : MonoBehaviour
	{
		private const int Segments = 32;

		private const int SortingOrder = 1000;

		private const float VisualSizeMultiplier = 2.5f;

		private const float VisualMinScaleRatio = 0.65f;

		private float openRadius;

		private float closedRadius;

		private float duration;

		private float elapsed;

		private bool animating;

		private float currentVisualRadius;

		private LineRenderer line;

		private SpriteRenderer spriteRenderer;

		private Sprite grabSprite;

		private Sprite[] frames;

		private float secondsPerFrame;

		private float baseSpriteSize;

		private Transform debugMarker;

		private const float DebugMarkerRadius = 0.4f;

		public void Initialize(Vector3 center, float openRadius, float closedRadius, float duration, Color color, Sprite grabSprite, Sprite[] frames, float secondsPerFrame)
		{
			//IL_0035: 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_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			this.openRadius = openRadius;
			this.closedRadius = closedRadius;
			this.duration = duration;
			this.grabSprite = grabSprite;
			this.frames = frames;
			this.secondsPerFrame = secondsPerFrame;
			((Component)this).transform.position = center;
			Sprite val = (((Object)(object)grabSprite != (Object)null) ? grabSprite : FirstAvailableFrame());
			if ((Object)(object)val != (Object)null)
			{
				spriteRenderer = ((Component)this).gameObject.AddComponent<SpriteRenderer>();
				spriteRenderer.sprite = val;
				((Renderer)spriteRenderer).sortingOrder = 1000;
				Bounds bounds = val.bounds;
				Vector3 size = ((Bounds)(ref bounds)).size;
				baseSpriteSize = Mathf.Max(size.x, size.y);
				currentVisualRadius = openRadius;
				ApplyScale(currentVisualRadius);
				AddDebugPivotMarker();
			}
			else
			{
				line = ((Component)this).gameObject.AddComponent<LineRenderer>();
				line.loop = true;
				line.useWorldSpace = false;
				line.positionCount = 32;
				((Renderer)line).material = EffectMaterials.SpritesDefault;
				((Renderer)line).sortingOrder = 1000;
				line.startColor = color;
				line.endColor = color;
				currentVisualRadius = openRadius;
				Draw(currentVisualRadius);
			}
		}

		public void SetTrackedPosition(Vector3 center, float holdProgress)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			((Component)this).transform.position = center;
			currentVisualRadius = Mathf.Lerp(openRadius, closedRadius, Mathf.Clamp01(holdProgress));
			if ((Object)(object)spriteRenderer != (Object)null)
			{
				ApplyScale(currentVisualRadius);
				RefreshDebugMarkerScale();
			}
			else
			{
				Draw(currentVisualRadius);
			}
		}

		public void CommitAndStartAnimating(Vector3 center)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			((Component)this).transform.position = center;
			animating = true;
			if ((Object)(object)spriteRenderer != (Object)null)
			{
				Sprite val = FirstAvailableFrame();
				if ((Object)(object)val != (Object)null)
				{
					spriteRenderer.sprite = val;
				}
			}
		}

		public void RevertToStandardScale()
		{
			currentVisualRadius = openRadius;
			if ((Object)(object)spriteRenderer != (Object)null)
			{
				ApplyScale(currentVisualRadius);
				RefreshDebugMarkerScale();
			}
			else
			{
				Draw(currentVisualRadius);
			}
		}

		private void Update()
		{
			if (animating)
			{
				elapsed += Time.deltaTime;
				float num = Mathf.Clamp01(elapsed / duration);
				if ((Object)(object)spriteRenderer != (Object)null)
				{
					ApplyFrame();
				}
				if (num >= 1f)
				{
					Object.Destroy((Object)(object)((Component)this).gameObject);
				}
			}
		}

		private void AddDebugPivotMarker()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("KonMouth_DEBUG_Pivot");
			val.transform.SetParent(((Component)this).transform, false);
			val.transform.localPosition = Vector3.zero;
			debugMarker = val.transform;
			LineRenderer val2 = val.AddComponent<LineRenderer>();
			val2.loop = true;
			val2.useWorldSpace = false;
			val2.positionCount = 32;
			((Renderer)val2).material = EffectMaterials.SpritesDefault;
			((Renderer)val2).sortingOrder = 1001;
			val2.startColor = Color.magenta;
			val2.endColor = Color.magenta;
			val2.startWidth = 0.8f;
			val2.endWidth = 0.8f;
			for (int i = 0; i < 32; i++)
			{
				float num = (float)i * MathF.PI * 2f / 32f;
				val2.SetPosition(i, new Vector3(Mathf.Cos(num) * 0.4f, Mathf.Sin(num) * 0.4f, 0f));
			}
			RefreshDebugMarkerScale();
		}

		private void RefreshDebugMarkerScale()
		{
			//IL_001a: 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_0026: 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_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)debugMarker == (Object)null))
			{
				Vector3 localScale = ((Component)this).transform.localScale;
				debugMarker.localScale = new Vector3((localScale.x != 0f) ? (1f / localScale.x) : 1f, (localScale.y != 0f) ? (1f / localScale.y) : 1f, 1f);
			}
		}

		private void ApplyFrame()
		{
			if (frames != null && frames.Length != 0 && !(secondsPerFrame <= 0f))
			{
				int num = Mathf.Clamp(Mathf.FloorToInt(elapsed / secondsPerFrame), 0, frames.Length - 1);
				Sprite val = frames[num];
				if ((Object)(object)val != (Object)null)
				{
					spriteRenderer.sprite = val;
				}
			}
		}

		private Sprite FirstAvailableFrame()
		{
			if (frames == null)
			{
				return null;
			}
			for (int i = 0; i < frames.Length; i++)
			{
				if ((Object)(object)frames[i] != (Object)null)
				{
					return frames[i];
				}
			}
			return null;
		}

		private void ApplyScale(float radius)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Max(radius, openRadius * 0.65f);
			float num2 = num * 2f * 2.5f;
			float num3 = ((baseSpriteSize > 0f) ? (num2 / baseSpriteSize) : 1f);
			((Component)this).transform.localScale = Vector3.one * num3;
		}

		private void Draw(float radius)
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			line.startWidth = radius * 2f;
			line.endWidth = radius * 2f;
			for (int i = 0; i < 32; i++)
			{
				float num = (float)i * MathF.PI * 2f / 32f;
				line.SetPosition(i, new Vector3(Mathf.Cos(num) * radius, Mathf.Sin(num) * radius, 0f));
			}
		}
	}
	internal sealed class KonController : MonoBehaviour
	{
		public const float CooldownSeconds = 15f;

		internal const bool CooldownEnabled = true;

		public int StackCount;

		private Player ownerPlayer;

		private Block ownerBlock;

		private Sprite grabSprite;

		private Sprite[] animationFrames;

		private AudioClip konSound;

		private float cooldownRemaining;

		public void Init(Player player, Block block, Sprite grabSprite, Sprite[] animationFrames, AudioClip konSound)
		{
			ownerPlayer = player;
			ownerBlock = block;
			this.grabSprite = grabSprite;
			this.animationFrames = animationFrames;
			this.konSound = konSound;
			block.BlockAction = (Action<BlockTriggerType>)Delegate.Combine(block.BlockAction, new Action<BlockTriggerType>(OnBlock));
		}

		private void OnDestroy()
		{
			if ((Object)(object)ownerBlock != (Object)null)
			{
				Block obj = ownerBlock;
				obj.BlockAction = (Action<BlockTriggerType>)Delegate.Remove(obj.BlockAction, new Action<BlockTriggerType>(OnBlock));
			}
		}

		private void Update()
		{
			if (cooldownRemaining > 0f)
			{
				cooldownRemaining -= TimeHandler.deltaTime;
			}
		}

		private void OnBlock(BlockTriggerType triggerType)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)ownerPlayer == (Object)null) && StackCount > 0 && !(cooldownRemaining > 0f))
			{
				Player val = FindNearestEnemy();
				if (!((Object)(object)val == (Object)null))
				{
					cooldownRemaining = 15f;
					KonBiteWatcher konBiteWatcher = new GameObject("KonBiteWatcher").AddComponent<KonBiteWatcher