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";
}
}