Decompiled source of IndustrialFarmer v1.0.15

IndustrialFarmer.dll

Decompiled a week ago
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<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T>
{
	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<T>.Count => _items.Length;

	T IReadOnlyList<T>.this[int index] => _items[index];

	int ICollection<T>.Count => _items.Length;

	bool ICollection<T>.IsReadOnly => true;

	T IList<T>.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<T> IEnumerable<T>.GetEnumerator()
	{
		return ((IEnumerable<T>)_items).GetEnumerator();
	}

	void ICollection<T>.Add(T item)
	{
		throw new NotSupportedException();
	}

	void ICollection<T>.Clear()
	{
		throw new NotSupportedException();
	}

	bool ICollection<T>.Contains(T item)
	{
		return ((ICollection<T>)_items).Contains(item);
	}

	void ICollection<T>.CopyTo(T[] array, int arrayIndex)
	{
		((ICollection<T>)_items).CopyTo(array, arrayIndex);
	}

	bool ICollection<T>.Remove(T item)
	{
		throw new NotSupportedException();
	}

	int IList<T>.IndexOf(T item)
	{
		return ((IList<T>)_items).IndexOf(item);
	}

	void IList<T>.Insert(int index, T item)
	{
		throw new NotSupportedException();
	}

	void IList<T>.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<CreateSoundOnUpgradeModel>(towerModel, ModelExt.Duplicate<CreateSoundOnUpgradeModel>(TowerModelBehaviorExt.GetBehavior<CreateSoundOnUpgradeModel>(towerWithName)));
			TowerModelBehaviorExt.AddBehavior<CreateEffectOnUpgradeModel>(towerModel, ModelExt.Duplicate<CreateEffectOnUpgradeModel>(TowerModelBehaviorExt.GetBehavior<CreateEffectOnUpgradeModel>(towerWithName)));
			((EntityModel)towerModel).radius = ((EntityModel)towerWithName).radius;
			towerModel.footprint = ModelExt.Duplicate<FootprintModel>(towerWithName.footprint);
		}
	}
	public class IndustrialFarmerMod : BloonsTD6Mod
	{
	}
	public class Levels
	{
		public class Level2 : ModHeroLevel<IndustrialFarmer>
		{
			public override string Description => "Collected Bananas are worth 10% more.";

			public override int Level => 2;

			public override void ApplyUpgrade(TowerModel towerModel)
			{
				((Model)TowerModelBehaviorExt.GetBehavior<CollectCashZoneModel>(towerModel)).name = "CollectCashZoneModel_" + ((ModContent)this).Id;
			}
		}

		public class Level3 : ModHeroLevel<IndustrialFarmer>
		{
			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<AddBehaviorToBloonModel>(((Model)towerWithName2).GetDescendant<AddBehaviorToBloonModel>());
				val.mutationId = "Pesticide";
				val.glueLevel = 0;
				val.collideThisFrame = true;
				AbilityModel val2 = ModelExt.Duplicate<AbilityModel>(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<CreateSoundOnAbilityModel>(val2);
				AbilityModelBehaviorExt.AddBehavior<CreateSoundOnAbilityModel>(val2, ((Model)towerWithName3).GetDescendant<CreateSoundOnAbilityModel>());
				val2.Cooldown = 30f;
				TowerModelBehaviorExt.AddBehavior<AbilityModel>(towerModel, val2);
				AttackModel val3 = ((Il2CppArrayBase<AttackModel>)(object)AbilityModelBehaviorExt.GetBehavior<ActivateAttackModel>(val2).attacks)[0];
				val3.targetProvider = (TargetSupplierModel)(object)AttackModelBehaviorExt.GetBehavior<TargetStrongModel>(val3);
				AttackModelBehaviorExt.RemoveBehavior<TargetFirstModel>(val3);
				AttackModelBehaviorExt.RemoveBehavior<TargetCloseModel>(val3);
				AttackModelBehaviorExt.RemoveBehavior<TargetLastModel>(val3);
				PrefabReference assetId = ((Model)Game.instance.model.GetTower(TowerType.GlueGunner, 3, 2, 0)).GetDescendant<CreateEffectOnContactModel>().effectModel.assetId;
				EffectModel effectModel = ((Model)val3).GetDescendant<CreateEffectOnExhaustFractionModel>().effectModel;
				effectModel.assetId = assetId;
				effectModel.scale = 3f;
				ProjectileModel projectile = ((Model)val3).GetDescendant<CreateProjectileOnExhaustFractionModel>().projectile;
				ProjectileModelBehaviorExt.RemoveBehavior<DamageModel>(projectile);
				ProjectileModelBehaviorExt.RemoveBehavior<DamageModifierForTagModel>(projectile);
				ProjectileModelBehaviorExt.GetBehavior<AgeModel>(projectile).Lifespan = 0.1f;
				ProjectileModelBehaviorExt.RemoveBehavior<ClearHitBloonsModel>(projectile);
				ProjectileModelBehaviorExt.GetBehavior<ProjectileFilterModel>(projectile).filters = Il2CppReferenceArrayExt.RemoveItemOfType<FilterModel, FilterWithChanceModel>(ProjectileModelBehaviorExt.GetBehavior<ProjectileFilterModel>(projectile).filters);
				projectile.collisionPasses = Il2CppStructArray<int>.op_Implicit(new int[2] { -1, 0 });
				projectile.filters = ProjectileModelBehaviorExt.GetBehavior<ProjectileFilterModel>(projectile).filters;
				projectile.radius = 50f;
				ProjectileModelBehaviorExt.AddBehavior<AddBehaviorToBloonModel>(projectile, val);
			}
		}

		public class Level4 : ModHeroLevel<IndustrialFarmer>
		{
			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<FreeUpgradeSupportModel>(towerModel, new FreeUpgradeSupportModel("", 1, "IndustrialFarmer:FreeUpgrades", Il2CppReferenceArray<TowerFilterModel>.op_Implicit(array)));
			}
		}

		public class Level5 : ModHeroLevel<IndustrialFarmer>
		{
			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<FreezeNearbyWaterModel>(towerModel, new FreezeNearbyWaterModel("", towerModel.range, 1f, new PrefabReference(""), 0));
			}
		}

		public class Level6 : ModHeroLevel<IndustrialFarmer>
		{
			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<FreeUpgradeSupportModel>(towerModel).upgrade = 2;
			}
		}

		public class Level7 : ModHeroLevel<IndustrialFarmer>
		{
			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<CollectCashZoneModel>(towerModel);
				behavior.attractRange += 15f;
			}
		}

		public class Level8 : ModHeroLevel<IndustrialFarmer>
		{
			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<DiscountZoneModel>(towerModel, new DiscountZoneModel("", 0.1f, 1, "IndustrialFarmerDiscount", false, 6, 0, "", "", TowerType.BananaFarm, "", false, false, false));
			}
		}

		public class Level9 : ModHeroLevel<IndustrialFarmer>
		{
			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<CollectCashZoneModel>(towerModel)).name = "CollectCashZoneModel_" + ((ModContent)this).Id;
			}
		}

		public class Level10 : ModHeroLevel<IndustrialFarmer>
		{
			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<AttackModel>(TowerModelExt.GetAttackModel(tower, 2));
				List<FilterModel> list = Il2CppReferenceArrayExt.ToList<FilterModel>(AttackModelBehaviorExt.GetBehavior<AttackFilterModel>(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<CreateProjectileOnExhaustFractionModel>().projectile;
				projectile.radius = 50f;
				ProjectileModelBehaviorExt.GetBehavior<MorphBloonModel>(projectile).bloonId = "Green";
				Il2CppGenericIEnumerable.ForEach<FilterInvisibleModel>(((Model)projectile).GetDescendants<FilterInvisibleModel>(), (Action<FilterInvisibleModel>)delegate(FilterInvisibleModel model)
				{
					model.isActive = false;
				});
				projectile.pierce += 100f;
				AbilityModel val2 = ModelExt.Duplicate<AbilityModel>(TowerModelExt.GetAbility(towerModel));
				((Model)val2).name = "AbilityModel_GreenRevolution";
				val2.displayName = ((ModHeroLevel)this).AbilityName;
				val2.addedViaUpgrade = ((ModContent)this).Id;
				((Model)val2).GetDescendant<AttackFilterModel>().filters = ListExt.ToIl2CppReferenceArray<FilterModel>(list);
				((Model)val2).GetDescendant<CreateProjectileOnExhaustFractionModel>().projectile = projectile;
				((Model)val2).GetDescendant<CreateEffectOnExhaustFractionModel>().effectModel = ((Model)tower2).GetDescendant<CreateEffectOnAbilityModel>().effectModel;
				((Model)((Model)val2).GetDescendant<CreateProjectileOnExhaustFractionModel>()).AddChildDependant<ProjectileModel>(projectile);
				AbilityModelBehaviorExt.RemoveBehavior<CreateSoundOnAbilityModel>(val2);
				val2.Cooldown = 60f;
				val2.icon = ((ModContent)this).GetSpriteReference("GreenRevolution");
				TowerModelBehaviorExt.AddBehavior<AbilityModel>(towerModel, val2);
			}
		}

		public class Level11 : ModHeroLevel<IndustrialFarmer>
		{
			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<DamageOverTimeModel>();
				descendant.Interval = 0.1f;
			}
		}

		public class Level12 : ModHeroLevel<IndustrialFarmer>
		{
			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<CollectCashZoneModel>(towerModel);
				behavior.attractRange += 15f;
			}
		}

		public class Level13 : ModHeroLevel<IndustrialFarmer>
		{
			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<CollectCashZoneModel>(towerModel)).name = "CollectCashZoneModel_" + ((ModContent)this).Id;
			}
		}

		public class Level14 : ModHeroLevel<IndustrialFarmer>
		{
			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<AddBonusDamagePerHitToBloonModel>(((Model)tower).GetDescendant<AddBonusDamagePerHitToBloonModel>());
				ProjectileModel projectile = ((Model)TowerModelExt.GetAbility(towerModel, 0)).GetDescendant<CreateProjectileOnExhaustFractionModel>().projectile;
				AddBehaviorToBloonModel behavior = ProjectileModelBehaviorExt.GetBehavior<AddBehaviorToBloonModel>(projectile);
				val.mutationId = "PesticideDamageBonus";
				val.layers = behavior.layers;
				val.lifespan = behavior.lifespan;
				val.lifespanFrames = behavior.lifespanFrames;
				ProjectileModelBehaviorExt.AddBehavior<AddBonusDamagePerHitToBloonModel>(projectile, val);
			}
		}

		public class Level15 : ModHeroLevel<IndustrialFarmer>
		{
			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<DiscountZoneModel>(towerModel).discountMultiplier = 0.2f;
			}
		}

		public class Level16 : ModHeroLevel<IndustrialFarmer>
		{
			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<CreateProjectileOnExhaustFractionModel>().projectile;
				projectile.pierce += 100f;
				AttackFilterModel descendant = ((Model)TowerModelExt.GetAbility(towerModel, 1)).GetDescendant<AttackFilterModel>();
				List<FilterModel> list = Il2CppReferenceArrayExt.ToList<FilterModel>(descendant.filters);
				FilterOutTagModel val = default(FilterOutTagModel);
				list.RemoveAll((FilterModel model) => Il2CppSystemObjectExt.IsType<FilterOutTagModel>((Object)(object)model, ref val) && val.tag == "Ddt");
				list.RemoveAll((FilterModel model) => Il2CppSystemObjectExt.IsType<FilterOutTagModel>((Object)(object)model, ref val) && val.tag == "Zomg");
				descendant.filters = ListExt.ToIl2CppReferenceArray<FilterModel>(list);
			}
		}

		public class Level17 : ModHeroLevel<IndustrialFarmer>
		{
			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<DamageOverTimeModel>();
				descendant.damage = 5f;
			}
		}

		public class Level18 : ModHeroLevel<IndustrialFarmer>
		{
			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<CollectCashZoneModel>(towerModel);
				behavior.attractRange += 15f;
			}
		}

		public class Level19 : ModHeroLevel<IndustrialFarmer>
		{
			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<CollectCashZoneModel>(towerModel)).name = "CollectCashZoneModel_" + ((ModContent)this).Id;
			}
		}

		public class Level20 : ModHeroLevel<IndustrialFarmer>
		{
			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<CreateProjectileOnExhaustFractionModel>().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<Levels.Level2>()))
				{
					bananaBonus = 0.1f;
					crateBonus = 0.1f;
				}
				else if (name.Contains(ModContent.UpgradeID<Levels.Level9>()))
				{
					bananaBonus = 0.15f;
					crateBonus = 0.15f;
				}
				else if (name.Contains(ModContent.UpgradeID<Levels.Level13>()))
				{
					bananaBonus = 0.15f;
					crateBonus = 0.2f;
				}
				else if (name.Contains(ModContent.UpgradeID<Levels.Level19>()))
				{
					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<CashModel>(__instance.cashModel);
				if (CrateGUIDs.Contains(((CommonBehaviorProxy<IProjectileBehavior>)(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<string, List<DiscountZone>> __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<BuffQuery> __result)
			{
				if (__result == null || ((EntityModel)__instance.towerModel).baseId == TowerType.BananaFarm)
				{
					return;
				}
				foreach (BuffQuery item in ((IEnumerable<BuffQuery>)Enumerable.ToArray<BuffQuery>(__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<IndustrialFarmer>()).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<TowerModel>((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<IndustrialFarmer>
	{
		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<UnityDisplayNode>)delegate(UnityDisplayNode bananaFarmer)
			{
				GameObject gameObject = ((Component)UnityDisplayNodeExt.GetRenderers<SkinnedMeshRenderer>(bananaFarmer, true)[1]).gameObject;
				GameObject val = Object.Instantiate<GameObject>(gameObject, ((Component)node).transform.GetChild(0));
				SkinnedMeshRenderer component = val.GetComponent<SkinnedMeshRenderer>();
				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<Transform>(source.Select(new Func<string, Transform>(node, (nint)(delegate*<UnityDisplayNode, string, Transform>)(&UnityDisplayNodeExt.GetBone))));
				node.genericRenderers = Il2CppReferenceArrayExt.AddTo<Renderer>(node.genericRenderers, (Renderer)(object)component);
				PostAddPitchfork(node, gameObject);
				node.RecalculateGenericRenderers();
				onComplete();
			});
		}

		protected virtual void PostAddPitchfork(UnityDisplayNode node, GameObject pitchfork)
		{
			node.genericRendererLayers = new Il2CppStructArray<int>(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<GameObject>(pitchfork, ((Component)node).transform.GetChild(0));
			((Object)val).name = ((Object)val).name + "2";
			SkinnedMeshRenderer component = val.GetComponent<SkinnedMeshRenderer>();
			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<Transform>(source.Select(new Func<string, Transform>(node, (nint)(delegate*<UnityDisplayNode, string, Transform>)(&UnityDisplayNodeExt.GetBone))));
			node.genericRenderers = Il2CppReferenceArrayExt.AddTo<Renderer>(node.genericRenderers, (Renderer)(object)component);
			node.genericRendererLayers = new Il2CppStructArray<int>(4L);
		}
	}
}