Decompiled source of InstaMonkeyRework v1.1.9

InstaMonkeyRework.dll

Decompiled 5 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 BTD_Mod_Helper;
using BTD_Mod_Helper.Api;
using BTD_Mod_Helper.Extensions;
using HarmonyLib;
using Il2Cpp;
using Il2CppAssets.Scripts;
using Il2CppAssets.Scripts.Models;
using Il2CppAssets.Scripts.Models.Entities;
using Il2CppAssets.Scripts.Models.Powers;
using Il2CppAssets.Scripts.Models.Profile;
using Il2CppAssets.Scripts.Models.Towers;
using Il2CppAssets.Scripts.Models.Towers.Upgrades;
using Il2CppAssets.Scripts.Simulation.Objects;
using Il2CppAssets.Scripts.Simulation.Towers;
using Il2CppAssets.Scripts.Simulation.Towers.Behaviors;
using Il2CppAssets.Scripts.Unity;
using Il2CppAssets.Scripts.Unity.Player;
using Il2CppAssets.Scripts.Unity.UI_New.InGame;
using Il2CppAssets.Scripts.Unity.UI_New.InGame.RightMenu.Powers;
using Il2CppAssets.Scripts.Unity.UI_New.InGame.StoreMenu;
using Il2CppAssets.Scripts.Unity.UI_New.Popups;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppSystem.Collections.Generic;
using Il2CppTMPro;
using InstaMonkeyRework;
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(InstaMonkeyReworkMod), "Insta Monkey Rework", "1.1.9", "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("InstaMonkeyRework")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+c2b9ae02cbeb07e1ac9b2988764878542a69459a")]
[assembly: AssemblyProduct("InstaMonkeyRework")]
[assembly: AssemblyTitle("InstaMonkeyRework")]
[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 InstaMonkeyRework
{
	public class InstaMonkeyReworkMod : BloonsTD6Mod
	{
		[HarmonyPatch(typeof(InputManager), "TryPlace")]
		internal class InputManager_TryPlace
		{
			[HarmonyPrefix]
			internal static bool Prefix()
			{
				return !((Object)(object)PopupScreen.instance != (Object)null) || !PopupScreen.instance.IsPopupActive();
			}
		}

		[HarmonyPatch(typeof(InputManager), "ExitInstaMode")]
		internal class InputManager_ExitInstaMode
		{
			[HarmonyPostfix]
			internal static void Postfix(InputManager __instance)
			{
				InInstaMode = false;
			}
		}

		[HarmonyPatch(typeof(Btd6Player), "ConsumeInstaTower")]
		internal class Btd6Player_ConsumeInstaTower
		{
			[HarmonyPrefix]
			internal static bool Prefix()
			{
				if (ActuallyConsumeInsta)
				{
					ActuallyConsumeInsta = false;
					return true;
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(Tower), "OnPlace")]
		internal static class Tower_OnPlace
		{
			[HarmonyPrefix]
			private static void Prefix(Tower __instance)
			{
				//IL_00af: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
				TowerModel towerModel = __instance.towerModel;
				Warned = false;
				if (__instance.worth != 0f)
				{
					return;
				}
				string name = ((Model)towerModel).name;
				TowerModel? instaModel = InstaModel;
				if (name == ((instaModel != null) ? ((Model)instaModel).name : null) && (!InGame.instance.IsCoop || __instance.owner == GameExt.GetNkGI(Game.instance).PeerID))
				{
					int costForThing = GetCostForThing(__instance);
					if (InGameExt.GetCash(InGame.instance) >= (double)costForThing)
					{
						costForThing = GetCostForThing(__instance);
						InGameExt.AddCash(InGame.instance, (double)(-costForThing));
						__instance.worth = costForThing;
						Dictionary<int, string> savedPlacedInstas = SavedPlacedInstas;
						ObjectId id = ((RootObject)__instance).Id;
						savedPlacedInstas[((ObjectId)(ref id)).Id] = ((Model)towerModel).name;
					}
					else
					{
						ActuallyConsumeInsta = true;
						GameExt.GetBtd6Player(Game.instance).ConsumeInstaTower(((EntityModel)towerModel).baseId, towerModel.tiers);
					}
					InstaModel = null;
				}
			}
		}

		[HarmonyPatch(typeof(StandardInstaTowerButton), "UpdateUseCount")]
		internal class StandardInstaTowerButton_UpdateUseCount
		{
			[HarmonyPostfix]
			internal static void Postfix(StandardInstaTowerButton __instance, int useCount)
			{
				int num = useCount - GetTotalPlaced(((Model)__instance.instaTowerModel).name);
				((StandardPowerButton)__instance).powerCountText.SetText(num + "/" + useCount);
			}
		}

		[HarmonyPatch(typeof(StandardInstaTowerButton), "SetPower")]
		internal class StandardInstaTowerButton_SetPower
		{
			[HarmonyPostfix]
			internal static void Postfix(StandardInstaTowerButton __instance, PowerModel powerModel, bool isInsta)
			{
				//IL_008d: 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)
				TextMeshProUGUI val = ((IEnumerable<TextMeshProUGUI>)((Component)__instance).GetComponentsInChildren<TextMeshProUGUI>()).FirstOrDefault((Func<TextMeshProUGUI, bool>)((TextMeshProUGUI text) => ((Object)text).name == "Cost"));
				float num = ((TMP_Text)__instance.tiers).fontSize / 3f;
				if ((Object)(object)val == (Object)null)
				{
					val = (TextMeshProUGUI)(object)Object.Instantiate<NK_TextMeshProUGUI>(__instance.tiers, ((TMP_Text)__instance.tiers).transform.parent, true);
					((Object)val).name = "Cost";
					((TMP_Text)val).transform.Translate(0f, num, 0f);
					((Graphic)val).color = Color.red;
				}
				int costForThing = GetCostForThing(powerModel.tower);
				((TMP_Text)val).SetText($"${costForThing:n0}");
				int tier = __instance.instaTowerModel.tier;
				TextMeshProUGUI val2 = ((IEnumerable<TextMeshProUGUI>)((Component)__instance).GetComponentsInChildren<TextMeshProUGUI>()).FirstOrDefault((Func<TextMeshProUGUI, bool>)((TextMeshProUGUI text) => ((Object)text).name == "Discount"));
				if ((Object)(object)val2 == (Object)null)
				{
					val2 = (TextMeshProUGUI)(object)Object.Instantiate<NK_TextMeshProUGUI>(((StandardPowerButton)__instance).powerCountText, ((TMP_Text)((StandardPowerButton)__instance).powerCountText).transform.parent, true);
					((Object)val2).name = "Discount";
					((TMP_Text)val2).transform.Translate(num * 3f, 0f, 0f);
					((Graphic)val2).color = Color.green;
				}
				if (tier > 0)
				{
					((TMP_Text)val2).SetText("-" + tier * 5 + "%");
				}
				else
				{
					((TMP_Text)val2).SetText("");
				}
			}
		}

		[HarmonyPatch(typeof(TowerPurchaseButton), "ButtonActivated")]
		internal class TowerPurchaseButton_OnPointerClick
		{
			[HarmonyPrefix]
			internal static bool Prefix(TowerPurchaseButton __instance)
			{
				if (Input.GetMouseButton(1) && __instance.towerModel.IsBaseTower && !__instance.IsHero && InGameData.CurrentGame.ArePowersAllowed())
				{
					Context val = Il2CppGenerics.First<Context>(InGame.instance.playerContexts);
					val.rightMenu.ShowPowersMenu();
					PowersMenu powersMenu = ((Il2CppObjectBase)val.powersMenu).Cast<PowersMenu>();
					powersMenu.ShowInstaMonkeys();
					InGameExt[InGame.instance].ExitTowerMode();
					TaskScheduler.ScheduleTask((Action)delegate
					{
						powersMenu.instaTowersMenu.Show(__instance.towerModel);
					}, (Func<bool>)null);
					return false;
				}
				return true;
			}
		}

		public static bool ActuallyConsumeInsta;

		public static bool InInstaMode;

		public static TowerModel? InstaModel;

		public static bool Warned;

		public static Dictionary<int, string> SavedPlacedInstas;

		public override void OnMainMenu()
		{
			SavedPlacedInstas = new Dictionary<int, string>();
		}

		public override void OnRestart()
		{
			SavedPlacedInstas = new Dictionary<int, string>();
		}

		public static int GetCostForThing(TowerModel towerModel)
		{
			float num = Game.instance.model.GetTowerFromId(((Model)towerModel).name).cost + (float)TowerModelExt.GetAppliedUpgrades(towerModel).Sum((UpgradeModel model) => model.cost);
			switch (InGame.instance.SelectedDifficulty)
			{
			case "Easy":
				num *= 0.85f;
				break;
			case "Hard":
				num *= 1.08f;
				break;
			case "Impoppable":
				num *= 1.2f;
				break;
			}
			num *= 1f - 0.05f * (float)towerModel.tier;
			return (int)(5.0 * Math.Round(num / 5f));
		}

		public static int GetCostForThing(Tower tower)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			float cost = Game.instance.model.GetTowerFromId(((Model)tower.towerModel).name).cost;
			TowerManager towerManager = InGameExt.GetTowerManager(InGame.instance);
			Dictionary<string, List<DiscountZone>> zoneDiscount = towerManager.GetZoneDiscount(tower.towerModel, ((CommonBehaviorProxy<ITowerBehavior>)(object)tower).Position.ToVector3(), 0, 0, tower.owner, "");
			float discountMultiplier = towerManager.GetDiscountMultiplier(zoneDiscount);
			cost *= 1f - discountMultiplier;
			foreach (UpgradeModel appliedUpgrade in TowerModelExt.GetAppliedUpgrades(tower.towerModel))
			{
				float num = appliedUpgrade.cost;
				zoneDiscount = towerManager.GetZoneDiscount(tower.towerModel, ((CommonBehaviorProxy<ITowerBehavior>)(object)tower).Position.ToVector3(), appliedUpgrade.path, appliedUpgrade.tier, tower.owner, ((Model)appliedUpgrade).name);
				discountMultiplier = towerManager.GetDiscountMultiplier(zoneDiscount);
				num *= 1f - discountMultiplier;
				cost += num;
			}
			switch (InGame.instance.SelectedDifficulty)
			{
			case "Easy":
				cost *= 0.85f;
				break;
			case "Hard":
				cost *= 1.08f;
				break;
			case "Impoppable":
				cost *= 1.2f;
				break;
			}
			cost *= 1f - 0.05f * (float)tower.towerModel.tier;
			return (int)(5.0 * Math.Round(cost / 5f));
		}

		public static int GetTotalPlaced(string name)
		{
			return SavedPlacedInstas.Values.Count((string value) => value == name);
		}

		public override void OnUpdate()
		{
			//IL_0121: 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_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)InGame.instance == (Object)null || InGame.instance.bridge == null)
			{
				return;
			}
			InGame instance = InGame.instance;
			if (instance != null)
			{
				List<Context> playerContexts = instance.playerContexts;
				bool? obj;
				PowersMenu val = default(PowersMenu);
				if (playerContexts == null)
				{
					obj = null;
				}
				else
				{
					Context obj2 = Il2CppGenerics.FirstOrDefault<Context>(playerContexts);
					if (obj2 == null)
					{
						obj = null;
					}
					else
					{
						BasePowersMenu powersMenu = obj2.powersMenu;
						obj = ((powersMenu != null) ? new bool?(Il2CppSystemObjectExt.Is<PowersMenu>((Il2CppObjectBase)(object)powersMenu, ref val)) : ((bool?)null));
					}
				}
				bool? flag = obj;
				InstaTowersMenu val2 = default(InstaTowersMenu);
				if (flag == true && Il2CppSystemObjectExt.Is<InstaTowersMenu>(val.instaTowersMenu, ref val2))
				{
					foreach (StandardInstaTowerButton componentsInChild in ((Component)val2).GetComponentsInChildren<StandardInstaTowerButton>())
					{
						TextMeshProUGUI val3 = ((IEnumerable<TextMeshProUGUI>)((Component)componentsInChild).GetComponentsInChildren<TextMeshProUGUI>()).FirstOrDefault((Func<TextMeshProUGUI, bool>)((TextMeshProUGUI text) => ((Object)text).name == "Cost"));
						if (!((Object)(object)val3 == (Object)null))
						{
							int num = TextToInt(val3);
							((Graphic)val3).color = ((InGameExt.GetCash(InGame.instance) >= (double)num) ? Color.white : Color.red);
							int useCount = ((StandardPowerButton)componentsInChild).GetUseCount();
							int totalPlaced = GetTotalPlaced(((Model)componentsInChild.instaTowerModel).name);
							TextMeshProUGUI val4 = ((IEnumerable<TextMeshProUGUI>)((Component)componentsInChild).GetComponentsInChildren<TextMeshProUGUI>()).First((TextMeshProUGUI text) => ((Object)text).name == "Discount");
							if (totalPlaced >= useCount)
							{
								((Behaviour)val3).enabled = false;
								((Behaviour)val4).enabled = false;
								((Graphic)((StandardPowerButton)componentsInChild).powerCountText).color = Color.red;
							}
							else
							{
								((Behaviour)val3).enabled = true;
								((Behaviour)val4).enabled = true;
								((Graphic)((StandardPowerButton)componentsInChild).powerCountText).color = Color.white;
							}
						}
					}
				}
			}
			InputManager val5 = InGameExt[InGame.instance];
			if (val5 == null || !val5.inInstaMode || InInstaMode)
			{
				return;
			}
			int useCount2 = ((StandardPowerButton)val5.instaButton).GetUseCount();
			int totalPlaced2 = GetTotalPlaced(((Model)val5.instaModel).name);
			int costForThing = GetCostForThing(val5.instaModel);
			if (!Warned && (totalPlaced2 >= useCount2 || (double)costForThing > InGameExt.GetCash(InGame.instance)))
			{
				PopupScreen.instance.ShowPopup((Placement)0, "Real Insta Warning", "You are placing an actual Insta Monkey, and doing so will remove it from your inventory. Are you sure you want to continue?", ReturnCallback.op_Implicit((Action)delegate
				{
					Warned = true;
				}), "Yes", ReturnCallback.op_Implicit((Action)val5.CancelAllPlacementActions), "No", (TransitionAnim)1, (BackGround)1, false, false);
			}
			InInstaMode = true;
			InstaModel = val5.instaModel;
		}

		public static int TextToInt(TextMeshProUGUI textMeshProUGUI)
		{
			return int.Parse(((TMP_Text)textMeshProUGUI).text.Substring(1).Replace(",", ""));
		}

		public override void OnTowerSaved(Tower tower, TowerSaveDataModel saveData)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: 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_0034: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<int, string> savedPlacedInstas = SavedPlacedInstas;
			ObjectId id = ((RootObject)tower).Id;
			if (savedPlacedInstas.ContainsKey(((ObjectId)(ref id)).Id))
			{
				Dictionary<string, string> metaData = saveData.metaData;
				Dictionary<int, string> savedPlacedInstas2 = SavedPlacedInstas;
				id = ((RootObject)tower).Id;
				metaData["InstaMonkeyRework"] = savedPlacedInstas2[((ObjectId)(ref id)).Id];
			}
		}

		public override void OnTowerLoaded(Tower tower, TowerSaveDataModel saveData)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			if (saveData.metaData.ContainsKey("InstaMonkeyRework"))
			{
				Dictionary<int, string> savedPlacedInstas = SavedPlacedInstas;
				ObjectId id = ((RootObject)tower).Id;
				savedPlacedInstas[((ObjectId)(ref id)).Id] = saveData.metaData["InstaMonkeyRework"];
			}
		}

		public override void OnTowerDestroyed(Tower tower)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: 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_0029: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<int, string> savedPlacedInstas = SavedPlacedInstas;
			ObjectId id = ((RootObject)tower).Id;
			if (savedPlacedInstas.ContainsKey(((ObjectId)(ref id)).Id))
			{
				Dictionary<int, string> savedPlacedInstas2 = SavedPlacedInstas;
				id = ((RootObject)tower).Id;
				savedPlacedInstas2.Remove(((ObjectId)(ref id)).Id);
			}
		}
	}
	public static class ModHelperData
	{
		public const string WorksOnVersion = "54.0";

		public const string Version = "1.1.9";

		public const string Name = "Insta Monkey Rework";

		public const string Description = "Adds a new way to use insta monkeys: Instead of being one-time use only, you can optionally spend in-game cash for instas and they won't be removed from your collection. Price is discounted from the full amount based on the tier of the insta.";

		public const string RepoOwner = "doombubbles";

		public const string PrevRepoName = "insta-monkey-rework";

		public const string RepoName = "InstaMonkeyRework";
	}
}