using System; using System.Collections; 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.Display; using BTD_Mod_Helper.Api.Towers; using BTD_Mod_Helper.Extensions; using HarmonyLib; using Il2CppAssets.Scripts.Models; using Il2CppAssets.Scripts.Models.Bloons.Behaviors; 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.Behaviors.Abilities; using Il2CppAssets.Scripts.Models.Towers.Behaviors.Abilities.Behaviors; using Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack; using Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.Behaviors; using Il2CppAssets.Scripts.Models.Towers.Filters; using Il2CppAssets.Scripts.Models.Towers.Projectiles; using Il2CppAssets.Scripts.Models.Towers.Projectiles.Behaviors; using Il2CppAssets.Scripts.Models.Towers.TowerFilters; using Il2CppAssets.Scripts.Simulation; using Il2CppAssets.Scripts.Simulation.Bloons; using Il2CppAssets.Scripts.Simulation.Input; using Il2CppAssets.Scripts.Simulation.Objects; using Il2CppAssets.Scripts.Simulation.Towers; using Il2CppAssets.Scripts.Simulation.Towers.Behaviors; using Il2CppAssets.Scripts.Simulation.Towers.Projectiles; using Il2CppAssets.Scripts.Simulation.Towers.Projectiles.Behaviors; using Il2CppAssets.Scripts.Simulation.Track; using Il2CppAssets.Scripts.Unity; using Il2CppAssets.Scripts.Unity.Bridge; using Il2CppAssets.Scripts.Unity.Display; using Il2CppAssets.Scripts.Unity.UI_New.InGame; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppNinjaKiwi.Common.ResourceUtils; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using Il2CppSystem.Linq; using IndustrialFarmer; using MelonLoader; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: MelonInfo(typeof(IndustrialFarmerMod), "Industrial Farmer", "1.0.15", "doombubbles", null)] [assembly: MelonGame("Ninja Kiwi", "BloonsTD6")] [assembly: MelonGame("Ninja Kiwi", "BloonsTD6-Epic")] [assembly: MelonOptionalDependencies(new string[] { "AbilityChoice" })] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("IndustrialFarmer")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+e26594e9448fa47e946a68d4b701f083b87ce8a0")] [assembly: AssemblyProduct("IndustrialFarmer")] [assembly: AssemblyTitle("IndustrialFarmer")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] [CompilerGenerated] internal sealed class <>z__ReadOnlyArray : IEnumerable, ICollection, IList, IEnumerable, IReadOnlyCollection, IReadOnlyList, ICollection, IList { int ICollection.Count => _items.Length; bool ICollection.IsSynchronized => false; object ICollection.SyncRoot => this; object? IList.this[int index] { get { return _items[index]; } set { throw new NotSupportedException(); } } bool IList.IsFixedSize => true; bool IList.IsReadOnly => true; int IReadOnlyCollection.Count => _items.Length; T IReadOnlyList.this[int index] => _items[index]; int ICollection.Count => _items.Length; bool ICollection.IsReadOnly => true; T IList.this[int index] { get { return _items[index]; } set { throw new NotSupportedException(); } } public <>z__ReadOnlyArray(T[] items) { _items = items; } IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)_items).GetEnumerator(); } void ICollection.CopyTo(Array array, int index) { ((ICollection)_items).CopyTo(array, index); } int IList.Add(object? value) { throw new NotSupportedException(); } void IList.Clear() { throw new NotSupportedException(); } bool IList.Contains(object? value) { return ((IList)_items).Contains(value); } int IList.IndexOf(object? value) { return ((IList)_items).IndexOf(value); } void IList.Insert(int index, object? value) { throw new NotSupportedException(); } void IList.Remove(object? value) { throw new NotSupportedException(); } void IList.RemoveAt(int index) { throw new NotSupportedException(); } IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)_items).GetEnumerator(); } void ICollection.Add(T item) { throw new NotSupportedException(); } void ICollection.Clear() { throw new NotSupportedException(); } bool ICollection.Contains(T item) { return ((ICollection)_items).Contains(item); } void ICollection.CopyTo(T[] array, int arrayIndex) { ((ICollection)_items).CopyTo(array, arrayIndex); } bool ICollection.Remove(T item) { throw new NotSupportedException(); } int IList.IndexOf(T item) { return ((IList)_items).IndexOf(item); } void IList.Insert(int index, T item) { throw new NotSupportedException(); } void IList.RemoveAt(int index) { throw new NotSupportedException(); } } 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 IndustrialFarmer { public class IndustrialFarmer : ModHero { public const string IndustrialFarmerDiscount = "IndustrialFarmerDiscount"; public override string BaseTower => TowerType.BananaFarmer; public override int Cost => 1400; public override string DisplayName => "Norman"; public override string Title => "Industrial Farmer"; public override string Level1Description => "Collects nearby bananas. Your next Banana Farm is free."; public override string Description => "Norman collects your Bananas and helps you expand your farming operations."; public override string NameStyle => TowerType.Gwendolin; public override string BackgroundStyle => TowerType.Etienne; public override string GlowStyle => TowerType.StrikerJones; public override float XpRatio => 1f; public override string RogueStarterArtifact => "TheUnspokenHeroes1"; public override IEnumerable<(string, int[])> RogueStarterInstas => new <>z__ReadOnlyArray<(string, int[])>(new(string, int[])[2] { (TowerType.BananaFarm, new int[3]), (TowerType.EngineerMonkey, new int[3] { 0, 0, 2 }) }); public override void ModifyBaseTowerModel(TowerModel towerModel) { TowerModel towerWithName = Game.instance.model.GetTowerWithName(TowerType.Quincy); TowerModelBehaviorExt.AddBehavior(towerModel, ModelExt.Duplicate(TowerModelBehaviorExt.GetBehavior(towerWithName))); TowerModelBehaviorExt.AddBehavior(towerModel, ModelExt.Duplicate(TowerModelBehaviorExt.GetBehavior(towerWithName))); ((EntityModel)towerModel).radius = ((EntityModel)towerWithName).radius; towerModel.footprint = ModelExt.Duplicate(towerWithName.footprint); } } public class IndustrialFarmerMod : BloonsTD6Mod { } public class Levels { public class Level2 : ModHeroLevel { public override string Description => "Collected Bananas are worth 10% more."; public override int Level => 2; public override void ApplyUpgrade(TowerModel towerModel) { ((Model)TowerModelBehaviorExt.GetBehavior(towerModel)).name = "CollectCashZoneModel_" + ((ModContent)this).Id; } } public class Level3 : ModHeroLevel { public override string AbilityName => "Bloon Pesticide"; public override string AbilityDescription => "Spray Bloons in a large area with pesticide, damaging them over time."; public override string Description => ((ModHeroLevel)this).AbilityName + ": " + ((ModHeroLevel)this).AbilityDescription; public override int Level => 3; public override void ApplyUpgrade(TowerModel towerModel) { TowerModel towerWithName = Game.instance.model.GetTowerWithName(TowerType.Quincy + " 10"); TowerModel towerWithName2 = Game.instance.model.GetTowerWithName(TowerType.GlueGunner + "-300"); TowerModel towerWithName3 = Game.instance.model.GetTowerWithName(TowerType.GlueGunner + "-040"); AddBehaviorToBloonModel val = ModelExt.Duplicate(((Model)towerWithName2).GetDescendant()); val.mutationId = "Pesticide"; val.glueLevel = 0; val.collideThisFrame = true; AbilityModel val2 = ModelExt.Duplicate(TowerModelExt.GetAbility(towerWithName, 1)); ((Model)val2).name = "AbilityModel_BloonPesticide"; val2.displayName = ((ModHeroLevel)this).AbilityName; val2.addedViaUpgrade = ((ModContent)this).Id; val2.icon = ((ModContent)this).GetSpriteReference("BloonPesticide"); AbilityModelBehaviorExt.RemoveBehavior(val2); AbilityModelBehaviorExt.AddBehavior(val2, ((Model)towerWithName3).GetDescendant()); val2.Cooldown = 30f; TowerModelBehaviorExt.AddBehavior(towerModel, val2); AttackModel val3 = ((Il2CppArrayBase)(object)AbilityModelBehaviorExt.GetBehavior(val2).attacks)[0]; val3.targetProvider = (TargetSupplierModel)(object)AttackModelBehaviorExt.GetBehavior(val3); AttackModelBehaviorExt.RemoveBehavior(val3); AttackModelBehaviorExt.RemoveBehavior(val3); AttackModelBehaviorExt.RemoveBehavior(val3); PrefabReference assetId = ((Model)Game.instance.model.GetTower(TowerType.GlueGunner, 3, 2, 0)).GetDescendant().effectModel.assetId; EffectModel effectModel = ((Model)val3).GetDescendant().effectModel; effectModel.assetId = assetId; effectModel.scale = 3f; ProjectileModel projectile = ((Model)val3).GetDescendant().projectile; ProjectileModelBehaviorExt.RemoveBehavior(projectile); ProjectileModelBehaviorExt.RemoveBehavior(projectile); ProjectileModelBehaviorExt.GetBehavior(projectile).Lifespan = 0.1f; ProjectileModelBehaviorExt.RemoveBehavior(projectile); ProjectileModelBehaviorExt.GetBehavior(projectile).filters = Il2CppReferenceArrayExt.RemoveItemOfType(ProjectileModelBehaviorExt.GetBehavior(projectile).filters); projectile.collisionPasses = Il2CppStructArray.op_Implicit(new int[2] { -1, 0 }); projectile.filters = ProjectileModelBehaviorExt.GetBehavior(projectile).filters; projectile.radius = 50f; ProjectileModelBehaviorExt.AddBehavior(projectile, val); } } public class Level4 : ModHeroLevel { public override string Description => "All Banana Farms in radius get tier 1 upgrades for free."; public override int Level => 4; public override void ApplyUpgrade(TowerModel towerModel) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown TowerFilterModel[] array = (TowerFilterModel[])(object)new FilterInBaseTowerIdModel[1] { new FilterInBaseTowerIdModel("", Il2CppStringArray.op_Implicit(new string[1] { TowerType.BananaFarm })) }; TowerModelBehaviorExt.AddBehavior(towerModel, new FreeUpgradeSupportModel("", 1, "IndustrialFarmer:FreeUpgrades", Il2CppReferenceArray.op_Implicit(array))); } } public class Level5 : ModHeroLevel { public override string Description => "Banana Farms can be placed on nearby water."; public override int Level => 5; public override void ApplyUpgrade(TowerModel towerModel) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown TowerModelBehaviorExt.AddBehavior(towerModel, new FreezeNearbyWaterModel("", towerModel.range, 1f, new PrefabReference(""), 0)); } } public class Level6 : ModHeroLevel { public override string Description => "All Banana Farms in radius get tier 2 upgrades for free."; public override int Level => 6; public override void ApplyUpgrade(TowerModel towerModel) { TowerModelBehaviorExt.GetBehavior(towerModel).upgrade = 2; } } public class Level7 : ModHeroLevel { public override string Description => "Range is increased."; public override int Level => 7; public override void ApplyUpgrade(TowerModel towerModel) { towerModel.range += 15f; CollectCashZoneModel behavior = TowerModelBehaviorExt.GetBehavior(towerModel); behavior.attractRange += 15f; } } public class Level8 : ModHeroLevel { public override string Description => "Banana Farms in radius and their upgrades cost 10% less."; public override int Level => 8; public override void ApplyUpgrade(TowerModel towerModel) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown TowerModelBehaviorExt.AddBehavior(towerModel, new DiscountZoneModel("", 0.1f, 1, "IndustrialFarmerDiscount", false, 6, 0, "", "", TowerType.BananaFarm, "", false, false, false)); } } public class Level9 : ModHeroLevel { public override string Description => "Collected Bananas are now worth 15% more."; public override int Level => 9; public override void ApplyUpgrade(TowerModel towerModel) { ((Model)TowerModelBehaviorExt.GetBehavior(towerModel)).name = "CollectCashZoneModel_" + ((ModContent)this).Id; } } public class Level10 : ModHeroLevel { public override string AbilityName => "Green Revolution"; public override string AbilityDescription => "Transforms some of the Largest Bloons on screen into Green Bloons. Targets up to BFBs."; public override string Description => ((ModHeroLevel)this).AbilityName + ": " + ((ModHeroLevel)this).AbilityDescription; public override int Level => 10; public override void ApplyUpgrade(TowerModel towerModel) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected O, but got Unknown //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected O, but got Unknown //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Expected O, but got Unknown //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected O, but got Unknown //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Expected O, but got Unknown //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Expected O, but got Unknown //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Expected O, but got Unknown //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Expected O, but got Unknown TowerModel tower = Game.instance.model.GetTower(TowerType.Alchemist, 0, 0, 5); TowerModel tower2 = Game.instance.model.GetTower(TowerType.SuperMonkey, 0, 4, 0); AttackModel val = ModelExt.Duplicate(TowerModelExt.GetAttackModel(tower, 2)); List list = Il2CppReferenceArrayExt.ToList(AttackModelBehaviorExt.GetBehavior(val).filters); list.Add((FilterModel)new FilterOutTagModel("1", "Red", new Il2CppStringArray(0L))); list.Add((FilterModel)new FilterOutTagModel("2", "Blue", new Il2CppStringArray(0L))); list.Add((FilterModel)new FilterOutTagModel("3", "Green", new Il2CppStringArray(0L))); list.Add((FilterModel)new FilterOutTagModel("4", "Ddt", new Il2CppStringArray(0L))); list.Add((FilterModel)new FilterOutTagModel("5", "Zomg", new Il2CppStringArray(0L))); ProjectileModel projectile = ((Model)val).GetDescendant().projectile; projectile.radius = 50f; ProjectileModelBehaviorExt.GetBehavior(projectile).bloonId = "Green"; Il2CppGenericIEnumerable.ForEach(((Model)projectile).GetDescendants(), (Action)delegate(FilterInvisibleModel model) { model.isActive = false; }); projectile.pierce += 100f; AbilityModel val2 = ModelExt.Duplicate(TowerModelExt.GetAbility(towerModel)); ((Model)val2).name = "AbilityModel_GreenRevolution"; val2.displayName = ((ModHeroLevel)this).AbilityName; val2.addedViaUpgrade = ((ModContent)this).Id; ((Model)val2).GetDescendant().filters = ListExt.ToIl2CppReferenceArray(list); ((Model)val2).GetDescendant().projectile = projectile; ((Model)val2).GetDescendant().effectModel = ((Model)tower2).GetDescendant().effectModel; ((Model)((Model)val2).GetDescendant()).AddChildDependant(projectile); AbilityModelBehaviorExt.RemoveBehavior(val2); val2.Cooldown = 60f; val2.icon = ((ModContent)this).GetSpriteReference("GreenRevolution"); TowerModelBehaviorExt.AddBehavior(towerModel, val2); } } public class Level11 : ModHeroLevel { public override string Description => "Bloon Pesticide's damage over time is significantly increased"; public override int Level => 11; public override void ApplyUpgrade(TowerModel towerModel) { DamageOverTimeModel descendant = ((Model)TowerModelExt.GetAbility(towerModel, 0)).GetDescendant(); descendant.Interval = 0.1f; } } public class Level12 : ModHeroLevel { public override string Description => "Further increased range"; public override int Level => 12; public override void ApplyUpgrade(TowerModel towerModel) { towerModel.range += 15f; CollectCashZoneModel behavior = TowerModelBehaviorExt.GetBehavior(towerModel); behavior.attractRange += 15f; } } public class Level13 : ModHeroLevel { public override string Description => "Collected Bananas Crates are now worth 20% more."; public override int Level => 13; public override void ApplyUpgrade(TowerModel towerModel) { ((Model)TowerModelBehaviorExt.GetBehavior(towerModel)).name = "CollectCashZoneModel_" + ((ModContent)this).Id; } } public class Level14 : ModHeroLevel { public override string Description => "Bloon Pesticide makes Bloons take additional damage from attacks."; public override int Level => 14; public override void ApplyUpgrade(TowerModel towerModel) { TowerModel tower = Game.instance.model.GetTower(TowerType.IceMonkey, 5, 0, 0); AddBonusDamagePerHitToBloonModel val = ModelExt.Duplicate(((Model)tower).GetDescendant()); ProjectileModel projectile = ((Model)TowerModelExt.GetAbility(towerModel, 0)).GetDescendant().projectile; AddBehaviorToBloonModel behavior = ProjectileModelBehaviorExt.GetBehavior(projectile); val.mutationId = "PesticideDamageBonus"; val.layers = behavior.layers; val.lifespan = behavior.lifespan; val.lifespanFrames = behavior.lifespanFrames; ProjectileModelBehaviorExt.AddBehavior(projectile, val); } } public class Level15 : ModHeroLevel { public override string Description => "Banana Farms in radius and their upgrades now cost 20% less."; public override int Level => 15; public override void ApplyUpgrade(TowerModel towerModel) { TowerModelBehaviorExt.GetBehavior(towerModel).discountMultiplier = 0.2f; } } public class Level16 : ModHeroLevel { public override string Description => "Green Revolution can hit more Bloons, including ZOMGs and DDTs."; public override int Level => 16; public override void ApplyUpgrade(TowerModel towerModel) { ProjectileModel projectile = ((Model)TowerModelExt.GetAbility(towerModel, 1)).GetDescendant().projectile; projectile.pierce += 100f; AttackFilterModel descendant = ((Model)TowerModelExt.GetAbility(towerModel, 1)).GetDescendant(); List list = Il2CppReferenceArrayExt.ToList(descendant.filters); FilterOutTagModel val = default(FilterOutTagModel); list.RemoveAll((FilterModel model) => Il2CppSystemObjectExt.IsType((Object)(object)model, ref val) && val.tag == "Ddt"); list.RemoveAll((FilterModel model) => Il2CppSystemObjectExt.IsType((Object)(object)model, ref val) && val.tag == "Zomg"); descendant.filters = ListExt.ToIl2CppReferenceArray(list); } } public class Level17 : ModHeroLevel { public override string Description => "Bloon Pesticide's damage over time is massively increased."; public override int Level => 17; public override void ApplyUpgrade(TowerModel towerModel) { DamageOverTimeModel descendant = ((Model)TowerModelExt.GetAbility(towerModel, 0)).GetDescendant(); descendant.damage = 5f; } } public class Level18 : ModHeroLevel { public override string Description => "Further increased range"; public override int Level => 18; public override void ApplyUpgrade(TowerModel towerModel) { towerModel.range += 15f; CollectCashZoneModel behavior = TowerModelBehaviorExt.GetBehavior(towerModel); behavior.attractRange += 15f; } } public class Level19 : ModHeroLevel { public override string Description => "Collected Bananas Crates are now worth 25% more."; public override int Level => 19; public override void ApplyUpgrade(TowerModel towerModel) { ((Model)TowerModelBehaviorExt.GetBehavior(towerModel)).name = "CollectCashZoneModel_" + ((ModContent)this).Id; } } public class Level20 : ModHeroLevel { public override string Description => "Green Revolution affects even more Bloons and has reduced cooldown."; public override int Level => 20; public override void ApplyUpgrade(TowerModel towerModel) { AbilityModel ability = TowerModelExt.GetAbility(towerModel, 1); ability.Cooldown = 45f; ProjectileModel projectile = ((Model)ability).GetDescendant().projectile; projectile.pierce += 700f; } } } public static class ModHelperData { public const string WorksOnVersion = "50.0"; public const string Version = "1.0.15"; public const string Name = "Industrial Farmer"; public const string Description = "A custom hero who collects your bananas and helps you expand your farming operations."; public const string RepoOwner = "doombubbles"; public const string RepoName = "IndustrialFarmer"; public const string Icon = "IndustrialFarmer-Icon.png"; } } namespace IndustrialFarmer.Patches { public class BloonMorphing { [HarmonyPatch(typeof(MorphBloon), "Collide")] internal class MorphBloon_Collide { [HarmonyPrefix] internal static void Prefix(MorphBloon __instance) { bloonId = __instance.morphBloonModel.bloonId; } [HarmonyPostfix] internal static void Postfix(MorphBloon __instance) { bloonId = null; } } [HarmonyPatch(typeof(BloonDegradeStepper), "GetTotalBloonHealth")] internal static class BloonDegradeStepper_GetTotalBloonHealth { [HarmonyPostfix] private static void Postfix(ref int __result) { if (bloonId == "Green") { __result -= 2; } } } [HarmonyPatch(typeof(CosmeticHelper), "GetBloonModel")] internal class CosmeticHelper_GetBloonModel { [HarmonyPrefix] internal static void Postfix(int emissionIndex, ref string id) { if (bloonId != null) { id = bloonId; } } } private static string? bloonId; } public class CashCollection { [HarmonyPatch(typeof(CollectCashZone), "Process")] internal class CollectCashZone_Process { [HarmonyPrefix] internal static void Prefix(CollectCashZone __instance) { string name = ((Model)__instance.collectCashZoneModel).name; if (name.Contains(ModContent.UpgradeID())) { bananaBonus = 0.1f; crateBonus = 0.1f; } else if (name.Contains(ModContent.UpgradeID())) { bananaBonus = 0.15f; crateBonus = 0.15f; } else if (name.Contains(ModContent.UpgradeID())) { bananaBonus = 0.15f; crateBonus = 0.2f; } else if (name.Contains(ModContent.UpgradeID())) { bananaBonus = 0.15f; crateBonus = 0.25f; } else { bananaBonus = 0f; crateBonus = 0f; } } [HarmonyPostfix] internal static void Postfix(CollectCashZone __instance) { bananaBonus = 0f; crateBonus = 0f; } } [HarmonyPatch(typeof(Cash), "Pickup")] internal class Cash_Pickup { [HarmonyPrefix] internal static void Prefix(Cash __instance) { CashModel val = ModelExt.Duplicate(__instance.cashModel); if (CrateGUIDs.Contains(((CommonBehaviorProxy)(object)((ProjectileBehavior)__instance).projectile).Display.displayModel.display.guidRef)) { val.bonusMultiplier += crateBonus; } else { val.bonusMultiplier += bananaBonus; } ((RootBehavior)__instance).UpdatedModel((Model)(object)val); } } private static readonly string[] CrateGUIDs = new string[2] { "88442e0b3684e3446aaa70a036da69c9", "0d60d713eef3d3043915b89b35b04670" }; private static float bananaBonus; private static float crateBonus; } public static class Discounts { [HarmonyPatch(typeof(TowerToSimulation), "GetUpgradeCost")] internal class TowerToSimulation_GetUpgradeCost { [HarmonyPrefix] internal static void Prefix(TowerToSimulation? __instance) { discountingTower = ((__instance != null) ? __instance.Def : null); } } [HarmonyPatch(typeof(TowerInventory), "GetTowerCost")] internal class TowerManager_GetTowerCost { [HarmonyPrefix] internal static void Prefix(TowerModel tower) { discountingTower = tower; } } [HarmonyPatch(typeof(TowerManager), "GetZoneDiscount")] internal class TowerManager_GetZoneDiscount { [HarmonyPostfix] internal static void Postfix(ref Dictionary> __result) { if (__result != null && discountingTower != null && ((EntityModel)discountingTower).baseId != TowerType.BananaFarm && __result.ContainsKey("IndustrialFarmerDiscount")) { __result["IndustrialFarmerDiscount"].Clear(); } discountingTower = null; } } [HarmonyPatch(typeof(Tower), "AddDiscountZoneBuffs")] internal class Tower_AddDiscountZoneBuffs { [HarmonyPostfix] internal static void Postfix(Tower __instance, ref IEnumerable __result) { if (__result == null || ((EntityModel)__instance.towerModel).baseId == TowerType.BananaFarm) { return; } foreach (BuffQuery item in ((IEnumerable)Enumerable.ToArray(__result)).Where((BuffQuery buffQuery) => buffQuery != null && ((Model)buffQuery.buffIndicator).name.Contains("IndustrialFarmer"))) { item.canCurrentlyBuff = false; } } } private static TowerModel? discountingTower; } public class TowerCreation { [HarmonyPatch(typeof(CreateTowerAtAction), "Run")] internal static class UnityToSimulation_CreateTowerAt { [HarmonyPostfix] private static void Postfix(CreateTowerAtAction __instance, UnityToSimulation uts) { if (__instance.towerModelName.StartsWith(((ModContent)ModContent.GetInstance()).Id)) { uts.Simulation.GetTowerInventory((int)((GameplayAction)__instance).initiatingPlayerNumber).AddFreeTowers(TowerType.BananaFarm, 1, "", 0, InGame.Bridge.Simulation); } } } } public class WaterFreezing { [HarmonyPatch(typeof(Map), "ZoneAllowsPlacement")] internal class Map_ZoneAllowsPlacement { [HarmonyPrefix] internal static void Prefix(IPlaceableEntity pe) { TowerModel currentTowerModel = default(TowerModel); if (Il2CppSystemObjectExt.Is((Il2CppObjectBase)(object)pe, ref currentTowerModel)) { WaterFreezing.currentTowerModel = currentTowerModel; } } [HarmonyPostfix] internal static void Postfix() { currentTowerModel = null; } } [HarmonyPatch(typeof(FreezeNearbyWater), "IsInZone")] internal class FreezeNearbyWater_IsInZone { [HarmonyPostfix] internal static void Postfix(FreezeNearbyWater __instance, ref bool __result) { TowerModel towerModel = ((TowerBehavior)__instance).tower.towerModel; if (((towerModel != null) ? TowerModelExt.GetModTower(towerModel) : null) is IndustrialFarmer && currentTowerModel != null && ((EntityModel)currentTowerModel).baseId != TowerType.BananaFarm) { __result = false; } } } private static TowerModel? currentTowerModel; } } namespace IndustrialFarmer.Displays { public abstract class IndustrialFarmerDisplay : ModTowerDisplay { public override float Scale => 1.05f; public override void ModifyDisplayNode(UnityDisplayNode node) { UnityDisplayNodeExt.RemoveBone(node, "MonkeyRig:Propjectile_R", false); } public unsafe override void ModifyDisplayNodeAsync(UnityDisplayNode node, Action onComplete) { ((ModDisplay)this).UseNode(((ModDisplay)this).GetDisplay(TowerType.BananaFarmer, 0, 0, 0), (Action)delegate(UnityDisplayNode bananaFarmer) { GameObject gameObject = ((Component)UnityDisplayNodeExt.GetRenderers(bananaFarmer, true)[1]).gameObject; GameObject val = Object.Instantiate(gameObject, ((Component)node).transform.GetChild(0)); SkinnedMeshRenderer component = val.GetComponent(); component.rootBone = UnityDisplayNodeExt.GetBone(node, "MonkeyRig:MonkeyJnt_Spine02"); string[] source = new string[5] { "MonkeyRig:MonkeyJnt_Hand_R", "MonkeyRig:MonkeyJnt_Hand_R", "MonkeyRig:MonkeyJnt_Hand_R", "MonkeyRig:MonkeyJnt_Hand_R", "MonkeyRig:MonkeyJnt_Hand_R" }; component.bones = IEnumerableExt.ToIl2CppReferenceArray(source.Select(new Func(node, (nint)(delegate*)(&UnityDisplayNodeExt.GetBone)))); node.genericRenderers = Il2CppReferenceArrayExt.AddTo(node.genericRenderers, (Renderer)(object)component); PostAddPitchfork(node, gameObject); node.RecalculateGenericRenderers(); onComplete(); }); } protected virtual void PostAddPitchfork(UnityDisplayNode node, GameObject pitchfork) { node.genericRendererLayers = new Il2CppStructArray(4L); } } public class IndustrialFarmerDisplay1 : IndustrialFarmerDisplay { public override string BaseDisplay => ((ModDisplay)this).GetDisplay(TowerType.EngineerMonkey, 0, 0, 0); public override bool UseForTower(params int[] tiers) { return tiers[0] < 3; } } public class IndustrialFarmerDisplay2 : IndustrialFarmerDisplay { public override string BaseDisplay => ((ModDisplay)this).GetDisplay(TowerType.EngineerMonkey, 0, 1, 0); public override bool UseForTower(params int[] tiers) { return 3 <= tiers[0] && tiers[0] < 7; } } public class IndustrialFarmerDisplay3 : IndustrialFarmerDisplay { public override string BaseDisplay => ((ModDisplay)this).GetDisplay(TowerType.EngineerMonkey, 0, 2, 0); public override bool UseForTower(params int[] tiers) { return 7 <= tiers[0] && tiers[0] < 10; } } public class IndustrialFarmerDisplay4 : IndustrialFarmerDisplay { public override string BaseDisplay => ((ModDisplay)this).GetDisplay(TowerType.EngineerMonkey, 3, 0, 0); public override bool UseForTower(params int[] tiers) { return 10 <= tiers[0] && tiers[0] < 20; } public override void ModifyDisplayNode(UnityDisplayNode node) { base.ModifyDisplayNode(node); UnityDisplayNodeExt.RemoveBone(node, "MonkeyRig:Propjectile_L", false); } } public class IndustrialFarmerDisplay5 : IndustrialFarmerDisplay { public override string BaseDisplay => ((ModDisplay)this).GetDisplay(TowerType.EngineerMonkey, 3, 0, 0); public override bool UseForTower(params int[] tiers) { return tiers[0] == 20; } protected unsafe override void PostAddPitchfork(UnityDisplayNode node, GameObject pitchfork) { GameObject val = Object.Instantiate(pitchfork, ((Component)node).transform.GetChild(0)); ((Object)val).name = ((Object)val).name + "2"; SkinnedMeshRenderer component = val.GetComponent(); component.rootBone = UnityDisplayNodeExt.GetBone(node, "MonkeyRig:MonkeyJnt_Spine02"); string[] source = new string[5] { "MonkeyRig:Propjectile_L", "MonkeyRig:Propjectile_L", "MonkeyRig:Propjectile_L", "MonkeyRig:Propjectile_L", "MonkeyRig:Propjectile_L" }; component.bones = IEnumerableExt.ToIl2CppReferenceArray(source.Select(new Func(node, (nint)(delegate*)(&UnityDisplayNodeExt.GetBone)))); node.genericRenderers = Il2CppReferenceArrayExt.AddTo(node.genericRenderers, (Renderer)(object)component); node.genericRendererLayers = new Il2CppStructArray(4L); } } }