Decompiled source of Paragonomics v1.0.6

Paragonomics.dll

Decompiled 9 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
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.ModOptions;
using BTD_Mod_Helper.Extensions;
using HarmonyLib;
using Il2Cpp;
using Il2CppAssets.Scripts.Data.ParagonData;
using Il2CppAssets.Scripts.Models;
using Il2CppAssets.Scripts.Models.Effects;
using Il2CppAssets.Scripts.Models.Entities;
using Il2CppAssets.Scripts.Models.Towers;
using Il2CppAssets.Scripts.Models.Towers.Behaviors;
using Il2CppAssets.Scripts.Models.Towers.Upgrades;
using Il2CppAssets.Scripts.Simulation.Objects;
using Il2CppAssets.Scripts.Simulation.SMath;
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 Il2CppAssets.Scripts.Unity.UI_New.Popups;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Il2CppTMPro;
using MelonLoader;
using Microsoft.CodeAnalysis;
using Paragonomics;
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(ParagonomicsMod), "Paragonomics", "1.0.6", "doombubbles", null)]
[assembly: MelonGame("Ninja Kiwi", "BloonsTD6")]
[assembly: MelonGame("Ninja Kiwi", "BloonsTD6-Epic")]
[assembly: MelonOptionalDependencies(new string[] { "BuffsInShop" })]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("Paragonomics")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+cd122a2d9a79721a1b928fd6b43b65f55d643544")]
[assembly: AssemblyProduct("Paragonomics")]
[assembly: AssemblyTitle("Paragonomics")]
[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 Paragonomics
{
	public static class Calculations
	{
		public static readonly Queue<int> DegreeCalculationHints = new Queue<int>();

		public static double DegreeToPower(long d)
		{
			if (1 == 0)
			{
			}
			double result;
			if (d > 0)
			{
				if (d <= 100)
				{
					if (d != 1)
					{
						if (d != 100)
						{
							goto IL_0066;
						}
						result = 200000.0;
					}
					else
					{
						result = 0.0;
					}
				}
				else
				{
					if (!ModSettingBool.op_Implicit(ParagonomicsMod.LinearScalingPastLimit))
					{
						goto IL_0066;
					}
					result = d * 2000;
				}
			}
			else
			{
				result = 0.0 - DegreeToPower(-d + 1);
			}
			goto IL_00c1;
			IL_0066:
			result = Math.Round((50.0 * Math.Pow(d, 3.0) + 5025.0 * Math.Pow(d, 2.0) + (double)(168324 * d) + 843000.0) / 600.0);
			goto IL_00c1;
			IL_00c1:
			if (1 == 0)
			{
			}
			return result;
		}

		public static long PowerToDegree(double power)
		{
			if (power != 0.0)
			{
				if (!(power < 0.0))
				{
					if (power != 200000.0)
					{
						if (power > 200000.0 && ModSettingBool.op_Implicit(ParagonomicsMod.LinearScalingPastLimit))
						{
							return (long)Math.Round(power / 2000.0);
						}
						if (!DegreeCalculationHints.TryDequeue(out var result))
						{
							result = 100;
						}
						double num = result;
						for (int i = 1; i < 100; i++)
						{
							double num2 = DegreeToPower((long)num);
							double num3 = DegreeToPower((long)num + 1);
							if (num2 <= power && num3 > power)
							{
								return (long)num;
							}
							double num4 = num2 - power;
							double num5 = (150.0 * Math.Pow(num, 2.0) + 10050.0 * num + 168324.0) / 600.0;
							double num6 = num4 / num5;
							num -= num6;
							num = Math.Max(1.0, num);
						}
						return (int)num;
					}
					return 100L;
				}
				return Math.Min(-PowerToDegree(0.0 - power) + 1, -1L);
			}
			return 1L;
		}

		public static int GetDisplayDegreeIndex(ParagonTower paragon, int degree)
		{
			Il2CppReferenceArray<AssetPathModel> displayDegreePaths = paragon.paragonTowerModel.displayDegreePaths;
			if (!((IEnumerable<AssetPathModel>)displayDegreePaths).Any())
			{
				return -1;
			}
			Il2CppStructArray<int> powerDegreeRequirements = ((RootObject)paragon).Sim.model.paragonDegreeDataModel.powerDegreeRequirements;
			return Math.Min(degree / (((Il2CppArrayBase<int>)(object)powerDegreeRequirements).Length / ((Il2CppArrayBase<AssetPathModel>)(object)displayDegreePaths).Length), ((Il2CppArrayBase<int>)(object)powerDegreeRequirements).Length - 1);
		}

		public static float GetCostFactor(ParagonTower paragon)
		{
			string baseId = ((EntityModel)((TowerBehavior)paragon).tower.towerModel).baseId;
			GameModel model = ((RootObject)paragon).Sim.model;
			float num = Math.Max(model.GetTower(baseId, 0, 0, 0).cost, 1f) * 3f;
			int num2 = (from tower in Il2CppGenericIEnumerable.AsIEnumerable<TowerModel>(model.GetTowersWithBaseId(baseId, false))
				where !tower.isParagon
				select tower).SelectMany((TowerModel tower) => (IEnumerable<string>)tower.appliedUpgrades).Distinct().Select((Func<string, UpgradeModel>)model.GetUpgrade)
				.Sum((UpgradeModel upgrade) => Math.Max(upgrade.cost, 1));
			int num3 = Math.Max(ParagonomicsMod.GetParagonUpgrade(((TowerBehavior)paragon).tower).cost, 10);
			return (num + (float)num2) / (num + (float)num2 + (float)num3);
		}

		public static float FactorForBaseDegree(float factor, int baseDegree)
		{
			return 100f * ((1f / factor - 1f) / (float)baseDegree);
		}

		public static PowerDegreeMutator GetDegreeMutator(ParagonTower paragon, int degree, AssetPathModel displayDegree)
		{
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Expected O, but got Unknown
			ParagonDegreeDataModel paragonDegreeDataModel = InGame.Bridge.Simulation.model.paragonDegreeDataModel;
			int num = degree - 1;
			float num2 = Math.Sign((float)num) * Math.Round(Math.Sqrt(Math.Abs((float)num) * paragonDegreeDataModel.attackCooldownReductionX) * 10f) / 10f;
			float num3 = (float)num * paragonDegreeDataModel.piercePercentPerDegree;
			float num4 = (float)num * paragonDegreeDataModel.pierceIncreasePerDegree;
			float num5 = (float)num * paragonDegreeDataModel.damagePercentPerDegree;
			float num6 = (float)num / paragonDegreeDataModel.damageIncreaseForDegrees * paragonDegreeDataModel.damageIncreasePerDegree;
			if (degree >= paragonDegreeDataModel.degreeCount)
			{
				num3 += paragonDegreeDataModel.piercePercentPerDegree;
				num4 += paragonDegreeDataModel.piercePercentPerDegree;
				num6 += paragonDegreeDataModel.damageIncreasePerDegree;
			}
			float num7 = 0f;
			if (degree >= paragonDegreeDataModel.bonusBossDamagePerDegrees)
			{
				num7 = (float)(degree / paragonDegreeDataModel.bonusBossDamagePerDegrees) * paragonDegreeDataModel.bonusBossDamagePercent;
			}
			int num8 = GetDisplayDegreeIndex(paragon, degree) + 1;
			if (num < 0)
			{
				num6 = Math.Max(0f, num6);
				num4 = Math.Max(0f, num4);
				float costFactor = GetCostFactor(paragon);
				float num9 = FactorForBaseDegree(costFactor, 29) * (1f + num2 / 100f);
				num3 = 0f - (100f + 10000f / (-100f + num3 * num9));
				num5 = 0f - (100f + 10000f / (-100f + num5 * num9));
			}
			return new PowerDegreeMutator(degree, num2, num3, num4, num5, (float)(int)num6, num8, displayDegree, paragon.paragonTowerModel.changeAttackDisplay, paragon.paragonTowerModel.changeAirUnitDisplay, num7);
		}
	}
	public static class ModHelperData
	{
		public const string WorksOnVersion = "54.0";

		public const string Version = "1.0.6";

		public const string Name = "Paragonomics";

		public const string Description = "Adds new ways to change Paragon degrees using cash.\n\nSubprime Paragons: Buy negative degree paragons for less cash than normal.\nParagon Investing: Spend cash to increase paragon degree after creation.\nSet Degree: Directly set paragon degree in Sandbox mode.";

		public const string RepoOwner = "doombubbles";

		public const string PrevRepoName = "paragonomics";

		public const string RepoName = "Paragonomics";
	}
	public class ParagonomicsMod : BloonsTD6Mod
	{
		public const int MinimumCostFactor = 100;

		public static readonly ModSettingBool AllowDegreeSettingOutsideSandbox = new ModSettingBool(false)
		{
			description = "Allows the cheat-y Set Degree feature to be used outside Sandbox mode.",
			icon = "1bf486871cae1224ca90cf52c1965462"
		};

		public static readonly ModSettingBool NoDegreeLimit = new ModSettingBool(false)
		{
			description = "Removes the standard degree 100 limit for the purposes of investing and degree setting.",
			icon = "1757f8ef9167a3842b6d977f379d8548"
		};

		public static readonly ModSettingBool LinearScalingPastLimit = new ModSettingBool(false)
		{
			description = "Makes the power investment requirement scaling be linear when the degree increases beyond 100, rather than continuing to be exponentially more."
		};

		public override object? Call(string operation, params object[] p)
		{
			if (1 == 0)
			{
			}
			float investment = default(float);
			object result = ((!(operation == "GetDegree") || !ArrayExt.CheckTypes<float>(p, ref investment)) ? null : ((object)GetDegree(investment)));
			if (1 == 0)
			{
			}
			return result;
		}

		public static void DegreeBtnPressed(ParagonTower paragon)
		{
			Calculations.DegreeCalculationHints.Enqueue(paragon.GetCurrentDegree());
			PopupScreenExt.SafelyQueue(PopupScreen.instance, (Action<PopupScreen>)delegate(PopupScreen screen)
			{
				//IL_0035: Unknown result type (might be due to invalid IL or missing references)
				screen.ShowSetValuePopup("Set Paragon Degree", "Directly set the degree of this paragon at no cost.", Action<int>.op_Implicit((Action<int>)delegate(int degree)
				{
					SetDegree(paragon, degree);
				}), GetDegree(paragon.investmentInfo.totalInvestment));
			});
		}

		public static UpgradeModel GetParagonUpgrade(Tower tower)
		{
			GameModel val = (((Object)(object)InGame.instance != (Object)null) ? InGame.Bridge.Model : Game.instance.model);
			BloonsMod val2 = default(BloonsMod);
			return (((Mutable)tower).IsMutatedBy("HonoraryParagon") && ModHelper.HasMod("HonoraryParagons", ref val2)) ? val2.Call<UpgradeModel>("GetParagonUpgrade", new object[2] { val, tower.towerModel }) : val.GetParagonUpgradeForTowerId(((EntityModel)tower.towerModel).baseId);
		}

		public static bool HasEnoughToShowPopup(Tower tower)
		{
			UpgradeModel paragonUpgrade = GetParagonUpgrade(tower);
			if (InGame.Bridge.GetCash(-1) * 100.0 >= (double)paragonUpgrade.cost)
			{
				return true;
			}
			StartPopup();
			PopupScreenExt.SafelyQueue(PopupScreen.instance, (Action<PopupScreen>)delegate(PopupScreen screen)
			{
				screen.ShowOkPopup("You must have at least 1% of the Paragon's Cost in cash.", ReturnCallback.op_Implicit((Action)FinishPopup));
			});
			return false;
		}

		public static void InvestBtnPressed(ParagonTower paragon, Action<double>? okCallback = null, Action? cancelCallback = null)
		{
			if (!HasEnoughToShowPopup(((TowerBehavior)paragon).tower))
			{
				return;
			}
			StartPopup();
			PopupScreenExt.SafelyQueue(PopupScreen.instance, (Action<PopupScreen>)delegate(PopupScreen screen)
			{
				screen.ShowParagonConfirmationPopup((Placement)0, "Invest in Paragon", "Add to your current Paragon Power investment.", Action<double>.op_Implicit((Action<double>)delegate(double cash)
				{
					FinishPopup();
					InvestInParagon(paragon, cash);
					okCallback?.Invoke(cash);
				}), "Do It", Action.op_Implicit((Action)delegate
				{
					FinishPopup();
					cancelCallback?.Invoke();
				}), "Cancel", (TransitionAnim)1, (int)InGame.Bridge.GetCash(-1), int.MaxValue, 0);
			});
		}

		public static void NegativeParagonPopup(TowerSelectionMenu tsm, int index)
		{
			if (!HasEnoughToShowPopup(tsm.selectedTower.tower))
			{
				return;
			}
			UpgradeModel upgrade = GetParagonUpgrade(tsm.selectedTower.tower);
			int minCost = upgrade.cost / 100;
			if (tsm.Bridge.GetCash(-1) >= (double)upgrade.cost || tsm.Bridge.GetCash(-1) < (double)minCost || !TowerSelectionMenuUtils.CanUpgradeToParagon(tsm.selectedTower, true))
			{
				return;
			}
			StartPopup();
			PopupScreenExt.SafelyQueue(PopupScreen.instance, (Action<PopupScreen>)delegate(PopupScreen screen)
			{
				screen.ShowParagonConfirmationPopup((Placement)0, "Subprime Paragon", "You dont have enough cash to initiate a full Paragon sacrifice. However, you can spend the cash you do have to get a weaker, Negative-Degree Paragon and invest more later.", Action<double>.op_Implicit((Action<double>)delegate(double amount)
				{
					FinishPopup();
					tsm.isUpgradePopupShowing = false;
					double num = amount + (double)minCost;
					Tower tower = tsm.selectedTower.tower;
					tsm.UpgradeTower(upgrade, index, (float)num, num - (double)upgrade.cost);
					tower.worth -= (float)upgrade.cost;
					tower.worth += (float)num;
				}), "Do It", Action.op_Implicit((Action)FinishPopup), "Cancel", (TransitionAnim)1, (int)InGame.Bridge.GetCash(-1) - minCost, upgrade.cost, minCost);
			});
		}

		public static void StartPopup()
		{
			InGame.instance.StopClock(true);
			InGame.instance.hotkeys.SuppressHotkeys = true;
			TowerSelectionMenuExt.instance.isUpgradePopupShowing = true;
		}

		public static void FinishPopup()
		{
			InGame.instance.ResumeClock(true);
			InGame.instance.hotkeys.SuppressHotkeys = false;
			TowerSelectionMenuExt.instance.isUpgradePopupShowing = false;
		}

		public static int GetDegree(float investment)
		{
			ParagonDegreeDataModel paragonDegreeDataModel = InGame.Bridge.Model.paragonDegreeDataModel;
			Il2CppStructArray<int> powerDegreeRequirements = paragonDegreeDataModel.powerDegreeRequirements;
			if (investment < 0f || (investment > (float)paragonDegreeDataModel.MaxInvestment && ModSettingBool.op_Implicit(NoDegreeLimit)))
			{
				return (int)Calculations.PowerToDegree(investment);
			}
			int i;
			for (i = 0; i < ((Il2CppArrayBase<int>)(object)powerDegreeRequirements).Length && investment >= (float)((Il2CppArrayBase<int>)(object)powerDegreeRequirements)[i]; i++)
			{
			}
			return i;
		}

		public static void SetDegree(ParagonTower paragon, int degree)
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: 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)
			GameModel model = ((RootObject)paragon).Sim.model;
			ParagonDegreeDataModel paragonDegreeDataModel = model.paragonDegreeDataModel;
			if (degree < 1 || degree > ((Il2CppArrayBase<int>)(object)paragonDegreeDataModel.powerDegreeRequirements).Length)
			{
				paragon.investmentInfo = new InvestmentInfo
				{
					totalInvestment = (float)Calculations.DegreeToPower(degree)
				};
				Calculations.DegreeCalculationHints.Enqueue(degree);
			}
			else
			{
				paragon.investmentInfo = new InvestmentInfo
				{
					totalInvestment = ((Il2CppArrayBase<int>)(object)paragonDegreeDataModel.powerDegreeRequirements)[degree - 1]
				};
			}
			OnDegreeChanged(paragon);
		}

		public static void InvestInParagon(ParagonTower paragon, double investment)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: 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)
			ParagonDegreeDataModel paragonDegreeDataModel = ((RootObject)paragon).Sim.model.paragonDegreeDataModel;
			int cost = GetParagonUpgrade(((TowerBehavior)paragon).tower).cost;
			float num = (float)investment * paragonDegreeDataModel.moneySpentOverX / ((1f + paragonDegreeDataModel.paidContributionPenalty) * (float)Math.Max(cost, 1));
			InvestmentInfo investmentInfo = paragon.investmentInfo;
			investmentInfo.totalInvestment = paragon.investmentInfo.totalInvestment + num;
			paragon.investmentInfo = investmentInfo;
			OnDegreeChanged(paragon);
			InGame.Bridge.SetCash(InGame.Bridge.GetCash(-1) - investment);
		}

		public static void OnDegreeChanged(ParagonTower paragon)
		{
			paragon.UpdateDegree();
			paragon.PlayParagonUpgradeSound();
			paragon.Finish();
			Il2CppGenericIEnumerable.ForEach<TowerCreateParagonTower>(((RootBehavior)paragon).entity.GetBehaviorsInDependants<TowerCreateParagonTower>(), (Action<TowerCreateParagonTower>)delegate(TowerCreateParagonTower tower)
			{
				tower.towerAdded = false;
			});
			TowerSelectionMenu instance = TowerSelectionMenuExt.instance;
			object obj;
			if (instance == null)
			{
				obj = null;
			}
			else
			{
				TowerToSimulation selectedTower = instance.selectedTower;
				obj = ((selectedTower != null) ? selectedTower.tower : null);
			}
			if (obj == ((TowerBehavior)paragon).tower)
			{
				TowerSelectionMenuExt.instance.OnTowerSelectionPanelForceUpdate();
			}
		}
	}
	[HarmonyPatch(typeof(TowerSelectionMenu), "UpdateParagon")]
	internal static class TowerSelectionMenu_UpdateParagon
	{
		[HarmonyPostfix]
		internal static void Postfix(TowerSelectionMenu __instance)
		{
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Expected O, but got Unknown
			//IL_0103: 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_0121: 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_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			GameObject gameObject = ((Component)((TMP_Text)__instance.paragonDegree).transform.parent).gameObject;
			if (!Object.op_Implicit((Object)(object)gameObject.GetComponent<Button>()) && (ModSettingBool.op_Implicit(ParagonomicsMod.AllowDegreeSettingOutsideSandbox) || __instance.Bridge.IsSandboxMode()))
			{
				Button val = gameObject.AddComponent<Button>();
				((Selectable)val).transition = (Transition)3;
				Animator val2 = gameObject.AddComponent<Animator>();
				val2.runtimeAnimatorController = Animations.GlobalButtonAnimation;
				val2.updateMode = (AnimatorUpdateMode)2;
				((Graphic)gameObject.GetComponent<Image>()).raycastTarget = true;
				ButtonExt.SetOnClick(val, (Function)delegate
				{
					ParagonomicsMod.DegreeBtnPressed(TowerBehaviorExt.GetTowerBehavior<ParagonTower>(__instance.selectedTower.tower));
				});
			}
			if (!Object.op_Implicit((Object)(object)GameObjectExt.GetComponentInChildrenByName<ModHelperButton>(__instance.paragonDetails, "ParagonomicsBtn")))
			{
				RectTransform val3 = ((Il2CppObjectBase)__instance.paragonDetails.transform.Find("ParagonInfo/ParagonTitle")).Cast<RectTransform>();
				Info val4 = default(Info);
				((Info)(ref val4))..ctor("ParagonomicsBtn");
				((Info)(ref val4)).set_AnchorMin(val3.anchorMin);
				((Info)(ref val4)).set_AnchorMax(val3.anchorMax);
				((Info)(ref val4)).set_Pivot(val3.pivot);
				((Info)(ref val4)).set_Position(Vector2.op_Implicit(((Transform)val3).localPosition));
				Rect rect = val3.rect;
				((Info)(ref val4)).set_Height(((Rect)(ref rect)).height);
				rect = val3.rect;
				((Info)(ref val4)).set_Width(((Rect)(ref rect)).width + 50f);
				ModHelperButton val5 = ModHelperButton.Create(val4, "Ui[ParagonBtnLong]", Action.op_Implicit((Action)delegate
				{
					ParagonomicsMod.InvestBtnPressed(TowerBehaviorExt.GetTowerBehavior<ParagonTower>(__instance.selectedTower.tower));
				}));
				((ModHelperComponent)val5).SetParent(((Transform)val3).parent);
				((Transform)val3).SetParent(((Component)val5).transform);
				val3.anchorMin = new Vector2(0f, 0f);
				val3.anchorMax = new Vector2(1f, 1f);
				val3.pivot = new Vector2(0.5f, 0.5f);
				val3.sizeDelta = new Vector2(0f, 0f);
				((Transform)val3).localPosition = new Vector3(0f, 10f, 0f);
			}
		}
	}
	[HarmonyPatch(typeof(ParagonTower), "GetDegreeMutator")]
	internal static class ParagonTower_GetDegreeMutator
	{
		[HarmonyPostfix]
		internal static void Postfix(ParagonTower __instance, AssetPathModel displayDegree, float investment, ref PowerDegreeMutator __result)
		{
			ParagonDegreeDataModel paragonDegreeDataModel = ((RootObject)__instance).Sim.model.paragonDegreeDataModel;
			if (investment < 0f || (investment > (float)paragonDegreeDataModel.MaxInvestment && ModSettingBool.op_Implicit(ParagonomicsMod.NoDegreeLimit)))
			{
				__result = Calculations.GetDegreeMutator(__instance, ParagonomicsMod.GetDegree(investment), displayDegree);
			}
		}
	}
	[HarmonyPatch(typeof(TowerSelectionMenu), "UpgradeTower", new Type[]
	{
		typeof(int),
		typeof(bool)
	})]
	internal static class TowerSelectionMenu_UpgradeTower
	{
		[HarmonyPrefix]
		internal static void Prefix(TowerSelectionMenu __instance, int index)
		{
			if (index >= ((Il2CppArrayBase<UpgradeObject>)(object)__instance.upgradeButtons).Length)
			{
				return;
			}
			UpgradeObject obj = ((Il2CppArrayBase<UpgradeObject>)(object)__instance.upgradeButtons)[index];
			if (obj != null)
			{
				UpgradeButton upgradeButton = obj.upgradeButton;
				if (((upgradeButton != null) ? new bool?(upgradeButton.IsParagon) : ((bool?)null)) == true)
				{
					ParagonomicsMod.NegativeParagonPopup(__instance, index);
				}
			}
		}
	}
	[HarmonyPatch(typeof(UpgradeButton), "UpdateCostVisuals")]
	internal static class UpgradeButton_UpdateCostVisuals
	{
		[HarmonyPostfix]
		internal static void Postfix(UpgradeButton __instance)
		{
			double cash = InGame.Bridge.GetCash(-1);
			if (__instance.IsParagon && cash < (double)__instance.upgradeCost && __instance.tts != null && cash * 100.0 >= (double)__instance.upgradeCost)
			{
				string text = __instance.upgradeCost.ToString(CultureInfo.InvariantCulture);
				NK_TextMeshProUGUI cost = __instance.Cost;
				string text2 = text;
				cost.SetText("<color=green>" + text2.Substring(0, text2.Length - 2) + "</color>" + text.Substring(text.Length - 2));
			}
		}
	}
	[HarmonyPatch(typeof(TowerCreateParagonTower), "GetParagonTowerModelTier")]
	internal static class TowerCreateParagonTower_GetParagonTowerModelTier
	{
		[HarmonyPrefix]
		internal static bool Prefix(TowerCreateParagonTower __instance, ref TowerModel __result)
		{
			int currentDegree = __instance.paragonTower.GetCurrentDegree();
			if (currentDegree >= 1)
			{
				return true;
			}
			__result = ((Il2CppArrayBase<TowerModel>)(object)__instance.behaviourModel.towerModels)[0];
			return false;
		}
	}
}