Decompiled source of ChaosMonkey v1.0.0

Mods/ChaosMonkey.dll

Decompiled 3 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BTD_Mod_Helper;
using BTD_Mod_Helper.Api;
using BTD_Mod_Helper.Api.Components;
using BTD_Mod_Helper.Api.Display;
using BTD_Mod_Helper.Api.Helpers;
using BTD_Mod_Helper.Api.Towers;
using BTD_Mod_Helper.Api.UI;
using BTD_Mod_Helper.Extensions;
using ChaosMonkey.Btd6;
using ChaosMonkey.Core;
using Il2Cpp;
using Il2CppAssets.Scripts.Models;
using Il2CppAssets.Scripts.Models.Entities;
using Il2CppAssets.Scripts.Models.GenericBehaviors;
using Il2CppAssets.Scripts.Models.TowerSets;
using Il2CppAssets.Scripts.Models.Towers;
using Il2CppAssets.Scripts.Models.Towers.Behaviors;
using Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack;
using Il2CppAssets.Scripts.Models.Towers.Filters;
using Il2CppAssets.Scripts.Models.Towers.Projectiles;
using Il2CppAssets.Scripts.Models.Towers.Projectiles.Behaviors;
using Il2CppAssets.Scripts.Models.Towers.Weapons;
using Il2CppAssets.Scripts.Simulation.Display;
using Il2CppAssets.Scripts.Simulation.Objects;
using Il2CppAssets.Scripts.Simulation.Towers;
using Il2CppAssets.Scripts.Unity.Display;
using Il2CppAssets.Scripts.Unity.UI_New.InGame;
using Il2CppAssets.Scripts.Unity.UI_New.InGame.TowerSelectionMenu;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppTMPro;
using MelonLoader;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(ChaosMonkeyMod), "Chaos Monkey", "1.0.0", "Lauri", null)]
[assembly: MelonGame("Ninja Kiwi", "BloonsTD6")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("ChaosMonkey")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ChaosMonkey")]
[assembly: AssemblyTitle("ChaosMonkey")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ChaosMonkey.Btd6
{
	public sealed class ChaosDeveloperWindow : ModWindow
	{
		private const int ItemsPerPage = 10;

		private const string PanelTexture = "ChaosGachaVerticalPanel";

		private const string TextFieldTexture = "ChaosTextField";

		private readonly Dictionary<EquipmentSlot, ModHelperText> slotTexts = new Dictionary<EquipmentSlot, ModHelperText>();

		private readonly List<ModHelperText> itemTexts = new List<ModHelperText>();

		private EquipmentSlot selectedSlot;

		private int itemPage;

		private ModHelperText? selectedSlotText;

		private ModHelperText? statusText;

		private ModHelperText? pageText;

		private string status = "WÄHLE EINEN SLOT UND DANACH EIN TEST-ITEM.";

		public override int DefaultWidth => 1280;

		public override int DefaultHeight => 1440;

		public override bool AllowMultiple => false;

		public override bool AllowResizing => false;

		public override Info WindowInfo
		{
			get
			{
				//IL_0035: 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_0057: Unknown result type (might be due to invalid IL or missing references)
				//IL_0061: Unknown result type (might be due to invalid IL or missing references)
				Info result = default(Info);
				((Info)(ref result))..ctor(((ModContent)this).Name);
				((Info)(ref result)).set_Width((float)((ModWindow)this).DefaultWidth);
				((Info)(ref result)).set_Height((float)((ModWindow)this).DefaultHeight);
				((Info)(ref result)).set_Anchor(new Vector2(0.5f, 0.5f));
				((Info)(ref result)).set_Pivot(new Vector2(0.5f, 0.5f));
				((Info)(ref result)).set_Position(Vector2.zero);
				return result;
			}
		}

		public override void ModifyWindow(ModHelperWindow window)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			((ModHelperComponent)window.content).AddImage(new Info("DeveloperPanel", 0f, 0f, 1150f, 1320f), ModContent.GetSpriteReference<ChaosMonkeyMod>("ChaosGachaVerticalPanel").guidRef);
			AddTextField(window, "DeveloperHeader", 0f, 572f, 880f, 68f, "CHAOS MONKEY • DEVELOPER LOADOUT", 31f);
			AddTextField(window, "DeveloperWarning", 0f, 497f, 880f, 52f, "TEST-MODUS • KEINE ROLLS, PITYS ODER ACHIEVEMENTS", 22f);
			selectedSlotText = AddTextField(window, "DeveloperSelectedSlot", 195f, 414f, 600f, 50f, BuildSelectedSlotText(), 23f);
			float num = 352f;
			EquipmentSlot[] values = Enum.GetValues<EquipmentSlot>();
			foreach (EquipmentSlot slot in values)
			{
				AddSlotButton(window, slot, num);
				num -= 114f;
			}
			for (int j = 0; j < 10; j++)
			{
				AddItemButton(window, j, 352f - (float)j * 84f);
			}
			AddPageButton(window, "DeveloperPreviousPage", -90f, -475f, "PREVIOUS PAGE", delegate
			{
				ChangePage(-1);
			});
			pageText = AddTextField(window, "DeveloperPage", 245f, -475f, 300f, 46f, BuildPageText(), 19f);
			AddPageButton(window, "DeveloperNextPage", 580f, -475f, "NEXT PAGE", delegate
			{
				ChangePage(1);
			});
			statusText = AddTextField(window, "DeveloperStatus", 0f, -540f, 930f, 62f, status, 20f);
			((Graphic)GameObjectExt.AddButton(((Component)window.content).gameObject, new Info("DeveloperClose", 0f, -612f, 560f, 62f), "F8 • SCHLIESSEN", (Action)delegate
			{
				window.Close();
			}).Image).color = new Color(1f, 1f, 1f, 0f);
		}

		public override void OnUpdate(ModHelperWindow window)
		{
			if (!ChaosMonkeyMod.IsDeveloperModeAvailable || !ChaosMonkeyMod.Session.IsChaosMonkeyPresent)
			{
				window.Close();
				return;
			}
			ModHelperText? obj = selectedSlotText;
			if (obj != null)
			{
				obj.SetText(BuildSelectedSlotText());
			}
			ModHelperText? obj2 = statusText;
			if (obj2 != null)
			{
				obj2.SetText(status);
			}
			ModHelperText? obj3 = pageText;
			if (obj3 != null)
			{
				obj3.SetText(BuildPageText());
			}
			if (Input.GetKeyDown((KeyCode)280) || Input.GetKeyDown((KeyCode)276))
			{
				ChangePage(-1);
			}
			if (Input.GetKeyDown((KeyCode)281) || Input.GetKeyDown((KeyCode)275))
			{
				ChangePage(1);
			}
			foreach (var (slot, val2) in slotTexts)
			{
				val2.SetText(BuildSlotText(slot));
			}
			IReadOnlyList<ItemDefinition> developerItems = ChaosMonkeyMod.Session.GetDeveloperItems(selectedSlot);
			int num = itemPage * 10;
			for (int i = 0; i < itemTexts.Count; i++)
			{
				int num2 = num + i;
				itemTexts[i].SetText((num2 < developerItems.Count) ? BuildItemText(developerItems[num2]) : string.Empty);
			}
		}

		public override void OnClose(ModHelperWindow window)
		{
			slotTexts.Clear();
			itemTexts.Clear();
			selectedSlotText = null;
			statusText = null;
			pageText = null;
			itemPage = 0;
		}

		private void AddSlotButton(ModHelperWindow window, EquipmentSlot slot, float y)
		{
			//IL_00bb: 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)
			slotTexts[slot] = AddTextField(window, $"DeveloperSlot{slot}", -302f, y, 390f, 88f, BuildSlotText(slot), 22f);
			((Graphic)GameObjectExt.AddButton(((Component)window.content).gameObject, new Info($"DeveloperSlotSelect{slot}", -302f, y, 408f, 94f), string.Empty, (Action)delegate
			{
				selectedSlot = slot;
				itemPage = 0;
				status = GetSlotName(slot) + " AUSGEWÄHLT • RECHTS EIN ITEM ANKLICKEN.";
			}).Image).color = new Color(1f, 1f, 1f, 0f);
		}

		private void AddItemButton(ModHelperWindow window, int index, float y)
		{
			//IL_00b0: 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)
			ModHelperText item = AddTextField(window, $"DeveloperItem{index}", 245f, y, 650f, 70f, string.Empty, 22f);
			itemTexts.Add(item);
			((Graphic)GameObjectExt.AddButton(((Component)window.content).gameObject, new Info($"DeveloperItemSelect{index}", 245f, y, 674f, 76f), string.Empty, (Action)delegate
			{
				ApplyItem(index);
			}).Image).color = new Color(1f, 1f, 1f, 0f);
		}

		private static void AddPageButton(ModHelperWindow window, string name, float x, float y, string label, Action action)
		{
			//IL_003d: 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)
			AddTextField(window, name + "Label", x, y, 200f, 46f, label, 17f);
			((Graphic)GameObjectExt.AddButton(((Component)window.content).gameObject, new Info(name, x, y, 206f, 52f), string.Empty, action).Image).color = new Color(1f, 1f, 1f, 0f);
		}

		private void ApplyItem(int index)
		{
			IReadOnlyList<ItemDefinition> developerItems = ChaosMonkeyMod.Session.GetDeveloperItems(selectedSlot);
			int num = itemPage * 10 + index;
			if (num >= developerItems.Count)
			{
				return;
			}
			try
			{
				ItemDefinition itemDefinition = developerItems[num];
				ChaosMonkeyMod.EquipDeveloperItem(itemDefinition.Id);
				status = "TEST-ITEM GESETZT: " + itemDefinition.DisplayName.ToUpperInvariant() + " • KEINE ACHIEVEMENTS.";
			}
			catch (InvalidOperationException ex)
			{
				status = ex.Message.ToUpperInvariant();
			}
		}

		private void ChangePage(int direction)
		{
			int pageCount = GetPageCount();
			itemPage = Mathf.Clamp(itemPage + direction, 0, pageCount - 1);
		}

		private int GetPageCount()
		{
			int count = ChaosMonkeyMod.Session.GetDeveloperItems(selectedSlot).Count;
			return Math.Max(1, (count + 10 - 1) / 10);
		}

		private string BuildPageText()
		{
			return $"SEITE {itemPage + 1} / {GetPageCount()}";
		}

		private string BuildSelectedSlotText()
		{
			EvolutionState evolutionState = ChaosMonkeyMod.Session.Match?.Evolution;
			string text = ((evolutionState != null && evolutionState.IsInProgress) ? "EVOLUTION LÄUFT • SLOTS GESPERRT" : ((evolutionState != null && evolutionState.IsComplete) ? "EVOLUTION ABGESCHLOSSEN • SLOTS GESPERRT" : "TEST-AUSRÜSTUNG"));
			return "AUSGEWÄHLT: " + GetSlotName(selectedSlot) + " • " + text;
		}

		private string BuildSlotText(EquipmentSlot slot)
		{
			ItemDefinition itemDefinition = ChaosMonkeyMod.Session.Match?.GetItem(slot);
			string text = ((slot == selectedSlot) ? "  •  AUSGEWÄHLT" : string.Empty);
			return GetSlotName(slot) + text + "\n" + (((object)itemDefinition == null) ? "LEER" : itemDefinition.DisplayName.ToUpperInvariant());
		}

		private static string BuildItemText(ItemDefinition item)
		{
			return $"{item.Rarity.ToString().ToUpperInvariant()}  •  {item.DisplayName.ToUpperInvariant()}\n{item.Summary.ToUpperInvariant()}";
		}

		private static ModHelperText AddTextField(ModHelperWindow window, string name, float x, float y, float width, float height, string text, float fontSize)
		{
			//IL_0017: 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)
			((ModHelperComponent)window.content).AddImage(new Info(name + "Panel", x, y, width, height), ModContent.GetSpriteReference<ChaosMonkeyMod>("ChaosTextField").guidRef);
			ModHelperText obj = ((ModHelperComponent)window.content).AddText(new Info(name, x, y, width - 28f, height - 8f), text, fontSize, (TextAlignmentOptions)514);
			obj.EnableAutoSizing(fontSize, 16f);
			return obj;
		}

		private static string GetSlotName(EquipmentSlot slot)
		{
			return slot switch
			{
				EquipmentSlot.Weapon => "WAFFE", 
				EquipmentSlot.Ammo => "MUNITION", 
				EquipmentSlot.Body => "KÖRPER", 
				EquipmentSlot.Head => "KOPF", 
				EquipmentSlot.Trait => "TRAIT", 
				EquipmentSlot.Ability => "FÄHIGKEIT", 
				_ => slot.ToString().ToUpperInvariant(), 
			};
		}
	}
	public sealed class ChaosMonkeyGodlyEvolutionDisplay : ModTowerCustomDisplay<ChaosMonkeyTower>
	{
		public override string AssetBundleName => "chaosmonkeyevolutions";

		public override string PrefabName => "ChaosMonkeyGodlyEvolution";

		public override bool LoadAsync => false;

		public override bool UseForTower(params int[] tiers)
		{
			return false;
		}

		public override void ModifyDisplayNode(UnityDisplayNode node)
		{
			ChaosEvolutionDisplayMaterials.Apply(node, secret: false);
		}
	}
	public sealed class ChaosMonkeySecretEvolutionDisplay : ModTowerCustomDisplay<ChaosMonkeyTower>
	{
		public override string AssetBundleName => "chaosmonkeyevolutions";

		public override string PrefabName => "ChaosMonkeySecretEvolution";

		public override bool LoadAsync => false;

		public override bool UseForTower(params int[] tiers)
		{
			return false;
		}

		public override void ModifyDisplayNode(UnityDisplayNode node)
		{
			ChaosEvolutionDisplayMaterials.Apply(node, secret: true);
		}
	}
	internal static class ChaosEvolutionDisplayMaterials
	{
		private static Material? safeTowerMaterial;

		internal static void CaptureTowerMaterial(UnityDisplayNode? node)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			if ((Object)(object)safeTowerMaterial != (Object)null || (Object)(object)node == (Object)null)
			{
				return;
			}
			foreach (Renderer componentsInChild in ((Component)node).GetComponentsInChildren<Renderer>(true))
			{
				if (!((Object)(object)componentsInChild.sharedMaterial == (Object)null))
				{
					safeTowerMaterial = new Material(componentsInChild.sharedMaterial);
					break;
				}
			}
		}

		internal static void Apply(UnityDisplayNode node, bool secret)
		{
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: 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_00e1: 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_0104: Unknown result type (might be due to invalid IL or missing references)
			Sprite sprite = ModContent.GetSprite<ChaosMonkeyMod>(secret ? "ChaosMonkeySecretEvolution" : "ChaosMonkeyGodlyEvolution", 100f);
			Texture2D val = ((sprite == null) ? null : sprite.texture);
			foreach (Renderer componentsInChild in ((Component)node).GetComponentsInChildren<Renderer>(true))
			{
				bool flag = ((Object)((Component)componentsInChild).gameObject).name.StartsWith("SolidMonkey_", StringComparison.Ordinal);
				Material val2 = CreateSafeMaterial(flag ? null : val);
				if (!((Object)(object)val2 == (Object)null))
				{
					if (val2.HasProperty("_Cull"))
					{
						val2.SetInt("_Cull", 0);
					}
					Color val3 = ((!flag && val != null) ? Color.white : GetPartColor(((Object)((Component)componentsInChild).gameObject).name, secret));
					if (val2.HasProperty("_Color"))
					{
						val2.SetColor("_Color", val3);
					}
					if (val2.HasProperty("_BaseColor"))
					{
						val2.SetColor("_BaseColor", val3);
					}
					if (val2.HasProperty("_EmissionColor"))
					{
						val2.SetColor("_EmissionColor", val3 * 0.2f);
					}
					componentsInChild.material = val2;
					componentsInChild.enabled = true;
				}
			}
		}

		private static Material? CreateSafeMaterial(Texture2D? conceptTexture)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Expected O, but got Unknown
			Shader val = Shader.Find("Sprites/Default");
			if ((Object)(object)val != (Object)null)
			{
				Material val2 = new Material(val);
				if (val2.HasProperty("_MainTex"))
				{
					val2.SetTexture("_MainTex", (Texture)(object)(conceptTexture ?? Texture2D.whiteTexture));
				}
				return val2;
			}
			if ((Object)(object)safeTowerMaterial != (Object)null)
			{
				return new Material(safeTowerMaterial);
			}
			Shader val3 = Shader.Find("Unlit/Color");
			if (!((Object)(object)val3 == (Object)null))
			{
				return new Material(val3);
			}
			return null;
		}

		private static Color GetPartColor(string name, bool secret)
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			int num = name.LastIndexOf("__CM", StringComparison.Ordinal);
			if (num >= 0 && name.Length >= num + "__CM".Length + 8)
			{
				string text = name.Substring(num + "__CM".Length, 8);
				Color result = default(Color);
				if (ColorUtility.TryParseHtmlString("#" + text, ref result))
				{
					return result;
				}
			}
			if (name.Contains("Eye"))
			{
				return new Color(0.1f, 0.94f, 1f, 1f);
			}
			if (name.Contains("Crystal") || name.Contains("Core") || name.Contains("Gem") || name.Contains("Planet"))
			{
				if (!secret)
				{
					return new Color(0.95f, 0.18f, 1f, 1f);
				}
				return new Color(0.86f, 0.07f, 1f, 1f);
			}
			if (name.Contains("Crown") || name.Contains("Halo") || name.Contains("Staff"))
			{
				if (!secret)
				{
					return new Color(1f, 0.72f, 0.1f, 1f);
				}
				return new Color(0.22f, 0.04f, 0.48f, 1f);
			}
			if (name.Contains("Robe") || name.Contains("Cape") || name.Contains("Hood"))
			{
				if (!secret)
				{
					return new Color(0.31f, 0.06f, 0.62f, 1f);
				}
				return new Color(0.035f, 0.008f, 0.1f, 1f);
			}
			if (!secret)
			{
				return new Color(0.47f, 0.2f, 0.09f, 1f);
			}
			return new Color(0.055f, 0.012f, 0.14f, 1f);
		}
	}
	internal static class ChaosItemArtwork
	{
		private static readonly Dictionary<string, Sprite> sprites = new Dictionary<string, Sprite>(StringComparer.Ordinal);

		internal static Sprite GetSprite(ItemDefinition item)
		{
			if (sprites.TryGetValue(item.Id, out Sprite value))
			{
				return value;
			}
			Sprite sprite = ModContent.GetSprite<ChaosMonkeyMod>($"ChaosItemIcon{item.Slot}{item.Rarity}", 100f);
			sprites[item.Id] = sprite;
			return sprite;
		}

		internal static Color GetTint(ItemDefinition item)
		{
			//IL_0026: 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_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: 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_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: 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)
			if (item.Tags.Contains("Fire"))
			{
				return new Color(1f, 0.58f, 0.38f, 1f);
			}
			if (item.Tags.Contains("Frost"))
			{
				return new Color(0.48f, 0.88f, 1f, 1f);
			}
			if (item.Tags.Contains("Poison"))
			{
				return new Color(0.55f, 1f, 0.42f, 1f);
			}
			if (item.Tags.Contains("Lightning"))
			{
				return new Color(0.72f, 0.86f, 1f, 1f);
			}
			if (item.Tags.Contains("Gravity") || item.Tags.Contains("Void"))
			{
				return new Color(0.72f, 0.45f, 1f, 1f);
			}
			if (item.Tags.Contains("Time"))
			{
				return new Color(1f, 0.78f, 0.35f, 1f);
			}
			if (item.Tags.Contains("Reality"))
			{
				return new Color(1f, 0.42f, 0.78f, 1f);
			}
			if (item.Rarity == Rarity.Secret)
			{
				return new Color(0.72f, 0.42f, 1f, 1f);
			}
			return Color.white;
		}
	}
	internal sealed record ChaosItemDetails(string Stats, string Effect, string Synergy);
	internal static class ChaosItemDetailsCatalog
	{
		public static ChaosItemDetails Get(ItemDefinition item)
		{
			return item.Id switch
			{
				"rusty-dart" => Detail("1 DMG • 3 PIERCE • 0.90s", "Simple rapid dart attack. A dependable opening weapon.", "Pairs with basic or burning ammunition."), 
				"chaos-slingshot" => Detail("2 DMG • 2 PIERCE • 1.00s", "Launches heavy chaotic pebbles for reliable early damage.", "Chaos Ammo effects can add splinters."), 
				"twin-darts" => Detail("2 DARTS • 1 DMG • 0.95s", "Fires a matched pair of darts with each attack.", "Benefits especially from split and burning ammunition."), 
				"scrap-blaster" => Detail("1 DMG • 6 PIERCE • 1.10s", "Sprays a broad piece of scrap through grouped Bloons.", "Pierce bonuses turn scrap into crowd control."), 
				"chaos-needle" => Detail("1 DMG • 2 PIERCE • 0.35s", "Fires extremely quickly at a single target.", "Proc ammunition has many chances to trigger."), 
				"pebble-launcher" => Detail("3 DMG • 2 PIERCE • 1.45s", "Throws slow, heavy pebbles with strong direct impact.", "Gravity effects keep targets in the impact line."), 
				"broken-wand" => Detail("1 DMG • BONUS HIT 15%", "A cracked wand occasionally fires an additional magic bolt.", "Luck improves the bonus-hit chance."), 
				"toy-cannon" => Detail("4 DMG • 3 PIERCE • 1.70s", "A deceptively strong toy shell fires very slowly.", "Explosion ammunition increases its impact area."), 
				"double-chaos-blaster" => Detail("2 BOLTS • 2 DMG • 0.80s", "Releases two chaotic bolts at once.", "Chaos Affinity strengthens both bolts."), 
				"spiked-launcher" => Detail("4 DMG • 8 PIERCE • 1.10s", "Fires a heavy spike that tears through dense groups.", "Piercing Plasma pushes the pierce even higher."), 
				"mini-cannon" => Detail("3 DMG • SMALL BLAST • 1.25s", "Fires compact shells that damage nearby Bloons on impact.", "Gravity Ammo clusters targets for the blast."), 
				"ricochet-gun" => Detail("2 DMG • 4 PIERCE • 1 BOUNCE", "Every shot rebounds once into a nearby Bloon.", "Extra bounces with Lightning Ammo."), 
				"poison-dart-gun" => Detail("1 DMG • POISON 4s • 0.70s", "Poisons hit Bloons, dealing damage over time.", "Toxic effects combine with Poison Ammo."), 
				"rapid-chaos-bow" => Detail("2 DMG • 3 PIERCE • 0.45s", "Rapidly fires chaotic arrows down the track.", "Chaos Split Ammo creates a fragment storm."), 
				"plasma-rifle" => Detail("3 DMG • 10 PIERCE • 0.65s", "Fires hot plasma rounds that cut through crowds.", "Plasma shots benefit strongly from Body bonuses."), 
				"gravity-cannon" => Detail("3 DMG • PULL • 1.15s", "Impacts create a small gravity pull around the target.", "Gravity Ammo extends the pull duration."), 
				"chain-lightning-staff" => Detail("2 DMG • 4 TARGETS • 0.80s", "A lightning strike jumps between nearby targets.", "Storm equipment adds chain targets."), 
				"frost-launcher" => Detail("2 DMG • CHILL 30% • 1.05s", "Chilling shells slow struck Bloons for a short time.", "Freezing effects strengthen the chill."), 
				"meteor-cannon" => Detail("5 DMG • METEOR 12% • 1.30s", "Occasionally calls a meteor onto the current target area.", "Meteor Ammo raises the impact frequency."), 
				"void-blaster" => Detail("4 DMG • 12 PIERCE • 0.75s", "Void bolts pierce dense groups and leave a brief tear.", "Void Mask and Void Ammo amplify rifts."), 
				"soul-reaper" => Detail("3 DMG • EXECUTE BONUS • 0.85s", "Deals increasing bonus damage to already weakened Bloons.", "Soul effects mark targets for the Reaper."), 
				"black-hole-launcher" => Detail("5 DMG • 6 PIERCE • 1.20s", "Impacts briefly pull Bloons toward a miniature singularity.", "Gravity equipment extends the pull."), 
				"chaos-accelerator" => Detail("2–8 DMG • COMBO • 0.55s", "Repeated hits on the same target grow stronger until the combo breaks.", "Focused keeps the combo on tough targets."), 
				"reality-rifle" => Detail("7 DMG • 18 PIERCE • 0.90s", "Some shots bypass ordinary Bloon physics and properties.", "Reality Ammo makes bypasses more reliable."), 
				"dragon-cannon" => Detail("8 DMG/s • BEAM • 18 PIERCE", "Channels a continuous dragonfire beam through Bloons.", "Dragonfire Ammo adds a spreading flame wave."), 
				"time-breaker" => Detail("6 DMG • TIME SLOW 20% • 1.00s", "Hits sometimes briefly slow the target; the effect is weaker against MOABs.", "Time Ammo and Time Crown extend the slow."), 
				"void-destroyer" => Detail("14 DMG • RIFT • 1.40s", "Each impact opens a damaging void rift on the track.", "Rift Ammo makes each rift wider."), 
				"judgement-cannon" => Detail("12 DMG • +MOAB DMG • 1.90s", "Fires an immense slow shell that deals more damage to powerful targets.", "Focused and World Eater raise its MOAB damage."), 
				"eternal-chaos" => Detail("CHAOS PROC • 0.55s", "Each attack randomly triggers lightning, gravity, fire, time or void.", "Full Godly Harmony stabilizes every chaos proc."), 
				"genesis-weapon" => Detail("ADAPTIVE ATTACK • 0.60s", "Changes its projectile form to match the equipped Ammo and build.", "Its strongest form is discovered through mixed-element loadouts."), 
				"basic-ammo" => Detail("STANDARD ROUND", "Reliable ammunition with no additional effect.", "A clean base for any weapon."), 
				"burning-ammo" => Detail("+1 BURN DMG • 3s", "Hits ignite Bloons and deal damage over time.", "Dragon Cannon turns burns into wider flames."), 
				"lightning-ammo" => Detail("+2 CHAIN TARGETS", "A hit releases a short chain of lightning.", "Storm Helmet and Staff increase the chain."), 
				"gravity-ammo" => Detail("PULL • 1.0s", "Hits drag nearby Bloons toward the impact point.", "Black Hole Launcher strengthens the pull."), 
				"void-ammo" => Detail("VOID TEAR • 12%", "Some impacts leave a brief damaging void tear.", "Void Blaster improves tear duration."), 
				"chaos-split-ammo" => Detail("3 SPLINTERS • 25%", "A quarter of hits split into three chaotic fragments.", "Chaos Affinity increases split reliability."), 
				"dragonfire-ammo" => Detail("FIRE WAVE • 4s", "Direct hits emit a short dragonfire wave.", "Dragon Cannon doubles the visual fire trail."), 
				"rift-ammo" => Detail("AREA RIFT • 2.5s", "Creates a larger area-damage rift after impact.", "Void and Reality loadouts expand the rift."), 
				"law-of-chaos-ammo" => Detail("ADAPTIVE PROC • EVERY HIT", "Adapts a random elemental effect to the equipped weapon.", "Full Godly Harmony lets all elements coexist."), 
				"basic-body" => Detail("+1 DMG • +1 PIERCE", "A small all-round improvement to the Monkey's attacks.", "Useful with every early loadout."), 
				"storm-body" => Detail("STORM PULSE • 5s", "Periodically releases a lightning pulse around the Monkey.", "Storm Helmet gives the pulse more targets."), 
				"gravity-body" => Detail("PULL AURA • 12 RANGE", "A small field slows and draws nearby Bloons together.", "Gravity Ammo makes the aura more forceful."), 
				"chaos-core-body" => Detail("ROTATING BONUS • 4s", "Cycles through small damage, pierce, speed and range bonuses.", "Chaos weapons inherit the active bonus."), 
				"time-lord-body" => Detail("TIME SLOW • 15%", "Nearby Bloons are periodically slowed by warped time.", "Time Crown extends the slow duration."), 
				"world-eater-body" => Detail("+MOAB DMG • STACKING", "Gains additional power while fighting MOAB-class Bloons.", "Focused makes every MOAB stack stronger."), 
				"celestial-core" => Detail("5-SLOT AMPLIFIER", "Empowers the other five equipped slots at once.", "A key component of Godly Harmony."), 
				"singularity-body" => Detail("BLACK HOLE • 18s", "Occasionally forms a compact black hole that pulls and damages Bloons.", "Secret Harmony turns it into a galaxy rift."), 
				"basic-cap" => Detail("FOCUS TARGETING", "Improves target focus for consistent first-target attacks.", "Works with every weapon."), 
				"storm-helmet" => Detail("+2 STORM TARGETS", "Storm and lightning effects can hit more targets.", "Best with Lightning Ammo or the Staff."), 
				"void-mask" => Detail("+20% VOID DURATION", "Void tears and rifts remain active longer.", "Pairs with Void Blaster and Rift Ammo."), 
				"reality-mask" => Detail("PROPERTY BYPASS • 20%", "Some attacks partially ignore Bloon properties.", "Reality Collapse gains extra area damage."), 
				"time-crown" => Detail("+30% TIME EFFECT", "Extends and strengthens all time manipulation.", "Time Stop becomes more reliable."), 
				"crown-of-oblivion" => Detail("OBLIVION MARK • 10%", "Marked Bloons receive amplified void and reality damage.", "Void Destroyer consumes the mark."), 
				"crown-of-infinity" => Detail("GODLY AMPLIFIER", "Raises the effect of every Godly item in the loadout.", "Required for a fully harmonized Godly build."), 
				"quick-learner" => Detail("+12% ATTACK SPEED", "The Monkey attacks faster with every weapon.", "A flexible early-game trait."), 
				"lucky" => Detail("+8% PROC CHANCE", "Slightly improves every chance-based effect.", "Helps chaos, void and critical effects."), 
				"focused" => Detail("+25% MOAB DMG", "Deals more damage to MOAB-class Bloons.", "Excellent with World Eater Body."), 
				"gambler" => Detail("CRIT • 8% ×5", "Rare hits deal massively increased damage.", "Absolute Luck increases crit consistency."), 
				"chaos-affinity" => Detail("+25% CHAOS POWER", "Strengthens random chaos effects and their duration.", "Eternal Chaos becomes much more stable."), 
				"reality-bender" => Detail("RULE SHIFT • 12s", "Periodically changes one active combat rule in your favor.", "Reality Mask reveals the next shift."), 
				"absolute-luck" => Detail("+35% PROC POWER", "Strongly boosts all chance-based effects and random outcomes.", "Godly Harmony shares the luck bonus."), 
				"chaos-blast" => Detail("ABILITY • 20s CD", "Detonates a small chaos blast at the selected location.", "Chaos Affinity adds a random secondary effect."), 
				"lightning-strike" => Detail("ABILITY • 24s CD", "Calls a targeted lightning strike onto the track.", "Storm equipment causes additional jumps."), 
				"gravity-pulse" => Detail("ABILITY • 28s CD", "Pulls nearby Bloons into a compact cluster.", "Gravity Body increases the pulse radius."), 
				"void-rift" => Detail("ABILITY • 34s CD", "Creates a large damaging rift on the track.", "Void Mask extends the rift duration."), 
				"time-stop" => Detail("ABILITY • 42s CD", "Temporarily slows the entire nearby track.", "Time Lord Body increases slow strength."), 
				"reality-collapse" => Detail("ABILITY • 50s CD", "Collapses reality in an area and deals damage over time.", "Reality Mask allows partial property bypass."), 
				"ascendant-chaos" => Detail("ABILITY • 60s CD", "Triggers a coordinated surge of all six Godly effects.", "Full Godly Harmony lowers its cooldown."), 
				"the-unwritten-blade" => Detail("UNWRITTEN RULE • PROPERTY ERASE", "A black blade can remove Camo, Regrow or Fortified from the target.", "Pairs with Reality effects; all six Secrets begin Unknown Resonance."), 
				"event-horizon" => Detail("COLLAPSE • SCALING SINGULARITY", "Creates a singularity at the target; stronger Bloons make stronger collapses.", "Combines with Singularity Core and The Black Halo."), 
				"null-weapon" => Detail("[NULL] • NO VISIBLE SHOT", "It seems to fire nothing until Bloons vanish outside normal damage rules.", "Its hidden interaction is revealed only by other Secret items."), 
				"forbidden-matter" => Detail("CORRUPTION • DETONATION", "Hits add corruption; a fully corrupted Bloon explodes.", "Works especially well with rapid or split weapons."), 
				"yesterday" => Detail("TIME ECHO • REWIND HIT", "A struck Bloon can be returned to an earlier point on the track.", "Pairs with Rewind for the Paradox Secret synergy."), 
				"outside" => Detail("OUTSIDE MAP • PHASE SHOT", "Shots pass obstacles, bypass protected targets and can reappear behind them.", "Reality and Null effects unlock its strangest behaviour."), 
				"observer-body" => Detail("OBSERVATION • ESCALATING MARK", "Bloons remaining in view are marked and take increasingly heavy damage.", "Pairs with The Watching Eye to form The Observer."), 
				"singularity-core" => Detail("GRAVITY • CROWD POWER", "Pulls nearby Bloons inward and becomes stronger as the crowd grows.", "Pairs with The Black Halo for Endless Gravity."), 
				"forgotten-body" => Detail("FORGOTTEN • RECOGNITION LOSS", "Some Bloons lose their normal recognition of the Monkey.", "A Secret-only defensive rule break."), 
				"watching-eye" => Detail("PREDICTION • PERFECT TRACKING", "Predicts movement for exceptionally precise target acquisition.", "Pairs with Observer Body for The Observer."), 
				"crown-of-nothing" => Detail("NOTHING • RULE REMOVAL", "Every 20–30 seconds removes a negative effect and may erase enemy properties.", "Reality effects make property removal more reliable."), 
				"the-black-halo" => Detail("GRAVITY RING • CHARGED WAVE", "Continuously slows and gathers Bloons before releasing a gravity wave.", "Pairs with Singularity Core for Endless Gravity."), 
				"impossible-luck" => Detail("INVISIBLE LUCK CHECK", "Every roll secretly receives a second luck check.", "A Secret effect: it never appears in the public odds table."), 
				"fate-secret" => Detail("FATE COUNTER • EVENT", "A hidden counter grows while the Monkey survives, then triggers a powerful random event.", "Works with Yesterday for the Paradox route."), 
				"existence" => Detail("EXISTENCE • SIX-SLOT BONUS", "Some normal rules cannot affect the Monkey; all six categories receive a small bonus.", "Enhances every completed Secret loadout."), 
				"erase" => Detail("ERASE • LONG COOLDOWN", "After a delay, destroys normal Bloons or deals huge BAD and boss damage.", "Secret Evolution turns it into an ascendant reality tear."), 
				"rewind" => Detail("REWIND • TIME RESET", "Returns Bloons to earlier positions and repeats part of recent damage.", "Pairs with Yesterday for the Paradox Secret synergy."), 
				"unknown-ability" => Detail("??? • UNPREDICTABLE", "After a silent delay, it chooses a massive random Secret effect.", "The full Secret set reveals the Unknown Resonance."), 
				_ => CreateDefault(item), 
			};
		}

		public static ChaosItemDetails Empty(EquipmentSlot slot)
		{
			return new ChaosItemDetails($"{ChaosEconomy.SlotRollCosts[slot]} SHARDS • SELECTED ROLL", "Choose " + SlotName(slot) + " and use a Normal Roll to discover its first item.", "Items with matching tags unlock synergy bonuses. The final evolutions remain hidden.");
		}

		public static string SlotName(EquipmentSlot slot)
		{
			return slot switch
			{
				EquipmentSlot.Weapon => "WEAPON", 
				EquipmentSlot.Ammo => "AMMO", 
				EquipmentSlot.Body => "BODY", 
				EquipmentSlot.Head => "HEAD", 
				EquipmentSlot.Trait => "TRAIT", 
				EquipmentSlot.Ability => "ABILITY", 
				_ => slot.ToString().ToUpperInvariant(), 
			};
		}

		private static ChaosItemDetails Detail(string stats, string effect, string synergy)
		{
			return new ChaosItemDetails(stats, effect, synergy);
		}

		private static ChaosItemDetails CreateDefault(ItemDefinition item)
		{
			string[] array = item.Tags.Where((string tag) => !string.Equals(tag, "Secret", StringComparison.OrdinalIgnoreCase)).ToArray();
			string text = ((array.Length == 0) ? "GENERAL" : string.Join(" • ", array).ToUpperInvariant());
			return Detail($"{item.Rarity.ToString().ToUpperInvariant()} {SlotName(item.Slot)} • {text}", item.Summary, (array.Length == 0) ? "A flexible item with no required pairing." : ("SYNERGY: combines with matching " + text + " equipment."));
		}
	}
	public sealed class ChaosLuckOddsWindow : ModWindow
	{
		private const float TableScale = 1.35f;

		private const string TextFieldTexture = "ChaosTextField";

		private readonly Dictionary<Rarity, ModHelperText> oddsLabels = new Dictionary<Rarity, ModHelperText>();

		private readonly GachaEngine gacha = new GachaEngine();

		private ModHelperText? luckText;

		private ModHelperText? nextLuckText;

		private ModHelperText? resultText;

		private string result = "NORMAL ROLLS USE THE DISPLAYED ODDS.";

		public override int DefaultWidth => 920;

		public override int DefaultHeight => 480;

		public override bool AllowMultiple => false;

		public override bool AllowResizing => false;

		public override Info WindowInfo
		{
			get
			{
				//IL_0035: 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_0061: Unknown result type (might be due to invalid IL or missing references)
				//IL_006b: Unknown result type (might be due to invalid IL or missing references)
				Info val = default(Info);
				((Info)(ref val))..ctor(((ModContent)this).Name);
				((Info)(ref val)).set_Width((float)((ModWindow)this).DefaultWidth);
				((Info)(ref val)).set_Height((float)((ModWindow)this).DefaultHeight);
				((Info)(ref val)).set_Anchor(new Vector2(0.5f, 1f));
				((Info)(ref val)).set_Pivot(new Vector2(0.5f, 1f));
				((Info)(ref val)).set_Position(new Vector2(-270f, -8f));
				return val;
			}
		}

		public override void ModifyWindow(ModHelperWindow window)
		{
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			AddField(window, "LuckOddsTitle", 0f, 102f, 560f, 42f, "LUCK & DROP ODDS", 24f);
			luckText = AddField(window, "CurrentLuck", -174f, 56f, 210f, 40f, BuildLuckText(), 22f);
			nextLuckText = AddField(window, "NextLuck", 165f, 56f, 290f, 40f, BuildNextLuckText(), 18f);
			((Graphic)GameObjectExt.AddButton(((Component)window.content).gameObject, TableInfo("BuyNextLuck", 165f, 56f, 292f, 42f), string.Empty, (Action)PurchaseNextLuck).Image).color = new Color(1f, 1f, 1f, 0f);
			AddOddsRow(window, Rarity.Common, -172f, 8f);
			AddOddsRow(window, Rarity.Uncommon, -172f, -36f);
			AddOddsRow(window, Rarity.Rare, -172f, -80f);
			AddOddsRow(window, Rarity.Epic, -172f, -124f);
			AddOddsRow(window, Rarity.Legendary, 172f, 8f);
			AddOddsRow(window, Rarity.Mythic, 172f, -36f);
			AddOddsRow(window, Rarity.Godly, 172f, -80f);
			resultText = AddField(window, "LuckOddsResult", 0f, -178f, 670f, 36f, result, 15f);
		}

		public override void OnUpdate(ModHelperWindow window)
		{
			ModHelperText? obj = luckText;
			if (obj != null)
			{
				obj.SetText(BuildLuckText());
			}
			ModHelperText? obj2 = nextLuckText;
			if (obj2 != null)
			{
				obj2.SetText(BuildNextLuckText());
			}
			ModHelperText? obj3 = resultText;
			if (obj3 != null)
			{
				obj3.SetText(result);
			}
			foreach (var (rarity2, val2) in oddsLabels)
			{
				val2.SetText(BuildOddsText(rarity2));
			}
		}

		public override void OnClose(ModHelperWindow window)
		{
			luckText = null;
			nextLuckText = null;
			resultText = null;
			oddsLabels.Clear();
		}

		private void AddOddsRow(ModHelperWindow window, Rarity rarity, float x, float y)
		{
			oddsLabels[rarity] = AddField(window, $"Odds{rarity}", x, y, 305f, 34f, BuildOddsText(rarity), 17f);
		}

		private void PurchaseNextLuck()
		{
			try
			{
				int? nextLuck = GetNextLuck();
				if (!nextLuck.HasValue)
				{
					result = "LUCK IS ALREADY AT THE MAXIMUM ×2048.";
					return;
				}
				ChaosMonkeyMatchState? match = ChaosMonkeyMod.Session.Match;
				InGame instance = InGame.instance;
				if (match == null || !ChaosMonkeyMod.Session.IsChaosMonkeyPresent || instance == null)
				{
					throw new InvalidOperationException("SELECT AN ACTIVE CHAOS MONKEY FIRST.");
				}
				int num = ChaosEconomy.LuckCashCosts[nextLuck.Value];
				if (InGameExt.GetCash(instance) < (double)num)
				{
					result = $"NOT ENOUGH CASH FOR LUCK ×{nextLuck.Value}.";
				}
				else
				{
					InGameExt.AddCash(instance, (double)(-num));
					ChaosMonkeyMod.Session.PurchaseLuck(nextLuck.Value);
					result = $"LUCK UPGRADED TO ×{nextLuck.Value}. DROP ODDS UPDATED.";
				}
			}
			catch (InvalidOperationException ex)
			{
				result = ex.Message.ToUpperInvariant();
			}
		}

		private static ModHelperText AddField(ModHelperWindow window, string name, float x, float y, float width, float height, string text, float fontSize)
		{
			//IL_0017: 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)
			((ModHelperComponent)window.content).AddImage(TableInfo(name + "Panel", x, y, width, height), ModContent.GetSpriteReference<ChaosMonkeyMod>("ChaosTextField").guidRef);
			ModHelperText obj = ((ModHelperComponent)window.content).AddText(TableInfo(name, x, y, width - 18f, height - 5f), text, fontSize * 1.35f, (TextAlignmentOptions)514);
			obj.EnableAutoSizing(fontSize * 1.35f, 16.2f);
			return obj;
		}

		private static Info TableInfo(string name, float x, float y, float width, float height)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			return new Info(name, x * 1.35f, y * 1.35f, width * 1.35f, height * 1.35f);
		}

		private static string BuildLuckText()
		{
			ChaosMonkeyMatchState match = ChaosMonkeyMod.Session.Match;
			if (match != null)
			{
				return $"CURRENT LUCK ×{match.PurchasedLuck}";
			}
			return "CURRENT LUCK ×—";
		}

		private static string BuildNextLuckText()
		{
			int? nextLuck = GetNextLuck();
			if (nextLuck.HasValue)
			{
				return $"BUY LUCK ×{nextLuck.Value} • ${ChaosEconomy.LuckCashCosts[nextLuck.Value]:N0}";
			}
			return "LUCK MAXIMUM ×2048";
		}

		private string BuildOddsText(Rarity rarity)
		{
			int luckMultiplier = ChaosMonkeyMod.Session.Match?.PurchasedLuck ?? 1;
			IReadOnlyDictionary<Rarity, double> displayedOdds = gacha.GetDisplayedOdds(luckMultiplier);
			return $"{rarity.ToString().ToUpperInvariant()} • {displayedOdds[rarity]:0.000}%";
		}

		private static int? GetNextLuck()
		{
			int num = ChaosMonkeyMod.Session.Match?.PurchasedLuck ?? 1;
			for (int i = 0; i < ChaosEconomy.PurchasableLuck.Count - 1; i++)
			{
				if (ChaosEconomy.PurchasableLuck[i] == num)
				{
					return ChaosEconomy.PurchasableLuck[i + 1];
				}
			}
			return null;
		}
	}
	internal static class ChaosMonkeyAppearance
	{
		private readonly record struct LayerLayout(string TextureName, Vector3 Position, Vector3 Scale, float Rotation, int SortingOrder);

		private readonly record struct AnimatedEvolutionPart(Transform Transform, Vector3 BaseScale, bool Pulses);

		private const string RootName = "ChaosMonkeyLoadoutVisual";

		private const float PixelsPerUnit = 420f;

		private static readonly IReadOnlyDictionary<EquipmentSlot, LayerLayout> Layouts = new Dictionary<EquipmentSlot, LayerLayout>
		{
			[EquipmentSlot.Weapon] = new LayerLayout("SlotWeaponIcon", new Vector3(0.58f, 0.08f, -0.3f), new Vector3(0.54f, 0.54f, 1f), -12f, 30),
			[EquipmentSlot.Ammo] = new LayerLayout("SlotAmmoIcon", new Vector3(-0.44f, -0.2f, -0.25f), new Vector3(0.38f, 0.38f, 1f), 16f, 40),
			[EquipmentSlot.Body] = new LayerLayout("SlotBodyIcon", new Vector3(0f, -0.06f, -0.2f), new Vector3(0.48f, 0.48f, 1f), 0f, 50),
			[EquipmentSlot.Head] = new LayerLayout("SlotHeadIcon", new Vector3(0f, 0.55f, -0.2f), new Vector3(0.46f, 0.46f, 1f), 0f, 60),
			[EquipmentSlot.Trait] = new LayerLayout("SlotTraitIcon", new Vector3(-0.62f, 0.42f, -0.35f), new Vector3(0.34f, 0.34f, 1f), 12f, 70),
			[EquipmentSlot.Ability] = new LayerLayout("SlotAbilityIcon", new Vector3(0f, -0.08f, 0.4f), new Vector3(0.68f, 0.68f, 1f), 0f, 10)
		};

		private static Tower? activeTower;

		private static UnityDisplayNode? activeDisplayNode;

		private static SpriteRenderer? pulseRenderer;

		private static float pulseEndsAt;

		private static Transform? evolutionRig;

		private static readonly List<AnimatedEvolutionPart> evolutionOrbitParts = new List<AnimatedEvolutionPart>();

		private static readonly List<Material> evolutionMaterials = new List<Material>();

		private static bool evolutionUsesMesh;

		private static bool evolutionUsesTowerDisplay;

		private static float evolutionOrbitTime;

		private static float nextEvolutionIntegrityCheckAt;

		private static EvolutionKind? appliedEvolutionDisplay;

		internal static void Attach(Tower tower)
		{
			activeTower = tower;
			ChaosMonkeyCombat.Apply(tower);
			Rebuild(celebrate: false, null);
		}

		internal static bool IsAttachedTo(Tower tower)
		{
			if (activeTower != null)
			{
				return activeTower == tower;
			}
			return false;
		}

		internal static void RegisterGraphics(IReadOnlyList<UnityDisplayNode> nodes)
		{
			activeDisplayNode = ((IEnumerable<UnityDisplayNode>)nodes).FirstOrDefault((Func<UnityDisplayNode, bool>)((UnityDisplayNode node) => (Object)(object)node != (Object)null));
			ModHelper.Msg<ChaosMonkeyMod>((object)$"Chaos graphics captured: {nodes.Count} node(s), live node: {(Object)(object)activeDisplayNode != (Object)null}.");
			if (activeTower != null)
			{
				Rebuild(celebrate: false, null);
			}
		}

		internal static void RefreshAfterRoll(RollResult result)
		{
			if (activeTower != null)
			{
				ChaosMonkeyCombat.Apply(activeTower);
			}
			Rebuild(celebrate: true, result);
		}

		internal static void RefreshAfterDeveloperLoadout()
		{
			if (activeTower != null)
			{
				ChaosMonkeyCombat.Apply(activeTower);
			}
			Rebuild(celebrate: false, null);
		}

		internal static void RefreshAfterEvolution()
		{
			if (activeTower != null)
			{
				ChaosMonkeyCombat.Apply(activeTower);
			}
			Rebuild(celebrate: false, null);
		}

		internal static void RefreshForSelection(Tower tower)
		{
			activeTower = tower;
			Rebuild(celebrate: false, null);
		}

		internal static void Reset()
		{
			activeTower = null;
			activeDisplayNode = null;
			pulseRenderer = null;
			pulseEndsAt = 0f;
			evolutionRig = null;
			evolutionOrbitParts.Clear();
			DisposeEvolutionMaterials();
			evolutionUsesMesh = false;
			evolutionUsesTowerDisplay = false;
			evolutionOrbitTime = 0f;
			nextEvolutionIntegrityCheckAt = 0f;
			appliedEvolutionDisplay = null;
		}

		internal static bool TrySellActiveTower()
		{
			if (activeTower == null)
			{
				return false;
			}
			TowerExt.SellTower(activeTower);
			return true;
		}

		internal static void Tick()
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			EnsureEvolutionVisualIsAttached();
			TickSecretEvolutionRig();
			if (pulseRenderer != null)
			{
				if (Time.time >= pulseEndsAt)
				{
					Object.Destroy((Object)(object)((Component)pulseRenderer).gameObject);
					pulseRenderer = null;
					return;
				}
				float num = 1f - (pulseEndsAt - Time.time) / 1.2f;
				float num2 = 0.75f + num * 1.15f;
				Color color = pulseRenderer.color;
				color.a = (1f - num) * 0.72f;
				pulseRenderer.color = color;
				((Component)pulseRenderer).transform.localScale = new Vector3(num2, num2, 1f);
				((Component)pulseRenderer).transform.localEulerAngles = new Vector3(0f, 0f, num * 220f);
			}
		}

		private static void Rebuild(bool celebrate, RollResult? result)
		{
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Expected O, but got Unknown
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: 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)
			if (activeTower == null || !ChaosMonkeyMod.Session.IsChaosMonkeyPresent)
			{
				return;
			}
			try
			{
				ChaosMonkeyMatchState match = ChaosMonkeyMod.Session.Match;
				UnityDisplayNode liveDisplayNode = GetLiveDisplayNode();
				if ((Object)(object)liveDisplayNode == (Object)null)
				{
					return;
				}
				Transform transform = ((Component)liveDisplayNode).transform;
				SetBaseRenderersVisible(transform, visible: true);
				Transform val = transform.Find("ChaosMonkeyLoadoutVisual");
				if (val != null)
				{
					Object.Destroy((Object)(object)((Component)val).gameObject);
				}
				DisposeEvolutionMaterials();
				evolutionRig = null;
				evolutionOrbitParts.Clear();
				evolutionOrbitTime = 0f;
				nextEvolutionIntegrityCheckAt = Time.time + 0.45f;
				Renderer val2 = ((IEnumerable<Renderer>)((Component)transform).GetComponentsInChildren<Renderer>(true)).FirstOrDefault((Func<Renderer, bool>)((Renderer renderer) => renderer != null && !((Object)((Component)renderer).gameObject).name.StartsWith("ChaosMonkeyLoadoutVisual", StringComparison.Ordinal)));
				ModHelper.Msg<ChaosMonkeyMod>((object)$"Chaos display renderer scan: {val2 != null} visible renderer anchor.");
				int num = ((val2 == null) ? ((Component)transform).gameObject.layer : ((Component)val2).gameObject.layer);
				GameObject val3 = new GameObject("ChaosMonkeyLoadoutVisual");
				val3.transform.SetParent(transform, false);
				val3.layer = num;
				val3.transform.localPosition = new Vector3(0f, 0f, -0.1f);
				if (match != null && match.Evolution.IsComplete)
				{
					ChaosEvolutionDisplayMaterials.CaptureTowerMaterial(GetLiveDisplayNode());
					if (!TryApplyEvolutionTowerDisplay(match.Evolution.Kind))
					{
						AddStableEvolutionVisual(val3.transform, match.Evolution.Kind, num);
					}
					return;
				}
				appliedEvolutionDisplay = null;
				evolutionUsesTowerDisplay = false;
				if (match != null)
				{
					foreach (KeyValuePair<EquipmentSlot, LayerLayout> layout in Layouts)
					{
						layout.Deconstruct(out var key, out var value);
						EquipmentSlot equipmentSlot = key;
						LayerLayout layerLayout = value;
						ItemDefinition item = match.GetItem(equipmentSlot);
						if ((object)item != null)
						{
							AddLayer(val3.transform, $"ChaosMonkey{equipmentSlot}{item.Id}", item, layerLayout.Position, layerLayout.Scale, layerLayout.Rotation, layerLayout.SortingOrder);
						}
					}
				}
				if (celebrate && (object)result != null)
				{
					AddRollPulse(val3.transform, result.Item);
				}
			}
			catch (Exception ex)
			{
				ModHelper.Error<ChaosMonkeyMod>((object)("Could not refresh Chaos Monkey appearance: " + ex.Message));
			}
		}

		private static void AddStableEvolutionVisual(Transform parent, EvolutionKind kind, int visibleLayer)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: 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_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject($"ChaosMonkey{kind}EvolutionVisual");
			val.transform.SetParent(parent, false);
			val.layer = visibleLayer;
			val.transform.localPosition = new Vector3(0f, 0f, -0.22f);
			val.transform.localScale = Vector3.one * 0.82f;
			SpriteRenderer obj = val.AddComponent<SpriteRenderer>();
			obj.sprite = ModContent.GetSprite<ChaosMonkeyMod>((kind == EvolutionKind.SecretAscension) ? "ChaosMonkeySecretEvolution" : "ChaosMonkeyGodlyEvolution", 950f);
			obj.color = Color.white;
			((Renderer)obj).sortingOrder = 250;
			evolutionRig = val.transform;
			evolutionOrbitParts.Clear();
			evolutionOrbitTime = 0f;
			evolutionUsesMesh = false;
			evolutionUsesTowerDisplay = false;
			appliedEvolutionDisplay = kind;
			ModHelper.Msg<ChaosMonkeyMod>((object)$"Attached stable {kind} evolution visual without loading a runtime AssetBundle.");
		}

		private static bool TryAddBundledEvolutionVisual(Transform parent, EvolutionKind kind, int visibleLayer, Renderer? materialAnchor)
		{
			//IL_00c8: 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_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Expected O, but got Unknown
			try
			{
				if (((materialAnchor != null) ? materialAnchor.sharedMaterial : null) == null)
				{
					ModHelper.Warning<ChaosMonkeyMod>((object)"Evolution mesh is waiting for a live BTD6 material; using the safe fallback.");
					return false;
				}
				string text = ((kind == EvolutionKind.SecretAscension) ? "ChaosMonkeySecretEvolution" : "ChaosMonkeyGodlyEvolution");
				GameObject val = AssetBundleExt.LoadAssetSync<GameObject>(ModContent.GetBundle<ChaosMonkeyMod>("chaosmonkeyevolutions"), text);
				if ((Object)(object)val == (Object)null)
				{
					ModHelper.Warning<ChaosMonkeyMod>((object)("Evolution mesh prefab " + text + " was not found; using the safe fallback."));
					return false;
				}
				GameObject val2 = Object.Instantiate<GameObject>(val);
				((Object)val2).name = $"ChaosMonkey{kind}EvolutionMesh";
				val2.transform.SetParent(parent, false);
				val2.transform.localPosition = new Vector3(0f, -0.4f, -0.72f);
				val2.transform.localScale = Vector3.one * 0.46f;
				SetLayerRecursively(val2.transform, visibleLayer);
				Il2CppArrayBase<MeshRenderer> componentsInChildren = val2.GetComponentsInChildren<MeshRenderer>(true);
				if (componentsInChildren.Length == 0)
				{
					Object.Destroy((Object)(object)val2);
					ModHelper.Warning<ChaosMonkeyMod>((object)("Evolution mesh prefab " + text + " has no meshes; using the safe fallback."));
					return false;
				}
				foreach (MeshRenderer item in componentsInChildren)
				{
					Shader val3 = Shader.Find("Unlit/Color");
					Material val4 = ((val3 == null) ? new Material(materialAnchor.sharedMaterial) : new Material(val3));
					evolutionMaterials.Add(val4);
					((Renderer)item).sharedMaterial = val4;
					ApplyEvolutionPartColor(val4, kind, ((Object)((Component)item).gameObject).name);
					val4.renderQueue = 4000;
					if (val4.HasProperty("_Cull"))
					{
						val4.SetInt("_Cull", 0);
					}
					((Renderer)item).enabled = true;
				}
				evolutionRig = val2.transform;
				evolutionOrbitParts.Clear();
				evolutionOrbitTime = 0f;
				evolutionUsesMesh = true;
				evolutionUsesTowerDisplay = false;
				appliedEvolutionDisplay = kind;
				ModHelper.Msg<ChaosMonkeyMod>((object)$"Attached clean native 3D {kind} evolution mesh ({componentsInChildren.Length} parts).");
				return true;
			}
			catch (Exception ex)
			{
				DisposeEvolutionMaterials();
				ModHelper.Error<ChaosMonkeyMod>((object)("Could not attach the clean 3D evolution mesh: " + ex.Message));
				return false;
			}
		}

		private static void ApplyEvolutionPartColor(Material material, EvolutionKind kind, string partName)
		{
			//IL_000f: 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_0014: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			Color val = ((kind == EvolutionKind.SecretAscension) ? GetSecretEvolutionColor(partName) : GetGodlyEvolutionColor(partName));
			if (material.HasProperty("_Color"))
			{
				material.SetColor("_Color", val);
			}
			if (material.HasProperty("_BaseColor"))
			{
				material.SetColor("_BaseColor", val);
			}
		}

		private static bool TryApplyEvolutionTowerDisplay(EvolutionKind kind)
		{
			if (activeTower == null)
			{
				return false;
			}
			if (evolutionUsesTowerDisplay && appliedEvolutionDisplay == kind)
			{
				return true;
			}
			try
			{
				TowerModel val = TowerModelExt.MakeCopy(activeTower.towerModel, $"ChaosMonkey{kind}EvolutionRuntime", false, ((EntityModel)activeTower.towerModel).baseId);
				if (kind == EvolutionKind.SecretAscension)
				{
					TowerModelExt.SetDisplay<ChaosMonkeySecretEvolutionDisplay>(val);
				}
				else
				{
					TowerModelExt.SetDisplay<ChaosMonkeyGodlyEvolutionDisplay>(val);
				}
				activeDisplayNode = null;
				TowerExt.SetTowerModel(activeTower, val);
				evolutionRig = null;
				evolutionOrbitParts.Clear();
				evolutionUsesMesh = false;
				evolutionUsesTowerDisplay = true;
				appliedEvolutionDisplay = kind;
				ModHelper.Msg<ChaosMonkeyMod>((object)$"Applied {kind} through BTD6's native tower display pipeline.");
				return true;
			}
			catch (Exception ex)
			{
				evolutionUsesTowerDisplay = false;
				ModHelper.Error<ChaosMonkeyMod>((object)("Could not apply the native evolution tower display: " + ex.Message));
				return false;
			}
		}

		private static Color GetGodlyEvolutionColor(string partName)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			if (partName.Contains("Eye", StringComparison.Ordinal))
			{
				return new Color(0.08f, 0.92f, 1f, 1f);
			}
			if (partName.Contains("Crystal", StringComparison.Ordinal) || partName.Contains("Gem", StringComparison.Ordinal) || partName.Contains("Core", StringComparison.Ordinal))
			{
				return new Color(0.95f, 0.18f, 1f, 1f);
			}
			if (partName.Contains("Crown", StringComparison.Ordinal) || partName.Contains("Halo", StringComparison.Ordinal) || partName.Contains("Staff", StringComparison.Ordinal))
			{
				return new Color(1f, 0.72f, 0.1f, 1f);
			}
			if (partName.Contains("Robe", StringComparison.Ordinal) || partName.Contains("Cape", StringComparison.Ordinal) || partName.Contains("Hood", StringComparison.Ordinal))
			{
				return new Color(0.31f, 0.06f, 0.62f, 1f);
			}
			return new Color(0.47f, 0.2f, 0.09f, 1f);
		}

		private static Color GetSecretEvolutionColor(string partName)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			if (partName.Contains("Eye", StringComparison.Ordinal))
			{
				return new Color(0.12f, 0.94f, 1f, 1f);
			}
			if (partName.Contains("Crystal", StringComparison.Ordinal) || partName.Contains("Core", StringComparison.Ordinal) || partName.Contains("Planet", StringComparison.Ordinal))
			{
				return new Color(0.86f, 0.07f, 1f, 1f);
			}
			if (partName.Contains("Halo", StringComparison.Ordinal) || partName.Contains("Staff", StringComparison.Ordinal))
			{
				return new Color(0.2f, 0.04f, 0.48f, 1f);
			}
			if (partName.Contains("Robe", StringComparison.Ordinal) || partName.Contains("Cape", StringComparison.Ordinal) || partName.Contains("Crown", StringComparison.Ordinal))
			{
				return new Color(0.035f, 0.008f, 0.1f, 1f);
			}
			return new Color(0.055f, 0.012f, 0.14f, 1f);
		}

		private static void SetBaseRenderersVisible(Transform displayTransform, bool visible)
		{
			Transform val = displayTransform.Find("ChaosMonkeyLoadoutVisual");
			foreach (Renderer componentsInChild in ((Component)displayTransform).GetComponentsInChildren<Renderer>(true))
			{
				if (val == null || !((Component)componentsInChild).transform.IsChildOf(val))
				{
					componentsInChild.enabled = visible;
				}
			}
		}

		private static void SetLayerRecursively(Transform transform, int layer)
		{
			((Component)transform).gameObject.layer = layer;
			for (int i = 0; i < transform.childCount; i++)
			{
				SetLayerRecursively(transform.GetChild(i), layer);
			}
		}

		private static void DisposeEvolutionMaterials()
		{
			foreach (Material evolutionMaterial in evolutionMaterials)
			{
				if ((Object)(object)evolutionMaterial != (Object)null)
				{
					Object.Destroy((Object)(object)evolutionMaterial);
				}
			}
			evolutionMaterials.Clear();
		}

		private static void AddLayer(Transform parent, string name, ItemDefinition item, Vector3 position, Vector3 scale, float rotation, int sortingOrder, float pixelsPerUnit = 420f)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: 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_002a: 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_0036: 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_004f: 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)
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent, false);
			val.layer = ((Component)parent).gameObject.layer;
			val.transform.localPosition = position;
			val.transform.localScale = scale;
			val.transform.localEulerAngles = new Vector3(0f, 0f, rotation);
			SpriteRenderer obj = val.AddComponent<SpriteRenderer>();
			obj.sprite = ChaosItemArtwork.GetSprite(item);
			obj.color = ChaosItemArtwork.GetTint(item);
			((Renderer)obj).sortingOrder = sortingOrder;
		}

		private static void AddRollPulse(Transform root, ItemDefinition item)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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_003d: 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_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("ChaosMonkeyRollPulse");
			val.transform.SetParent(root, false);
			val.layer = ((Component)root).gameObject.layer;
			val.transform.localPosition = new Vector3(0f, 0f, 0.6f);
			val.transform.localScale = new Vector3(0.75f, 0.75f, 1f);
			pulseRenderer = val.AddComponent<SpriteRenderer>();
			pulseRenderer.sprite = ModContent.GetSprite<ChaosMonkeyMod>("SlotAbilityIcon", 420f);
			Color itemColor = GetItemColor(item);
			itemColor.a = 0.72f;
			pulseRenderer.color = itemColor;
			((Renderer)pulseRenderer).sortingOrder = 100;
			pulseEndsAt = Time.time + 1.2f;
		}

		private static void AddSecretEvolutionRig(Transform parent, UnityDisplayNode displayNode)
		{
			//IL_0015: 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_002a: Expected O, but got Unknown
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: 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_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: 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_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_0288: Unknown result type (might be due to invalid IL or missing references)
			TintVanillaMonkey(displayNode, new Color(0.12f, 0.03f, 0.28f, 1f));
			GameObject val = new GameObject("ChaosMonkeySecretEvolution3DRig");
			val.transform.SetParent(parent, false);
			val.layer = ((Component)parent).gameObject.layer;
			val.transform.localPosition = new Vector3(0f, 0.03f, 0.25f);
			evolutionRig = val.transform;
			RegisterAnimatedPart(CreateEvolutionMesh("SecretVoidCore", (PrimitiveType)0, val.transform, new Vector3(0f, -0.02f, 0.35f), new Vector3(0.52f, 0.52f, 0.52f), new Color(0.035f, 0.008f, 0.1f, 1f)), pulse: false);
			CreateEvolutionMesh("SecretGalaxyHalo", (PrimitiveType)2, val.transform, new Vector3(0f, -0.04f, 0.2f), new Vector3(1.35f, 0.035f, 1.35f), new Color(0.18f, 0.02f, 0.42f, 0.85f)).transform.localEulerAngles = new Vector3(68f, 0f, 0f);
			Color[] array = (Color[])(object)new Color[6]
			{
				new Color(0.5f, 0.05f, 1f),
				new Color(0.05f, 0.82f, 1f),
				new Color(0.96f, 0.05f, 0.68f),
				new Color(0.16f, 0.03f, 0.35f),
				new Color(0.38f, 0.1f, 0.92f),
				new Color(0.05f, 0.46f, 0.92f)
			};
			for (int i = 0; i < array.Length; i++)
			{
				float num = (float)i * MathF.PI * 2f / (float)array.Length;
				GameObject obj = CreateEvolutionMesh($"SecretOrbitCrystal{i}", (PrimitiveType)1, val.transform, new Vector3(Mathf.Cos(num) * 1.12f, Mathf.Sin(num) * 0.72f, -0.06f), new Vector3(0.18f, 0.3f, 0.18f), array[i]);
				obj.transform.localEulerAngles = new Vector3(35f, (float)i * 55f, (float)(-i) * 21f);
				RegisterAnimatedPart(obj, pulse: true);
			}
		}

		private static void AddGodlyEvolutionRig(Transform parent, UnityDisplayNode displayNode)
		{
			//IL_0015: 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_002a: Expected O, but got Unknown
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: 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_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: 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_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_0295: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0312: Unknown result type (might be due to invalid IL or missing references)
			//IL_0317: Unknown result type (might be due to invalid IL or missing references)
			//IL_0332: Unknown result type (might be due to invalid IL or missing references)
			//IL_0337: Unknown result type (might be due to invalid IL or missing references)
			//IL_0352: Unknown result type (might be due to invalid IL or missing references)
			//IL_0357: Unknown result type (might be due to invalid IL or missing references)
			//IL_0372: Unknown result type (might be due to invalid IL or missing references)
			//IL_0377: Unknown result type (might be due to invalid IL or missing references)
			//IL_0392: Unknown result type (might be due to invalid IL or missing references)
			//IL_0397: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: 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_040d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0421: Unknown result type (might be due to invalid IL or missing references)
			//IL_0429: Unknown result type (might be due to invalid IL or missing references)
			//IL_0451: Unknown result type (might be due to invalid IL or missing references)
			TintVanillaMonkey(displayNode, new Color(0.66f, 0.25f, 0.98f, 1f));
			GameObject val = new GameObject("ChaosMonkeyGodlyEvolution3DRig");
			val.transform.SetParent(parent, false);
			val.layer = ((Component)parent).gameObject.layer;
			val.transform.localPosition = new Vector3(0f, 0.02f, 0.24f);
			evolutionRig = val.transform;
			CreateEvolutionMesh("GodlyCrownBand", (PrimitiveType)2, val.transform, new Vector3(0f, 0.7f, 0.05f), new Vector3(0.52f, 0.1f, 0.52f), new Color(1f, 0.7f, 0.08f, 1f)).transform.localEulerAngles = new Vector3(90f, 0f, 0f);
			for (int i = 0; i < 5; i++)
			{
				float num = (float)(i - 2) * 0.18f;
				RegisterAnimatedPart(CreateEvolutionMesh($"GodlyCrownCrystal{i}", (PrimitiveType)1, val.transform, new Vector3(num, 0.88f + (float)(i % 2) * 0.08f, 0.08f), new Vector3(0.11f, 0.28f, 0.11f), (i % 2 == 0) ? new Color(0.12f, 0.92f, 1f, 1f) : new Color(0.96f, 0.12f, 0.88f, 1f)), pulse: true);
			}
			RegisterAnimatedPart(CreateEvolutionMesh("GodlyChestCore", (PrimitiveType)0, val.transform, new Vector3(0f, 0.12f, 0.33f), new Vector3(0.34f, 0.34f, 0.2f), new Color(0.04f, 0.82f, 1f, 1f)), pulse: true);
			CreateEvolutionMesh("GodlyCrystalStaff", (PrimitiveType)2, val.transform, new Vector3(0.56f, 0.1f, 0.08f), new Vector3(0.08f, 0.72f, 0.08f), new Color(0.76f, 0.12f, 1f, 1f)).transform.localEulerAngles = new Vector3(0f, 0f, -28f);
			CreateEvolutionMesh("GodlyCrystalHalo", (PrimitiveType)2, val.transform, new Vector3(0f, 0.22f, 0.02f), new Vector3(1.22f, 0.025f, 1.22f), new Color(1f, 0.64f, 0.08f, 1f)).transform.localEulerAngles = new Vector3(68f, 0f, 0f);
			Color[] array = (Color[])(object)new Color[6]
			{
				new Color(0.08f, 0.92f, 1f, 1f),
				new Color(0.98f, 0.2f, 0.88f, 1f),
				new Color(0.4f, 1f, 0.22f, 1f),
				new Color(1f, 0.68f, 0.05f, 1f),
				new Color(0.48f, 0.18f, 1f, 1f),
				new Color(0.92f, 0.94f, 1f, 1f)
			};
			for (int j = 0; j < array.Length; j++)
			{
				float num2 = (float)j * MathF.PI * 2f / (float)array.Length;
				GameObject obj = CreateEvolutionMesh($"GodlyOrbitCrystal{j}", (PrimitiveType)1, val.transform, new Vector3(Mathf.Cos(num2) * 0.98f, 0.2f + Mathf.Sin(num2) * 0.6f, -0.08f), new Vector3(0.15f, 0.29f, 0.15f), array[j]);
				obj.transform.localEulerAngles = new Vector3(42f, (float)j * 56f, (float)(-j) * 23f);
				RegisterAnimatedPart(obj, pulse: true);
			}
		}

		private static GameObject CreateEvolutionMesh(string name, PrimitiveType type, Transform parent, Vector3 position, Vector3 scale, Color color)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = GameObject.CreatePrimitive(type);
			((Object)obj).name = name;
			obj.transform.SetParent(parent, false);
			obj.layer = ((Component)parent).gameObject.layer;
			obj.transform.localPosition = position + new Vector3(0f, 0f, -0.75f);
			obj.transform.localScale = scale;
			Collider component = obj.GetComponent<Collider>();
			if (component != null)
			{
				Object.Destroy((Object)(object)component);
			}
			Renderer component2 = obj.GetComponent<Renderer>();
			if (component2 != null)
			{
				Shader val = Shader.Find("Unlit/Color");
				if (val != null)
				{
					component2.material = new Material(val);
				}
				if (component2.material != null)
				{
					component2.material.renderQueue = 4000;
					if (component2.material.HasProperty("_Color"))
					{
						component2.material.color = color;
					}
				}
				component2.enabled = true;
			}
			return obj;
		}

		private static void TintVanillaMonkey(UnityDisplayNode displayNode, Color tint)
		{
			//IL_0039: 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)
			foreach (Renderer componentsInChild in ((Component)displayNode).GetComponentsInChildren<Renderer>(true))
			{
				if (((Object)((Component)componentsInChild).gameObject).name.StartsWith("ChaosMonkeyLoadoutVisual", StringComparison.Ordinal))
				{
					continue;
				}
				SpriteRenderer val = (SpriteRenderer)(object)((componentsInChild is SpriteRenderer) ? componentsInChild : null);
				if (val != null)
				{
					val.color = tint;
					continue;
				}
				Material material = componentsInChild.material;
				if (material != null && material.HasProperty("_Color"))
				{
					material.color = tint;
				}
			}
		}

		private static void ApplyNativeEvolutionColor(EvolutionKind kind)
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: 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_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			if (activeTower != null)
			{
				DisplayNode displayNode = TowerExt.GetDisplayNode(activeTower);
				if (displayNode != null)
				{
					Color val = ((kind == EvolutionKind.SecretAscension) ? new Color(0.1f, 0.02f, 0.24f, 1f) : new Color(0.72f, 0.22f, 0.98f, 1f));
					displayNode.modifyColor = true;
					displayNode.colorRed = val.r;
					displayNode.colorGreen = val.g;
					displayNode.colorBlue = val.b;
				}
			}
		}

		private static void ClearNativeEvolutionColor()
		{
			if (activeTower != null)
			{
				DisplayNode displayNode = TowerExt.GetDisplayNode(activeTower);
				if (displayNode != null)
				{
					displayNode.modifyColor = false;
				}
			}
		}

		private static void RegisterAnimatedPart(GameObject part, bool pulse)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			evolutionOrbitParts.Add(new AnimatedEvolutionPart(part.transform, part.transform.localScale, pulse));
		}

		private static void TickSecretEvolutionRig()
		{
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: 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_0135: 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)
			if ((Object)(object)evolutionRig == (Object)null)
			{
				evolutionRig = null;
				evolutionOrbitParts.Clear();
				return;
			}
			evolutionOrbitTime += Time.deltaTime;
			if (evolutionUsesMesh)
			{
				evolutionRig.localEulerAngles = new Vector3(Mathf.Sin(evolutionOrbitTime * 0.75f) * 4f, Mathf.Sin(evolutionOrbitTime * 0.55f) * 7f, 0f);
			}
			else
			{
				evolutionRig.localEulerAngles = new Vector3(0f, 0f, Mathf.Sin(evolutionOrbitTime * 0.75f) * 3f);
			}
			for (int i = 0; i < evolutionOrbitParts.Count; i++)
			{
				AnimatedEvolutionPart animatedEvolutionPart = evolutionOrbitParts[i];
				if (animatedEvolutionPart.Transform != null)
				{
					Transform transform = animatedEvolutionPart.Transform;
					transform.localEulerAngles += new Vector3(46f, 96f + (float)i * 13f, 72f) * Time.deltaTime;
					if (animatedEvolutionPart.Pulses)
					{
						float num = 1f + Mathf.Sin(evolutionOrbitTime * 3.2f + (float)i) * 0.1f;
						animatedEvolutionPart.Transform.localScale = animatedEvolutionPart.BaseScale * num;
					}
				}
			}
		}

		private static void EnsureEvolutionVisualIsAttached()
		{
			ChaosMonkeyMatchState match = ChaosMonkeyMod.Session.Match;
			if (activeTower == null || match == null || !match.Evolution.IsComplete || Time.time < nextEvolutionIntegrityCheckAt)
			{
				return;
			}
			nextEvolutionIntegrityCheckAt = Time.time + 0.45f;
			try
			{
				if (appliedEvolutionDisplay != match.Evolution.Kind || (!evolutionUsesTowerDisplay && (Object)(object)evolutionRig == (Object)null))
				{
					Rebuild(celebrate: false, null);
				}
			}
			catch (Exception ex)
			{
				ModHelper.Error<ChaosMonkeyMod>((object)("Could not restore Chaos Monkey evolution visual: " + ex.Message));
			}
		}

		private static UnityDisplayNode? GetLiveDisplayNode()
		{
			if ((Object)(object)activeDisplayNode != (Object)null)
			{
				return activeDisplayNode;
			}
			if (activeTower == null)
			{
				return null;
			}
			DisplayNode displayNode = TowerExt.GetDisplayNode(activeTower);
			if ((Object)(object)((displayNode != null) ? displayNode.graphic : null) != (Object)null)
			{
				activeDisplayNode = displayNode.graphic;
				ModHelper.Msg<ChaosMonkeyMod>((object)"Chaos Monkey live display acquired from its simulation node.");
				return activeDisplayNode;
			}
			UnityDisplayNode unityDisplayNode = TowerExt.GetUnityDisplayNode(activeTower);
			if ((Object)(object)unityDisplayNode != (Object)null)
			{
				activeDisplayNode = unityDisplayNode;
				ModHelper.Msg<ChaosMonkeyMod>((object)"Chaos Monkey live display acquired through the tower bridge.");
				return activeDisplayNode;
			}
			return null;
		}

		internal static Color GetItemColor(ItemDefinition item)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: 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_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: 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_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: 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_0140: 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_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: 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_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: 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_0278: Unknown result type (might be due to invalid IL or missing references)
			//IL_029f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0314: Unknown result type (might be due to invalid IL or missing references)
			//IL_033b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0362: Unknown result type (might be due to invalid IL or missing references)
			//IL_038f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0389: Unknown result type (might be due to invalid IL or missing references)
			Color result = (Color)(item.Rarity switch
			{
				Rarity.Common => new Color(0.82f, 0.84f, 0.88f), 
				Rarity.Uncommon => new Color(0.4f, 1f, 0.52f), 
				Rarity.Rare => new Color(0.22f, 0.72f, 1f), 
				Rarity.Epic => new Color(0.82f, 0.27f, 1f), 
				Rarity.Legendary => new Color(1f, 0.42f, 0.1f), 
				Rarity.Mythic => new Color(1f, 0.12f, 0.5f), 
				Rarity.Godly => new Color(1f, 0.84f, 0.22f), 
				Rarity.Secret => new Color(1f, 0.04f, 0.25f), 
				_ => Color.white, 
			});
			if (item.Tags.Contains("Fire"))
			{
				return new Color(1f, 0.28f, 0.06f);
			}
			if (item.Tags.Contains("Frost"))
			{
				return new Color(0.32f, 0.88f, 1f);
			}
			if (item.Tags.Contains("Lightning"))
			{
				return new Color(0.18f, 0.92f, 1f);
			}
			if (item.Tags.Contains("Gravity"))
			{
				return new Color(0.38f, 0.25f, 1f);
			}
			if (item.Tags.Contains("Void"))
			{
				return new Color(0.7f, 0.12f, 1f);
			}
			if (item.Tags.Contains("Poison"))
			{
				return new Color(0.34f, 0.94f, 0.2f);
			}
			if (item.Tags.Contains("Meteor"))
			{
				return new Color(1f, 0.48f, 0.08f);
			}
			if (item.Tags.Contains("Soul"))
			{
				return new Color(0.2f, 1f, 0.78f);
			}
			if (item.Tags.Contains("Time"))
			{
				return new Color(1f, 0.74f, 0.12f);
			}
			if (item.Tags.Contains("Reality"))
			{
				return new Color(1f, 0.18f, 0.64f);
			}
			if (item.Tags.Contains("Genesis"))
			{
				return new Color(1f, 0.95f, 0.42f);
			}
			if (item.Tags.Contains("Celestial"))
			{
				return new Color(0.72f, 0.92f, 1f);
			}
			if (item.Tags.Contains("Oblivion"))
			{
				return new Color(0.5f, 0.05f, 0.72f);
			}
			if (item.Tags.Contains("Luck"))
			{
				return new Color(0.36f, 1f, 0.58f);
			}
			if (item.Tags.Contains("Moab"))
			{
				return new Color(1f, 0.52f, 0.15f);
			}
			if (item.Tags.Contains("Galaxy"))
			{
				return new Color(0.2f, 0.82f, 1f);
			}
			if (item.Tags.Contains("Secret"))
			{
				return new Color(0.62f, 0.08f, 1f);
			}
			return result;
		}
	}
	internal static class ChaosMonkeyCombat
	{
		internal static void Apply(Tower tower)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Expected O, but got Unknown
			ChaosMonkeyMatchState match = ChaosMonkeyMod.Session.Match;
			if (match == null)
			{
				return;
			}
			try
			{
				ChaosCombatStats chaosCombatStats = ChaosCombatBalance.Calculate(match.Equipment, ChaosMonkeyMod.Session.ActiveSynergies, match.Evolution);
				TowerModel towerModel = tower.towerModel;
				OverrideCamoDetectionModel behavior = TowerModelBehaviorExt.GetBehavior<OverrideCamoDetectionModel>(towerModel);
				if (behavior == null)
				{
					TowerModelBehaviorExt.AddBehavior<OverrideCamoDetectionModel>(towerModel, new OverrideCamoDetectionModel("ChaosMonkeyAlwaysDetectsCamo", true));
				}
				else
				{
					behavior.detectCamo = true;
				}
				AttackModel behavior2 = TowerModelBehaviorExt.GetBehavior<AttackModel>(towerModel);
				if (behavior2 == null || ((Il2CppArrayBase<WeaponModel>)(object)behavior2.weapons).Length == 0)
				{
					return;
				}
				towerModel.range = chaosCombatStats.Range;
				behavior2.range = chaosCombatStats.Range;
				FilterInvisibleModel behavior3 = AttackModelBehaviorExt.GetBehavior<FilterInvisibleModel>(behavior2);
				if (behavior3 == null)
				{
					AttackModelBehaviorExt.AddBehavior<FilterInvisibleModel>(behavior2, new FilterInvisibleModel("ChaosMonkeyCamoTargeting", true, false));
				}
				else
				{
					behavior3.isActive = true;
				}
				match.Equipment.TryGetValue(EquipmentSlot.Weapon, out ItemDefinition value);
				foreach (WeaponModel item in (Il2CppArrayBase<WeaponModel>)(object)behavior2.weapons)
				{
					item.Rate = chaosCombatStats.AttackCooldown;
					item.projectile.pierce = chaosCombatStats.Pierce;
					ProjectileModelExt.SetHitCamo(item.projectile, true);
					DamageModel behavior4 = ProjectileModelBehaviorExt.GetBehavior<DamageModel>(item.projectile);
					if (behavior4 != null)
					{
						behavior4.damage = chaosCombatStats.Damage;
						behavior4.immuneBloonProperties = (BloonProperties)0;
					}
					if ((object)value != null)
					{
						ChaosWeaponProjectileDisplays.Apply(value.Id, item.projectile);
					}
				}
			}
			catch (Exception ex)
			{
				ModHelper.Error<ChaosMonkeyMod>((object)("Could not apply Chaos Monkey combat gear: " + ex.Message));
			}
		}
	}
	public sealed class ChaosMonkeyDashboardWindow : ModWindow
	{
		private const float BoardScale = 1.5f;

		private const string PanelTexture = "ChaosGachaPanel";

		private const string TextFieldTexture = "ChaosTextField";

		private const string ShardIconTexture = "ChaosShardIcon";

		private readonly Dictionary<EquipmentSlot, ModHelperText> slotLabels = new Dictionary<EquipmentSlot, ModHelperText>();

		private readonly Dictionary<EquipmentSlot, ModHelperImage> slotImages = new Dictionary<EquipmentSlot, ModHelperImage>();

		private readonly Dictionary<RollMode, ModHelperText> rollLabels = new Dictionary<RollMode, ModHelperText>();

		private EquipmentSlot selectedSlot;

		private ModHelperText? shardText;

		private ModHelperText? luckText;

		private ModHelperText? pityText;

		private ModHelperText? evolutionText;

		private ModHelperText? detailsTitle;

		private ModHelperText? detailsStats;

		private ModHelperText? detailsEffect;

		private ModHelperText? detailsSynergy;

		private ModHelperText? resultText;

		private ModHelperText? sellText;

		private ModHelperImage? loadoutPortrait;

		private string lastResult = "SELECT A SLOT, THEN ROLL FOR ITS FIRST PIECE OF GEAR.";

		public override int DefaultWidth => 2250;

		public override int DefaultHeight => 1530;

		public override bool AllowMultiple => false;

		public override bool AllowResizing => false;

		public override Info WindowInfo
		{
			get
			{
				//IL_0035: 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_0061: Unknown result type (might be due to invalid IL or missing references)
				//IL_006b: Unknown result type (might be due to invalid IL or missing references)
				Info result = default(Info);
				((Info)(ref result))..ctor(((ModContent)this).Name);
				((Info)(ref result)).set_Width((float)((ModWindow)this).DefaultWidth);
				((Info)(ref result)).set_Height((float)((ModWindow)this).DefaultHeight);
				((Info)(ref result)).set_Anchor(new Vector2(0.5f, 0.5f));
				((Info)(ref result)).set_Pivot(new Vector2(0.5f, 0.5f));
				((Info)(ref result)).set_Position(new Vector2(-235f, 0f));
				return result;
			}
		}

		public override void ModifyWindow(ModHelperWindow window)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			((ModHelperComponent)window.content).AddImage(BoardInfo("ChaosGachaBoard", 0f, 0f, 1360f, 790f), ModContent.GetSpriteReference<ChaosMonkeyMod>("ChaosGachaPanel").guidRef);
			AddField(window, "BoardTitle", 0f, 333f, 420f, 48f, "CHAOS MONKEY • GEAR BOARD", 27f);
			((ModHelperComponent)window.content).AddImage(BoardInfo("BoardShardIcon", -225f, 279f, 46f, 46f), ModContent.GetSpriteReference<ChaosMonkeyMod>("ChaosShardIcon").guidRef);
			shardText = AddField(window, "BoardShards", -75f, 279f, 235f, 50f, BuildShardText(), 28f);
			luckText = AddField(window, "BoardLuck", 220f, 279f, 190f, 50f, BuildLuckText(), 24f);
			pityText = ((ModHelperComponent)window.content).AddText(BoardInfo("BoardPities", 0f, 218f, 720f, 55f), BuildPityText(), BoardFont(20f), (TextAlignmentOptions)514);
			pityText.EnableAutoSizing(BoardFont(20f), BoardFont(14f));
			evolutionText = AddField(window, "BoardEvolution", 0f, 154f, 690f, 52f, BuildEvolutionText(), 19f);
			AddSlotButton(window, EquipmentSlot.Weapon, -488f, 135f);
			AddSlotButton(window, EquipmentSlot.Body, -488f, -18f);
			AddSlotButton(window, EquipmentSlot.Trait, -488f, -171f);
			AddSlotButton(window, EquipmentSlot.Head, 488f, 135f);
			AddSlotButton(window, EquipmentSlot.Ammo, 488f, -18f);
			AddSlotButton(window, EquipmentSlot.Ability, 488f, -171f);
			loadoutPortrait = ((ModHelperComponent)window.content).AddImage(BoardInfo("ChaosMonkeyLoadoutPortrait", 0f, 5f, 215f, 265f), ModContent.GetSpriteReference<ChaosMonkeyMod>("ChaosMonkeyBaseUnarmed").guidRef);
			loadoutPortrait.Image.preserveAspect = true;
			detailsTitle = AddField(window, "SelectedItemTitle", 0f, -175f, 360f, 48f, BuildDetailsTitle(), 24f);
			detailsStats = AddField(window, "SelectedItemStats", 0f, -227f, 520f, 42f, BuildDetails().Stats, 19f);
			detailsEffect = AddField(window, "SelectedItemEffect", 0f, -278f, 710f, 52f, "EFFEKT: " + BuildDetails().Effect, 18f);
			detailsSynergy = AddField(window, "SelectedItemSynergy", 0f, -335f, 710f, 46f, "SYNERGIE: " + BuildDetails().Synergy, 17f);
			AddRollButton(window, "NormalRoll", -420f, "NORMAL ROLL", RollMode.Normal);
			AddRollButton(window, "RandomRoll", -420f, "RANDOM ROLL", RollMode.Random, -310f);
			AddRollButton(window, "SpecialRoll", -420f, "SPECIAL ROLL", RollMode.Special, 310f);
			resultText = AddField(window, "RollResult", 0f, -480f, 860f, 46f, lastResult, 18f);
			AddSellButton(window, -535f);
		}

		public override void OnUpdate(ModHelperWindow window)
		{
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			ModHelperText? obj = shardText;
			if (obj != null)
			{
				obj.SetText(BuildShardText());
			}
			ModHelperText? obj2 = luckText;
			if (obj2 != null)
			{
				obj2.SetText(BuildLuckText());
			}
			ModHelperText? obj3 = pityText;
			if (obj3 != null)
			{
				obj3.SetText(BuildPityText());
			}
			ModHelperText? obj4 = evolutionText;
			if (obj4 != null)
			{
				obj4.SetText(BuildEvolutionText());
			}
			if (loadoutPortrait != null)
			{
				loadoutPortrait.Image.sprite = ModContent.GetSprite<ChaosMonkeyMod>(BuildPortraitAssetName(), 100f);
				loadoutPortrait.Image.preserveAspect = true;
				((Graphic)loadoutPortrait.Image).color = Color.white;
			}
			ModHelperText? obj5 = detailsTitle;
			if (obj5 != null)
			{
				obj5.SetText(BuildDetailsTitle());
			}
			ModHelperText? obj6 = detailsStats;
			if (obj6 != null)
			{
				obj6.SetText(BuildDetails().Stats);
			}
			ModHelperText? obj7 = detailsEffect;
			if (obj7 != null)
			{
				obj7.SetText("EFFEKT: " + BuildDetails().Effect);
			}
			ModHelperText? obj8 = detailsSynergy;
			if (obj8 != null)
			{
				obj8.SetText("SYNERGIE: " + BuildDetails().Synergy);
			}
			ModHelperText? obj9 = resultText;
			if (obj9 != null)
			{
				obj9.SetText(lastResult);
			}
			ModHelperText? obj10 = sellText;
			if (obj10 != null)
			{
				obj10.SetText(BuildSellText());
			}
			EquipmentSlot key;
			ModHelperText value;
			foreach (KeyValuePair<EquipmentSlot, ModHelperText> slotLabel in slotLabels)
			{
				slotLabel.Deconstruct(out key, out value);
				EquipmentSlot slot = key;
				value.SetText(BuildSlotText(slot));
			}
			foreach (KeyValuePair<EquipmentSlot, ModHelperImage> slotImage in slotImages)
			{
				slotImage.Deconstruct(out key, out var value2);
				EquipmentSlot slot2 = key;
				ModHelperImage val = value2;
				ItemDefinition itemDefinition = ChaosMonkeyMod.Session.Match?.GetItem(slot2);
				if ((object)itemDefinition != null)
				{
					val.Image.sprite = ChaosItemArtwork.GetSprite(itemDefinition);
					val.Image.preserveAspect = true;
					((Graphic)val.Image).color = ChaosItemArtwork.GetTint(itemDefinition);
				}
			}
			foreach (KeyValuePair<RollMode, ModHelperText> rollLabel in rollLabels)
			{
				rollLabel.Deconstruct(out var key2, out value);
				RollMode mode = key2;
				value.SetText(BuildRollText(mode));
			}
		}

		public override void OnClose(ModHelperWindow window)
		{
			shardText = null;
			luckText = null;
			pityText = null;
			evolutionText = null;
			detailsTitle = null;
			detailsStats = null;
			detailsEffect = null;
			detailsSynergy = null;
			resultText = null;
			sellText = null;
			loadoutPortrait = null;
			slotLabels.Clear();
			slotImages.Clear();
			rollLabels.Clear();
		}

		private void AddSlotButton(ModHelperWindow window, EquipmentSlot slot, float x, float y)
		{
			//IL_005d: 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_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_029c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0331: Unknown result type (might be due to invalid IL or missing references)
			//IL_0365: Unknown result type (might be due to invalid IL or missing references)
			((ModHelperComponent)window.content).AddImage(BoardInfo($"Slot{slot}Frame", x, y, 365f, 132f), ModContent.GetSpriteReference<ChaosMonkeyMod>("ChaosTextField").guidRef);
			ModHelperImage val = ((ModHelperComponent)window.content).AddImage(BoardInfo($"Slot{slot}Icon", x - 132f, y, 80f, 80f), ModContent.GetSpriteReference<ChaosMonkeyMod>($"Slot{slot}Icon").guidRef);
			val.Image.preserveAspect = true;
			slotImages[slot] = val;
			((ModHelperComponent)window.content).AddImage(BoardInfo($"Slot{slot}CostIcon", x + 81f, y - 39f, 28f, 28f), ModContent.GetSpriteReference<ChaosMonkeyMod>("ChaosShardIcon").guidRef);
			((ModHelperComponent)window.content).AddText(BoardInfo($"Slot{slot}Cost", x + 125f, y - 39f, 68f, 28f), ChaosEconomy.SlotRollCosts[slot].ToString(), BoardFont(18f), (TextAlignmentOptions)4097).EnableAutoSizing(BoardFont(18f), BoardFont(14f));
			slotLabels[slot] = ((ModHelperComponent)window.content).AddText(BoardInfo($"Slot{slot}Label", x + 36f, y + 8f, 254f, 82f), BuildSlotText(slot), BoardFont(20f), (TextAlignmentOptions)4097);
			slotLabels[slot].EnableAutoSizing(BoardFont(20f), BoardFont(14f));
			((Graphic)GameObjectExt.AddButton(((Component)window.content).gameObject, BoardInfo($"Slot{slot}", x, y, 365f, 132f), string.Empty, (Action)delegate
			{
				selectedSlot = slot;
				lastResult = ChaosItemDetailsCatalog.SlotName(slot) + " SELECTED • INSPECT THE ITEM EFFECT BELOW.";
			}).Image).color = new Color(1f, 1f, 1f, 0f);
		}

		private void AddRollButton(ModHelperWindow window, string name, float y, string label, RollMode mode, float x = 0f)
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			rollLabels[mode] = AddField(window, name + "Label", x, y, 250f, 72f, label, 21f);
			((Graphic)GameObjectExt.AddButton(((Component)window.content).gameObject, BoardInfo(name, x, y, 252f, 74f), string.Empty, (Action)delegate
			{
				Roll(mode);
			}).Image).color = new Color(1f, 1f, 1f, 0f);
		}

		private void AddSellButton(ModHelperWindow window, float y)
		{
			//IL_004b: 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)
			sellText = AddField(window, "SellResetLabel", 0f, y, 670f, 44f, BuildSellText(), 17f);
			((Graphic)GameObjectExt.AddButton(((Component)window.content).gameObject, BoardInfo("SellReset", 0f, y, 672f, 46f), string.Empty, (Action)delegate
			{
				if (ChaosMonkeyMod.TrySellActiveChaosMonkey())
				{
					lastResult = "MONKEY SOLD • SHARDS RETAINED • NEXT PLACEMENT HAS E