Decompiled source of MFM v3.7.1
MFM.dll
Decompiled 5 days ago
The result has been truncated due to the large size, download it to view full contents!
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)