MFM.dll

Decompiled 5 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Logging;
using CardChoiceSpawnUniqueCardPatch.CustomCategories;
using CardThemeLib;
using ClassesManagerReborn;
using ClassesManagerReborn.Util;
using CooldownUILib;
using HarmonyLib;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using ModdingUtils.Extensions;
using ModdingUtils.MonoBehaviours;
using ModdingUtils.RoundsEffects;
using ModdingUtils.Utils;
using MrFuntikMod.Cards;
using MrFuntikMod.Effects;
using MrFuntikMod.Extensions;
using MrFuntikMod.Helper;
using MrFuntikMod.MonoBehaviors;
using MrFuntikMod.MonoBehaviours;
using MrFuntikMod.Patches;
using Photon.Pun;
using RarityLib.Utils;
using Sonigon;
using Sonigon.Internal;
using SoundImplementation;
using UnboundLib;
using UnboundLib.Cards;
using UnboundLib.GameModes;
using UnboundLib.Networking;
using UnboundLib.Utils;
using UnityEngine;
using UnityEngine.Rendering;

[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: AssemblyCompany("MFM")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+72328ba5db5caeb8b2a773723b2e441dd25a3ee4")]
[assembly: AssemblyProduct("MFM")]
[assembly: AssemblyTitle("MFM")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace MrFuntikMod
{
	internal class Assets
	{
		private const string BUNDLE_IS = "isbundle";

		private const string BUNDLE_IS_V2 = "isbundlev2";

		private const string BUNDLE_DRON = "dron-asset-2";

		private const string BUNDLE_MFM = "myasset";

		private const string BUNDLE_BFRM = "bfrm";

		private static AssetBundle _bundle;

		private static AssetBundle _bundle2;

		private static AssetBundle _bundleDron;

		private static AssetBundle _bundleMFM;

		private static AssetBundle _bundleBFRM;

		private static bool _loadAttempted;

		private static readonly Dictionary<string, GameObject> _assetCache;

		private static readonly Dictionary<string, Sprite> _spriteCache;

		private static readonly Dictionary<string, AudioClip> _audioCache;

		public static GameObject StepBackArt => SafeLoadAsset(_bundle, "isbundle", "C_StepBack");

		public static GameObject BlackPillArt => SafeLoadAsset(_bundle, "isbundle", "C_BlackPill");

		public static GameObject GymBossArt => SafeLoadAsset(_bundle, "isbundle", "C_GymBoss");

		public static GameObject TakeAimArt => SafeLoadAsset(_bundle2, "isbundlev2", "C_TakeAim");

		public static GameObject AllCardArt => SafeLoadAsset(_bundle2, "isbundlev2", "C_AllCard");

		public static GameObject NothingArt => SafeLoadAsset(_bundle2, "isbundlev2", "C_Nothing");

		public static GameObject SomethingArt => SafeLoadAsset(_bundle2, "isbundlev2", "C_Something");

		public static GameObject ItBecomesAllArt => SafeLoadAsset(_bundle2, "isbundlev2", "C_ItBecomesAll");

		public static GameObject FragileStrengthArt => SafeLoadAsset(_bundle2, "isbundlev2", "C_FragileStrength");

		public static GameObject KamikazeArt => SafeLoadAsset(_bundleDron, "dron-asset-2", "C_Kamikaze");

		public static GameObject SpeedDemonArt => SafeLoadAsset(_bundleDron, "dron-asset-2", "С_Speed_Demon");

		public static GameObject QuickReloadArt => SafeLoadAsset(_bundleDron, "dron-asset-2", "C_QuickReload");

		public static GameObject MinigunArt => SafeLoadAsset(_bundleDron, "dron-asset-2", "C_Minigun");

		public static GameObject PhoenixArt => SafeLoadAsset(_bundleDron, "dron-asset-2", "C_Phoenix");

		public static GameObject TankArt => SafeLoadAsset(_bundleDron, "dron-asset-2", "C_Tank");

		public static GameObject SprayArt => SafeLoadAsset(_bundleDron, "dron-asset-2", "C_Spray");

		public static GameObject FriendlyBounceArt => SafeLoadAsset(_bundleDron, "dron-asset-2", "C_FriendlyBounce");

		public static GameObject JumperArt => SafeLoadAsset(_bundleDron, "dron-asset-2", "C_Jumper");

		public static GameObject HealMeArt => SafeLoadAsset(_bundleDron, "dron-asset-2", "C_HealMe");

		public static GameObject ThornShieldArt => SafeLoadAsset(_bundleDron, "dron-asset-2", "C_ThornShield");

		public static GameObject SmallButToughArt => SafeLoadAsset(_bundleDron, "dron-asset-2", "C_SmallButTough");

		public static GameObject BulletTeleporterArt => SafeLoadAsset(_bundleDron, "dron-asset-2", "C_BulletTeleporter");

		public static GameObject ComeToMeArt => SafeLoadAsset(_bundleDron, "dron-asset-2", "C_ComeToMe");

		public static GameObject AntiradarArt => SafeLoadAsset(_bundleDron, "dron-asset-2", "C_Antiradar");

		public static GameObject RandomTeleportArt => SafeLoadAsset(_bundleDron, "dron-asset-2", "С_RandomTeleport");

		public static GameObject DestroyerArt => SafeLoadAsset(_bundleDron, "dron-asset-2", "C_Destroyer");

		public static Sprite GunAsset => SafeLoadSprite(_bundleDron, "dron-asset-2", "Minigun-Gun");

		public static Sprite RedSquare => SafeLoadSprite(_bundleDron, "dron-asset-2", "RedSquare");

		public static GameObject MyBulletPrefab => SafeLoadAsset(_bundleDron, "dron-asset-2", "MyBullet");

		public static GameObject CHESS_KNIGHT_Art => SafeLoadAsset(_bundleMFM, "myasset", "C_CHESS_KNIGHT");

		public static GameObject Narcissism_Art => SafeLoadAsset(_bundleMFM, "myasset", "C_narcissism");

		public static GameObject CHESS_PAWN_Art => SafeLoadAsset(_bundleMFM, "myasset", "C_CHESS_PAWN");

		public static GameObject CHESS_ROOK_Art => SafeLoadAsset(_bundleMFM, "myasset", "C_CHESS_ROOK");

		public static GameObject CHESS_BISHOP_Art => SafeLoadAsset(_bundleMFM, "myasset", "C_CHESS_BISHOP");

		public static GameObject unstable_gun_Art => SafeLoadAsset(_bundleMFM, "myasset", "C_unstable_gun");

		public static GameObject NecroCardArt => SafeLoadAsset(_bundleMFM, "myasset", "C_necro_card");

		public static GameObject Necro2CardArt => SafeLoadAsset(_bundleMFM, "myasset", "C_necro2_card");

		public static GameObject Necro3CardArt => SafeLoadAsset(_bundleMFM, "myasset", "C_necro3_card");

		public static GameObject CHESS_QUEEN_Art => SafeLoadAsset(_bundleMFM, "myasset", "C_CHESS_QUEEN");

		public static GameObject VampireCastleArt => SafeLoadAsset(_bundleMFM, "myasset", "C_VAMPIRE_CASTLE");

		public static GameObject OneShotMan_Art => SafeLoadAsset(_bundleMFM, "myasset", "C_ONESHOT_MAN");

		public static GameObject DrillHands_Art => SafeLoadAsset(_bundleMFM, "myasset", "C_DRILL_HANDS");

		public static GameObject BounceConverter_Art => SafeLoadAsset(_bundleMFM, "myasset", "C_BOUNCE_CONVERTER");

		public static GameObject PhenomenalBalance_Art => SafeLoadAsset(_bundleMFM, "myasset", "C_PHENOMENAL_BALANCE");

		public static GameObject BalanceBlock_Art => SafeLoadAsset(_bundleMFM, "myasset", "C_BALANCE_BLOCK");

		public static GameObject BalanceTank_Art => SafeLoadAsset(_bundleMFM, "myasset", "C_BALANCE_TANK");

		public static GameObject BalanceHitman_Art => SafeLoadAsset(_bundleMFM, "myasset", "C_BALANCE_HITMAN");

		public static GameObject BalanceBullets_Art => SafeLoadAsset(_bundleMFM, "myasset", "C_BALANCE_BULLETS");

		public static GameObject BalanceMayhem_Art => SafeLoadAsset(_bundleMFM, "myasset", "C_BALANCE_MAYHEM");

		public static GameObject BalanceSpeed_Art => SafeLoadAsset(_bundleMFM, "myasset", "C_BALANCE_SPEED");

		public static GameObject BalanceReload_Art => SafeLoadAsset(_bundleMFM, "myasset", "C_BALANCE_RELOAD");

		public static GameObject Fadeout_Art => SafeLoadAsset(_bundleMFM, "myasset", "C_FADEOUT");

		public static GameObject Dominion_Art => SafeLoadAsset(_bundleMFM, "myasset", "C_DOMINION");

		public static GameObject AuraBloodRot_Art => SafeLoadAsset(_bundleMFM, "myasset", "C_AURA_BLOOD_ROT");

		public static GameObject AuraBrokenBurstRot_Art => SafeLoadAsset(_bundleMFM, "myasset", "C_AURA_BROKEN_BURST");

		public static GameObject AuraColdWater_Art => SafeLoadAsset(_bundleMFM, "myasset", "C_AURA_COLD_WATER");

		public static GameObject AuraDeathSentence_Art => SafeLoadAsset(_bundleMFM, "myasset", "C_AURA_DEATH_SENTENCE");

		public static GameObject AuraHeavyHands_Art => SafeLoadAsset(_bundleMFM, "myasset", "C_AURA_HEAVY_HANDS");

		public static GameObject AuraOverheated_Art => SafeLoadAsset(_bundleMFM, "myasset", "C_AURA_OVERHEATED");

		public static GameObject AuraSlowSleep_Art => SafeLoadAsset(_bundleMFM, "myasset", "C_AURA_SLOW_SLEEP");

		public static GameObject AuraSoftRicochet_Art => SafeLoadAsset(_bundleMFM, "myasset", "C_AURA_SOFT_RICOCHET");

		public static GameObject AuraWeakening_Art => SafeLoadAsset(_bundleMFM, "myasset", "C_AURA_WEAKENING");

		public static GameObject ThunderCode_Art => SafeLoadAsset(_bundleMFM, "myasset", "C_THUNDER_CORE");

		public static GameObject EarthSpears_Art => SafeLoadAsset(_bundleMFM, "myasset", "C_EARTHSPEARS");

		public static GameObject Dancer_Art => SafeLoadAsset(_bundleMFM, "myasset", "C_DANCER");

		public static GameObject Momentum_Art => SafeLoadAsset(_bundleMFM, "myasset", "C_MOMENTUM");

		public static GameObject Aegis_Art => SafeLoadAsset(_bundleMFM, "myasset", "C_AEGIS");

		public static GameObject Immunize_Art => SafeLoadAsset(_bundleMFM, "myasset", "C_IMMUNIZE");

		public static GameObject Rooted_Art => SafeLoadAsset(_bundleMFM, "myasset", "C_ROOTED");

		public static GameObject SonicRiot_Art => SafeLoadAsset(_bundleMFM, "myasset", "C_SONIC_RIOT");

		public static GameObject ControlledFire_Art => SafeLoadAsset(_bundleMFM, "myasset", "C_CONTROLLED_FIRE");

		public static GameObject Unstoppable_Art => SafeLoadAsset(_bundleMFM, "myasset", "C_UNSTOPPABLE");

		public static GameObject SaferyDetonator_Art => SafeLoadAsset(_bundleMFM, "myasset", "C_SAFETY_DETONATOR");

		public static GameObject AntiRadar_Art => SafeLoadAsset(_bundleMFM, "myasset", "C_ANTI_RADAR");

		public static GameObject Berserker_Art => SafeLoadAsset(_bundleMFM, "myasset", "C_BERSERKER");

		public static GameObject ExecutionerArt => SafeLoadAsset(_bundleBFRM, "bfrm", "C_EXECUTIONER");

		public static AudioClip ScorpionGetOverHereSound => SafeLoadAudioClip(_bundleBFRM, "bfrm", "scorpion_get_over_here");

		public static AudioClip DemRes1 => SafeLoadAudioClip(_bundleMFM, "myasset", "dem_res_1");

		public static AudioClip DemRes2 => SafeLoadAudioClip(_bundleMFM, "myasset", "dem_rev_2");

		public static AudioClip DemRes3 => SafeLoadAudioClip(_bundleMFM, "myasset", "dem_res_3");

		public static AudioClip DemRes4 => SafeLoadAudioClip(_bundleMFM, "myasset", "dem_res_4");

		public static AudioClip DemRes5 => SafeLoadAudioClip(_bundleMFM, "myasset", "dem_res_pontiff");

		static Assets()
		{
			_loadAttempted = false;
			_assetCache = new Dictionary<string, GameObject>();
			_spriteCache = new Dictionary<string, Sprite>();
			_audioCache = new Dictionary<string, AudioClip>();
		}

		public static void PreloadBundles()
		{
			LoadBundles();
		}

		private static void LoadBundles()
		{
			if (_loadAttempted)
			{
				return;
			}
			_loadAttempted = true;
			IEnumerable<AssetBundle> allLoadedAssetBundles = AssetBundle.GetAllLoadedAssetBundles();
			foreach (AssetBundle item in allLoadedAssetBundles)
			{
				if (((Object)item).name == "isbundle")
				{
					_bundle = item;
					MrFuntikMod.Log("[MFM][Assets] isbundle already loaded, reusing");
				}
				if (((Object)item).name == "isbundlev2")
				{
					_bundle2 = item;
					MrFuntikMod.Log("[MFM][Assets] isbundlev2 already loaded, reusing");
				}
				if (((Object)item).name == "dron-asset-2")
				{
					_bundleDron = item;
					MrFuntikMod.Log("[MFM][Assets] dron-asset-2 already loaded, reusing");
				}
				if (((Object)item).name == "myasset")
				{
					_bundleMFM = item;
					MrFuntikMod.Log("[MFM][Assets] myasset already loaded, reusing");
				}
				if (((Object)item).name == "bfrm")
				{
					_bundleBFRM = item;
					MrFuntikMod.Log("[MFM][Assets] bfrm already loaded, reusing");
				}
			}
			if ((Object)(object)_bundle == (Object)null)
			{
				try
				{
					_bundle = AssetUtils.LoadAssetBundleFromResources("isbundle", typeof(MrFuntikMod).Assembly);
				}
				catch (Exception ex)
				{
					MrFuntikMod.LogError("[MFM][Assets] FAILED to load isbundle: " + ex.Message);
				}
			}
			if ((Object)(object)_bundle2 == (Object)null)
			{
				try
				{
					_bundle2 = AssetUtils.LoadAssetBundleFromResources("isbundlev2", typeof(MrFuntikMod).Assembly);
				}
				catch (Exception ex2)
				{
					MrFuntikMod.LogError("[MFM][Assets] FAILED to load isbundlev2: " + ex2.Message);
				}
			}
			if ((Object)(object)_bundleDron == (Object)null)
			{
				try
				{
					_bundleDron = AssetUtils.LoadAssetBundleFromResources("dron-asset-2", typeof(MrFuntikMod).Assembly);
				}
				catch (Exception ex3)
				{
					MrFuntikMod.LogError("[MFM][Assets] FAILED to load dron-asset-2: " + ex3.Message);
				}
			}
			if ((Object)(object)_bundleMFM == (Object)null)
			{
				try
				{
					_bundleMFM = AssetUtils.LoadAssetBundleFromResources("myasset", typeof(MrFuntikMod).Assembly);
				}
				catch (Exception ex4)
				{
					MrFuntikMod.LogError("[MFM][Assets] FAILED to load myasset: " + ex4.Message);
				}
			}
			if (!((Object)(object)_bundleBFRM == (Object)null))
			{
				return;
			}
			try
			{
				_bundleBFRM = AssetUtils.LoadAssetBundleFromResources("bfrm", typeof(MrFuntikMod).Assembly);
			}
			catch (Exception ex5)
			{
				MrFuntikMod.LogError("[MFM][Assets] FAILED to load bfrm: " + ex5.Message);
			}
		}

		private static GameObject SafeLoadAsset(AssetBundle bundle, string bundleName, string assetName)
		{
			LoadBundles();
			string key = bundleName + ":" + assetName;
			if (_assetCache.TryGetValue(key, out GameObject value))
			{
				if ((Object)(object)value != (Object)null)
				{
					return value;
				}
				_assetCache.Remove(key);
			}
			if ((Object)(object)bundle == (Object)null)
			{
				return null;
			}
			try
			{
				GameObject val = bundle.LoadAsset<GameObject>(assetName);
				if ((Object)(object)val == (Object)null)
				{
					MrFuntikMod.LogWarning("[MFM][Assets] Asset '" + assetName + "' not found in '" + bundleName + "'");
				}
				else
				{
					_assetCache[key] = val;
				}
				return val;
			}
			catch (Exception ex)
			{
				MrFuntikMod.LogError("[MFM][Assets] Exception loading '" + assetName + "': " + ex.Message);
				return null;
			}
		}

		private static Sprite SafeLoadSprite(AssetBundle bundle, string bundleName, string assetName)
		{
			LoadBundles();
			string key = bundleName + ":" + assetName;
			if (_spriteCache.TryGetValue(key, out Sprite value))
			{
				if ((Object)(object)value != (Object)null)
				{
					return value;
				}
				_spriteCache.Remove(key);
			}
			if ((Object)(object)bundle == (Object)null)
			{
				return null;
			}
			try
			{
				Sprite val = bundle.LoadAsset<Sprite>(assetName);
				if ((Object)(object)val == (Object)null)
				{
					MrFuntikMod.LogWarning("[MFM][Assets] Sprite '" + assetName + "' not found in '" + bundleName + "'");
				}
				else
				{
					_spriteCache[key] = val;
				}
				return val;
			}
			catch (Exception ex)
			{
				MrFuntikMod.LogError("[MFM][Assets] Exception loading sprite '" + assetName + "': " + ex.Message);
				return null;
			}
		}

		private static AudioClip SafeLoadAudioClip(AssetBundle bundle, string bundleName, string assetName)
		{
			LoadBundles();
			string key = bundleName + ":" + assetName;
			if (_audioCache.TryGetValue(key, out AudioClip value))
			{
				if ((Object)(object)value != (Object)null)
				{
					return value;
				}
				_audioCache.Remove(key);
			}
			if ((Object)(object)bundle == (Object)null)
			{
				return null;
			}
			try
			{
				AudioClip val = bundle.LoadAsset<AudioClip>(assetName);
				if ((Object)(object)val == (Object)null)
				{
					MrFuntikMod.LogWarning("[MFM][Assets] AudioClip '" + assetName + "' not found in '" + bundleName + "'");
				}
				else
				{
					_audioCache[key] = val;
				}
				return val;
			}
			catch (Exception ex)
			{
				MrFuntikMod.LogError("[MFM][Assets] Exception loading AudioClip '" + assetName + "': " + ex.Message);
				return null;
			}
		}
	}
	internal static class ScreenEdgeBounceHelper
	{
		private static ObjectsToSpawn _cached;

		private static ObjectsToSpawn GetSpawnObject()
		{
			if (_cached != null)
			{
				return _cached;
			}
			try
			{
				IEnumerable<CardInfo> first = ((ObservableCollection<CardInfo>)typeof(CardManager).GetField("activeCards", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null)).ToList();
				List<CardInfo> second = (List<CardInfo>)typeof(CardManager).GetField("inactiveCards", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null);
				_cached = (from c in first.Concat(second)
					where ((Object)((Component)c).gameObject).name == "TargetBounce"
					select c).SelectMany((CardInfo c) => ((Component)c).GetComponent<Gun>().objectsToSpawn).FirstOrDefault((Func<ObjectsToSpawn, bool>)((ObjectsToSpawn o) => (Object)(object)o.AddToProjectile.GetComponent<ScreenEdgeBounce>() != (Object)null));
			}
			catch (Exception ex)
			{
				MrFuntikMod.LogError("[ScreenEdgeBounceHelper] Failed to get spawn object: " + ex.Message);
			}
			return _cached;
		}

		public static void Add(Gun gun)
		{
			ObjectsToSpawn item = GetSpawnObject();
			if (item != null && !((Object)(object)gun == (Object)null))
			{
				List<ObjectsToSpawn> list = ((IEnumerable<ObjectsToSpawn>)(((object)gun.objectsToSpawn) ?? ((object)new ObjectsToSpawn[0]))).ToList();
				if (!list.Any((ObjectsToSpawn o) => o != null && (Object)(object)o.AddToProjectile == (Object)(object)item.AddToProjectile))
				{
					list.Add(item);
					gun.objectsToSpawn = list.ToArray();
				}
			}
		}

		public static void Remove(Gun gun)
		{
			ObjectsToSpawn spawnObject = GetSpawnObject();
			if (spawnObject != null && !((Object)(object)gun == (Object)null))
			{
				List<ObjectsToSpawn> list = ((IEnumerable<ObjectsToSpawn>)(((object)gun.objectsToSpawn) ?? ((object)new ObjectsToSpawn[0]))).ToList();
				if (list.Remove(spawnObject))
				{
					gun.objectsToSpawn = list.ToArray();
				}
			}
		}
	}
	internal class CardCheck : MonoBehaviour
	{
		public static readonly string[] AllowedModInitials = new string[4] { "BFRM", "MFM", "IS", "DRON" };

		public static int Amount(Player player, string cardName)
		{
			if ((Object)(object)player == (Object)null || (Object)(object)player.data == (Object)null || player.data.currentCards == null)
			{
				return 0;
			}
			List<CardInfo> currentCards = player.data.currentCards;
			int num = 0;
			for (int num2 = currentCards.Count - 1; num2 >= 0; num2--)
			{
				if ((Object)(object)currentCards[num2] != (Object)null && currentCards[num2].cardName == cardName)
				{
					num++;
				}
			}
			return num;
		}

		public static int AmountFromAllowedMods(Player player, string cardName)
		{
			if ((Object)(object)player == (Object)null || (Object)(object)player.data == (Object)null || player.data.currentCards == null)
			{
				return 0;
			}
			List<CardInfo> currentCards = player.data.currentCards;
			int num = 0;
			for (int num2 = currentCards.Count - 1; num2 >= 0; num2--)
			{
				CardInfo val = currentCards[num2];
				if ((Object)(object)val != (Object)null && val.cardName == cardName && IsFromAllowedMod(val))
				{
					num++;
				}
			}
			return num;
		}

		public static bool HasCardFromAllowedMods(Player player, string cardName)
		{
			return AmountFromAllowedMods(player, cardName) > 0;
		}

		public static bool IsFromAllowedMod(CardInfo card)
		{
			if ((Object)(object)card == (Object)null)
			{
				return false;
			}
			string cardModName = GetCardModName(card);
			if (string.IsNullOrEmpty(cardModName))
			{
				return false;
			}
			for (int i = 0; i < AllowedModInitials.Length; i++)
			{
				if (cardModName == AllowedModInitials[i])
				{
					return true;
				}
			}
			return false;
		}

		private static string GetCardModName(CardInfo card)
		{
			if ((Object)(object)card == (Object)null)
			{
				return null;
			}
			string cardName = card.cardName;
			if ((Object)(object)card.sourceCard != (Object)null)
			{
				cardName = card.sourceCard.cardName;
			}
			try
			{
				foreach (KeyValuePair<string, Card> card2 in CardManager.cards)
				{
					if ((Object)(object)card2.Value.cardInfo != (Object)null && card2.Value.cardInfo.cardName == cardName)
					{
						return card2.Value.category;
					}
				}
			}
			catch
			{
			}
			return null;
		}
	}
	public class DestroyerProjectileBreakHandler : MonoBehaviour
	{
		private ProjectileHit projectileHit = null;

		private RayHitReflect reflect = null;

		private int breakCount = 1;

		private int lastHitFrame = -1;

		private int lastHitColliderID;

		private Vector2 lastHitPoint;

		public void Initialize(ProjectileHit hit, int chunksPerHit)
		{
			projectileHit = hit;
			breakCount = Mathf.Clamp(chunksPerHit, 1, 5);
			RegisterReflect();
		}

		private void Start()
		{
			if ((Object)(object)projectileHit == (Object)null)
			{
				projectileHit = ((Component)this).GetComponent<ProjectileHit>();
			}
			RegisterReflect();
		}

		private void OnDestroy()
		{
			if ((Object)(object)reflect != (Object)null)
			{
				RayHitReflect obj = reflect;
				obj.reflectAction = (Action<HitInfo>)Delegate.Remove(obj.reflectAction, new Action<HitInfo>(TryBreakHit));
			}
		}

		public void TryBreakHit(HitInfo hitInfo)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)projectileHit == (Object)null)
			{
				projectileHit = ((Component)this).GetComponent<ProjectileHit>();
			}
			if (!((Object)(object)projectileHit == (Object)null) && !((Object)(object)hitInfo.collider == (Object)null) && !IsDuplicateSameFrameHit(hitInfo.collider, hitInfo.point))
			{
				DestroyerChunkManager.TryBreakFromProjectile(hitInfo, projectileHit, breakCount);
			}
		}

		private void RegisterReflect()
		{
			RayHitReflect val = ((Component)this).GetComponent<RayHitReflect>();
			if ((Object)(object)val == (Object)null)
			{
				val = ((Component)this).GetComponentInParent<RayHitReflect>();
			}
			if (!((Object)(object)val == (Object)(object)reflect))
			{
				if ((Object)(object)reflect != (Object)null)
				{
					RayHitReflect obj = reflect;
					obj.reflectAction = (Action<HitInfo>)Delegate.Remove(obj.reflectAction, new Action<HitInfo>(TryBreakHit));
				}
				reflect = val;
				if ((Object)(object)reflect != (Object)null)
				{
					RayHitReflect obj2 = reflect;
					obj2.reflectAction = (Action<HitInfo>)Delegate.Combine(obj2.reflectAction, new Action<HitInfo>(TryBreakHit));
				}
			}
		}

		private bool IsDuplicateSameFrameHit(Collider2D collider, Vector2 point)
		{
			//IL_001f: 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)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: 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)
			int instanceID = ((Object)collider).GetInstanceID();
			if (lastHitFrame == Time.frameCount && lastHitColliderID == instanceID)
			{
				Vector2 val = lastHitPoint - point;
				if (((Vector2)(ref val)).sqrMagnitude < 0.0004f)
				{
					return true;
				}
			}
			lastHitFrame = Time.frameCount;
			lastHitColliderID = instanceID;
			lastHitPoint = point;
			return false;
		}
	}
	public static class DestroyerChunkManager
	{
		private struct Candidate
		{
			public Collider2D Collider;

			public SpriteRenderer Renderer;

			public string Path;

			public int EstimatedChunks;

			public int ChunkBudget;
		}

		private struct BudgetRemainder
		{
			public int Index;

			public float Fraction;
		}

		private const float DamageThreshold = 0f;

		private const float TargetChunkSize = 0.7f;

		private const float MaxChunkWorldSize = 1.25f;

		private const float MinObjectSize = 0.45f;

		private const int MaxCellsPerAxis = 96;

		private const int BaseMaxChunksPerObject = 80;

		private const int MaxDynamicChunksPerObject = 1400;

		private const float MaxObjectBudgetFraction = 0.4f;

		private const int StandardTotalChunks = 1200;

		private const int MaxDynamicTotalChunks = 2400;

		private const float ProtectedSeedChunkFraction = 0.05f;

		private const int ProtectedClusterTargetSize = 2;

		private const float MinChunkPolygonArea = 0.01f;

		private const float PolygonPointEpsilon = 0.001f;

		private const float MaskTexturePixelsPerUnit = 48f;

		private const int MinMaskTexturePixels = 8;

		private const int MaxMaskTexturePixels = 48;

		private const bool DiagnosticsEnabled = true;

		internal const int MaxBreaksPerHit = 5;

		private const float UnitRatio = 1f / 27f;

		private const float DefaultHalfWidth = 35.56f;

		private const float DefaultHalfHeight = 20f;

		private const float StandardBoundsArea = 2844.8f;

		private static readonly List<Candidate> candidates = new List<Candidate>(128);

		private static readonly Dictionary<int, DestroyerChunkObject> objectsById = new Dictionary<int, DestroyerChunkObject>();

		private static readonly Dictionary<int, Candidate> candidatesById = new Dictionary<int, Candidate>();

		private static readonly Dictionary<Collider2D, int> objectIdsByCollider = new Dictionary<Collider2D, int>();

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

		private static int preparedMapID = -1;

		private static int preparedMapInstanceID;

		private static int totalChunks;

		private static int totalChunkBudget = 1200;

		private static float preparedBoundsWidth;

		private static float preparedBoundsHeight;

		private static int nextEventID;

		private static bool mapsExtendedProbed;

		private static MethodInfo? getCustomMap;

		private static PropertyInfo? settingsProp;

		private static PropertyInfo? mapSizeProp;

		private static MethodInfo? getMinX;

		private static MethodInfo? getMaxX;

		private static MethodInfo? getMinY;

		private static MethodInfo? getMaxY;

		public static bool CanBreak(float totalDamage)
		{
			return totalDamage > 0f;
		}

		internal static int CountDestroyerCards(Player player)
		{
			if ((Object)(object)player == (Object)null || (Object)(object)player.data == (Object)null || player.data.currentCards == null)
			{
				return 0;
			}
			int num = 0;
			for (int i = 0; i < player.data.currentCards.Count; i++)
			{
				CardInfo val = player.data.currentCards[i];
				if ((Object)(object)val != (Object)null && val.cardName == "Destroyer")
				{
					num++;
				}
			}
			return num;
		}

		internal static int GetBreaksPerHit(Player player)
		{
			return Mathf.Clamp(CountDestroyerCards(player), 1, 5);
		}

		internal static void TryBreakFromProjectile(HitInfo hitInfo, ProjectileHit projectileHit, int breakCount)
		{
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = hitInfo.transform;
			if ((Object)(object)((transform != null) ? ((Component)transform).GetComponent<Player>() : null) != (Object)null || (Object)(object)hitInfo.collider == (Object)null || (Object)(object)((Component)hitInfo.collider).gameObject == (Object)null || (Object)(object)projectileHit == (Object)null)
			{
				return;
			}
			Player ownPlayer = projectileHit.ownPlayer;
			if (!((Object)(object)ownPlayer == (Object)null) && !((Object)(object)ownPlayer.data == (Object)null))
			{
				float totalDamage = projectileHit.damage * projectileHit.dealDamageMultiplierr;
				if (CanBreak(totalDamage))
				{
					TryBreak(hitInfo.collider, hitInfo.point, totalDamage, ownPlayer.playerID, projectileHit, breakCount);
				}
			}
		}

		internal static void LogDiagnostic(string message)
		{
			bool flag = true;
			ManualLogSource modLogger = MrFuntikMod.ModLogger;
			if (modLogger != null)
			{
				modLogger.LogInfo((object)message);
			}
		}

		internal static void LogDiagnosticWarning(string message)
		{
			bool flag = true;
			ManualLogSource modLogger = MrFuntikMod.ModLogger;
			if (modLogger != null)
			{
				modLogger.LogWarning((object)message);
			}
		}

		public static bool PrepareCurrentMap()
		{
			Map currentMap = GetCurrentMap();
			if ((Object)(object)currentMap == (Object)null)
			{
				return false;
			}
			int currentLevelID = MapManager.instance.currentLevelID;
			int instanceID = ((Object)((Component)currentMap).gameObject).GetInstanceID();
			if (preparedMapID == currentLevelID && preparedMapInstanceID == instanceID)
			{
				return true;
			}
			ResetAllLocal();
			preparedMapID = currentLevelID;
			preparedMapInstanceID = instanceID;
			totalChunks = 0;
			totalChunkBudget = CalculateTotalChunkBudget();
			candidates.Clear();
			candidatesById.Clear();
			objectIdsByCollider.Clear();
			Collider2D[] componentsInChildren = ((Component)currentMap).GetComponentsInChildren<Collider2D>();
			foreach (Collider2D val in componentsInChildren)
			{
				if (IsValidMapCollider(val, out SpriteRenderer renderer))
				{
					candidates.Add(new Candidate
					{
						Collider = val,
						Renderer = renderer,
						Path = GetStablePath(((Component)currentMap).transform, ((Component)val).transform) + "#" + GetColliderComponentIndex(val).ToString("D2")
					});
				}
			}
			candidates.Sort((Candidate a, Candidate b) => string.CompareOrdinal(a.Path, b.Path));
			AssignCandidateBudgets(candidates);
			for (int num = 0; num < candidates.Count; num++)
			{
				candidatesById[num] = candidates[num];
				objectIdsByCollider[candidates[num].Collider] = num;
			}
			int num2 = 0;
			int num3 = 0;
			for (int num4 = 0; num4 < candidates.Count; num4++)
			{
				num2 += candidates[num4].ChunkBudget;
				num3 += candidates[num4].EstimatedChunks;
			}
			LogDiagnostic($"[Destroyer] Prepared map id={preparedMapID} instance={preparedMapInstanceID}: candidates={candidatesById.Count}, chunkBudget={totalChunkBudget}, assignedBudget={num2}, estimatedBudget={num3}, mapBounds={preparedBoundsWidth:F2}x{preparedBoundsHeight:F2}");
			candidates.Clear();
			return candidatesById.Count > 0;
		}

		public static void TryBreak(Collider2D hitCollider, Vector2 hitPoint, float totalDamage, int ownerPlayerID, ProjectileHit projectileHit, int breakCount)
		{
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)hitCollider == (Object)null || totalDamage <= 0f)
			{
				return;
			}
			bool flag = PhotonNetwork.OfflineMode;
			if (!flag && (Object)(object)projectileHit != (Object)null && (Object)(object)projectileHit.view != (Object)null)
			{
				flag = projectileHit.view.IsMine;
			}
			if (!flag && (Object)(object)projectileHit != (Object)null && (Object)(object)projectileHit.ownPlayer != (Object)null && (Object)(object)projectileHit.ownPlayer.data?.view != (Object)null)
			{
				flag = projectileHit.ownPlayer.data.view.IsMine;
			}
			if (flag && PrepareCurrentMap() && TryGetObjectID(hitCollider, out var objectID))
			{
				int num = NextEventID();
				int num2 = MakeSeed(ownerPlayerID, objectID, num);
				float breakRadius = GetBreakRadius(totalDamage);
				int num3 = Mathf.Clamp(breakCount, 1, 5);
				if (PhotonNetwork.OfflineMode)
				{
					RPCA_BreakChunks(ownerPlayerID, preparedMapID, objectID, hitPoint.x, hitPoint.y, breakRadius, num, num2, num3);
					return;
				}
				NetworkingManager.RPC(typeof(DestroyerChunkManager), "RPCA_BreakChunks", new object[9] { ownerPlayerID, preparedMapID, objectID, hitPoint.x, hitPoint.y, breakRadius, num, num2, num3 });
			}
		}

		[UnboundRPC]
		public static void RPCA_BreakChunks(int ownerPlayerID, int mapID, int objectID, float hitX, float hitY, float radius, int eventID, int seed, int breakCount)
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)MapManager.instance == (Object)null) && MapManager.instance.currentLevelID == mapID && PrepareCurrentMap())
			{
				int item = MakeSeed(ownerPlayerID, mapID, eventID);
				if (processedEvents.Add(item) && EnsureMaterialized(objectID, out DestroyerChunkObject target))
				{
					target.BreakAround(new Vector2(hitX, hitY), Mathf.Max(0.15f, radius), seed, breakCount);
				}
			}
		}

		public static void ResetAllLocal()
		{
			foreach (DestroyerChunkObject value in objectsById.Values)
			{
				if ((Object)(object)value != (Object)null)
				{
					value.RestoreAndDestroyChunks();
				}
			}
			DestroyerDebris[] array = Object.FindObjectsOfType<DestroyerDebris>();
			for (int num = array.Length - 1; num >= 0; num--)
			{
				if ((Object)(object)array[num] != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)array[num]).gameObject);
				}
			}
			DestroyerProtectedFlash[] array2 = Object.FindObjectsOfType<DestroyerProtectedFlash>();
			for (int num2 = array2.Length - 1; num2 >= 0; num2--)
			{
				if ((Object)(object)array2[num2] != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)array2[num2]).gameObject);
				}
			}
			objectsById.Clear();
			candidatesById.Clear();
			objectIdsByCollider.Clear();
			processedEvents.Clear();
			candidates.Clear();
			preparedMapID = -1;
			preparedMapInstanceID = 0;
			totalChunks = 0;
			totalChunkBudget = 1200;
			preparedBoundsWidth = 0f;
			preparedBoundsHeight = 0f;
		}

		private static Map GetCurrentMap()
		{
			if ((Object)(object)MapManager.instance == (Object)null || MapManager.instance.currentMap == null)
			{
				return null;
			}
			return MapManager.instance.currentMap.Map;
		}

		private static bool IsValidMapCollider(Collider2D collider, out SpriteRenderer renderer)
		{
			//IL_00f0: 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_00f8: 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_010b: Unknown result type (might be due to invalid IL or missing references)
			renderer = null;
			if ((Object)(object)collider == (Object)null || !((Behaviour)collider).enabled || collider.isTrigger || !((Component)collider).gameObject.activeInHierarchy)
			{
				return false;
			}
			if ((Object)(object)((Component)collider).GetComponent<DestroyerChunk>() != (Object)null || (Object)(object)((Component)collider).GetComponentInParent<DestroyerChunkObject>() != (Object)null)
			{
				return false;
			}
			if ((Object)(object)((Component)collider).GetComponentInParent<Player>() != (Object)null || (Object)(object)((Component)collider).GetComponentInParent<SpawnedAttack>() != (Object)null)
			{
				return false;
			}
			if (HasDynamicOrScriptedMapObject(collider))
			{
				return false;
			}
			renderer = ((Component)collider).GetComponent<SpriteRenderer>();
			if ((Object)(object)renderer == (Object)null || (Object)(object)renderer.sprite == (Object)null || !((Renderer)renderer).enabled || renderer.color.a < 0.5f)
			{
				return false;
			}
			Bounds bounds = collider.bounds;
			if (((Bounds)(ref bounds)).size.x < 0.45f || ((Bounds)(ref bounds)).size.y < 0.45f)
			{
				return false;
			}
			SFPolygon component = ((Component)collider).GetComponent<SFPolygon>();
			if ((Object)(object)component != (Object)null && !((Behaviour)component).isActiveAndEnabled)
			{
				return false;
			}
			return true;
		}

		private static bool HasDynamicOrScriptedMapObject(Collider2D collider)
		{
			return HasComponentAround<Rigidbody2D>(collider) || HasComponentAround<Joint2D>(collider) || HasComponentAround<NetworkPhysicsObject>(collider) || HasComponentAround<PhotonMapObject>(collider) || HasComponentAround<MapObjet_Rope>(collider) || HasComponentNamedAround(collider, "Animator") || HasComponentNamedAround(collider, "Animation") || HasComponentAround<CodeAnimation>(collider) || HasComponentAround<CurveAnimation>(collider) || HasComponentAround<MoveTransform>(collider) || HasComponentAround<DamageBox>(collider) || HasComponentAround<Damagable>(collider) || HasComponentAround<DestructibleBoxDestruction>(collider);
		}

		private static bool HasComponentAround<T>(Collider2D collider) where T : Component
		{
			return (Object)(object)((Component)collider).GetComponentInParent<T>() != (Object)null || (Object)(object)((Component)collider).GetComponentInChildren<T>() != (Object)null;
		}

		private static bool HasComponentNamedAround(Collider2D collider, string typeName)
		{
			Component[] componentsInParent = ((Component)collider).GetComponentsInParent<Component>(true);
			for (int i = 0; i < componentsInParent.Length; i++)
			{
				if ((Object)(object)componentsInParent[i] != (Object)null && ((object)componentsInParent[i]).GetType().Name == typeName)
				{
					return true;
				}
			}
			Component[] componentsInChildren = ((Component)collider).GetComponentsInChildren<Component>(true);
			for (int j = 0; j < componentsInChildren.Length; j++)
			{
				if ((Object)(object)componentsInChildren[j] != (Object)null && ((object)componentsInChildren[j]).GetType().Name == typeName)
				{
					return true;
				}
			}
			return false;
		}

		private static bool EnsureMaterialized(int objectID, out DestroyerChunkObject target)
		{
			if (objectsById.TryGetValue(objectID, out target) && (Object)(object)target != (Object)null)
			{
				return true;
			}
			target = null;
			if (!candidatesById.TryGetValue(objectID, out var value))
			{
				return false;
			}
			Map currentMap = GetCurrentMap();
			if ((Object)(object)currentMap == (Object)null)
			{
				return false;
			}
			return CreateChunksForCandidate(currentMap, value, objectID, out target);
		}

		private static bool CreateChunksForCandidate(Map map, Candidate candidate, int objectID, out DestroyerChunkObject owner)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: 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_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: 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_03f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_040b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0310: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			owner = null;
			Collider2D collider = candidate.Collider;
			SpriteRenderer renderer = candidate.Renderer;
			if ((Object)(object)collider == (Object)null || (Object)(object)renderer == (Object)null)
			{
				return false;
			}
			Bounds bounds = collider.bounds;
			int columns = Mathf.Clamp(Mathf.CeilToInt(((Bounds)(ref bounds)).size.x / 0.7f), 1, 96);
			int rows = Mathf.Clamp(Mathf.CeilToInt(((Bounds)(ref bounds)).size.y / 0.7f), 1, 96);
			int num = Mathf.Min(candidate.ChunkBudget, Mathf.Max(0, totalChunkBudget - totalChunks));
			if (num <= 0)
			{
				LogDiagnosticWarning($"[Destroyer] Materialize skipped no budget: object={objectID}, candidateBudget={candidate.ChunkBudget}, totalChunks={totalChunks}/{totalChunkBudget}, collider={((object)collider).GetType().Name}, bounds={((Bounds)(ref bounds)).size.x:F2}x{((Bounds)(ref bounds)).size.y:F2}");
				return false;
			}
			ReduceGridToBudget(ref columns, ref rows, num, ((Bounds)(ref bounds)).size.x, ((Bounds)(ref bounds)).size.y);
			float num2 = ((Bounds)(ref bounds)).size.x / (float)columns;
			float num3 = ((Bounds)(ref bounds)).size.y / (float)rows;
			if (num2 <= 0f || num3 <= 0f)
			{
				return false;
			}
			owner = ((Component)collider).gameObject.AddComponent<DestroyerChunkObject>();
			owner.Initialize(objectID, collider, renderer, ((Component)collider).GetComponent<SFPolygon>(), ((Component)collider).GetComponent<SpriteMask>());
			int num4 = 0;
			Vector2 center = default(Vector2);
			for (int i = 0; i < rows; i++)
			{
				if (totalChunks >= totalChunkBudget)
				{
					break;
				}
				for (int j = 0; j < columns; j++)
				{
					if (totalChunks >= totalChunkBudget)
					{
						break;
					}
					((Vector2)(ref center))..ctor(((Bounds)(ref bounds)).min.x + num2 * ((float)j + 0.5f), ((Bounds)(ref bounds)).min.y + num3 * ((float)i + 0.5f));
					DestroyerChunk destroyerChunk = CreateChunk(map, owner, renderer, center, num2, num3, num4);
					if (!((Object)(object)destroyerChunk == (Object)null))
					{
						owner.Chunks.Add(destroyerChunk);
						num4++;
						totalChunks++;
					}
				}
			}
			if (owner.Chunks.Count == 0)
			{
				LogDiagnosticWarning($"[Destroyer] Materialize failed: object={objectID}, collider={((object)collider).GetType().Name}, grid={columns}x{rows}, objectBudget={num}, bounds={((Bounds)(ref bounds)).size.x:F2}x{((Bounds)(ref bounds)).size.y:F2}, cell={num2:F2}x{num3:F2}");
				Object.Destroy((Object)(object)owner);
				owner = null;
				return false;
			}
			int num5 = AssignProtectedChunkClusters(owner);
			int num6 = CountProtectedChunks(owner);
			LogDiagnostic($"[Destroyer] Materialized object={objectID}: collider={((object)collider).GetType().Name}, renderer={((Object)renderer).name}, grid={columns}x{rows}, chunks={owner.Chunks.Count}, protected={num6}, protectedClusters={num5}, objectBudget={num}, totalChunks={totalChunks}/{totalChunkBudget}, bounds={((Bounds)(ref bounds)).size.x:F2}x{((Bounds)(ref bounds)).size.y:F2}, cell={num2:F2}x{num3:F2}");
			if (Mathf.Max(num2, num3) > 1.375f)
			{
				LogDiagnosticWarning($"[Destroyer] Large chunk cells remain: object={objectID}, cell={num2:F2}x{num3:F2}, maxTarget={1.25f:F2}, objectBudget={num}, remainingBudget={totalChunkBudget - totalChunks}");
			}
			owner.ActivateChunkedVisual(map);
			objectsById[objectID] = owner;
			return true;
		}

		private static int AssignProtectedChunkClusters(DestroyerChunkObject owner)
		{
			if ((Object)(object)owner == (Object)null || owner.Chunks.Count < 2)
			{
				return 0;
			}
			int seed = MakeSeed(preparedMapID, owner.ObjectID, 9109);
			float num = (float)owner.Chunks.Count * 0.05f;
			int num2 = Mathf.FloorToInt(num);
			if (Hash01(seed, owner.Chunks.Count) < num - (float)num2)
			{
				num2++;
			}
			if (num2 <= 0)
			{
				LogDiagnostic($"[Destroyer] Protected clusters object={owner.ObjectID}: clusters=0, protected=0/{owner.Chunks.Count}, seedTarget=0, mode=seed+above");
				return 0;
			}
			int num3 = Mathf.Min(owner.Chunks.Count, num2 * 2);
			List<DestroyerChunk> list = SelectProtectedSeeds(owner.Chunks, num2, seed);
			int num4 = 0;
			int num5 = 0;
			for (int i = 0; i < list.Count; i++)
			{
				if (num5 >= num3)
				{
					break;
				}
				DestroyerChunk destroyerChunk = list[i];
				if ((Object)(object)destroyerChunk == (Object)null || destroyerChunk.IsProtected)
				{
					continue;
				}
				DestroyerChunk destroyerChunk2 = FindVerticalNeighbor(owner.Chunks, destroyerChunk, 1);
				if (!((Object)(object)destroyerChunk2 == (Object)null))
				{
					int num6 = 0;
					if (ProtectChunk(destroyerChunk))
					{
						num6++;
					}
					if (ProtectChunk(destroyerChunk2))
					{
						num6++;
					}
					if (num6 == 2)
					{
						num5 += num6;
						num4++;
					}
				}
			}
			LogDiagnostic($"[Destroyer] Protected clusters object={owner.ObjectID}: clusters={num4}, protected={num5}/{owner.Chunks.Count}, seedTarget={num2}, requestedSeeds={list.Count}, mode=seed+above");
			return num4;
		}

		private static List<DestroyerChunk> SelectProtectedSeeds(List<DestroyerChunk> chunks, int seedTarget, int seed)
		{
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			List<DestroyerChunk> list = new List<DestroyerChunk>(chunks.Count);
			for (int i = 0; i < chunks.Count; i++)
			{
				if ((Object)(object)chunks[i] != (Object)null && (Object)(object)FindVerticalNeighbor(chunks, chunks[i], 1) != (Object)null)
				{
					list.Add(chunks[i]);
				}
			}
			list.Sort(delegate(DestroyerChunk a, DestroyerChunk b)
			{
				float num5 = Hash01(seed, a.ChunkIndex);
				float value = Hash01(seed, b.ChunkIndex);
				int num6 = num5.CompareTo(value);
				return (num6 != 0) ? num6 : a.ChunkIndex.CompareTo(b.ChunkIndex);
			});
			List<DestroyerChunk> list2 = new List<DestroyerChunk>(seedTarget);
			Bounds val = CalculateChunkBounds(list);
			float num = Mathf.Max(0.01f, ((Bounds)(ref val)).size.x * ((Bounds)(ref val)).size.y);
			float num2 = Mathf.Sqrt(num / (float)Mathf.Max(1, seedTarget)) * 0.65f;
			float[] array = new float[4]
			{
				num2,
				num2 * 0.75f,
				num2 * 0.5f,
				0f
			};
			for (int num3 = 0; num3 < array.Length; num3++)
			{
				if (list2.Count >= seedTarget)
				{
					break;
				}
				float minDistanceSqr = array[num3] * array[num3];
				for (int num4 = 0; num4 < list.Count; num4++)
				{
					if (list2.Count >= seedTarget)
					{
						break;
					}
					DestroyerChunk destroyerChunk = list[num4];
					if (!((Object)(object)destroyerChunk == (Object)null) && !ContainsChunk(list2, destroyerChunk) && IsFarEnoughFromSeeds(destroyerChunk, list2, minDistanceSqr))
					{
						list2.Add(destroyerChunk);
					}
				}
			}
			return list2;
		}

		private static Bounds CalculateChunkBounds(List<DestroyerChunk> chunks)
		{
			//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_00c5: 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_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//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)
			Bounds result = default(Bounds);
			((Bounds)(ref result))..ctor(Vector3.zero, Vector3.zero);
			bool flag = false;
			Bounds val = default(Bounds);
			for (int i = 0; i < chunks.Count; i++)
			{
				DestroyerChunk destroyerChunk = chunks[i];
				if (!((Object)(object)destroyerChunk == (Object)null))
				{
					Vector2 center = destroyerChunk.Center;
					Vector2 size = destroyerChunk.Size;
					((Bounds)(ref val))..ctor(new Vector3(center.x, center.y, 0f), new Vector3(Mathf.Max(0.01f, size.x), Mathf.Max(0.01f, size.y), 0f));
					if (!flag)
					{
						result = val;
						flag = true;
					}
					else
					{
						((Bounds)(ref result)).Encapsulate(val);
					}
				}
			}
			return result;
		}

		private static bool ContainsChunk(List<DestroyerChunk> chunks, DestroyerChunk chunk)
		{
			for (int i = 0; i < chunks.Count; i++)
			{
				if ((Object)(object)chunks[i] == (Object)(object)chunk)
				{
					return true;
				}
			}
			return false;
		}

		private static bool IsFarEnoughFromSeeds(DestroyerChunk candidate, List<DestroyerChunk> selected, float minDistanceSqr)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			if (minDistanceSqr <= 0f)
			{
				return true;
			}
			for (int i = 0; i < selected.Count; i++)
			{
				DestroyerChunk destroyerChunk = selected[i];
				if ((Object)(object)destroyerChunk != (Object)null)
				{
					Vector2 val = candidate.Center - destroyerChunk.Center;
					if (((Vector2)(ref val)).sqrMagnitude < minDistanceSqr)
					{
						return false;
					}
				}
			}
			return true;
		}

		private static bool ProtectChunk(DestroyerChunk chunk)
		{
			if ((Object)(object)chunk != (Object)null && !chunk.IsProtected)
			{
				chunk.SetProtected(isProtected: true);
				return true;
			}
			return false;
		}

		private static DestroyerChunk FindVerticalNeighbor(List<DestroyerChunk> chunks, DestroyerChunk seed, int direction)
		{
			//IL_0061: 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_00a2: 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_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			if (chunks == null || (Object)(object)seed == (Object)null)
			{
				return null;
			}
			DestroyerChunk result = null;
			float num = float.PositiveInfinity;
			for (int i = 0; i < chunks.Count; i++)
			{
				DestroyerChunk destroyerChunk = chunks[i];
				if ((Object)(object)destroyerChunk == (Object)null || (Object)(object)destroyerChunk == (Object)(object)seed || destroyerChunk.IsProtected)
				{
					continue;
				}
				float num2 = destroyerChunk.Center.y - seed.Center.y;
				if ((direction < 0) ? (num2 >= -0.001f) : (num2 <= 0.001f))
				{
					continue;
				}
				float num3 = Mathf.Abs(destroyerChunk.Center.x - seed.Center.x);
				float num4 = Mathf.Max(seed.Size.x, destroyerChunk.Size.x) * 0.75f;
				if (!(num3 > num4))
				{
					float num5 = Mathf.Abs(num2) + num3 * 4f;
					if (num5 < num)
					{
						num = num5;
						result = destroyerChunk;
					}
				}
			}
			return result;
		}

		private static int CountProtectedChunks(DestroyerChunkObject owner)
		{
			int num = 0;
			if ((Object)(object)owner == (Object)null)
			{
				return num;
			}
			for (int i = 0; i < owner.Chunks.Count; i++)
			{
				DestroyerChunk destroyerChunk = owner.Chunks[i];
				if ((Object)(object)destroyerChunk != (Object)null && destroyerChunk.IsProtected)
				{
					num++;
				}
			}
			return num;
		}

		private static void AssignCandidateBudgets(List<Candidate> sortedCandidates)
		{
			if (sortedCandidates == null || sortedCandidates.Count == 0)
			{
				return;
			}
			int num = Mathf.Clamp(Mathf.FloorToInt((float)totalChunkBudget * 0.4f), 80, 1400);
			int num2 = 0;
			for (int i = 0; i < sortedCandidates.Count; i++)
			{
				Candidate value = sortedCandidates[i];
				value.ChunkBudget = Mathf.Clamp(value.EstimatedChunks = EstimateDesiredChunks(value.Collider), 1, num);
				sortedCandidates[i] = value;
				num2 += value.ChunkBudget;
			}
			if (num2 <= totalChunkBudget)
			{
				LogDiagnostic($"[Destroyer] Candidate budgets fit: assigned={num2}/{totalChunkBudget}, candidates={sortedCandidates.Count}, perObjectCap={num}");
				return;
			}
			int num3 = 0;
			float num4 = (float)totalChunkBudget / (float)num2;
			List<BudgetRemainder> list = new List<BudgetRemainder>(sortedCandidates.Count);
			for (int j = 0; j < sortedCandidates.Count; j++)
			{
				Candidate value2 = sortedCandidates[j];
				float num5 = (float)value2.ChunkBudget * num4;
				int num6 = Mathf.FloorToInt(num5);
				if (num6 <= 0 && value2.ChunkBudget > 0 && num3 < totalChunkBudget)
				{
					num6 = 1;
				}
				value2.ChunkBudget = Mathf.Min(num6, value2.ChunkBudget);
				sortedCandidates[j] = value2;
				num3 += value2.ChunkBudget;
				list.Add(new BudgetRemainder
				{
					Index = j,
					Fraction = num5 - Mathf.Floor(num5)
				});
			}
			list.Sort((BudgetRemainder a, BudgetRemainder b) => b.Fraction.CompareTo(a.Fraction));
			int num7 = Mathf.Max(0, totalChunkBudget - num3);
			for (int num8 = 0; num8 < list.Count; num8++)
			{
				if (num7 <= 0)
				{
					break;
				}
				int index = list[num8].Index;
				Candidate value3 = sortedCandidates[index];
				int num9 = Mathf.Clamp(value3.EstimatedChunks, 1, num);
				if (value3.ChunkBudget < num9)
				{
					value3.ChunkBudget++;
					sortedCandidates[index] = value3;
					num7--;
				}
			}
			LogDiagnosticWarning($"[Destroyer] Candidate budgets scaled: desired={num2}, assigned={totalChunkBudget - num7}/{totalChunkBudget}, candidates={sortedCandidates.Count}, scale={num4:F3}, perObjectCap={num}");
		}

		private static int EstimateDesiredChunks(Collider2D collider)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)collider == (Object)null)
			{
				return 0;
			}
			Bounds bounds = collider.bounds;
			int num = Mathf.Clamp(Mathf.CeilToInt(((Bounds)(ref bounds)).size.x / 0.7f), 1, 96);
			int num2 = Mathf.Clamp(Mathf.CeilToInt(((Bounds)(ref bounds)).size.y / 0.7f), 1, 96);
			return Mathf.Max(1, num * num2);
		}

		private static int CalculateTotalChunkBudget()
		{
			GetMapBoundsSize(out var width, out var height);
			preparedBoundsWidth = width;
			preparedBoundsHeight = height;
			float num = Mathf.Max(0f, width) * Mathf.Max(0f, height);
			if (num <= 0.01f)
			{
				return 1200;
			}
			float num2 = Mathf.Max(1f, num / 2844.8f);
			int num3 = Mathf.RoundToInt(1200f * num2);
			return Mathf.Clamp(num3, 1200, 2400);
		}

		private static void GetMapBoundsSize(out float width, out float height)
		{
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			ProbeMapsExtended();
			if (getMinX != null && getMaxX != null && getMinY != null && getMaxY != null)
			{
				try
				{
					float num = (float)getMinX.Invoke(null, null);
					float num2 = (float)getMaxX.Invoke(null, null);
					float num3 = (float)getMinY.Invoke(null, null);
					float num4 = (float)getMaxY.Invoke(null, null);
					width = Mathf.Abs(num2 - num);
					height = Mathf.Abs(num4 - num3);
					return;
				}
				catch
				{
				}
			}
			if (getCustomMap != null && settingsProp != null && mapSizeProp != null && (Object)(object)MapManager.instance != (Object)null)
			{
				try
				{
					object obj2 = getCustomMap.Invoke(null, new object[1] { MapManager.instance });
					object obj3 = ((obj2 != null) ? settingsProp.GetValue(obj2) : null);
					if (((obj3 != null) ? mapSizeProp.GetValue(obj3) : null) is Vector2 val)
					{
						width = Mathf.Abs(val.x * (1f / 27f));
						height = Mathf.Abs(val.y * (1f / 27f));
						return;
					}
				}
				catch
				{
				}
			}
			width = 71.12f;
			height = 40f;
		}

		private static void ProbeMapsExtended()
		{
			if (mapsExtendedProbed)
			{
				return;
			}
			mapsExtendedProbed = true;
			try
			{
				Assembly assembly = null;
				Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
				foreach (Assembly assembly2 in assemblies)
				{
					if (assembly2 != null && assembly2.GetName().Name == "MapsExtended")
					{
						assembly = assembly2;
						break;
					}
				}
				if (assembly == null)
				{
					return;
				}
				getCustomMap = assembly.GetType("MapsExt.MapManagerExtensions")?.GetMethod("GetCurrentCustomMap", BindingFlags.Static | BindingFlags.Public);
				Type type = assembly.GetType("MapsExt.CustomMap");
				Type type2 = assembly.GetType("MapsExt.CustomMapSettings");
				settingsProp = type?.GetProperty("Settings", BindingFlags.Instance | BindingFlags.Public);
				mapSizeProp = type2?.GetProperty("MapSize", BindingFlags.Instance | BindingFlags.Public);
				Type[] types = assembly.GetTypes();
				foreach (Type type3 in types)
				{
					if (!(type3 == null) && !(type3.Name != "OutOfBoundsHandler_Patch"))
					{
						getMinX = type3.GetMethod("GetMinX", BindingFlags.Static | BindingFlags.NonPublic);
						getMaxX = type3.GetMethod("GetMaxX", BindingFlags.Static | BindingFlags.NonPublic);
						getMinY = type3.GetMethod("GetMinY", BindingFlags.Static | BindingFlags.NonPublic);
						getMaxY = type3.GetMethod("GetMaxY", BindingFlags.Static | BindingFlags.NonPublic);
						break;
					}
				}
			}
			catch
			{
			}
		}

		private static DestroyerChunk CreateChunk(Map map, DestroyerChunkObject owner, SpriteRenderer sourceRenderer, Vector2 center, float width, float height, int chunkIndex)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			//IL_0040: 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_0052: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject($"DestroyerChunk_{owner.ObjectID}_{chunkIndex}");
			val.layer = ((Component)owner.OriginalCollider).gameObject.layer;
			val.transform.position = new Vector3(center.x, center.y, ((Component)sourceRenderer).transform.position.z);
			val.transform.rotation = Quaternion.identity;
			val.transform.SetParent(((Component)map).transform, true);
			val.transform.localScale = Vector3.one;
			List<Vector2[]> localPaths;
			Collider2D val2 = CreateChunkCollider(val, owner.OriginalCollider, center, width, height, out localPaths);
			if ((Object)(object)val2 == (Object)null)
			{
				Object.Destroy((Object)(object)val);
				return null;
			}
			DestroyerChunk destroyerChunk = val.AddComponent<DestroyerChunk>();
			destroyerChunk.Initialize(owner, chunkIndex, val2, center, new Vector2(width * 0.5f, height * 0.5f), localPaths);
			return destroyerChunk;
		}

		private static Collider2D CreateChunkCollider(GameObject chunkObject, Collider2D sourceCollider, Vector2 center, float width, float height, out List<Vector2[]> localPaths)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			localPaths = new List<Vector2[]>(1);
			Rect rect = Rect.MinMaxRect(center.x - width * 0.5f, center.y - height * 0.5f, center.x + width * 0.5f, center.y + height * 0.5f);
			List<Vector2[]> clippedColliderPaths = GetClippedColliderPaths(sourceCollider, rect, center);
			if (clippedColliderPaths.Count > 0)
			{
				PolygonCollider2D val = chunkObject.AddComponent<PolygonCollider2D>();
				val.pathCount = clippedColliderPaths.Count;
				for (int i = 0; i < clippedColliderPaths.Count; i++)
				{
					val.SetPath(i, clippedColliderPaths[i]);
				}
				localPaths = clippedColliderPaths;
				return (Collider2D)(object)val;
			}
			return null;
		}

		private static List<Vector2[]> GetClippedColliderPaths(Collider2D sourceCollider, Rect rect, Vector2 chunkCenter)
		{
			//IL_00cd: 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_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: 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_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: 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_012b: 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_0135: 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_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_0278: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			List<Vector2[]> list = new List<Vector2[]>(2);
			PolygonCollider2D val = (PolygonCollider2D)(object)((sourceCollider is PolygonCollider2D) ? sourceCollider : null);
			if ((Object)(object)val != (Object)null)
			{
				for (int i = 0; i < val.pathCount; i++)
				{
					Vector2[] path = val.GetPath(i);
					List<Vector2> list2 = new List<Vector2>(path.Length);
					for (int j = 0; j < path.Length; j++)
					{
						list2.Add(Vector2.op_Implicit(((Component)val).transform.TransformPoint(Vector2.op_Implicit(path[j] + ((Collider2D)val).offset))));
					}
					AddClippedPath(list, list2, rect, chunkCenter);
				}
				return list;
			}
			BoxCollider2D val2 = (BoxCollider2D)(object)((sourceCollider is BoxCollider2D) ? sourceCollider : null);
			if ((Object)(object)val2 != (Object)null)
			{
				Vector2 val3 = val2.size * 0.5f;
				Vector2 offset = ((Collider2D)val2).offset;
				List<Vector2> worldPath = new List<Vector2>(4)
				{
					Vector2.op_Implicit(((Component)val2).transform.TransformPoint(Vector2.op_Implicit(offset + new Vector2(0f - val3.x, 0f - val3.y)))),
					Vector2.op_Implicit(((Component)val2).transform.TransformPoint(Vector2.op_Implicit(offset + new Vector2(0f - val3.x, val3.y)))),
					Vector2.op_Implicit(((Component)val2).transform.TransformPoint(Vector2.op_Implicit(offset + new Vector2(val3.x, val3.y)))),
					Vector2.op_Implicit(((Component)val2).transform.TransformPoint(Vector2.op_Implicit(offset + new Vector2(val3.x, 0f - val3.y))))
				};
				AddClippedPath(list, worldPath, rect, chunkCenter);
			}
			CircleCollider2D val4 = (CircleCollider2D)(object)((sourceCollider is CircleCollider2D) ? sourceCollider : null);
			if ((Object)(object)val4 != (Object)null)
			{
				List<Vector2> list3 = new List<Vector2>(20);
				for (int k = 0; k < 20; k++)
				{
					float num = (float)k * MathF.PI * 2f / 20f;
					Vector2 val5 = ((Collider2D)val4).offset + new Vector2(Mathf.Cos(num) * val4.radius, Mathf.Sin(num) * val4.radius);
					list3.Add(Vector2.op_Implicit(((Component)val4).transform.TransformPoint(Vector2.op_Implicit(val5))));
				}
				AddClippedPath(list, list3, rect, chunkCenter);
			}
			return list;
		}

		private static void AddClippedPath(List<Vector2[]> paths, List<Vector2> worldPath, Rect rect, Vector2 chunkCenter)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: 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_008b: Unknown result type (might be due to invalid IL or missing references)
			List<Vector2> list = SanitizePolygon(ClipPolygonToRect(worldPath, rect));
			float polygonArea = GetPolygonArea(list);
			if (list.Count < 3 || Mathf.Abs(polygonArea) < 0.01f)
			{
				return;
			}
			if (polygonArea < 0f)
			{
				list.Reverse();
			}
			if (DestroyerVisualMesh.Triangulate(new List<Vector2>(list)).Count >= 3)
			{
				Vector2[] array = (Vector2[])(object)new Vector2[list.Count];
				for (int i = 0; i < list.Count; i++)
				{
					array[i] = list[i] - chunkCenter;
				}
				paths.Add(array);
			}
		}

		private static List<Vector2> SanitizePolygon(List<Vector2> polygon)
		{
			//IL_001f: 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)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: 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_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: 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_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			List<Vector2> list = new List<Vector2>(polygon.Count);
			float num = 1.0000001E-06f;
			Vector2 val2;
			for (int i = 0; i < polygon.Count; i++)
			{
				Vector2 val = polygon[i];
				if (float.IsNaN(val.x) || float.IsNaN(val.y) || float.IsInfinity(val.x) || float.IsInfinity(val.y))
				{
					continue;
				}
				if (list.Count != 0)
				{
					val2 = list[list.Count - 1] - val;
					if (!(((Vector2)(ref val2)).sqrMagnitude > num))
					{
						continue;
					}
				}
				list.Add(val);
			}
			if (list.Count > 1)
			{
				val2 = list[0] - list[list.Count - 1];
				if (((Vector2)(ref val2)).sqrMagnitude <= num)
				{
					list.RemoveAt(list.Count - 1);
				}
			}
			int num2 = list.Count * list.Count;
			bool flag;
			do
			{
				flag = false;
				int num3 = list.Count - 1;
				while (num3 >= 0 && list.Count >= 3)
				{
					Vector2 val3 = list[(num3 - 1 + list.Count) % list.Count];
					Vector2 val4 = list[num3];
					Vector2 val5 = list[(num3 + 1) % list.Count];
					Vector2 a = val4 - val3;
					Vector2 b = val5 - val4;
					val2 = val5 - val3;
					if (((Vector2)(ref val2)).sqrMagnitude <= num || Mathf.Abs(Cross(a, b)) <= 0.001f * Mathf.Max(((Vector2)(ref a)).magnitude, ((Vector2)(ref b)).magnitude))
					{
						list.RemoveAt(num3);
						flag = true;
					}
					num3--;
				}
			}
			while (flag && num2-- > 0);
			return list;
		}

		private static List<Vector2> ClipPolygonToRect(List<Vector2> polygon, Rect rect)
		{
			//IL_0007: 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)
			List<Vector2> input = ClipPolygon(polygon, (Vector2 p) => p.x >= ((Rect)(ref rect)).xMin, (Vector2 a, Vector2 b) => IntersectVertical(a, b, ((Rect)(ref rect)).xMin));
			input = ClipPolygon(input, (Vector2 p) => p.x <= ((Rect)(ref rect)).xMax, (Vector2 a, Vector2 b) => IntersectVertical(a, b, ((Rect)(ref rect)).xMax));
			input = ClipPolygon(input, (Vector2 p) => p.y >= ((Rect)(ref rect)).yMin, (Vector2 a, Vector2 b) => IntersectHorizontal(a, b, ((Rect)(ref rect)).yMin));
			return ClipPolygon(input, (Vector2 p) => p.y <= ((Rect)(ref rect)).yMax, (Vector2 a, Vector2 b) => IntersectHorizontal(a, b, ((Rect)(ref rect)).yMax));
		}

		private static List<Vector2> ClipPolygon(List<Vector2> input, Func<Vector2, bool> inside, Func<Vector2, Vector2, Vector2> intersect)
		{
			//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)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: 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_006d: 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)
			List<Vector2> list = new List<Vector2>(input.Count + 2);
			if (input.Count == 0)
			{
				return list;
			}
			Vector2 val = input[input.Count - 1];
			bool flag = inside(val);
			for (int i = 0; i < input.Count; i++)
			{
				Vector2 val2 = input[i];
				bool flag2 = inside(val2);
				if (flag2)
				{
					if (!flag)
					{
						list.Add(intersect(val, val2));
					}
					list.Add(val2);
				}
				else if (flag)
				{
					list.Add(intersect(val, val2));
				}
				val = val2;
				flag = flag2;
			}
			return list;
		}

		private static Vector2 IntersectVertical(Vector2 a, Vector2 b, float x)
		{
			//IL_0001: 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_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: 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_002d: 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)
			float num = b.x - a.x;
			if (Mathf.Abs(num) < 0.0001f)
			{
				return new Vector2(x, a.y);
			}
			float num2 = Mathf.Clamp01((x - a.x) / num);
			return new Vector2(x, Mathf.Lerp(a.y, b.y, num2));
		}

		private static Vector2 IntersectHorizontal(Vector2 a, Vector2 b, float y)
		{
			//IL_0001: 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_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)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: 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_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			float num = b.y - a.y;
			if (Mathf.Abs(num) < 0.0001f)
			{
				return new Vector2(a.x, y);
			}
			float num2 = Mathf.Clamp01((y - a.y) / num);
			return new Vector2(Mathf.Lerp(a.x, b.x, num2), y);
		}

		private static float GetPolygonArea(List<Vector2> polygon)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: 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)
			//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_0033: 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)
			float num = 0f;
			for (int i = 0; i < polygon.Count; i++)
			{
				Vector2 val = polygon[i];
				Vector2 val2 = polygon[(i + 1) % polygon.Count];
				num += val.x * val2.y - val2.x * val.y;
			}
			return num * 0.5f;
		}

		private static float Cross(Vector2 a, Vector2 b)
		{
			//IL_0001: 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_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			return a.x * b.y - a.y * b.x;
		}

		private static void ReduceGridToBudget(ref int columns, ref int rows, int chunkBudget, float width, float height)
		{
			chunkBudget = Mathf.Max(1, chunkBudget);
			while (columns * rows > chunkBudget)
			{
				bool flag = columns > 1;
				bool flag2 = rows > 1;
				if (!flag && !flag2)
				{
					break;
				}
				bool flag3;
				if (!flag2)
				{
					flag3 = true;
				}
				else if (!flag)
				{
					flag3 = false;
				}
				else
				{
					float num = Mathf.Max(width / (float)(columns - 1), height / (float)rows);
					float num2 = Mathf.Max(width / (float)columns, height / (float)(rows - 1));
					flag3 = ((!(Mathf.Abs(num - num2) > 0.001f)) ? (columns >= rows) : (num <= num2));
				}
				if (flag3)
				{
					columns--;
				}
				else
				{
					rows--;
				}
			}
		}

		private static bool TryGetObjectID(Collider2D collider, out int objectID)
		{
			objectID = -1;
			if ((Object)(object)collider == (Object)null)
			{
				return false;
			}
			DestroyerChunk component = ((Component)collider).GetComponent<DestroyerChunk>();
			if ((Object)(object)component != (Object)null && (Object)(object)component.Owner != (Object)null)
			{
				objectID = component.Owner.ObjectID;
				return true;
			}
			DestroyerChunkObject component2 = ((Component)collider).GetComponent<DestroyerChunkObject>();
			if ((Object)(object)component2 != (Object)null)
			{
				objectID = component2.ObjectID;
				return true;
			}
			return objectIdsByCollider.TryGetValue(collider, out objectID);
		}

		private static float GetBreakRadius(float totalDamage)
		{
			float num = Mathf.InverseLerp(0f, 1050f, totalDamage);
			return Mathf.Lerp(0.62f, 1.25f, num);
		}

		private static int NextEventID()
		{
			nextEventID++;
			if (nextEventID == 0)
			{
				nextEventID = 1;
			}
			return nextEventID;
		}

		private static int MakeSeed(int a, int b, int c)
		{
			int num = 17;
			num = num * 31 + a;
			num = num * 31 + b;
			return num * 31 + c;
		}

		internal static float Hash01(int seed, int value)
		{
			uint num = (uint)(seed ^ (value * 73244475));
			num ^= num >> 16;
			num *= 2146121005;
			num ^= num >> 15;
			num *= 2221713035u;
			num ^= num >> 16;
			return (float)(num & 0xFFFFFF) / 16777215f;
		}

		internal static Sprite CreateChunkMaskSprite(DestroyerChunk chunk, string name, out Texture2D texture, out int filledPixels)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: 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_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: 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_00fb: 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_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Expected O, but got Unknown
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_0290: 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_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			texture = null;
			filledPixels = 0;
			if ((Object)(object)chunk == (Object)null || chunk.LocalPaths == null || chunk.LocalPaths.Count == 0)
			{
				return null;
			}
			Vector2 size = chunk.Size;
			if (size.x <= 0.001f || size.y <= 0.001f)
			{
				return null;
			}
			int num = Mathf.Clamp(Mathf.CeilToInt(size.x * 48f), 8, 48);
			int num2 = Mathf.Clamp(Mathf.CeilToInt(size.y * 48f), 8, 48);
			Color32[] array = (Color32[])(object)new Color32[num * num2];
			Color32 val = default(Color32);
			((Color32)(ref val))..ctor((byte)0, (byte)0, (byte)0, (byte)0);
			Color32 val2 = default(Color32);
			((Color32)(ref val2))..ctor(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue);
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = val;
			}
			Vector2 val3 = size * 0.5f;
			for (int j = 0; j < num2; j++)
			{
				float num3 = Mathf.Lerp(0f - val3.y, val3.y, ((float)j + 0.5f) / (float)num2);
				for (int k = 0; k < num; k++)
				{
					float num4 = Mathf.Lerp(0f - val3.x, val3.x, ((float)k + 0.5f) / (float)num);
					if (PointInAnyPath(new Vector2(num4, num3), chunk.LocalPaths))
					{
						array[j * num + k] = val2;
						filledPixels++;
					}
				}
			}
			if (filledPixels == 0)
			{
				LogDiagnosticWarning($"[Destroyer] Empty exact mask: object={chunk.Owner?.ObjectID ?? (-1)} chunk={chunk.ChunkIndex} size={size.x:F3}x{size.y:F3} paths={chunk.LocalPaths.Count}");
				return null;
			}
			texture = new Texture2D(num, num2, (TextureFormat)4, false);
			((Object)texture).name = name + "_Texture";
			((Texture)texture).filterMode = (FilterMode)0;
			((Texture)texture).wrapMode = (TextureWrapMode)1;
			texture.SetPixels32(array);
			texture.Apply(false, true);
			Sprite val4 = Sprite.Create(texture, new Rect(0f, 0f, (float)num, (float)num2), new Vector2(0.5f, 0.5f), 48f);
			((Object)val4).name = name;
			return val4;
		}

		internal static Vector3 GetChunkSpriteScale(DestroyerChunk chunk, Sprite sprite)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: 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_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: 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_00b2: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)chunk == (Object)null || (Object)(object)sprite == (Object)null)
			{
				return Vector3.one;
			}
			Rect rect = sprite.rect;
			float num = ((Rect)(ref rect)).width / sprite.pixelsPerUnit;
			rect = sprite.rect;
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(num, ((Rect)(ref rect)).height / sprite.pixelsPerUnit);
			float num2 = ((val.x > 0.001f) ? (chunk.Size.x / val.x) : 1f);
			float num3 = ((val.y > 0.001f) ? (chunk.Size.y / val.y) : 1f);
			return new Vector3(num2, num3, 1f);
		}

		private static bool PointInAnyPath(Vector2 point, List<Vector2[]> paths)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < paths.Count; i++)
			{
				Vector2[] array = paths[i];
				if (array != null && array.Length >= 3 && PointInPath(point, array))
				{
					return true;
				}
			}
			return false;
		}

		private static bool PointInPath(Vector2 point, Vector2[] path)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: 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_0030: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: 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_0055: 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_0063: 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_0078: Unknown result type (might be due to invalid IL or missing references)
			bool flag = false;
			int num = path.Length - 1;
			for (int i = 0; i < path.Length; i++)
			{
				Vector2 val = path[i];
				Vector2 val2 = path[num];
				if (val.y > point.y != val2.y > point.y && point.x < (val2.x - val.x) * (point.y - val.y) / (val2.y - val.y + 1E-06f) + val.x)
				{
					flag = !flag;
				}
				num = i;
			}
			return flag;
		}

		private static string GetStablePath(Transform root, Transform transform)
		{
			string text = transform.GetSiblingIndex().ToString("D4");
			Transform parent = transform.parent;
			while ((Object)(object)parent != (Object)null && (Object)(object)parent != (Object)(object)root)
			{
				text = parent.GetSiblingIndex().ToString("D4") + "/" + text;
				parent = parent.parent;
			}
			return text;
		}

		private static int GetColliderComponentIndex(Collider2D collider)
		{
			Collider2D[] components = ((Component)collider).GetComponents<Collider2D>();
			for (int i = 0; i < components.Length; i++)
			{
				if ((Object)(object)components[i] == (Object)(object)collider)
				{
					return i;
				}
			}
			return 0;
		}
	}
	public class DestroyerChunkObject : MonoBehaviour
	{
		public readonly List<DestroyerChunk> Chunks = new List<DestroyerChunk>(64);

		private SpriteRenderer originalRenderer = null;

		private SFPolygon originalShadow = null;

		private SpriteMask originalMask = null;

		private DestroyerVisualMesh visualMesh = null;

		private readonly List<GameObject> chunkMasks = new List<GameObject>(64);

		private bool originalColliderEnabled;

		private bool originalRendererEnabled;

		private bool originalShadowEnabled;

		private bool originalMaskEnabled;

		public int ObjectID { get; private set; }

		public Collider2D OriginalCollider { get; private set; } = null;

		public SpriteRenderer OriginalRenderer => originalRenderer;

		public void Initialize(int objectID, Collider2D sourceCollider, SpriteRenderer sourceRenderer, SFPolygon shadow, SpriteMask mask)
		{
			ObjectID = objectID;
			OriginalCollider = sourceCollider;
			originalRenderer = sourceRenderer;
			originalShadow = shadow;
			originalMask = mask;
			originalColliderEnabled = (Object)(object)sourceCollider != (Object)null && ((Behaviour)sourceCollider).enabled;
			originalRendererEnabled = (Object)(object)sourceRenderer != (Object)null && ((Renderer)sourceRenderer).enabled;
			originalShadowEnabled = (Object)(object)shadow != (Object)null && ((Behaviour)shadow).enabled;
			originalMaskEnabled = (Object)(object)mask != (Object)null && ((Renderer)mask).enabled;
		}

		public void ActivateChunkedVisual(Map map)
		{
			if ((Object)(object)OriginalCollider != (Object)null)
			{
				((Behaviour)OriginalCollider).enabled = false;
			}
			if ((Object)(object)originalRenderer != (Object)null)
			{
				visualMesh = DestroyerVisualMesh.Create(this, originalRenderer, map);
				visualMesh.Rebuild();
				((Renderer)originalRenderer).enabled = false;
			}
			if ((Object)(object)originalMask != (Object)null && originalMaskEnabled)
			{
				BuildChunkMasks(map);
				((Renderer)originalMask).enabled = false;
			}
			else
			{
				DestroyerChunkManager.LogDiagnostic(string.Format("[Destroyer] Exact masks skipped object={0}: originalMask={1}", ObjectID, ((Object)(object)originalMask != (Object)null) ? "disabled" : "missing"));
			}
			if ((Object)(object)originalShadow != (Object)null)
			{
				((Behaviour)originalShadow).enabled = false;
			}
		}

		public void RestoreAndDestroyChunks()
		{
			if ((Object)(object)OriginalCollider != (Object)null)
			{
				((Behaviour)OriginalCollider).enabled = originalColliderEnabled;
			}
			if ((Object)(object)originalRenderer != (Object)null)
			{
				((Renderer)originalRenderer).enabled = originalRendererEnabled;
			}
			if ((Object)(object)originalShadow != (Object)null)
			{
				((Behaviour)originalShadow).enabled = originalShadowEnabled;
			}
			if ((Object)(object)originalMask != (Object)null)
			{
				((Renderer)originalMask).enabled = originalMaskEnabled;
			}
			if (visualMesh != null)
			{
				visualMesh.DestroyVisual();
				visualMesh = null;
			}
			for (int num = chunkMasks.Count - 1; num >= 0; num--)
			{
				if ((Object)(object)chunkMasks[num] != (Object)null)
				{
					chunkMasks[num].SetActive(false);
					Object.Destroy((Object)(object)chunkMasks[num]);
				}
			}
			chunkMasks.Clear();
			for (int num2 = Chunks.Count - 1; num2 >= 0; num2--)
			{
				if ((Object)(object)Chunks[num2] != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)Chunks[num2]).gameObject);
				}
			}
			Chunks.Clear();
			Object.Destroy((Object)(object)this);
		}

		public void BreakAround(Vector2 hitPoint, float radius, int seed, int breakCount)
		{
			//IL_00dd: 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_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			float num = radius * radius;
			int num2 = 0;
			int num3 = Mathf.Clamp(breakCount, 1, 5);
			for (int i = 0; i < num3; i++)
			{
				DestroyerChunk destroyerChunk = null;
				float num4 = float.PositiveInfinity;
				for (int j = 0; j < Chunks.Count; j++)
				{
					DestroyerChunk destroyerChunk2 = Chunks[j];
					if ((Object)(object)destroyerChunk2 == (Object)null || destroyerChunk2.IsBroken)
					{
						continue;
					}
					float num5 = destroyerChunk2.DistanceSqrTo(hitPoint);
					if (!(num5 > num) || num2 <= 0)
					{
						float num6 = 0.9f + DestroyerChunkManager.Hash01(seed, destroyerChunk2.ChunkIndex) * 0.2f;
						float num7 = num5 * num6;
						if (num7 < num4)
						{
							num4 = num7;
							destroyerChunk = destroyerChunk2;
						}
					}
				}
				if ((Object)(object)destroyerChunk == (Object)null || (num2 == 0 && destroyerChunk.DistanceSqrTo(hitPoint) > num * 2.25f))
				{
					break;
				}
				if (destroyerChunk.IsProtected)
				{
					destroyerChunk.HitProtected(hitPoint, seed + num2);
					break;
				}
				destroyerChunk.Break(hitPoint, seed + num2);
				num2++;
			}
		}

		public void OnChunkBroken(DestroyerChunk chunk)
		{
			if (!((Object)(object)chunk == (Object)null))
			{
				if (visualMesh != null)
				{
					visualMesh.Rebuild();
				}
				if (chunk.ChunkIndex >= 0 && chunk.ChunkIndex < chunkMasks.Count && (Object)(object)chunkMasks[chunk.ChunkIndex] != (Object)null)
				{
					chunkMasks[chunk.ChunkIndex].SetActive(false);
				}
			}
		}

		public void OnProtectedChunkHit(DestroyerChunk chunk, Vector2 hitPoint, int seed)
		{
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Expected O, but got Unknown
			//IL_00be: 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_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)chunk == (Object)null) && !((Object)(object)originalRenderer == (Object)null))
			{
				Texture2D texture;
				int filledPixels;
				Sprite val = DestroyerChunkManager.CreateChunkMaskSprite(chunk, $"DestroyerProtectedFlashSprite_{ObjectID}_{chunk.ChunkIndex}", out texture, out filledPixels);
				if ((Object)(object)val == (Object)null || (Object)(object)texture == (Object)null)
				{
					DestroyerChunkManager.LogDiagnosticWarning($"[Destroyer] Protected flash failed: object={ObjectID} chunk={chunk.ChunkIndex}");
					return;
				}
				GameObject val2 = new GameObject("DestroyerProtectedFlash");
				val2.layer = ((Component)originalRenderer).gameObject.layer;
				val2.transform.position = new Vector3(chunk.Center.x, chunk.Center.y, ((Component)originalRenderer).transform.position.z);
				val2.transform.rotation = Quaternion.identity;
				val2.transform.localScale = DestroyerChunkManager.GetChunkSpriteScale(chunk, val);
				SpriteRenderer val3 = val2.AddComponent<SpriteRenderer>();
				val3.sprite = val;
				((Renderer)val3).sortingLayerName = "MostFront";
				((Renderer)val3).sortingOrder = 180;
				val3.color = Color.white;
				DestroyerProtectedFlash destroyerProtectedFlash = val2.AddComponent<DestroyerProtectedFlash>();
				destroyerProtectedFlash.Initialize(val3, val, texture, seed);
				DestroyerChunkManager.LogDiagnostic($"[Destroyer] Protected hit: object={ObjectID} chunk={chunk.ChunkIndex} filledPixels={filledPixels} point=({hitPoint.x:F2},{hitPoint.y:F2})");
			}
		}

		public Material GetVisualMaterial()
		{
			if (visualMesh == null)
			{
				return null;
			}
			return visualMesh.Material;
		}

		private void BuildChunkMasks(Map map)
		{
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Expected O, but got Unknown
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)