Decompiled source of AscendedUpgrades v1.2.2

AscendedUpgrades.dll

Decompiled 6 hours 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 AscendedUpgrades;
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.ModOptions;
using BTD_Mod_Helper.Extensions;
using HarmonyLib;
using Il2CppAssets.Scripts;
using Il2CppAssets.Scripts.Models;
using Il2CppAssets.Scripts.Models.GenericBehaviors;
using Il2CppAssets.Scripts.Models.Profile;
using Il2CppAssets.Scripts.Models.SimulationBehaviors;
using Il2CppAssets.Scripts.Models.Towers;
using Il2CppAssets.Scripts.Models.Towers.Behaviors;
using Il2CppAssets.Scripts.Models.Towers.Behaviors.Abilities.Behaviors;
using Il2CppAssets.Scripts.Models.Towers.Projectiles;
using Il2CppAssets.Scripts.Models.Towers.Projectiles.Behaviors;
using Il2CppAssets.Scripts.Models.Towers.Upgrades;
using Il2CppAssets.Scripts.Models.Towers.Weapons.Behaviors;
using Il2CppAssets.Scripts.Simulation;
using Il2CppAssets.Scripts.Simulation.Objects;
using Il2CppAssets.Scripts.Simulation.Towers;
using Il2CppAssets.Scripts.Simulation.Towers.Behaviors;
using Il2CppAssets.Scripts.Unity;
using Il2CppAssets.Scripts.Unity.Bridge;
using Il2CppAssets.Scripts.Unity.UI_New.InGame;
using Il2CppAssets.Scripts.Unity.UI_New.InGame.TowerSelectionMenu;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppNinjaKiwi.Common.ResourceUtils;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Il2CppSystem.Linq;
using MelonLoader;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(AscendedUpgradesMod), "Ascended Upgrades", "1.2.2", "doombubbles", null)]
[assembly: MelonGame("Ninja Kiwi", "BloonsTD6")]
[assembly: MelonGame("Ninja Kiwi", "BloonsTD6-Epic")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("AscendedUpgrades")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+1545ac989e2843e8e6aa6cc9b045302be9e2d7ce")]
[assembly: AssemblyProduct("AscendedUpgrades")]
[assembly: AssemblyTitle("AscendedUpgrades")]
[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 AscendedUpgrades
{
	public class AscendedForce : AscendedUpgrade<AscendedForceIcon>
	{
		public override string Description => "Infinitely Repeatable: Improved pierce, range, capacity, and range/pierce buffs.";

		public override int Path => 2;

		protected override BehaviorMutator CreateMutator(int stacks)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			return (BehaviorMutator)new MutatorTower(false, ((ModContent)this).Id, 0f, AscendedUpgrade.GetFactor(stacks), base.BuffIndicatorModel)
			{
				priority = stacks
			};
		}
	}
	public class AscendedForceIcon : ModBuffIcon
	{
		public override string Icon => "AscendedForce";

		public override int MaxStackSize => 999;

		protected override int Order => 2;
	}
	[HarmonyPatch(typeof(MutatorTower), "Mutate")]
	internal static class RangeSupport_MutatorTower_Mutate
	{
		[HarmonyPrefix]
		private static bool Prefix(MutatorTower __instance, Model model)
		{
			if (((BehaviorMutator)__instance).id == ((ModContent)ModContent.GetInstance<AscendedForce>()).Id)
			{
				float mult = 1f + __instance.multiplier;
				Il2CppGenericIEnumerable.ForEach<ProjectileModel>(model.GetDescendants<ProjectileModel>(), (Action<ProjectileModel>)delegate(ProjectileModel projectileModel)
				{
					projectileModel.pierce *= mult;
				});
				Il2CppGenericIEnumerable.ForEach<BankModel>(model.GetDescendants<BankModel>(), (Action<BankModel>)delegate(BankModel bankModel)
				{
					bankModel.capacity *= mult;
				});
				Il2CppGenericIEnumerable.ForEach<EatBloonModel>(model.GetDescendants<EatBloonModel>(), (Action<EatBloonModel>)delegate(EatBloonModel eatBloonModel)
				{
					eatBloonModel.rbeCapacity *= mult;
				});
				Il2CppGenericIEnumerable.ForEach<RangeSupportModel>(model.GetDescendants<RangeSupportModel>(), (Action<RangeSupportModel>)delegate(RangeSupportModel supportModel)
				{
					supportModel.multiplier *= mult;
				});
				Il2CppGenericIEnumerable.ForEach<ActivatePierceSupportZoneModel>(model.GetDescendants<ActivatePierceSupportZoneModel>(), (Action<ActivatePierceSupportZoneModel>)delegate(ActivatePierceSupportZoneModel zoneModel)
				{
					zoneModel.pierceIncrease += (int)((float)zoneModel.pierceIncrease * __instance.multiplier);
				});
				Il2CppGenericIEnumerable.ForEach<PierceSupportModel>(model.GetDescendants<PierceSupportModel>(), (Action<PierceSupportModel>)delegate(PierceSupportModel supportModel)
				{
					supportModel.pierce *= mult;
				});
				Il2CppGenericIEnumerable.ForEach<ActivateRangeSupportZoneModel>(model.GetDescendants<ActivateRangeSupportZoneModel>(), (Action<ActivateRangeSupportZoneModel>)delegate(ActivateRangeSupportZoneModel zoneModel)
				{
					zoneModel.multiplier *= mult;
				});
				Il2CppGenericIEnumerable.ForEach<CallToArmsModel>(model.GetDescendants<CallToArmsModel>(), (Action<CallToArmsModel>)delegate(CallToArmsModel zoneModel)
				{
					zoneModel.multiplier *= (float)Math.Sqrt(mult);
				});
				Il2CppGenericIEnumerable.ForEach<PoplustSupportModel>(model.GetDescendants<PoplustSupportModel>(), (Action<PoplustSupportModel>)delegate(PoplustSupportModel supportModel)
				{
					supportModel.piercePercentIncrease *= mult;
				});
				Il2CppGenericIEnumerable.ForEach<OverclockModel>(model.GetDescendants<OverclockModel>(), (Action<OverclockModel>)delegate(OverclockModel overclockModel)
				{
					overclockModel.villageRangeModifier *= mult;
				});
				Il2CppGenericIEnumerable.ForEach<OverclockPermanentModel>(model.GetDescendants<OverclockPermanentModel>(), (Action<OverclockPermanentModel>)delegate(OverclockPermanentModel permanentModel)
				{
					permanentModel.villageRangeModifier *= mult;
				});
			}
			return true;
		}
	}
	[RegisterTypeInIl2Cpp(false)]
	public class AscendedPips : MonoBehaviour
	{
		public UpgradeObject upgradeObject = null;

		public ModHelperScrollPanel scrollPanel = null;

		public List<GameObject>? pips;

		public GameObject pipPrefab = null;

		public AscendedPips(IntPtr obj0)
			: base(obj0)
		{
		}

		public void Init(UpgradeObject obj, ModHelperScrollPanel panel)
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			upgradeObject = obj;
			scrollPanel = panel;
			pips = new List<GameObject>();
			scrollPanel.ScrollRect.vertical = false;
			((ModHelperComponent)scrollPanel).AddComponent<Image>();
			((Component)scrollPanel).GetComponent<Mask>().showMaskGraphic = false;
			ModHelperPanel scrollContent = scrollPanel.ScrollContent;
			RectTransform rectTransform = ((ModHelperComponent)scrollContent).RectTransform;
			Vector2 val = (rectTransform.anchorMax = Vector2.zero);
			Vector2 pivot = (rectTransform.anchorMin = val);
			rectTransform.pivot = pivot;
			GridLayoutGroup val3 = ((ModHelperComponent)scrollContent).AddComponent<GridLayoutGroup>();
			val3.cellSize = new Vector2(55f, 55f);
			val3.spacing = new Vector2(4f, 4f);
			val3.constraint = (Constraint)2;
			val3.constraintCount = 5;
			val3.startCorner = (Corner)2;
			((LayoutGroup)val3).childAlignment = (TextAnchor)6;
			val3.startAxis = (Axis)1;
			ContentSizeFitter val4 = ((ModHelperComponent)scrollContent).AddComponent<ContentSizeFitter>();
			val4.horizontalFit = (FitMode)2;
			val4.verticalFit = (FitMode)2;
			pipPrefab = CreatePipPrefab();
			((Behaviour)((Component)scrollPanel).GetComponent<Mask>()).enabled = false;
			((Behaviour)((Component)scrollPanel).GetComponent<Mask>()).enabled = true;
		}

		public void SetAmount(int amount)
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			if (pips != null)
			{
				for (int i = pips.Count; i < amount; i++)
				{
					AddPip(i);
				}
				Il2CppArrayBase<GameObject> val = pips.ToArray();
				for (int j = 0; j < pips.Count; j++)
				{
					GameObject val2 = val[j];
					val2.SetActive(j < amount);
					val2.transform.localScale = Vector3.one;
				}
				((Behaviour)scrollPanel.ScrollRect).enabled = amount > 35;
			}
		}

		public GameObject CreatePipPrefab()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			GameObject val = new GameObject("Pip");
			val.transform.SetParent((Transform)(object)ModHelperComponent.op_Implicit((ModHelperComponent)(object)scrollPanel.ScrollContent));
			Image val2 = val.AddComponent<Image>();
			ImageExt.SetSprite(val2, ModContent.GetSpriteReference<AscendedUpgradesMod>("AscendedPip"));
			val.AddComponent<LayoutElement>();
			val.SetActive(false);
			return val;
		}

		public void AddPip(int i)
		{
			if (pips != null)
			{
				GameObject val = GameObjectExt.Duplicate<GameObject>(pipPrefab, (Transform)(object)ModHelperComponent.op_Implicit((ModHelperComponent)(object)scrollPanel.ScrollContent));
				((Object)val).name = $"Pip{i}";
				pips.Add(val);
			}
		}

		private void FixedUpdate()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			((Component)this).transform.localPosition = new Vector3(-370f, 6f, 0f);
		}

		public static AscendedPips Create(UpgradeObject __instance)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			GameObject gameObject = ((Component)__instance).gameObject;
			Info val = default(Info);
			((Info)(ref val))..ctor("AscendedPips", 500f, -40f);
			((Info)(ref val)).set_AnchorMin(new Vector2(0f, 0f));
			((Info)(ref val)).set_AnchorMax(new Vector2(0f, 1f));
			((Info)(ref val)).set_Pivot(new Vector2(0f, 0.5f));
			ModHelperScrollPanel val2 = GameObjectExt.AddModHelperScrollPanel(gameObject, val, (Axis?)null, (string)null, 0f, 0);
			((Component)val2).transform.SetSiblingIndex(1);
			AscendedPips ascendedPips = ((ModHelperComponent)val2).AddComponent<AscendedPips>();
			ascendedPips.Init(__instance, val2);
			return ascendedPips;
		}
	}
	public class AscendedSpeed : AscendedUpgrade<AscendedSpeedIcon>
	{
		public override string Description => "Infinitely Repeatable: Improved attack speed, production speed, and attack speed buffs.";

		public override int Path => 1;

		protected override BehaviorMutator CreateMutator(int stacks)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			return (BehaviorMutator)new RateSupportMutator(false, ((ModContent)this).Id, 1f / (1f + AscendedUpgrade.GetFactor(stacks)), stacks, base.BuffIndicatorModel, false, (DisplayModel)null);
		}
	}
	public class AscendedSpeedIcon : ModBuffIcon
	{
		public override string Icon => "AscendedSpeed";

		public override int MaxStackSize => 999;

		protected override int Order => 1;
	}
	[HarmonyPatch(typeof(RateSupportMutator), "Mutate")]
	internal static class RateMutator_Mutate
	{
		[HarmonyPrefix]
		private static bool Prefix(RateSupportMutator __instance, Model model)
		{
			if (((BehaviorMutator)__instance).id == ((ModContent)ModContent.GetInstance<AscendedSpeed>()).Id)
			{
				Il2CppGenericIEnumerable.ForEach<EmissionsPerRoundFilterModel>(model.GetDescendants<EmissionsPerRoundFilterModel>(), (Action<EmissionsPerRoundFilterModel>)delegate(EmissionsPerRoundFilterModel filter)
				{
					filter.count = (int)Math.Ceiling((float)filter.count / __instance.multiplier);
				});
				Il2CppGenericIEnumerable.ForEach<RateSupportModel>(model.GetDescendants<RateSupportModel>(), (Action<RateSupportModel>)delegate(RateSupportModel supportModel)
				{
					supportModel.multiplier *= __instance.multiplier;
				});
				Il2CppGenericIEnumerable.ForEach<ActivateRateSupportZoneModel>(model.GetDescendants<ActivateRateSupportZoneModel>(), (Action<ActivateRateSupportZoneModel>)delegate(ActivateRateSupportZoneModel zoneModel)
				{
					zoneModel.rateModifier *= __instance.multiplier;
				});
				Il2CppGenericIEnumerable.ForEach<CallToArmsModel>(model.GetDescendants<CallToArmsModel>(), (Action<CallToArmsModel>)delegate(CallToArmsModel zoneModel)
				{
					zoneModel.multiplier *= (float)Math.Sqrt(1f / __instance.multiplier);
				});
				Il2CppGenericIEnumerable.ForEach<PoplustSupportModel>(model.GetDescendants<PoplustSupportModel>(), (Action<PoplustSupportModel>)delegate(PoplustSupportModel supportModel)
				{
					supportModel.ratePercentIncrease /= __instance.multiplier;
				});
				Il2CppGenericIEnumerable.ForEach<OverclockModel>(model.GetDescendants<OverclockModel>(), (Action<OverclockModel>)delegate(OverclockModel overclockModel)
				{
					overclockModel.rateModifier *= __instance.multiplier;
				});
				Il2CppGenericIEnumerable.ForEach<OverclockPermanentModel>(model.GetDescendants<OverclockPermanentModel>(), (Action<OverclockPermanentModel>)delegate(OverclockPermanentModel permanentModel)
				{
					permanentModel.rateModifier *= __instance.multiplier;
				});
			}
			return true;
		}
	}
	public class AscendedStrength : AscendedUpgrade<AscendedStrengthIcon>
	{
		public override string Description => "Infinitely Repeatable: Improved damage, boss damage, cash generated, and damage buffs.";

		public override int Path => 0;

		protected override BehaviorMutator CreateMutator(int stacks)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			return (BehaviorMutator)new MutatorTower(AscendedUpgrade.GetFactor(stacks), false, ((ModContent)this).Id, base.BuffIndicatorModel)
			{
				priority = stacks
			};
		}
	}
	public class AscendedStrengthIcon : ModBuffIcon
	{
		public override string Icon => "AscendedStrength";

		public override int MaxStackSize => 999;

		protected override int Order => 0;
	}
	[HarmonyPatch(typeof(MutatorTower), "Mutate")]
	internal static class DamageSupport_MutatorTower_Mutate
	{
		[HarmonyPrefix]
		private static bool Prefix(MutatorTower __instance, Model model, ref bool __result)
		{
			if (((BehaviorMutator)__instance).id == ((ModContent)ModContent.GetInstance<AscendedStrength>()).Id)
			{
				float mult = 1f + __instance.increase;
				Il2CppGenericIEnumerable.ForEach<ProjectileModel>(model.GetDescendants<ProjectileModel>(), (Action<ProjectileModel>)delegate(ProjectileModel proj)
				{
					//IL_0068: Unknown result type (might be due to invalid IL or missing references)
					//IL_0072: Expected O, but got Unknown
					DamageModel val = default(DamageModel);
					if (ProjectileModelBehaviorExt.HasBehavior<DamageModel>(proj, ref val) && val.damage > 0f)
					{
						DamageModel obj = val;
						obj.damage *= mult;
						string text = "DamageModifierForTagModel_" + ((BehaviorMutator)__instance).id;
						ProjectileModelBehaviorExt.AddBehavior<DamageModifierForTagModel>(proj, new DamageModifierForTagModel(text, "Boss", mult, 0f, false, true, false));
						proj.hasDamageModifiers = true;
					}
				});
				Il2CppGenericIEnumerable.ForEach<CashModel>(model.GetDescendants<CashModel>(), (Action<CashModel>)delegate(CashModel cashModel)
				{
					cashModel.bonusMultiplier += __instance.increase;
				});
				Il2CppGenericIEnumerable.ForEach<BonusCashPerRoundModel>(model.GetDescendants<BonusCashPerRoundModel>(), (Action<BonusCashPerRoundModel>)delegate(BonusCashPerRoundModel roundModel)
				{
					roundModel.baseCash *= mult;
				});
				Il2CppGenericIEnumerable.ForEach<EatBloonModel>(model.GetDescendants<EatBloonModel>(), (Action<EatBloonModel>)delegate(EatBloonModel eatBloonModel)
				{
					eatBloonModel.rbeCashMultiplier *= mult;
				});
				Il2CppGenericIEnumerable.ForEach<DamageSupportModel>(model.GetDescendants<DamageSupportModel>(), (Action<DamageSupportModel>)delegate(DamageSupportModel supportModel)
				{
					supportModel.increase *= mult;
				});
				Il2CppGenericIEnumerable.ForEach<ActivateTowerDamageSupportZoneModel>(model.GetDescendants<ActivateTowerDamageSupportZoneModel>(), (Action<ActivateTowerDamageSupportZoneModel>)delegate(ActivateTowerDamageSupportZoneModel zoneModel)
				{
					zoneModel.damageIncrease *= mult;
				});
				__result = true;
				return false;
			}
			return true;
		}
	}
	public abstract class AscendedUpgrade : NamedModContent
	{
		public static readonly Dictionary<int, string> IdByPath = new Dictionary<int, string>();

		public static readonly Dictionary<int, AscendedUpgrade> ByPath = new Dictionary<int, AscendedUpgrade>();

		public static readonly Dictionary<string, AscendedUpgrade> ById = new Dictionary<string, AscendedUpgrade>();

		protected abstract ModBuffIcon ModBuffIcon { get; }

		protected BuffIndicatorModel? BuffIndicatorModel
		{
			get
			{
				object result;
				if (!ModSettingBool.op_Implicit(AscendedUpgradesMod.ShowBuffIndicators))
				{
					result = null;
				}
				else
				{
					InGame obj = GameObjectExt.Exists<InGame>(InGame.instance);
					result = ((IEnumerable<BuffIndicatorModel>)(((obj != null) ? InGameExt.GetGameModel(obj) : null) ?? Game.instance.model).buffIndicatorModels).First((BuffIndicatorModel model) => ((Model)model).name == "BuffIndicatorModel_" + ((ModContent)ModBuffIcon).Id + "-" + ModBuffIcon.Icon);
				}
				return (BuffIndicatorModel?)result;
			}
		}

		public abstract int Path { get; }

		protected sealed override int Order => Path;

		protected virtual string Icon => ((ModContent)this).Name;

		protected virtual SpriteReference IconReference => ((ModContent)this).GetSpriteReferenceOrDefault(Icon);

		public override void Register()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			UpgradeModel val = new UpgradeModel(((ModContent)this).Id, ModSettingInt.op_Implicit(AscendedUpgradesMod.BaseUpgradeCost), 0, IconReference, Path, 4, 0, "", "");
			GameModelExt.AddUpgrade(Game.instance.model, val);
			IdByPath[Path] = ((ModContent)this).Id;
			ByPath[Path] = this;
			ById[((ModContent)this).Id] = this;
		}

		protected abstract BehaviorMutator CreateMutator(int stacks);

		public UpgradeModel GetUpgradeModel(GameModel? gameModel = null)
		{
			object obj = gameModel;
			if (obj == null)
			{
				InGame obj2 = GameObjectExt.Exists<InGame>(InGame.instance);
				obj = ((obj2 != null) ? InGameExt.GetGameModel(obj2) : null) ?? Game.instance.model;
			}
			return ((GameModel)obj).GetUpgrade(((ModContent)this).Id);
		}

		public void Apply(Tower tower, int stacks)
		{
			((Mutable)tower).RemoveMutatorsById(((ModContent)this).Id);
			BehaviorMutator val = CreateMutator(stacks);
			val.cantBeAbsorbed = false;
			tower.AddMutatorIncludeSubTowers(val, -1, true, true, false, true, -1);
		}

		public virtual int GetStacks(BehaviorMutator behaviorMutator)
		{
			return behaviorMutator.priority;
		}

		protected static float GetFactor(int stacks)
		{
			return ModSettingBool.op_Implicit(AscendedUpgradesMod.OpMultiplicativeScaling) ? ((float)Math.Pow(1f + ModSettingDouble.op_Implicit(AscendedUpgradesMod.UpgradeFactor), stacks) - 1f) : (ModSettingDouble.op_Implicit(AscendedUpgradesMod.UpgradeFactor) * (float)stacks);
		}
	}
	public abstract class AscendedUpgrade<T> : AscendedUpgrade where T : ModBuffIcon
	{
		protected override ModBuffIcon ModBuffIcon => (ModBuffIcon)(object)ModContent.GetInstance<T>();
	}
	public class AscendedUpgradesMod : BloonsTD6Mod
	{
		public static readonly ModSettingInt BaseUpgradeCost;

		public static readonly ModSettingInt IncreaseUpgradeCost;

		public static readonly ModSettingDouble UpgradeFactor;

		public static readonly ModSettingBool OpMultiplicativeScaling;

		public static readonly ModSettingInt MaxUpgradePips;

		public static readonly ModSettingBool ShowBuffIndicators;

		public static readonly ModSettingBool SharedUpgradeScaling;

		private static Dictionary<AscendedUpgrade, int>? clipboard;

		public override void OnProfileLoaded(ProfileModel profile)
		{
			foreach (AscendedUpgrade item in ModContent.GetContent<AscendedUpgrade>())
			{
				profile.acquiredUpgrades.AddIfNotPresent(((ModContent)item).Id);
			}
		}

		public override void PreCleanProfile(ProfileModel profile)
		{
			string[] ids = (from upgrade in ModContent.GetContent<AscendedUpgrade>()
				select ((ModContent)upgrade).Id).ToArray();
			profile.acquiredUpgrades.RemoveWhere(Predicate<string>.op_Implicit((Func<string, bool>)((string s) => ((ReadOnlySpan<string>)ids).Contains(s))));
		}

		public override void PostCleanProfile(ProfileModel profile)
		{
			((BloonsTD6Mod)this).OnProfileLoaded(profile);
		}

		public override void OnTowerSaved(Tower tower, TowerSaveDataModel saveData)
		{
			foreach (var (ascendedUpgrade2, num2) in tower.GetAscendedStacks())
			{
				if (num2 > 0)
				{
					saveData.metaData[((ModContent)ascendedUpgrade2).Id] = num2.ToString();
				}
			}
		}

		public override void OnTowerLoaded(Tower tower, TowerSaveDataModel saveData)
		{
			foreach (AscendedUpgrade item in ModContent.GetContent<AscendedUpgrade>())
			{
				if (saveData.metaData.ContainsKey(((ModContent)item).Id) && int.TryParse(saveData.metaData[((ModContent)item).Id], out var result))
				{
					item.Apply(tower, result);
				}
			}
		}

		public override object Call(string operation, params object[] parameters)
		{
			AscendedUpgrade key;
			int value;
			switch (operation)
			{
			case "OnTowerCopied":
			{
				Tower tower3 = default(Tower);
				if (ArrayExt.CheckTypes<Tower>(parameters, ref tower3))
				{
					clipboard = tower3.GetAscendedStacks();
				}
				break;
			}
			case "OnTowerPasted":
			{
				Tower tower2 = default(Tower);
				if (!ArrayExt.CheckTypes<Tower>(parameters, ref tower2) || clipboard == null)
				{
					break;
				}
				foreach (KeyValuePair<AscendedUpgrade, int> item in clipboard)
				{
					item.Deconstruct(out key, out value);
					AscendedUpgrade ascendedUpgrade = key;
					int stacks = value;
					ascendedUpgrade.Apply(tower2, stacks);
				}
				break;
			}
			case "OnClipboardCleared":
				clipboard = null;
				break;
			case "ModifyClipboardCost":
			{
				Tower tower = default(Tower);
				if (!ArrayExt.CheckTypes<Tower>(parameters, ref tower))
				{
					break;
				}
				int num = 0;
				int num2 = 0;
				foreach (KeyValuePair<AscendedUpgrade, int> ascendedStack in tower.GetAscendedStacks())
				{
					ascendedStack.Deconstruct(out key, out value);
					int num3 = value;
					if (ModSettingBool.op_Implicit(SharedUpgradeScaling))
					{
						for (int i = 0; i < num3; i++)
						{
							num += CostHelper.CostForDifficulty(ModSettingInt.op_Implicit(BaseUpgradeCost), InGame.instance);
							num += (num2++ + i) * CostHelper.CostForDifficulty(ModSettingInt.op_Implicit(IncreaseUpgradeCost), InGame.instance);
						}
					}
					else
					{
						for (int j = 0; j < num3; j++)
						{
							num += CostHelper.CostForDifficulty(ModSettingInt.op_Implicit(BaseUpgradeCost), InGame.instance);
							num += j * CostHelper.CostForDifficulty(ModSettingInt.op_Implicit(IncreaseUpgradeCost), InGame.instance);
						}
					}
				}
				return num;
			}
			}
			return ((BloonsMod)this).Call(operation, parameters);
		}

		static AscendedUpgradesMod()
		{
			//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_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Expected O, but got Unknown
			//IL_0087: 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_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Expected O, but got Unknown
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Expected O, but got Unknown
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Expected O, but got Unknown
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Expected O, but got Unknown
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Expected O, but got Unknown
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: 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_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Expected O, but got Unknown
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Expected O, but got Unknown
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Expected O, but got Unknown
			//IL_014b: Expected O, but got Unknown
			//IL_014c: 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_015c: 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_0177: Expected O, but got Unknown
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Expected O, but got Unknown
			ModSettingInt val = new ModSettingInt(5000)
			{
				description = "The starting price of Ascended Upgrades (medium difficulty)."
			};
			((ModSettingNumber<long>)val).min = 1000L;
			((ModSetting<long>)val).onSave = delegate(long cost)
			{
				ModContent.GetContent<AscendedUpgrade>().ForEach(delegate(AscendedUpgrade upgrade)
				{
					upgrade.GetUpgradeModel().cost = (int)cost;
				});
			};
			((ModSetting)val).icon = "Ui[CoinIcon]";
			BaseUpgradeCost = val;
			ModSettingInt val2 = new ModSettingInt(500)
			{
				description = "How much the cost increases for further Ascended Upgrades each time you buy one (medium difficulty)."
			};
			((ModSettingNumber<long>)val2).min = 0L;
			((ModSetting)val2).icon = "40f5a514d7763a94682e5d0705409d15";
			IncreaseUpgradeCost = val2;
			ModSettingDouble val3 = new ModSettingDouble(0.1)
			{
				description = "How much Ascended Upgrades buff by. Default of .1 is buffing each listed stat by 10%."
			};
			((ModSettingNumber<double>)val3).slider = true;
			((ModSettingNumber<double>)val3).min = 0.01;
			((ModSettingNumber<double>)val3).max = 0.25;
			((ModSetting)val3).icon = "PowerIcons[MonkeyBoostIcon]";
			UpgradeFactor = val3;
			OpMultiplicativeScaling = new ModSettingBool(false)
			{
				description = "Brings back the old behavior of multiplicative upgrade effect scaling that was very OP given that the cost scaling was additive.",
				icon = "c31086e809068459da27672977fe1c5c"
			};
			ModSettingInt val4 = new ModSettingInt(25)
			{
				displayName = "Max Upgrade Pips",
				description = "The max number of total blue upgrade that shoul appear as you purchase Ascended Upgrades",
				icon = ModContent.GetTextureGUID<AscendedUpgradesMod>("AscendedPip")
			};
			((ModSettingNumber<long>)val4).min = 0L;
			((ModSettingNumber<long>)val4).max = 100L;
			((ModSettingNumber<long>)val4).slider = true;
			MaxUpgradePips = val4;
			ShowBuffIndicators = new ModSettingBool(true)
			{
				displayName = "Show Buff Indicators",
				description = "Whether to show the number of Ascended Upgrades purchased as buffs on the tower",
				icon = "UiBuffIcons[BuffIconComeOnEverybodyRate]"
			};
			SharedUpgradeScaling = new ModSettingBool(false)
			{
				displayName = "Cost Scaling Across Upgrades",
				description = "Whether the 3 Ascended Upgrades scale in cost all together vs individually.",
				button = true,
				disabledText = "Individual",
				disabledButton = "Ui[BlueBtnLong]",
				enabledText = "Together",
				enabledButton = "Ui[YellowBtnLong]"
			};
		}
	}
	public static class Extensions
	{
		public static bool ShowAscendedUpgrades(this TowerSelectionMenu tsm)
		{
			return (Object)(object)tsm != (Object)null && tsm.selectedTower != null && (((IEnumerable<UpgradeObject>)tsm.upgradeButtons).All((UpgradeObject o) => (int)o.upgradeButton.upgradeStatus == 0 || (o.upgradeButton.upgrade?.IsAscended() ?? false)) || tsm.selectedTower.tower.GetAscendedStacks().Values.Sum() > 0);
		}

		public static bool IsAscended(this UpgradeModel upgrade)
		{
			return AscendedUpgrade.IdByPath.ContainsValue(((Model)upgrade).name);
		}

		public static int AscendedStackCount(this BehaviorMutator behaviorMutator)
		{
			AscendedUpgrade value;
			return AscendedUpgrade.ById.TryGetValue(behaviorMutator.id, out value) ? value.GetStacks(behaviorMutator) : 0;
		}

		public static Dictionary<AscendedUpgrade, int> GetAscendedStacks(this Tower tower)
		{
			return ModContent.GetContent<AscendedUpgrade>().ToDictionary((AscendedUpgrade upgrade) => upgrade, (AscendedUpgrade upgrade) => (from mutator in (IEnumerable<TimedMutator>)Enumerable.ToArray<TimedMutator>(((Il2CppObjectBase)((Mutable)tower).GetMutators()).Cast<IEnumerable<TimedMutator>>())
				where mutator.mutator.id.Contains(((ModContent)upgrade).Id)
				select mutator.mutator.AscendedStackCount()).SingleOrDefault(0));
		}
	}
	public static class ModHelperData
	{
		public const string WorksOnVersion = "52.0";

		public const string Version = "1.2.2";

		public const string Name = "Ascended Upgrades";

		public const string Description = "Adds special Ascended Upgrades that you can use to infinitely upgrade towers.\nWhen a tower has no more available upgrades, you can begin choosing between 3 repeatable Ascended Upgrades to continue powering it up. Each Ascended Upgrade you use increases the cost of future ones.";

		public const string RepoOwner = "doombubbles";

		public const string PrevRepoName = "ascended-upgrades";

		public const string RepoName = "AscendedUpgrades";
	}
	[HarmonyPatch(typeof(TowerSelectionMenu), "IsUpgradePathClosed")]
	internal class TowerSelectionMenu_IsUpgradePathClosed
	{
		[HarmonyPrefix]
		[HarmonyPriority(0)]
		internal static bool Prefix(TowerSelectionMenu __instance, int path, ref bool __result)
		{
			if (path <= 2 && __instance.ShowAscendedUpgrades())
			{
				__result = false;
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(UpgradeObject), "LoadUpgrades")]
	internal static class UpgradeObject_LoadUpgrades
	{
		[HarmonyPostfix]
		private static void Postfix(UpgradeObject __instance)
		{
			Setup(__instance, retry: true);
		}

		private static void Setup(UpgradeObject __instance, bool retry)
		{
			if (retry)
			{
				TaskScheduler.ScheduleTask((Action)delegate
				{
					Setup(__instance, retry: false);
				}, (Func<bool>)null);
			}
			AscendedPips ascendedPips = ((Component)((Component)__instance).transform).GetComponentInChildren<AscendedPips>();
			if ((Object)(object)ascendedPips == (Object)null)
			{
				ascendedPips = AscendedPips.Create(__instance);
			}
			if (!__instance.towerSelectionMenu.ShowAscendedUpgrades() || __instance.path >= 3)
			{
				if (!retry)
				{
					ascendedPips.SetAmount(0);
				}
				return;
			}
			GameModel model = InGame.instance.bridge.Model;
			string text = AscendedUpgrade.IdByPath[__instance.path];
			__instance.upgradeButton.SetUpgradeModel(model.GetUpgrade(text));
			Tower tower = __instance.towerSelectionMenu.selectedTower.tower;
			ascendedPips.SetAmount(Math.Min(tower.GetAscendedStacks().First<KeyValuePair<AscendedUpgrade, int>>((KeyValuePair<AscendedUpgrade, int> pair) => pair.Key.Path == __instance.path).Value, ModSettingInt.op_Implicit(AscendedUpgradesMod.MaxUpgradePips)));
			__instance.UpdateVisuals(__instance.path, false);
		}
	}
	[HarmonyPatch(typeof(UpgradeObject), "IncreaseTier")]
	internal static class UpgradeObject_IncreaseTier
	{
		[HarmonyPrefix]
		private static bool Prefix(UpgradeObject __instance)
		{
			TowerSelectionMenu towerSelectionMenu = __instance.towerSelectionMenu;
			int? obj;
			if (towerSelectionMenu == null)
			{
				obj = null;
			}
			else
			{
				TowerToSimulation selectedTower = towerSelectionMenu.selectedTower;
				obj = ((selectedTower == null) ? ((int?)null) : selectedTower.tower?.GetAscendedStacks().Values.Sum());
			}
			int? num = obj;
			return num.GetValueOrDefault() == 0;
		}
	}
	[HarmonyPatch]
	internal static class UpgradeButton_Visuals
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			yield return AccessTools.Method(typeof(UpgradeButton), "UpdateVisuals", (Type[])null, (Type[])null);
			yield return AccessTools.Method(typeof(UpgradeButton), "LoadBackground", (Type[])null, (Type[])null);
			yield return AccessTools.Method(typeof(UpgradeButton), "CheckCash", (Type[])null, (Type[])null);
		}

		[HarmonyPostfix]
		private static void Postfix(UpgradeButton __instance)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Invalid comparison between Unknown and I4
			UpgradeModel upgrade = __instance.upgrade;
			string value = ((upgrade != null) ? ((Model)upgrade).name : null) ?? "";
			if (AscendedUpgrade.IdByPath.ContainsValue(value) && (int)__instance.upgradeStatus == 5)
			{
				ImageExt.SetSprite(__instance.background, ModContent.GetSprite<AscendedUpgradesMod>("AscendedArrowBtn", 10f));
			}
		}
	}
	[HarmonyPatch(typeof(TowerSelectionMenu), "UpgradeTower", new Type[]
	{
		typeof(UpgradeModel),
		typeof(int),
		typeof(float),
		typeof(double)
	})]
	internal static class TowerSelectionMenu_UpgradeTower
	{
		[HarmonyPrefix]
		private static void Prefix(UpgradeModel upgrade)
		{
			UnityToSimulation_UpgradeTower_Impl.current = upgrade;
			UnityToSimulation_UpgradeTower_Impl.cash = InGameExt.GetCash(InGame.instance);
		}
	}
	[HarmonyPatch(typeof(UnityToSimulation), "UpgradeTower_Impl")]
	internal static class UnityToSimulation_UpgradeTower_Impl
	{
		internal static UpgradeModel? current;

		internal static double cash;

		[HarmonyPostfix]
		private static bool Prefix(UnityToSimulation __instance, ObjectId id, int callbackId, int pathIndex, int inputId)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			if (current == null || pathIndex >= 3 || !((Model)current).name.StartsWith("AscendedUpgrade"))
			{
				return true;
			}
			Action<bool> val = __instance.UnregisterCallback(callbackId, inputId);
			TowerManager towerManager = __instance.simulation.towerManager;
			Tower towerById = towerManager.GetTowerById(id);
			float towerUpgradeCost = towerManager.GetTowerUpgradeCost(towerById, pathIndex, 5, -1f, false);
			towerManager.UpgradeTower(inputId, towerById, ((Il2CppObjectBase)((Mutable)towerById).rootModel).Cast<TowerModel>(), pathIndex, towerUpgradeCost, 1f, true, true, true, false, false, 0, 0.0);
			InGameExt.SetCash(InGame.instance, cash - (double)towerUpgradeCost);
			AscendedUpgrade ascendedUpgrade = AscendedUpgrade.ByPath[pathIndex];
			int num = towerById.GetAscendedStacks()[ascendedUpgrade];
			ascendedUpgrade.Apply(towerById, num + 1);
			if ((Delegate)(object)val != (Delegate)null)
			{
				val.Invoke(true);
			}
			UpgradeButton.upgradeCashOffset = 0f;
			current = null;
			return false;
		}
	}
	[HarmonyPatch(typeof(TowerManager), "GetTowerUpgradeCost")]
	internal static class TowerManager_GetTowerUpgradeCost
	{
		[HarmonyPrefix]
		internal static bool Prefix(Tower tower, int path, ref float __result)
		{
			if (!((Object)(object)TowerSelectionMenuExt.instance == (Object)null))
			{
				TowerToSimulation selectedTower = TowerSelectionMenuExt.instance.selectedTower;
				if (((selectedTower != null) ? selectedTower.tower : null) == tower && TowerSelectionMenuExt.instance.ShowAscendedUpgrades())
				{
					__result = CostHelper.CostForDifficulty(ModSettingInt.op_Implicit(AscendedUpgradesMod.BaseUpgradeCost), InGame.instance);
					Dictionary<AscendedUpgrade, int> ascendedStacks = tower.GetAscendedStacks();
					int num = (ModSettingBool.op_Implicit(AscendedUpgradesMod.SharedUpgradeScaling) ? ascendedStacks.Sum((KeyValuePair<AscendedUpgrade, int> pair) => pair.Value) : (from pair in ascendedStacks
						where pair.Key.Path == path
						select pair.Value).SingleOrDefault());
					__result += num * CostHelper.CostForDifficulty(ModSettingInt.op_Implicit(AscendedUpgradesMod.IncreaseUpgradeCost), InGame.instance);
					return false;
				}
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(BuffIcon), "Show")]
	internal static class BuffIcon_Show
	{
		[HarmonyPrefix]
		private static void Prefix(BuffQuery buff)
		{
			if (((Model)buff.buffIndicator).name.Contains("AscendedUpgrades"))
			{
				buff.availableBuffCount = buff.timedMutator.mutator.AscendedStackCount();
			}
		}
	}
}