using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BTD_Mod_Helper;
using BTD_Mod_Helper.Api;
using BTD_Mod_Helper.Api.Data;
using BTD_Mod_Helper.Api.Helpers;
using BTD_Mod_Helper.Api.ModOptions;
using BTD_Mod_Helper.Api.Towers;
using BTD_Mod_Helper.Extensions;
using HarmonyLib;
using Il2Cpp;
using Il2CppAssets.Scripts.Data;
using Il2CppAssets.Scripts.Data.Cosmetics;
using Il2CppAssets.Scripts.Data.Cosmetics.PowerAssetChanges;
using Il2CppAssets.Scripts.Data.TrophyStore;
using Il2CppAssets.Scripts.Models;
using Il2CppAssets.Scripts.Models.Entities;
using Il2CppAssets.Scripts.Models.Gameplay.Mods;
using Il2CppAssets.Scripts.Models.Powers;
using Il2CppAssets.Scripts.Models.Profile;
using Il2CppAssets.Scripts.Models.TowerSets;
using Il2CppAssets.Scripts.Models.Towers;
using Il2CppAssets.Scripts.Models.Towers.Behaviors;
using Il2CppAssets.Scripts.Models.Towers.Projectiles;
using Il2CppAssets.Scripts.Models.Towers.Upgrades;
using Il2CppAssets.Scripts.Simulation;
using Il2CppAssets.Scripts.Simulation.Input;
using Il2CppAssets.Scripts.Simulation.Objects;
using Il2CppAssets.Scripts.Simulation.SMath;
using Il2CppAssets.Scripts.Simulation.Towers;
using Il2CppAssets.Scripts.Unity;
using Il2CppAssets.Scripts.Unity.Bridge;
using Il2CppAssets.Scripts.Unity.Player;
using Il2CppAssets.Scripts.Unity.UI_New.InGame;
using Il2CppAssets.Scripts.Unity.UI_New.InGame.RightMenu;
using Il2CppAssets.Scripts.Unity.UI_New.InGame.RightMenu.Powers;
using Il2CppAssets.Scripts.Unity.UI_New.InGame.StoreMenu;
using Il2CppAssets.Scripts.Unity.UI_New.InGame.TowerSelectionMenu.TowerSelectionMenuThemes;
using Il2CppAssets.Scripts.Unity.UI_New.Upgrade;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppNinjaKiwi.Common.ResourceUtils;
using Il2CppNinjaKiwi.LiNK.Client;
using Il2CppSystem.Collections.Generic;
using Il2CppTMPro;
using MelonLoader;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json.Linq;
using PowersInShop;
using PowersInShop.Towers;
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(PowersInShopMod), "Powers in Shop", "3.1.1", "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("PowersInShop")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+faaf826a5c9731e6693b3dd23aa3fa05252814fa")]
[assembly: AssemblyProduct("PowersInShop")]
[assembly: AssemblyTitle("PowersInShop")]
[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 PowersInShop
{
public interface IPowerTower
{
string Id { get; }
string Name { get; }
string DisplayName { get; }
SpriteReference IconReference { get; }
int BaseCost { get; }
ModSettingInt _cost { get; set; }
void LoadImpl()
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: 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_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Expected O, but got Unknown
_cost = new ModSettingInt(BaseCost)
{
category = PowersInShopMod.Costs,
displayName = DisplayName,
description = "In Game Cost for " + DisplayName + ". Set to a negative number to disable the buff."
};
((BloonsMod)ModContent.GetInstance<PowersInShopMod>()).ModSettings[Name + "Cost"] = (ModSetting)(object)_cost;
}
void RegisterImpl()
{
PowersInShopMod.PowersByName[Name] = this;
PowersInShopMod.PowersById[Id] = this;
((ModSetting)_cost).icon = IconReference.AssetGUID;
}
}
public static class ModHelperData
{
public const string WorksOnVersion = "55.0";
public const string Version = "3.1.1";
public const string RepoOwner = "doombubbles";
public const string PrevRepoName = "powers-in-shop";
public const string RepoName = "PowersInShop";
public const string Name = "Powers in Shop";
public const string Description = "Adds many of the Monkey Money Powers to the in-game shop for purchase with normal currency.";
public const string Icon = "Powers-Button.png";
}
public abstract class ModInstantPower : ModFakeTower<Powers>, IPowerTower
{
public override bool DontAddToShop => ((ModTower)this).Cost < 0;
public override string DisplayName => "[" + ((ModContent)this).Name + "]";
public sealed override string Description => "[" + ((ModContent)this).Name + " Description]";
public override string Icon => SpriteResizer.Scaled(PowerModel.icon.AssetGUID, 0.75f, true);
public abstract int BaseCost { get; }
public ModSettingInt _cost { get; set; } = null;
public sealed override int Cost => ModSettingInt.op_Implicit(_cost);
protected IPowerTower This => this;
public static Simulation Sim => InGame.Bridge.Simulation;
public static GameModel GameModel => ((Object)(object)InGame.instance == (Object)null) ? Game.instance.model : Sim.model;
public PowerModel PowerModel => GameModel.GetPowerWithId(((ModContent)this).Name);
public override IEnumerable<ModContent> Load()
{
This.LoadImpl();
return ((ModContent)this).Load();
}
public override void Register()
{
This.RegisterImpl();
((ModTower)this).Register();
}
public override bool CanPlaceAt(Vector2 at, Tower hoveredTower, ref string helperMessage)
{
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
if (TimeManager.inBetweenRounds && !PowerModel.canBeActivatedBetweenRounds)
{
helperMessage = "Can only be used when a round is active.";
return false;
}
return InGame.Bridge.CheckPowerLocation(at, PowerModel);
}
public override void ModifyBaseTowerModel(TowerModel towerModel)
{
((ModFakeTower)this).ModifyBaseTowerModel(towerModel);
if (((EntityModel)towerModel).behaviors == null)
{
Il2CppReferenceArray<Model> val = (((EntityModel)towerModel).behaviors = new Il2CppReferenceArray<Model>(0L));
}
}
public override void ModifyTowerModelForMatch(TowerModel towerModel, GameModel gameModel)
{
PowerModel powerWithId = gameModel.GetPowerWithId(((ModContent)this).Name);
if (ModSettingBool.op_Implicit(PowersInShopMod.ChangeIconsForSkins))
{
towerModel.icon.guidRef = SpriteResizer.Scaled(powerWithId.icon.AssetGUID, 0.75f, true);
}
towerModel.portrait = towerModel.icon;
}
public sealed override void OnPlace(Vector2 at, TowerModel towerModelFake, Tower hoveredTower, float cost)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
ActivatePower(new Vector2(at), PowerModel);
}
public virtual void ActivatePower(Vector2 at, PowerModel powerModel)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
Sim.powerManager.Activate(at, ref powerModel, InGame.Bridge.MyPlayerNumber);
}
string IPowerTower.get_Id()
{
return ((ModContent)this).Id;
}
}
public abstract class ModPowerTower : ModPowerTowerBase
{
public sealed override int TopPathUpgrades => 0;
public sealed override int MiddlePathUpgrades => 0;
public sealed override int BottomPathUpgrades => 0;
public sealed override string Description => "[" + ((ModContent)this).Name + " Description]";
}
public abstract class ModPowerTowerBase : ModTower<Powers>, IPowerTower, IModSettings, IModContent
{
public override bool DontAddToShop => !Application.isBatchMode && ((ModTower)this).Cost < 0;
public override string DisplayName => "[" + ((ModContent)this).Name + "]";
public abstract int BaseCost { get; }
public ModSettingInt _cost { get; set; } = null;
public sealed override int Cost => ModSettingInt.op_Implicit(_cost);
protected IPowerTower This => this;
public override string BaseTower => ((ModContent)this).Name;
public PowerModel PowerModel => Game.instance.model.GetPowerWithId(((ModContent)this).Name);
public sealed override SpriteReference IconReference => ((ModTower)this).PortraitReference;
public sealed override SpriteReference PortraitReference
{
get
{
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Expected O, but got Unknown
SpriteReference portrait = PowerModel.tower.portrait;
object obj = ((portrait != null) ? portrait.AssetGUID : null);
if (obj == null)
{
SpriteReference icon = PowerModel.tower.icon;
obj = ((icon != null) ? icon.AssetGUID : null) ?? PowerModel.icon.AssetGUID;
}
return new SpriteReference((string)obj);
}
}
public sealed override bool IncludeInMonkeyTeams => false;
public override TowerModel GetBaseTowerModel(params int[] tiers)
{
return TowerModelExt.MakeCopy(PowerModel.tower, ((ModContent)this).Id, false, (string)null);
}
public override void ModifyBaseTowerModel(TowerModel towerModel)
{
}
public override IEnumerable<ModContent> Load()
{
This.LoadImpl();
return ((ModContent)this).Load();
}
public override void Register()
{
This.RegisterImpl();
((ModTower)this).Register();
}
public override void ModifyTowerModelForMatch(TowerModel towerModel, GameModel gameModel)
{
TowerModel tower = gameModel.GetPowerWithId(((ModContent)this).Name).tower;
string baseId = ((EntityModel)towerModel).baseId;
string name = ((Model)towerModel).name;
float cost = towerModel.cost;
SpriteReference icon = towerModel.icon;
towerModel.CopyFrom(tower, false);
((EntityModel)towerModel).baseId = baseId;
((Model)towerModel).name = name;
towerModel.cost = cost;
towerModel.icon = (ModSettingBool.op_Implicit(PowersInShopMod.ChangeIconsForSkins) ? towerModel.portrait : icon);
towerModel.powerName = null;
}
public virtual void MutateTower(TowerModel towerModel)
{
}
string IPowerTower.get_Id()
{
return ((ModContent)this).Id;
}
}
public abstract class ModPowerTowerPro : ModPowerTowerBase
{
public static readonly Dictionary<string, ModPowerTowerPro> ByName = new Dictionary<string, ModPowerTowerPro>();
public static readonly Dictionary<string, ModPowerTowerPro> ById = new Dictionary<string, ModPowerTowerPro>();
public static readonly Dictionary<string, string> Upgrades = new Dictionary<string, string>();
public sealed override int TopPathUpgrades => 3;
public sealed override int MiddlePathUpgrades => 3;
public sealed override int BottomPathUpgrades => 3;
public override bool DontApplyModUpgrades => true;
public sealed override string Description => "[" + ((ModContent)this).Name + "Power Description]";
public override bool IsValidCrosspath(params int[] tiers)
{
return tiers.Count((int tier) => tier > 0) <= 1;
}
public override void ModifyBaseTowerModel(TowerModel towerModel)
{
base.ModifyBaseTowerModel(towerModel);
foreach (string item in (Il2CppArrayBase<string>)(object)towerModel.appliedUpgrades)
{
Upgrades.TryAdd(item, ((ModContent)this).Name);
}
}
public override void Register()
{
base.Register();
ById[((ModContent)this).Id] = this;
ByName[((ModContent)this).Name] = this;
foreach (IGrouping<int, PowerProUpgradeModel> item in from pair in Upgrades
where pair.Value == ((ModContent)this).Name
select Game.instance.model.GetPowerProUpgrade(pair.Key) into model
group model by ((UpgradeModel)model).tier)
{
int xpCost = item.Max((PowerProUpgradeModel model) => ((UpgradeModel)model).xpCost);
foreach (PowerProUpgradeModel item2 in item)
{
((UpgradeModel)item2).xpCost = xpCost;
}
}
}
public override TowerModel GetBaseTowerModel(params int[] tiers)
{
return TowerModelExt.MakeCopy(((IEnumerable<TowerModel>)Game.instance.model.GetPowerProModel(((ModContent)this).Name).towerModels).First((TowerModel model) => model.CheckTiersAreEqual(tiers[0], tiers[1], tiers[2])), ((ModContent)this).Id, false, (string)null);
}
public override int? MaxUpgradePips(TowerToSimulation tower, int path, int defaultMax)
{
return Math.Min(3, defaultMax);
}
}
public abstract class ModTrackPower : ModInstantPower
{
private ModSettingInt pierce = null;
protected abstract int BasePierce { get; }
public override IEnumerable<ModContent> Load()
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: 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_0025: Expected O, but got Unknown
//IL_002a: Expected O, but got Unknown
ModSettingInt val = new ModSettingInt(BasePierce)
{
category = PowersInShopMod.Properties
};
((ModSettingNumber<long>)val).min = 0L;
pierce = val;
return base.Load();
}
public override void Register()
{
base.Register();
((ModSetting)pierce).icon = ((ModTower)this).IconReference.AssetGUID;
}
public override void ActivatePower(Vector2 at, PowerModel powerModel)
{
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
ProjectileModel descendant = ((Model)Game.instance.model.GetPowerWithId(((ModContent)this).Name)).GetDescendant<ProjectileModel>();
powerModel = ModelExt.Duplicate<PowerModel>(powerModel);
ProjectileModel descendant2 = ((Model)powerModel).GetDescendant<ProjectileModel>();
descendant2.pierce *= (float)ModSettingInt.op_Implicit(pierce) / descendant.pierce;
base.ActivatePower(at, powerModel);
}
}
public class Powers : ModTowerSet
{
public override bool AllowInRestrictedModes => ModSettingBool.op_Implicit(PowersInShopMod.AllowInRestrictedModes);
public override int GetTowerSetIndex(List<TowerSet> towerSets)
{
return towerSets.IndexOf((TowerSet)8) + 1;
}
}
public class PowersInShopMod : BloonsTD6Mod
{
public const string MutatorId = "PowersInShop";
public static readonly Dictionary<string, IPowerTower> PowersByName = new Dictionary<string, IPowerTower>();
public static readonly Dictionary<string, IPowerTower> PowersById = new Dictionary<string, IPowerTower>();
private static readonly ModSettingBool AllowInChimps = new ModSettingBool(false)
{
icon = "3f868bbf2f43344a78ddff2450dfa493"
};
public static readonly ModSettingBool AllowInRestrictedModes = new ModSettingBool(true)
{
description = "Determines whether power towers will be usable in Primary Only, Military Only and Magic Only game modes.",
icon = "MainMenuUiAtlas[MagicBtn]",
requiresRestart = true
};
public static readonly ModSettingBool OverrideHotkeys = new ModSettingBool(true)
{
description = "Disables the hotkeys for activating real powers, and assigns them to the shop ones instead.",
icon = "Ui[HotkeysIcon]"
};
public static readonly ModSettingBool ChangeIconsForSkins = new ModSettingBool(false)
{
description = "Whether to change the icons in the shop to reflect the power skin being used.",
icon = "95f6bb31750d2f64d90b44cc452d8ec8"
};
public static readonly ModSettingCategory Costs = ModSettingCategory.op_Implicit("Costs");
public static readonly ModSettingCategory RechargeCosts = ModSettingCategory.op_Implicit("Recharge Costs");
public static readonly ModSettingCategory Properties = ModSettingCategory.op_Implicit("Properties");
private static bool clipboardIsPowerFromShop;
public override void OnTitleScreen()
{
HandleChimps();
}
public override void OnSaveSettings(JObject settings)
{
foreach (ModTower item in from tower in ModContent.GetContent<ModTower>()
where tower is IPowerTower
select tower)
{
foreach (TowerModel item2 in Il2CppGenericIEnumerable.AsIEnumerable<TowerModel>(Game.instance.model.GetTowersWithBaseId(((ModContent)item).Id, false)))
{
item2.cost = item.Cost;
}
item.AddOrRemoveFromShop();
}
HandleChimps();
}
public static void HandleChimps()
{
//IL_016a: Unknown result type (might be due to invalid IL or missing references)
//IL_0174: Expected O, but got Unknown
ModModel val = ((IEnumerable<ModModel>)GameData.Instance.mods).FirstOrDefault((Func<ModModel, bool>)((ModModel model) => ((Model)model).name == "Clicks"));
if (val == null)
{
return;
}
List<MutatorModModel> chimpsMutators = Il2CppReferenceArrayExt.ToList<MutatorModModel>(val.mutatorMods);
Dictionary<string, LockTowerModModel> dictionary = (from tower in ModContent.GetContent<ModTower>()
where tower is IPowerTower
select tower).ToDictionary((ModTower tower) => ((ModContent)tower).Id, (ModTower tower) => chimpsMutators.OfType<LockTowerModModel>().FirstOrDefault((Func<LockTowerModModel, bool>)((LockTowerModModel model) => model.towerToLock == ((ModContent)tower).Id)));
if (ModSettingBool.op_Implicit(AllowInChimps))
{
foreach (LockTowerModModel item in dictionary.Values.Where((LockTowerModModel lockTowerModel) => lockTowerModel != null))
{
chimpsMutators.Remove((MutatorModModel)(object)item);
}
}
else
{
foreach (var (text2, val3) in dictionary)
{
if (val3 == null)
{
chimpsMutators.Add((MutatorModModel)new LockTowerModModel("", text2));
}
}
}
val.mutatorMods = ListExt.ToIl2CppReferenceArray<MutatorModModel>(chimpsMutators);
}
public static void MarkAsPowerFromShop(Tower tower)
{
MutableExt.AddMutator<PowersInShopMutator>((Mutable)(object)tower, (JToken)null, -1, true, true, false, true, false, false, false, -1, false, false);
}
public static bool IsPowerFromShop(Tower tower)
{
return MutableExt.IsMutatedBy<PowersInShopMutator>((Mutable)(object)tower);
}
public override void OnTowerSaved(Tower tower, TowerSaveDataModel saveData)
{
if (IsPowerFromShop(tower))
{
saveData.metaData["PowersInShop"] = "true";
}
}
public override void OnTowerLoaded(Tower tower, TowerSaveDataModel saveData)
{
if (saveData.metaData.ContainsKey("PowersInShop"))
{
MarkAsPowerFromShop(tower);
}
}
public static void SyncInventoryCounts(TowerInventory ti, PowerInventory pi, string powerName, Func<int, int, int> operation)
{
string id = ModContent.GetId<PowersInShopMod>(powerName);
ModTower val = default(ModTower);
if (!ModContent.TryFind<ModTower>(id, ref val))
{
return;
}
int num2 = default(int);
int num3 = default(int);
int num = operation(ti.towerCounts.TryGetValue(((ModContent)val).Id, ref num2) ? num2 : 0, pi.powerCounts.TryGetValue(((ModContent)val).Name, ref num3) ? num3 : 0);
ti.towerCounts[((ModContent)val).Id] = num;
pi.powerCounts[((ModContent)val).Name] = num;
ShopMenu instance = ShopMenuExt.instance;
if (instance != null)
{
Transform towerButtonFromBaseId = instance.GetTowerButtonFromBaseId(id);
if (towerButtonFromBaseId != null)
{
((Object)towerButtonFromBaseId).MarkDirty();
}
}
}
public override object? Call(string operation, params object[] parameters)
{
switch (operation)
{
case "OnTowerCopied":
{
Tower tower2 = default(Tower);
if (ArrayExt.CheckTypes<Tower>(parameters, ref tower2))
{
clipboardIsPowerFromShop = IsPowerFromShop(tower2);
}
break;
}
case "OnTowerPasted":
{
Tower tower = default(Tower);
if (ArrayExt.CheckTypes<Tower>(parameters, ref tower) && clipboardIsPowerFromShop)
{
MarkAsPowerFromShop(tower);
}
break;
}
case "OnClipboardCleared":
clipboardIsPowerFromShop = false;
break;
case "ModifyClipboardCost":
{
Tower val = default(Tower);
if (!ArrayExt.CheckTypes<Tower>(parameters, ref val))
{
break;
}
if (IsPowerFromShop(val) && ModPowerTowerPro.ByName.TryGetValue(((EntityModel)val.towerModel).baseId, out ModPowerTowerPro value))
{
return InGame.Bridge.Model.GetTower(((ModContent)value).Id, 0, 0, 0).cost;
}
return 0;
}
}
return null;
}
}
public class PowersInShopMutator : ModMutator
{
public override bool Saved => false;
public override int Priority => 10;
public override bool Mutate(Model baseModel, Model model, JToken data)
{
TowerModel val = default(TowerModel);
if (!Il2CppSystemObjectExt.Is<TowerModel>((Il2CppObjectBase)(object)model, ref val) || !PowersInShopMod.PowersByName.TryGetValue(((EntityModel)val).baseId, out IPowerTower value) || !(value is ModPowerTowerBase modPowerTowerBase))
{
return true;
}
modPowerTowerBase.MutateTower(val);
return true;
}
}
}
namespace PowersInShop.Towers
{
public class BananaFarmer : ModPowerTower
{
public override int BaseCost => 500;
protected override int Order => 5;
}
public class BananaFarmerPro : ModPowerTowerPro
{
public override string BaseTower => TowerType.BananaFarmerPro;
protected override int Order => 15;
public override int BaseCost => 1000;
}
public class CamoTrap : ModTrackPower
{
protected override int BasePierce => 500;
protected override int Order => 4;
public override int BaseCost => 600;
}
public class CaveMonkey : ModPowerTower
{
public override int BaseCost => 750;
protected override int Order => 14;
}
public class DartTime : ModInstantPower
{
public override int BaseCost => -1;
protected override int Order => 13;
}
public class EnergisingTotem : ModPowerTower
{
public static readonly ModSettingDouble TotemAttackSpeed;
public static readonly ModSettingInt TotemRechargeCost;
public override string BaseTower => TowerType.EnergisingTotem;
protected override int Order => 7;
public override int BaseCost => 1000;
public override void MutateTower(TowerModel towerModel)
{
TowerModelBehaviorExt.GetBehavior<RateSupportModel>(towerModel).multiplier = 1f / (1f + ModSettingDouble.op_Implicit(TotemAttackSpeed));
}
static EnergisingTotem()
{
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: 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_0038: Expected O, but got Unknown
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: Expected O, but got Unknown
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_0080: Expected O, but got Unknown
//IL_0085: Expected O, but got Unknown
ModSettingDouble val = new ModSettingDouble(0.15)
{
description = ".15 = 15%, down by default from the normal 25% boost so it isn't as blatantly overpowered",
category = PowersInShopMod.Properties
};
((ModSettingNumber<double>)val).min = 0.0;
((ModSetting)val).icon = "PowerIcons[EnergisingTotemIcon]";
TotemAttackSpeed = val;
ModSettingInt val2 = new ModSettingInt(500)
{
description = "In in-game cash, not monkey money",
category = PowersInShopMod.RechargeCosts,
icon = "PowerIcons[EnergisingTotemIcon]"
};
((ModSettingNumber<long>)val2).min = 0L;
TotemRechargeCost = val2;
}
}
public class GlueTrap : ModTrackPower
{
protected override int BasePierce => 300;
protected override int Order => 3;
public override int BaseCost => 500;
}
public class MoabMine : ModTrackPower
{
protected override int BasePierce => 1;
protected override int Order => 2;
public override int BaseCost => 2000;
}
public class MonkeyBoost : ModInstantPower
{
public override int BaseCost => -1;
protected override int Order => 11;
}
public class MonkeyBoostPro : ModPowerTowerPro
{
public static readonly ModSettingInt HypeRechargeCost = new ModSettingInt(1000)
{
description = "In in-game cash, not monkey money",
icon = "acf8fc839c349344e940ffb014577a0c",
category = PowersInShopMod.RechargeCosts
};
public override string BaseTower => "MonkeyBoostPro";
protected override int Order => 17;
public override int BaseCost => 4000;
public override void MutateTower(TowerModel towerModel)
{
base.MutateTower(towerModel);
if (towerModel.towerSelectionMenuThemeId == "Default")
{
towerModel.towerSelectionMenuThemeId = "SuperMonkeyBeacon";
}
}
}
public class Pontoon : ModPowerTower
{
protected override int Order => 8;
public override int BaseCost => 450;
}
public class PortableLake : ModPowerTower
{
protected override int Order => 9;
public override int BaseCost => 500;
}
public class RoadSpikes : ModTrackPower
{
protected override int BasePierce => 20;
protected override int Order => 1;
public override int BaseCost => 50;
}
public class SuperMonkeyBeacon : ModPowerTowerPro
{
public static readonly ModSettingInt BeaconRechargeCost = new ModSettingInt(2000)
{
description = "In in-game cash, not monkey money",
icon = "24ec1eea1a05c1b47975e8d2fd57513b",
category = PowersInShopMod.RechargeCosts
};
protected override int Order => 16;
public override int BaseCost => 4000;
}
public class SuperMonkeyStorm : ModInstantPower
{
public override int BaseCost => -1;
protected override int Order => 10;
}
public class TechBot : ModPowerTower
{
protected override int Order => 6;
public override int BaseCost => 375;
}
public class TechBotPrime : ModPowerTowerPro
{
public override string BaseTower => TowerType.TechBotPrime;
protected override int Order => 18;
public override int BaseCost => 1000;
}
public class Thrive : ModInstantPower
{
public override int BaseCost => -1;
protected override int Order => 12;
}
}
namespace PowersInShop.Patches
{
[HarmonyPatch(typeof(Hotkeys), "Setup")]
internal static class Hotkeys_Setup
{
[HarmonyPostfix]
private static void Postfix(Hotkeys __instance)
{
//IL_011f: 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_012d: Unknown result type (might be due to invalid IL or missing references)
//IL_0136: Unknown result type (might be due to invalid IL or missing references)
//IL_0143: Expected O, but got Unknown
if (!ModSettingBool.op_Implicit(PowersInShopMod.OverrideHotkeys))
{
return;
}
Dictionary<string, PowerHotkeyInfo> dictionary = ((IEnumerable<PowerHotkeyInfo>)__instance.powerHotkeys.ToArray()).Where((PowerHotkeyInfo info) => PowersInShopMod.PowersByName.ContainsKey(((Model)((PowerButton)info.standardPowerButton).powerModel).name)).DistinctBy((PowerHotkeyInfo info) => ((Model)((PowerButton)info.standardPowerButton).powerModel).name).ToDictionary((PowerHotkeyInfo info) => ((Model)((PowerButton)info.standardPowerButton).powerModel).name);
Enumerator<ITowerPurchaseButton> enumerator = ShopMenuExt.instance.ActiveTowerButtons.GetEnumerator();
while (enumerator.MoveNext())
{
ITowerPurchaseButton current = enumerator.Current;
string baseId = ((EntityModel)current.TowerModel).baseId;
if (PowersInShopMod.PowersById.TryGetValue(baseId, out IPowerTower value))
{
HotkeyButton hotkeyButton;
if (dictionary.TryGetValue(value.Name, out var value2))
{
__instance.powerHotkeys.Remove(value2);
hotkeyButton = value2.hotkeyButton;
}
else
{
hotkeyButton = __instance.hotKeyButtonSet.GetButton(value.Name);
}
__instance.towerHotkeys.Add(new TowerHotkeyInfo
{
towerBaseId = baseId,
hotkeyButton = hotkeyButton,
towerPurchaseButton = current
});
}
}
}
}
[HarmonyPatch(typeof(InputManager), "CreatePlacementTower")]
internal static class InputManager_CreatePlacementTower
{
[HarmonyPatch(typeof(Tower), "OnPlace")]
internal static class Tower_OnPlace
{
[HarmonyPostfix]
internal static void Postfix(Tower __instance)
{
if (nextPlace != null && !(((Model)__instance.towerModel).name != ((Model)nextPlace).name))
{
__instance.worth = nextCost;
PowersInShopMod.MarkAsPowerFromShop(__instance);
nextPlace = null;
nextCost = 0f;
}
}
}
internal static TowerModel? nextPlace;
internal static float nextCost;
[HarmonyPrefix]
internal static void Prefix(InputManager __instance, Vector2 pos)
{
//IL_0061: 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)
//IL_0072: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_009a: Unknown result type (might be due to invalid IL or missing references)
if (TowerModelExt.GetModTower(__instance.placementModel) is ModPowerTowerBase modPowerTowerBase)
{
TowerModel placementModel = ModelExt.Duplicate<TowerModel>(__instance.Bridge.Model.GetPowerWithId(((ModContent)modPowerTowerBase).Name).tower);
int myPlayerNumber = InGame.Bridge.MyPlayerNumber;
Simulation simulation = InGame.Bridge.Simulation;
float terrainHeight = simulation.Map.GetTerrainHeight(new Vector2(pos), false, false);
Vector3 val = default(Vector3);
((Vector3)(ref val))..ctor(pos.x, pos.y, terrainHeight);
TowerInventory towerInventory = simulation.GetTowerInventory(myPlayerNumber);
float towerCost = simulation.towerManager.GetTowerCost(__instance.placementModel, val, towerInventory, myPlayerNumber);
simulation.RemoveCash((double)towerCost, (CashType)0, myPlayerNumber, (CashSource)4);
__instance.placementModel = placementModel;
nextCost = towerCost;
nextPlace = placementModel;
}
}
}
[HarmonyPatch(typeof(Simulation), "StockStandardPowerInventory")]
internal static class Simulation_StockStandardPowerInventory
{
[HarmonyPostfix]
internal static void Postfix(Simulation __instance, PowerInventory pi)
{
int item = Il2CppSystemDictionaryExt.Entries<int, PowerInventory>(__instance.powerInventories).First<(int, PowerInventory)>(((int key, PowerInventory value) tuple) => tuple.value == pi).Item1;
TowerInventory val = __instance.towerInventories[item];
int num2 = default(int);
int num3 = default(int);
foreach (IPowerTower item2 in ModContent.GetContent<ModTower>().OfType<IPowerTower>())
{
int num = Math.Min(val.towerMaxes.TryGetValue(item2.Id, ref num2) ? num2 : int.MaxValue, pi.powerMaxes.TryGetValue(item2.Name, ref num3) ? num3 : int.MaxValue);
val.towerMaxes[item2.Id] = num;
pi.powerMaxes[item2.Name] = num;
}
}
}
[HarmonyPatch(typeof(Tower), "OnPlace")]
internal static class Tower_OnPlace
{
[HarmonyPostfix]
internal static void Postfix(Tower __instance)
{
if (__instance.towerModel.isPowerTower)
{
Simulation sim = ((RootObject)__instance).Sim;
PowerInventory pi = sim.powerInventories[__instance.owner];
TowerInventory ti = sim.towerInventories[__instance.owner];
PowersInShopMod.SyncInventoryCounts(ti, pi, __instance.towerModel.powerName, Math.Max);
}
}
}
[HarmonyPatch(typeof(Tower), "OnDestroy")]
internal static class Tower_OnDestroy
{
[HarmonyPostfix]
internal static void Postfix(Tower __instance)
{
if (__instance.towerModel.isPowerTower)
{
Simulation sim = ((RootObject)__instance).Sim;
PowerInventory val = sim.powerInventories[__instance.owner];
TowerInventory ti = sim.towerInventories[__instance.owner];
Dictionary<string, int> powerCounts = val.powerCounts;
string powerName = __instance.towerModel.powerName;
int num = powerCounts[powerName];
powerCounts[powerName] = num - 1;
PowersInShopMod.SyncInventoryCounts(ti, val, __instance.towerModel.powerName, Math.Min);
}
}
}
[HarmonyPatch]
public class TSMThemeRecharge_OnButtonPress
{
private static IEnumerable<MethodBase> TargetMethods()
{
yield return AccessTools.Method(typeof(TSMThemeEnergisingTotem), "OnButtonPress", new Type[2]
{
typeof(TowerToSimulation),
typeof(TSMButton)
}, (Type[])null);
yield return AccessTools.Method(typeof(TSMThemeSuperMonkeyBeacon), "OnButtonPress", new Type[2]
{
typeof(TowerToSimulation),
typeof(TSMButton)
}, (Type[])null);
}
[HarmonyPrefix]
public static bool Prefix(TSMThemeDefault __instance, TowerToSimulation tower, TSMButton button)
{
if (!PowersInShopMod.IsPowerFromShop(tower.tower))
{
return true;
}
int num;
if (Il2CppSystemObjectExt.Is<TSMThemeEnergisingTotem>((Il2CppObjectBase)(object)__instance))
{
num = ModSettingInt.op_Implicit(EnergisingTotem.TotemRechargeCost);
}
else
{
if (!Il2CppSystemObjectExt.Is<TSMThemeSuperMonkeyBeacon>((Il2CppObjectBase)(object)__instance))
{
return true;
}
num = ModSettingInt.op_Implicit((((EntityModel)tower.tower.towerModel).baseId == TowerType.SuperMonkeyBeacon) ? SuperMonkeyBeacon.BeaconRechargeCost : MonkeyBoostPro.HypeRechargeCost);
}
int num2 = CostHelper.CostForDifficulty(num, InGame.instance);
double cash = InGame.Bridge.GetCash(-1);
if (cash < (double)num2)
{
return false;
}
InGame.Bridge.Simulation.RemoveCash((double)num2, (CashType)1, tower.owner, (CashSource)0);
tower.PerformCustomUIAction(button.buttonId);
return false;
}
}
[HarmonyPatch]
internal static class TSMThemeRecharge_Selected
{
private static IEnumerable<MethodBase> TargetMethods()
{
yield return AccessTools.Method(typeof(TSMThemeEnergisingTotem), "Selected", new Type[2]
{
typeof(TowerToSimulation),
typeof(bool)
}, (Type[])null);
yield return AccessTools.Method(typeof(TSMThemeSuperMonkeyBeacon), "Selected", new Type[2]
{
typeof(TowerToSimulation),
typeof(bool)
}, (Type[])null);
}
[HarmonyPostfix]
internal static void Postfix(TSMThemeDefault __instance, TowerToSimulation tower)
{
//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
bool flag = PowersInShopMod.IsPowerFromShop(tower.tower);
TSMThemeEnergisingTotem val = default(TSMThemeEnergisingTotem);
GameObject gameObject;
int num;
if (Il2CppSystemObjectExt.Is<TSMThemeEnergisingTotem>((Il2CppObjectBase)(object)__instance, ref val))
{
gameObject = ((Component)val.rechargeButton).gameObject;
num = ModSettingInt.op_Implicit(EnergisingTotem.TotemRechargeCost);
}
else
{
TSMThemeSuperMonkeyBeacon val2 = default(TSMThemeSuperMonkeyBeacon);
if (!Il2CppSystemObjectExt.Is<TSMThemeSuperMonkeyBeacon>((Il2CppObjectBase)(object)__instance, ref val2))
{
return;
}
gameObject = ((Component)val2.rechargeButton).gameObject;
num = ModSettingInt.op_Implicit((((EntityModel)tower.tower.towerModel).baseId == TowerType.SuperMonkeyBeacon) ? SuperMonkeyBeacon.BeaconRechargeCost : MonkeyBoostPro.HypeRechargeCost);
}
int value = CostHelper.CostForDifficulty(num, InGame.instance);
NK_TextMeshProUGUI componentInChildrenByName = GameObjectExt.GetComponentInChildrenByName<NK_TextMeshProUGUI>(gameObject, "Text");
((Behaviour)componentInChildrenByName).enabled = true;
((TMP_Text)componentInChildrenByName).text = $"${value:N0}";
((TMP_Text)componentInChildrenByName).margin = new Vector4(0f, 25f, 0f, 0f);
((Component)componentInChildrenByName).gameObject.SetActive(flag);
((Behaviour)GameObjectExt.GetComponentInChildrenByName<Image>(gameObject, "MmIcon")).enabled = !flag;
((Behaviour)GameObjectExt.GetComponentInChildrenByName<NK_TextMeshProUGUI>(gameObject, "TextCount")).enabled = !flag;
}
}
[HarmonyPatch(typeof(CosmeticHelper), "ApplyAssetChangesToPowerModel")]
internal static class CosmeticHelper_ApplyAssetChangesToPowerModel
{
[HarmonyPostfix]
internal static void Postfix(PowerModel pm, PowerAssetChange pac)
{
//IL_0094: 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)
//IL_009c: Expected O, but got Unknown
//IL_00a1: Expected O, but got Unknown
if (!ModSettingBool.op_Implicit(PowersInShopMod.ChangeIconsForSkins) || !PowersInShopMod.PowersByName.TryGetValue(((Model)pm).name, out IPowerTower value) || !(value is ModTrackPower modTrackPower))
{
return;
}
TrophyStoreItem val = Il2CppGenerics.First<TrophyStoreItem>(GameData.Instance.trophyStoreItems.GetAllItems(), (Func<TrophyStoreItem, bool>)((TrophyStoreItem storeItem) => Il2CppReferenceArray.Any<TrophyItemTypeData>(storeItem.itemTypes, (Func<TrophyItemTypeData, bool>)((TrophyItemTypeData data) => data.itemTarget.id == ((AssetChangeItem)pac).id))));
TowerModel towerWithName = CosmeticHelper.rootGameModel.GetTowerWithName(((ModContent)modTrackPower).Id);
SpriteReference val2 = new SpriteReference(SpriteResizer.Scaled(val.icon.AssetGUID, 0.75f, true));
SpriteReference portrait = val2;
towerWithName.icon = val2;
towerWithName.portrait = portrait;
}
}
[HarmonyPatch(typeof(Btd6Player), "HasUnlockedTower")]
internal static class Btd6Player_HasUnlockedTower
{
[HarmonyPrefix]
internal static bool Prefix(Btd6Player __instance, string? towerId, ref bool __result)
{
if (towerId != null && ModPowerTowerPro.ById.TryGetValue(towerId, out ModPowerTowerPro value))
{
PowersProSaveData powersProSaveData = ((Player<ProfileModel>)(object)__instance).Data.powersProSaveData;
PowersProPowerSaveData val = default(PowersProPowerSaveData);
__result = powersProSaveData != null && powersProSaveData.dataByPower?.TryGetValue(((ModContent)value).Name, ref val) == true && val.seenUnlockPro.ValueBool;
return false;
}
return true;
}
}
[HarmonyPatch(typeof(Btd6Player), "HasUpgrade")]
internal static class Btd6Player_HasUpgrade
{
[HarmonyPrefix]
internal static bool Prefix(Btd6Player __instance, string upgradeId, ref bool __result)
{
if (ModPowerTowerPro.Upgrades.TryGetValue(upgradeId, out string value))
{
PowerProUpgradeModel powerProUpgrade = ((Player<ProfileModel>)(object)__instance).Data.Model.GetPowerProUpgrade(upgradeId);
PowersProSaveData powersProSaveData = ((Player<ProfileModel>)(object)__instance).Data.powersProSaveData;
PowersProPowerSaveData val = default(PowersProPowerSaveData);
__result = powersProSaveData != null && powersProSaveData.dataByPower?.TryGetValue(value, ref val) == true && val.unlockedTier.ValueInt > ((UpgradeModel)powerProUpgrade).tier;
return false;
}
return true;
}
}
[HarmonyPatch(typeof(SelectedUpgrade), "UpdateButtonState")]
internal static class SelectedUpgrade_UpdateButtonState
{
[HarmonyPostfix]
internal static void Postfix(SelectedUpgrade __instance)
{
GameObject gameObject = ((Component)((Component)__instance.aquireButton).transform.parent).gameObject;
UpgradeDetails selectedDetails = __instance.SelectedDetails;
int active;
if (selectedDetails == null)
{
active = 1;
}
else
{
UpgradeModel upgrade = selectedDetails.upgrade;
active = ((((upgrade != null) ? new bool?(Il2CppSystemObjectExt.Is<PowerProUpgradeModel>((Il2CppObjectBase)(object)upgrade)) : ((bool?)null)) != true) ? 1 : 0);
}
gameObject.SetActive((byte)active != 0);
}
}
[HarmonyPatch(typeof(UpgradeScreen), "ResetUpgradeUnlocks")]
internal static class UpgradeScreen_ResetUpgradeUnlocks
{
[HarmonyPostfix]
internal static void Postfix(Il2CppReferenceArray<UpgradeDetails> upgrades)
{
foreach (UpgradeDetails item in ((IEnumerable<UpgradeDetails>)upgrades).Where(delegate(UpgradeDetails upgrade)
{
UpgradeModel upgrade2 = upgrade.upgrade;
return upgrade2 != null && Il2CppSystemObjectExt.Is<PowerProUpgradeModel>((Il2CppObjectBase)(object)upgrade2) && !upgrade.hasUpgrade;
}))
{
item.SetLocked();
}
}
}
[HarmonyPatch(typeof(InGame), "ShowUpgradeTree", new Type[] { typeof(PlayerContext) })]
internal static class InGame_ShowUpgradeTree1
{
public static bool Active { get; private set; }
[HarmonyPrefix]
internal static void Prefix()
{
Active = true;
}
[HarmonyPostfix]
internal static void Postfix()
{
Active = false;
}
}
[HarmonyPatch(typeof(InGame), "ShowUpgradeTree", new Type[]
{
typeof(TowerModel),
typeof(Context),
typeof(bool)
})]
internal static class InGame_ShowUpgradeTree2
{
public static bool Active { get; private set; }
[HarmonyPrefix]
internal static void Prefix()
{
Active = true;
}
[HarmonyPostfix]
internal static void Postfix()
{
Active = false;
}
}
[HarmonyPatch(typeof(ReadonlyInGameData), "ArePowersAllowed")]
internal static class ReadonlyInGameData_ArePowersAllowed
{
[HarmonyPrefix]
internal static bool Prefix(ref bool __result)
{
if (InGame_ShowUpgradeTree1.Active || InGame_ShowUpgradeTree2.Active)
{
__result = true;
return false;
}
return true;
}
}
}