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 System.Text.RegularExpressions; using AbilityChoice; using AbilityChoice.AbilityChoices.Hero.Adora; using AbilityChoice.AbilityChoices.Magic.WizardMonkey; using AbilityChoice.AbilityChoices.Primary.IceMonkey; using AbilityChoice.Descriptions; using AbilityChoice.Displays; using AbilityChoice.Patches; using BTD_Mod_Helper; using BTD_Mod_Helper.Api; using BTD_Mod_Helper.Api.Components; using BTD_Mod_Helper.Api.Data; using BTD_Mod_Helper.Api.Display; using BTD_Mod_Helper.Api.ModOptions; using BTD_Mod_Helper.Api.Testing; using BTD_Mod_Helper.Api.Towers; using BTD_Mod_Helper.Extensions; using HarmonyLib; using Il2Cpp; using Il2CppAssets.Scripts; using Il2CppAssets.Scripts.Data; using Il2CppAssets.Scripts.Data.Legends; using Il2CppAssets.Scripts.Models; using Il2CppAssets.Scripts.Models.Artifacts; using Il2CppAssets.Scripts.Models.Artifacts.Behaviors; using Il2CppAssets.Scripts.Models.Audio; using Il2CppAssets.Scripts.Models.Bloons; using Il2CppAssets.Scripts.Models.Bloons.Behaviors; using Il2CppAssets.Scripts.Models.CorvusSpells; using Il2CppAssets.Scripts.Models.CorvusSpells.Continuous; using Il2CppAssets.Scripts.Models.CorvusSpells.Instant; using Il2CppAssets.Scripts.Models.Effects; using Il2CppAssets.Scripts.Models.Entities; using Il2CppAssets.Scripts.Models.GenericBehaviors; using Il2CppAssets.Scripts.Models.GeraldoItems; using Il2CppAssets.Scripts.Models.Map; 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.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.Behaviors.Emissions; 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.Models.Towers.Upgrades; using Il2CppAssets.Scripts.Models.Towers.Weapons; using Il2CppAssets.Scripts.Models.Towers.Weapons.Behaviors; using Il2CppAssets.Scripts.Simulation; using Il2CppAssets.Scripts.Simulation.Bloons; using Il2CppAssets.Scripts.Simulation.Corvus.Spells; using Il2CppAssets.Scripts.Simulation.Corvus.Spells.Continuous; using Il2CppAssets.Scripts.Simulation.Corvus.Spells.Instant; using Il2CppAssets.Scripts.Simulation.Corvus.TowerManager; using Il2CppAssets.Scripts.Simulation.GeraldoItems; using Il2CppAssets.Scripts.Simulation.Objects; using Il2CppAssets.Scripts.Simulation.SMath; using Il2CppAssets.Scripts.Simulation.SimulationBehaviors; using Il2CppAssets.Scripts.Simulation.Towers; using Il2CppAssets.Scripts.Simulation.Towers.Behaviors; using Il2CppAssets.Scripts.Simulation.Towers.Behaviors.Abilities; using Il2CppAssets.Scripts.Simulation.Towers.Behaviors.Abilities.Behaviors; using Il2CppAssets.Scripts.Simulation.Towers.Behaviors.Attack; using Il2CppAssets.Scripts.Simulation.Towers.Behaviors.Attack.Behaviors; using Il2CppAssets.Scripts.Simulation.Towers.Projectiles; using Il2CppAssets.Scripts.Simulation.Track; using Il2CppAssets.Scripts.Unity; using Il2CppAssets.Scripts.Unity.Bridge; using Il2CppAssets.Scripts.Unity.Display; using Il2CppAssets.Scripts.Unity.Menu; using Il2CppAssets.Scripts.Unity.UI_New.HeroInGame; using Il2CppAssets.Scripts.Unity.UI_New.InGame; using Il2CppAssets.Scripts.Unity.UI_New.InGame.TowerSelectionMenu; using Il2CppAssets.Scripts.Unity.UI_New.InGame.TowerSelectionMenu.TowerSelectionMenuThemes; using Il2CppAssets.Scripts.Unity.UI_New.Legends; using Il2CppAssets.Scripts.Unity.UI_New.Main.HeroSelect; using Il2CppAssets.Scripts.Unity.UI_New.Popups; using Il2CppAssets.Scripts.Unity.UI_New.Upgrade; using Il2CppAssets.Scripts.Utils; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppNinjaKiwi.Common; using Il2CppNinjaKiwi.Common.ResourceUtils; using Il2CppNinjaKiwi.Localization; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using Il2CppSystem.IO; using Il2CppSystem.Linq; using Il2CppSystem.Reflection; using Il2CppTMPro; using MelonLoader; using MelonLoader.Preferences; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; 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(AbilityChoiceMod), "Ability Choice", "4.4.6", "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("AbilityChoice")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+6af2178126a26e4e9bdf233b0f27ec8180dddd5f")] [assembly: AssemblyProduct("AbilityChoice")] [assembly: AssemblyTitle("AbilityChoice")] [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 AbilityChoice { public abstract class AbilityChoice : NamedModContent { internal static int? overrideMode; protected MelonPreferences_Entry setting; protected readonly HashSet affectedIds = new HashSet(); protected readonly List affectedOrder = new List(); public virtual string AbilityName => Regex.Replace(((ModContent)this).Name, "(? null; public override string DisplayName => "[" + AbilityName + " Ability]"; public bool Enabled { get { int mode = Mode; if ((uint)(mode - 1) <= 1u) { return true; } return false; } } protected bool Mode2 => Mode == 2; public int Mode { get { return Math.Clamp(overrideMode ?? setting?.Value ?? 0, 0, (!HasMode2) ? 1 : 2); } set { setting.Value = value; if (setting.Value == 2 && !HasMode2) { setting.Value = 1; } } } protected abstract bool HasMode2 { get; } protected override float RegistrationPriority => 25f; public virtual SpriteReference Icon => null; public override void Register() { setting = AbilityChoiceMod.AbilityChoiceSettings.CreateEntry(((ModContent)this).Id, 1, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); } internal void CacheAffectedIds() { affectedIds.Clear(); affectedOrder.Clear(); foreach (string item in from model in GetAffected(Game.instance.model) select ((Model)model).name) { if (affectedIds.Add(item)) { affectedOrder.Add(item); } } } public void Toggle() { MelonPreferences_Entry obj = setting; int value = obj.Value; obj.Value = value + 1; if (setting.Value > 2 || (setting.Value > 1 && !HasMode2)) { setting.Value = 0; } } public virtual void Apply1(TowerModel model) { } public virtual void Apply2(TowerModel model) { } protected virtual void ApplyBoth(TowerModel model) { } public void Apply(TowerModel towerModel) { if (Mode2) { Apply2(towerModel); } else { Apply1(towerModel); } ApplyBoth(towerModel); RemoveAbility(towerModel); } protected virtual AbilityModel AbilityModel(TowerModel model) { return ((IEnumerable)TowerModelBehaviorExt.GetBehaviors(model)).FirstOrDefault((Func)((AbilityModel abilityModel) => abilityModel.displayName == AbilityName || abilityModel.displayName == BackUpAbilityName)); } protected virtual void RemoveAbility(TowerModel model) { AbilityModel val = AbilityModel(model); if (val != null) { TowerModelBehaviorExt.RemoveBehavior(model, val); } } public virtual bool AppliesTo(TowerModel towerModel) { return AbilityModel(towerModel) != null; } public virtual void Apply(GameModel gameModel) { foreach (TowerModel item in GetAffectedCached(gameModel)) { Apply(item); } } public IEnumerable GetAffectedCached(GameModel gameModel) { Dictionary towers = ((IEnumerable)gameModel.towers).Where((TowerModel model) => affectedIds.Contains(((Model)model).name)).DistinctBy((TowerModel model) => ((Model)model).name).ToDictionary((TowerModel model) => ((Model)model).name); return affectedOrder.Select((string s) => towers[s]).Where(AppliesTo); } public abstract IEnumerable GetAffected(GameModel gameModel); public static float CalcAvgBonus(float uptime, float dpsMult) { return uptime * dpsMult + (1f - uptime); } internal void TechBotify(TowerModel model, AbilityModel ability = null) { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected O, but got Unknown //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Expected O, but got Unknown if (ability == null) { ability = AbilityModel(model); } ability.isHidden = true; string name = "TechBotify_" + ability.displayName.Replace(" ", ""); if (IEnumerableExt.OfIl2CppType((IEnumerable)((EntityModel)model).behaviors).All(delegate(ActivateAbilityAfterIntervalModel m) { AbilityModel abilityModel = m.abilityModel; return ((abilityModel != null) ? abilityModel.displayName : null) != ability.displayName; })) { Args val = new Args(); ((ModelArgs)val).name = name; val.abilityModel = ability; val.interval = ability.Cooldown; TowerModelBehaviorExt.AddBehavior(model, CreateActivateAbilityAfterIntervalModelExt.Create(val)); } } } public class AbilityChoiceMod : BloonsTD6Mod { [HarmonyPatch(typeof(CosmeticHelper), "ApplyCosmeticsToGameModel")] internal static class CosmeticHelper_ApplyCosmeticsToGameModel { [HarmonyPostfix] internal static void Postfix() { GameModel rootGameModel = CosmeticHelper.rootGameModel; if (UseLateOnNewGameModel) { ApplyAbilityChoices(rootGameModel); } } } private static readonly ModSettingBool ApplyAfterChallengeRules = new ModSettingBool(true) { icon = "MainMenuUiAtlas[ChallengeRulesBtn]", description = "Makes Ability Choices calculate and apply their tower modification AFTER Challenge Rules change the cooldowns of towers rather than before" }; private static readonly ModSettingButton SetAllToOff = new ModSettingButton { action = delegate { ModContent.GetContent().ForEach(delegate(TowerAbilityChoice choice) { choice.Mode = 0; }); }, icon = TowerAbilityChoice.IconForMode(0), description = "Sets all abilities back to their default vanilla affects.", buttonSprite = "Ui[YellowBtnLong]", buttonText = "Set All" }; private static readonly ModSettingButton SetAllToMode1 = new ModSettingButton { action = delegate { ModContent.GetContent().ForEach(delegate(TowerAbilityChoice choice) { choice.Mode = 1; }); }, icon = TowerAbilityChoice.IconForMode(1), description = "For most towers, this is a permanent but weaker version of the ability.", buttonSprite = "Ui[RedBtnLong]", buttonText = "Set All" }; private static readonly ModSettingButton SetAllToMode2 = new ModSettingButton { action = delegate { ModContent.GetContent().ForEach(delegate(TowerAbilityChoice choice) { choice.Mode = 2; }); }, icon = TowerAbilityChoice.IconForMode(2), description = "For the towers that have it, a different alternate affect to the ability. Towers that don'thave a second mode will be set to Mode 1.", buttonSprite = "Ui[BlueBtnLong]", buttonText = "Set All" }; public static readonly ModSettingBool MoreBalanced = new ModSettingBool(true) { description = "Nerfs a few effects that were unbalanced in their initial implementation" }; public static readonly ModSettingInt MagusPerfectusSwitchThreshold; public override bool UsesArtifactDependants => true; public static MelonPreferences_Category AbilityChoiceSettings { get; private set; } private static bool UseLateOnNewGameModel => ModSettingBool.op_Implicit(ApplyAfterChallengeRules) && !InGameData.CurrentGame.IsLegend(); public override void OnMainMenu() { AbilityChoiceSettings.SaveToFile(false); } public override void OnTitleScreen() { foreach (AbilityChoice item in ModContent.GetContent()) { item.CacheAffectedIds(); } } public override void OnUpdate() { //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Expected O, but got Unknown if (UnityToSimulationExt.Current != null && ModContent.GetInstance().Mode == 1 && Il2CppGenericIEnumerable.Any(UnityToSimulationExt.Current.GetAllTowers(), (Func)((TowerToSimulation tower) => ((tower != null) ? tower.Def : null) != null && ((EntityModel)tower.Def).baseId == TowerType.IceMonkey && tower.Def.isParagon)) && UnityToSimulationExt.Current.GetBossBloon() != null && UnityToSimulationExt.Current.GetCurrentBossSkull() == 0) { SimulationExt.Current.blockNextBossSkull = true; } if (!Input.GetMouseButtonUp(1)) { return; } List val = new List(); PointerEventData val2 = new PointerEventData(EventSystem.current) { position = Vector2.op_Implicit(Input.mousePosition) }; EventSystem.current.RaycastAll(val2, val); Enumerator enumerator = val.GetEnumerator(); TowerAbilityChoiceInfo towerAbilityChoiceInfo = default(TowerAbilityChoiceInfo); HeroAbilityChoiceInfo heroAbilityChoiceInfo = default(HeroAbilityChoiceInfo); while (enumerator.MoveNext()) { RaycastResult current = enumerator.Current; if (GameObjectExt.HasComponent(current.gameObject, ref towerAbilityChoiceInfo)) { towerAbilityChoiceInfo.abilityChoice.Toggle(); towerAbilityChoiceInfo.UpdateIcon(); towerAbilityChoiceInfo.upgradeDetails.OnPointerExit(val2); towerAbilityChoiceInfo.upgradeDetails.OnPointerEnter(val2); } else { if (!GameObjectExt.HasComponent(current.gameObject, ref heroAbilityChoiceInfo)) { continue; } heroAbilityChoiceInfo.abilityChoice.Toggle(); heroAbilityChoiceInfo.UpdateIcon(); heroAbilityChoiceInfo.UpdateDescriptions(); } if ((Object)(object)InGame.instance != (Object)null && !PopupScreen.instance.IsPopupActive()) { PopupScreen.instance.ShowOkPopup("In order for this to take effect, you'll need to exit to the main menu and come back to the game.", (ReturnCallback)null); } else { AudioClipExtensions.Play(MenuManager.instance.buttonClickSound, "ClickSounds", 1f); } } } public override void OnApplicationStart() { AbilityChoiceSettings = MelonPreferences.CreateCategory("AbilityChoiceSettings"); } public static void ApplyAbilityChoices(GameModel gameModel) { GetRelevantArtifactEffects(out var boosts, out var towerSetChanges, out var abilityStackings); ReadonlyInGameData currentGame = InGameData.CurrentGame; if (((currentGame != null) ? currentGame.rogueData : null) != null) { RogueLegendsManager instance = RogueLegendsManager.instance; if (((instance != null) ? instance.RogueSaveData : null) != null) { ProcessBoosts(gameModel, boosts, towerSetChanges, abilityStackings, unapply: false); } } foreach (AbilityChoice item in from choice in ModContent.GetContent() where choice.Enabled select choice) { try { item.Apply(gameModel); } catch (Exception ex) { ModHelper.Error((object)ex); } } ReadonlyInGameData currentGame2 = InGameData.CurrentGame; if (((currentGame2 != null) ? currentGame2.rogueData : null) != null) { RogueLegendsManager instance2 = RogueLegendsManager.instance; if (((instance2 != null) ? instance2.RogueSaveData : null) != null) { ProcessBoosts(gameModel, boosts, towerSetChanges, abilityStackings, unapply: true); } } } public override void OnNewGameModel(GameModel gameModel) { if (!UseLateOnNewGameModel) { ApplyAbilityChoices(gameModel); } } private static void GetRelevantArtifactEffects(out List boosts, out List towerSetChanges, out List abilityStackings) { boosts = new List(); towerSetChanges = new List(); abilityStackings = new List(); ReadonlyInGameData currentGame = InGameData.CurrentGame; if (((currentGame != null) ? currentGame.rogueData : null) == null) { return; } RogueLegendsManager instance = RogueLegendsManager.instance; if (((instance != null) ? instance.RogueSaveData : null) == null) { return; } Enumerator enumerator = RogueLegendsManager.instance.RogueSaveData.artifactsInventory.GetEnumerator(); BoostArtifactModel item = default(BoostArtifactModel); while (enumerator.MoveNext()) { ArtifactLoot current = enumerator.Current; Model val = GameData.Instance.artifactsData.GetArtifactData(current.artifactName).ArtifactModel(); if (Il2CppSystemObjectExt.Is((Il2CppObjectBase)(object)val, ref item)) { boosts.Add(item); } boosts.AddRange((IEnumerable)MonoLinqHelper.ToArray(val.GetDescendants())); towerSetChanges.AddRange((IEnumerable)MonoLinqHelper.ToArray(val.GetDescendants())); abilityStackings.AddRange((IEnumerable)MonoLinqHelper.ToArray(val.GetDescendants())); } } public static void ProcessBoosts(GameModel gameModel, List boosts, List towerSetChanges, List abilityStackings, bool unapply) { //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_02f6: Unknown result type (might be due to invalid IL or missing references) //IL_02fb: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_03ac: Unknown result type (might be due to invalid IL or missing references) //IL_03cb: Unknown result type (might be due to invalid IL or missing references) //IL_034e: Unknown result type (might be due to invalid IL or missing references) //IL_0353: Unknown result type (might be due to invalid IL or missing references) //IL_035e: Unknown result type (might be due to invalid IL or missing references) //IL_0363: Unknown result type (might be due to invalid IL or missing references) //IL_0365: Unknown result type (might be due to invalid IL or missing references) foreach (BoostArtifactModel boost in boosts) { List cooldownBehaviors = ArtifactModelBehaviorExt.GetBehaviors(boost); if (!cooldownBehaviors.Any()) { continue; } foreach (TowerModel tower in (Il2CppArrayBase)(object)gameModel.towers) { if ((boost.towerTypes != null && ((IEnumerable)boost.towerTypes).Any() && ((Il2CppArrayBase)(object)boost.towerTypes).Contains(((EntityModel)tower).baseId) == boost.inverseSets) || !tower.CheckTiers(boost.tiers, boost.tiersMustBeEqual, boost.inverseTiers)) { continue; } TowerSet towerSet = tower.towerSet; foreach (CountAllCategoriesBehaviorModel item in towerSetChanges.Where((CountAllCategoriesBehaviorModel towerSetChange) => TowerSetHelpers.ContainsFlags(towerSetChange.towerSetList, tower.towerSet))) { foreach (TowerSet item2 in (Il2CppArrayBase)(object)item.alsoCountsAsList) { TowerModel obj = tower; obj.towerSet |= item2; } } bool flag = tower.CheckSet(boost.towerSet, boost.inverseSets); tower.towerSet = towerSet; if (!flag) { continue; } Il2CppGenericIEnumerable.ForEach(((Model)tower).GetDescendants(), (Action)delegate(AbilityModel ability) { using List.Enumerator enumerator9 = cooldownBehaviors.GetEnumerator(); if (enumerator9.MoveNext()) { CooldownBoostBehaviorModel current6 = enumerator9.Current; (bool, bool) tuple = (((BoostArtifactBehaviorModel)current6).multiplier < 1f, unapply); (bool, bool) tuple2 = tuple; if (!tuple2.Item1) { if (!tuple2.Item2) { ability.Cooldown /= ((BoostArtifactBehaviorModel)current6).multiplier; } else { ability.Cooldown *= ((BoostArtifactBehaviorModel)current6).multiplier; } } else if (!tuple2.Item2) { ability.Cooldown *= 2f - ((BoostArtifactBehaviorModel)current6).multiplier; } else { ability.Cooldown /= 2f - ((BoostArtifactBehaviorModel)current6).multiplier; } } }); } } foreach (AbilityStackingBehaviorModel abilityStacking in abilityStackings) { foreach (TowerModel tower2 in (Il2CppArrayBase)(object)gameModel.towers) { if (abilityStacking.towerTypes != null && ((IEnumerable)abilityStacking.towerTypes).Any() && ((Il2CppArrayBase)(object)abilityStacking.towerTypes).Contains(((EntityModel)tower2).baseId) == abilityStacking.inverseSets) { continue; } TowerSet towerSet2 = tower2.towerSet; foreach (CountAllCategoriesBehaviorModel item3 in towerSetChanges.Where((CountAllCategoriesBehaviorModel towerSetChange) => TowerSetHelpers.ContainsFlags(towerSetChange.towerSetList, tower2.towerSet))) { foreach (TowerSet item4 in (Il2CppArrayBase)(object)item3.alsoCountsAsList) { TowerModel obj2 = tower2; obj2.towerSet |= item4; } } bool flag2 = tower2.CheckSet(abilityStacking.towerSet, abilityStacking.inverseSets); tower2.towerSet = towerSet2; if (!flag2) { continue; } Il2CppGenericIEnumerable.ForEach(((Model)tower2).GetDescendants(), (Action)delegate(AbilityModel ability) { float num = 1f + (float)abilityStacking.stackCount * 0.15f; if (unapply) { ability.Cooldown *= num; } else { ability.Cooldown /= num; } }); } } } public override void OnRoundStart() { Syphon_OnBloonCreate.counter = 0; } public override void OnGameObjectsReset() { OverclockHandler.Dots.Clear(); BloodSacrifice.NextSacrificeTimes.Clear(); CorvusHandler.SpellsToReactivate.Clear(); } public override bool PreBloonLeaked(Bloon bloon) { UnityToSimulation bridge = InGame.Bridge; int num = ((bridge != null) ? bridge.MyPlayerNumber : (-1)); if (((RootObject)bloon).Sim.GetCorvusManagerExists(num)) { CorvusManager corvusManager = ((RootObject)bloon).Sim.GetCorvusManager(num); if (corvusManager.CanSpellBeCast((CorvusSpellType)6) && CorvusAbilityChoice.EnabledForSpell((CorvusSpellType)6)) { corvusManager.CastSpell((CorvusSpellType)6); } } return true; } public override void OnTowerSaved(Tower tower, TowerSaveDataModel saveData) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (BloodSacrifice.NextSacrificeTimes.TryGetValue(((RootObject)tower).Id, out var value)) { saveData.metaData["AbilityChoice-NextSacrificeTime"] = value.ToString(); } TimedMutator val = default(TimedMutator); OverclockMutator val2 = default(OverclockMutator); if (Il2CppSystemObjectExt.Is(((Mutable)tower).GetMutatorById("Overclock"), ref val) && Il2CppSystemObjectExt.Is((Il2CppObjectBase)(object)val.mutator, ref val2)) { OverclockModel overclockModel = val2.overclockModel; if (((Model)(object)overclockModel).OverclockAbilityChoice()) { saveData.metaData["OverclockAbilityChoice-rateModifier"] = overclockModel.rateModifier.ToString(); saveData.metaData["OverclockAbilityChoice-villageRangeModifier"] = overclockModel.villageRangeModifier.ToString(); } } TakeAimMutator val3 = default(TakeAimMutator); if (Il2CppSystemObjectExt.Is(((Mutable)tower).GetMutatorById("TakeAim"), ref val) && Il2CppSystemObjectExt.Is((Il2CppObjectBase)(object)val.mutator, ref val3)) { TakeAimModel takeAimModel = val3.takeAimModel; if (((Model)(object)takeAimModel).OverclockAbilityChoice()) { saveData.metaData["TakeAimAbilityChoice-rangeModifier"] = takeAimModel.rangeModifier.ToString(); saveData.metaData["TakeAimAbilityChoice-spreadModifier"] = takeAimModel.spreadModifier.ToString(); } } } public override void OnTowerLoaded(Tower tower, TowerSaveDataModel saveData) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) string s = default(string); if (saveData.metaData.TryGetValue("AbilityChoice-NextSacrificeTime", ref s)) { BloodSacrifice.NextSacrificeTimes[((RootObject)tower).Id] = int.Parse(s); } TimedMutator val = default(TimedMutator); if (Il2CppSystemObjectExt.Is(((Mutable)tower).GetMutatorById("Overclock"), ref val)) { OverclockMutator val2 = ((Il2CppObjectBase)val.mutator).Cast(); OverclockModel overclockModel = val2.overclockModel; if (((Model)(object)overclockModel).OverclockAbilityChoice()) { val.totalDuration = -1; val.removeAt = -1; string s2 = default(string); if (saveData.metaData.TryGetValue("OverclockAbilityChoice-rateModifier", ref s2) && float.TryParse(s2, out var result)) { overclockModel.rateModifier = result; } string s3 = default(string); if (saveData.metaData.TryGetValue("OverclockAbilityChoice-villageRangeModifier", ref s3) && float.TryParse(s3, out var result2)) { overclockModel.villageRangeModifier = result2; } ((BehaviorMutator)val2).resultCache.Clear(); ((Mutable)tower).ApplyMutation(); } } if (!Il2CppSystemObjectExt.Is(((Mutable)tower).GetMutatorById("TakeAim"), ref val)) { return; } TakeAimMutator val3 = ((Il2CppObjectBase)val.mutator).Cast(); TakeAimModel takeAimModel = val3.takeAimModel; if (((Model)(object)takeAimModel).OverclockAbilityChoice()) { val.totalDuration = -1; val.removeAt = -1; string s4 = default(string); if (saveData.metaData.TryGetValue("TakeAimAbilityChoice-rangeModifier", ref s4) && float.TryParse(s4, out var result3)) { takeAimModel.rangeModifier = result3; } string s5 = default(string); if (saveData.metaData.TryGetValue("TakeAimAbilityChoice-spreadModifier", ref s5) && float.TryParse(s5, out var result4)) { takeAimModel.spreadModifier = result4; } ((BehaviorMutator)val3).resultCache.Clear(); ((Mutable)tower).ApplyMutation(); } } static AbilityChoiceMod() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Expected O, but got Unknown //IL_006e: 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_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Expected O, but got Unknown //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Expected O, but got Unknown //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Expected O, but got Unknown //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_012f: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Expected O, but got Unknown //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Expected O, but got Unknown //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Expected O, but got Unknown ModSettingInt val = new ModSettingInt(0) { description = "Controls the threshold where the Magus Perfectus will switch to its mana generating attack when it drops below this amount of mana." }; ((ModSettingNumber)val).min = 0L; ((ModSettingNumber)val).max = 100000L; ((ModSetting)val).icon = "48e18ca7bb56c1c429c530f5d79832fe"; MagusPerfectusSwitchThreshold = val; } } public class AbilityChoiceTest : ModTest { public override IEnumerator Test() { int mode; for (mode = 1; mode <= 2; mode++) { yield return ((ModTest)this).EnsureOnMainMenuWithNoPopUps(); AbilityChoice.overrideMode = mode; yield return ((ModTest)this).LoadIntoGame((InGameData)null); foreach (TowerModel towerModel in (from choice in ModContent.GetContent() where choice.Mode == mode select choice).SelectMany((AbilityChoice abilityChoice) => abilityChoice.GetAffectedCached(((ModTest)this).Bridge.Model)).Distinct()) { TowerToSimulation tower = ((ModTest)this).AssertNotNull(ModTest.CreateTowerAt(((ModTest)this).Bridge, new Vector2(0f, 0f), towerModel, true, true, 0), ((Model)towerModel).name); yield return null; yield return null; yield return null; ((ModTest)this).Bridge.SellTower(tower.Id); } } AbilityChoice.overrideMode = null; } } public class AdoraTsmTheme : ModTsmTheme { private ModHelperPanel panel; private ModHelperSlider slider; private ModHelperSlider slider20; public override string BaseTheme => "Default"; public static int SacrificeAmount { get; private set; } public override void SetupTheme(BaseTSMTheme theme) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0077: 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) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) panel = GameObjectExt.AddModHelperPanel(((Component)theme).gameObject, new Info("AdoraSacrificePanel", (InfoPreset)0), (string)null, (Axis?)null, 50f, 0); ((ModHelperComponent)panel).AddImage(new Info("Icon", 372f, -75f, 120f), "de1e7961f691d41eea5aa65b821708ac"); slider = ((ModHelperComponent)panel).AddSlider(new Info("SacrificeSlider", 0f, -75f, 550f, 75f), 0f, 0f, 150f, 5f, new Vector2(100f, 100f), UnityAction.op_Implicit((Action)delegate(float amount) { SacrificeAmount = (int)amount; }), 52f, "$/s"); slider20 = ((ModHelperComponent)panel).AddSlider(new Info("SacrificeSliderLvl20", 0f, -75f, 550f, 75f), 0f, 0f, 33f, 1f, new Vector2(100f, 100f), UnityAction.op_Implicit((Action)delegate(float amount) { SacrificeAmount = (int)amount; }), 52f, "$/s"); ((Graphic)GameObjectExt.GetComponentInChildrenByName(((Component)slider).gameObject, "Fill")).color = new Color(1f, 1f, 0f); ((Graphic)GameObjectExt.GetComponentInChildrenByName(((Component)slider20).gameObject, "Fill")).color = new Color(1f, 1f, 0.5f); ((Transform)GameObjectExt.GetComponentInChildrenByName(((Component)slider).gameObject, "Label")).localPosition = new Vector3(0f, -80f, 0f); ((Transform)GameObjectExt.GetComponentInChildrenByName(((Component)slider20).gameObject, "Label")).localPosition = new Vector3(0f, -80f, 0f); ((TMP_Text)GameObjectExt.GetComponentInChildrenByName(((Component)slider).gameObject, "Label")).fontStyle = (FontStyles)32; ((TMP_Text)GameObjectExt.GetComponentInChildrenByName(((Component)slider20).gameObject, "Label")).fontStyle = (FontStyles)32; ((Component)GameObjectExt.GetComponentInChildrenByName(((Component)slider).gameObject, "DefaultNotch")).gameObject.SetActive(false); ((Component)GameObjectExt.GetComponentInChildrenByName(((Component)slider20).gameObject, "DefaultNotch")).gameObject.SetActive(false); } public override void TowerChanged(BaseTSMTheme theme, TowerToSimulation tower) { //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) if (tower == null || ((EntityModel)tower.Def).baseId != TowerType.Adora || tower.Def.tier < 7) { ((ModHelperComponent)panel).SetActive(false); return; } ((ModHelperComponent)panel).SetActive(true); if (tower.Def.tier < 20) { ((ModHelperComponent)slider).SetActive(true); ((ModHelperComponent)slider20).SetActive(false); slider.SetCurrentValue((float)Math.Clamp(SacrificeAmount, 0, 150), true); } else { ((ModHelperComponent)slider20).SetActive(true); ((ModHelperComponent)slider).SetActive(false); slider20.SetCurrentValue((float)Math.Clamp(SacrificeAmount, 0, 33), true); ((Graphic)GameObjectExt.GetComponentInChildrenByName(((Component)slider20).gameObject, "Fill")).color = ((((Mutable)tower.tower).GetMutatorById("AdoraSunGodTransformationVengeance") != null) ? new Color(0.75f, 0f, 0f) : new Color(1f, 1f, 0.5f)); } } } public abstract class CorvusAbilityChoice : HeroAbilityChoice { protected const int ContinuousFactor = 20; public sealed override string HeroId => TowerType.Corvus; protected override float RegistrationPriority => base.RegistrationPriority + 1f; public sealed override Dictionary Descriptions1 => new Dictionary(); public sealed override Dictionary Descriptions2 => new Dictionary(); public virtual string Description1 => null; public virtual string Description2 => null; public virtual string Description1Lvl20 => null; public virtual string Description2Lvl20 => null; public override SpriteReference Icon => ((TowerBasedShopItemModel)Spell(Game.instance.model.GetTowerWithName("Corvus 20"))).defaultIcon; public CorvusSpellType SpellType => Enum.Parse(((ModContent)this).Name); public CorvusSpellModel Spell(TowerModel model) { return ((IEnumerable)TowerModelBehaviorExt.GetBehaviors(model)).FirstOrDefault((Func)((CorvusSpellModel spellModel) => ((TowerBasedShopItemModel)spellModel).locsId == ((ModContent)this).Name)); } public CorvusContinuousSpellModel ContinuousSpell(TowerModel model) { return ((IEnumerable)TowerModelBehaviorExt.GetBehaviors(model)).FirstOrDefault((Func)((CorvusContinuousSpellModel spellModel) => ((TowerBasedShopItemModel)spellModel).locsId == ((ModContent)this).Name)); } public CorvusInstantSpellModel InstantSpell(TowerModel model) { return ((IEnumerable)TowerModelBehaviorExt.GetBehaviors(model)).FirstOrDefault((Func)((CorvusInstantSpellModel spellModel) => ((TowerBasedShopItemModel)spellModel).locsId == ((ModContent)this).Name)); } public override bool AppliesTo(TowerModel towerModel) { return Spell(towerModel) != null; } public static bool EnabledForSpell(CorvusSpellType spellType) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) return ModContent.GetContent().Any((CorvusAbilityChoice choice) => choice.SpellType == spellType && choice.Enabled); } public override void Apply(GameModel gameModel) { foreach (TowerModel item in GetAffected(gameModel)) { if (base.Mode2) { Apply2(item); } else { Apply1(item); } ApplyBoth(item); } } public override IEnumerable Load() { yield return (ModContent)(object)this; if (Description1 != null) { yield return (ModContent)(object)new CorvusAbilityChoiceDescription(this, 1, Description1); } if (Description2 != null) { yield return (ModContent)(object)new CorvusAbilityChoiceDescription(this, 2, Description2); } if (Description1Lvl20 != null) { yield return (ModContent)(object)new CorvusAbilityChoiceDescription(this, 1, Description1Lvl20, lvl20: true); } if (Description2Lvl20 != null) { yield return (ModContent)(object)new CorvusAbilityChoiceDescription(this, 2, Description2Lvl20, lvl20: true); } } } public static class CorvusHandler { [HarmonyPatch(typeof(CorvusManager), "ConsumeContinuousSpellMana")] internal static class CorvusManager_ConsumeContinuousSpellMana { [HarmonyPrefix] internal static void Prefix(CorvusManager __instance, ref List __state) { __state = Il2CppSystemDictionaryExt.Keys(__instance.activeContinuousSpells).ToList(); } [HarmonyPostfix] internal static void Postfix(CorvusManager __instance, CorvusContinuousSpell spell, ref List __state) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) if (__instance.IsSpellActive((CorvusSpell)(object)spell)) { return; } SpellsToReactivate.TryAdd(__instance.owner, new HashSet()); HashSet hashSet = SpellsToReactivate[__instance.owner]; foreach (CorvusContinuousSpell item in __state.Where((CorvusContinuousSpell s) => CorvusAbilityChoice.EnabledForSpell(((CorvusSpell)s).SpellType))) { hashSet.Add(((CorvusSpell)item).SpellType); } } } [HarmonyPatch(typeof(CorvusManager), "Process")] internal static class CorvusManager_Process { [HarmonyPostfix] internal static void Postfix(CorvusManager __instance) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Invalid comparison between Unknown and I4 //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Invalid comparison between Unknown and I4 //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Invalid comparison between Unknown and I4 //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Invalid comparison between Unknown and I4 //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Invalid comparison between Unknown and I4 //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) SpellsToReactivate.TryAdd(__instance.owner, new HashSet()); CorvusSpellType[] array = (CorvusSpellType[])(object)new CorvusSpellType[2] { (CorvusSpellType)9, (CorvusSpellType)13 }; List val2 = default(List); foreach (CorvusSpellType val in array) { if (CorvusAbilityChoice.EnabledForSpell(val) && __instance.spellRestrictions.TryGetValue(val, ref val2)) { val2.Clear(); } } foreach (CorvusInstantSpell item in Il2CppSystemDictionaryExt.Keys(__instance.activeInstantSpells).ToList()) { CorvusInstantSpellTiming val3 = __instance.activeInstantSpells[item]; if (!CorvusAbilityChoice.EnabledForSpell(((CorvusSpell)item).SpellType) || val3.FramesRemainingActive > 1 || (int)((CorvusSpell)item).SpellType == 6) { continue; } if (__instance.TryConsumeMana(((CorvusSpellModel)item.SpellModel).initialManaCost)) { val3.totalFramesActive += (int)(item.SpellModel.duration * 60f); CorvusSpellType spellType = ((CorvusSpell)item).SpellType; if (((int)spellType == 9 || spellType - 13 <= 1) ? true : false) { item.Cast(); } } else { CorvusSpellType spellType = ((CorvusSpell)item).SpellType; if (((int)spellType != 9 && (int)spellType != 14) || 1 == 0) { __instance.CancelInstantSpell(((CorvusSpell)item).SpellType); } SpellsToReactivate[__instance.owner].Add(((CorvusSpell)item).SpellType); } } foreach (CorvusSpellType item2 in SpellsToReactivate[__instance.owner].ToList()) { if (__instance.CanSpellBeCast(item2) && __instance.HasEnoughManaForSpell(__instance.LookupSpellByType(item2))) { SpellsToReactivate[__instance.owner].Remove(item2); if (!__instance.IsSpellActive(item2)) { __instance.CastSpell(item2); } } } } } [HarmonyPatch(typeof(CorvusManager), "GetSpellStatus")] internal static class CorvusManager_GetSpellStatus { [HarmonyPostfix] internal static void Postfix(CorvusSpellType spellType, ref CorvusSpellStatus __result) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) if (CorvusAbilityChoice.EnabledForSpell(spellType) && (int)spellType != 6) { __result = new CorvusSpellStatus(spellType, __result.isActive, __result.canSpellBeCast, 0f, 0f); } } } [HarmonyPatch(typeof(CorvusManager), "IsManaDraining")] internal static class CorvusManager_IsManaDraining { [HarmonyPostfix] internal static void Postfix(CorvusManager __instance, ref bool __result) { __result |= Il2CppSystemDictionaryExt.Keys(__instance.activeInstantSpells).Any((CorvusInstantSpell spell) => CorvusAbilityChoice.EnabledForSpell(((CorvusSpell)spell).SpellType)); } } [HarmonyPatch(typeof(CorvusSpellbookUi), "UpdateDeactivateButton")] internal static class CorvusSpellbookUi_UpdateDeactivateButton { [HarmonyPostfix] internal static bool Prefix(CorvusSpellbookUi __instance) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) CorvusInstantSpellModel val = default(CorvusInstantSpellModel); if (!TowerSelectionMenuExt.instance.IsSecondarySelectionMenuVisible() || !Il2CppSystemObjectExt.Is((Il2CppObjectBase)(object)((SecondarySelectionMenuUi)__instance).TowerBasedShopItemModel, ref val) || !CorvusAbilityChoice.EnabledForSpell(((CorvusSpellModel)val).spellType)) { return true; } CorvusSpellStatus corvusSpellStatus = InGame.Bridge.GetCorvusSpellStatus(((CorvusSpellModel)val).spellType, InGame.Bridge.MyPlayerNumber); ((Component)__instance.deactivateButton).gameObject.SetActive(corvusSpellStatus.isActive); return false; } } [HarmonyPatch(typeof(CorvusSpellbookUi), "DeactivateSelectedSpell")] internal static class CorvusSpellbookUi_DeactivateSelectedSpell { [HarmonyPrefix] internal static bool Prefix(CorvusSpellbookUi __instance) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) CorvusInstantSpellModel val = default(CorvusInstantSpellModel); if (!Il2CppSystemObjectExt.Is((Il2CppObjectBase)(object)((SecondarySelectionMenuUi)__instance).TowerBasedShopItemModel, ref val) || !CorvusAbilityChoice.EnabledForSpell(((CorvusSpellModel)val).spellType)) { return true; } InGame.Bridge.Simulation.GetCorvusManager(InGame.Bridge.MyPlayerNumber).CancelInstantSpell(((CorvusSpellModel)val).spellType); return false; } } [HarmonyPatch(typeof(CorvusManager), "TriggerCorvusToReleaseSpirit")] internal static class CorvusManager_TriggerCorvusToReleaseSpirit { public static bool releasing; [HarmonyPrefix] internal static void Prefix(CorvusManager __instance) { releasing = true; } [HarmonyPostfix] internal static void Postfix(CorvusManager __instance) { releasing = false; if (CorvusAbilityChoice.EnabledForSpell((CorvusSpellType)12) && __instance.IsSpellActive((CorvusSpellType)12) && __instance.duplicateSpiritSubTower == null) { ((Il2CppObjectBase)__instance.LookupSpellByType((CorvusSpellType)12)).Cast().CreateDuplicateSpirit(); } } } [HarmonyPatch(typeof(CorvusManager), "GetSaveMetaData")] internal static class CorvusManager_GetSaveMetaData { [HarmonyPostfix] internal unsafe static void Postfix(CorvusManager __instance, Dictionary metaData) { if (SpellsToReactivate.TryGetValue(__instance.owner, out var value)) { metaData.Add("CorvusMetadata_SpellsToReactivate" + __instance.owner, GeneralExtensions.Join(value.Select((CorvusSpellType type) => ((object)(*(CorvusSpellType*)(&type))/*cast due to .constrained prefix*/).ToString()), (Func)null, ",")); } } } [HarmonyPatch(typeof(CorvusManager), "SetSaveMetaData")] internal static class CorvusManager_SetSaveMetaData { [HarmonyPostfix] internal static void Postfix(CorvusManager __instance, Dictionary metaData) { string text = default(string); if (metaData.TryGetValue("CorvusMetadata_SpellsToReactivate" + __instance.owner, ref text)) { SpellsToReactivate[__instance.owner] = text.Split(",", StringSplitOptions.RemoveEmptyEntries).Select(Enum.Parse).ToHashSet(); } } } public static readonly Dictionary> SpellsToReactivate = new Dictionary>(); } public abstract class GeraldoAbilityChioce : HeroAbilityChoice { public sealed override string HeroId => TowerType.Geraldo; protected abstract int CostMult { get; } protected sealed override bool HasMode2 => false; public abstract override Dictionary Descriptions2 { get; } public override SpriteReference Icon => ((TowerBasedShopItemModel)GeraldoItem()).defaultIcon; public GeraldoItemModel GeraldoItem(GameModel gameModel = null) { return (gameModel ?? Game.instance.model).GetGeraldoItemWithName(((ModContent)this).Name); } public override bool AppliesTo(TowerModel towerModel) { return Math.Clamp(GeraldoItem().levelUnlockedAt, 1, 20) == towerModel.tier; } public override IEnumerable Load() { yield return (ModContent)(object)this; int key; string value; foreach (KeyValuePair item in Descriptions1) { item.Deconstruct(out key, out value); int level = key; string description = value; yield return (ModContent)(object)new HeroAbilityChoiceDescription(this, level, 1, description); } foreach (KeyValuePair item2 in Descriptions2) { item2.Deconstruct(out key, out value); int level2 = key; string description2 = value; yield return (ModContent)(object)new GeraldoAbilityChoiceDescription(this, level2, description2); } } public sealed override void Apply1(TowerModel model) { } public sealed override void Apply2(TowerModel model) { } public override void Apply(GameModel gameModel) { GeraldoItemModel val = GeraldoItem(gameModel); val.cost *= CostMult; Apply(val); } protected abstract void Apply(GeraldoItemModel geraldoItem); } public abstract class HeroAbilityChoice : AbilityChoice { public static readonly Dictionary Cache = new Dictionary(); public abstract string HeroId { get; } public sealed override string Description => ((NamedModContent)this).Description; public abstract Dictionary Descriptions1 { get; } public virtual Dictionary Descriptions2 { get; } protected override bool HasMode2 => Descriptions2 != null; public override IEnumerable Load() { yield return (ModContent)(object)this; foreach (int level in Descriptions1.Keys) { yield return (ModContent)(object)new HeroAbilityChoiceDescription(this, level, 1, $"[{((ModContent)this).Id} Description1 {level}]"); } if (!HasMode2) { yield break; } foreach (int level2 in Descriptions2.Keys) { yield return (ModContent)(object)new HeroAbilityChoiceDescription(this, level2, 2, $"[{((ModContent)this).Id} Description2 {level2}]"); } } public override void Register() { base.Register(); Cache[((ModContent)this).Id] = this; } public override IEnumerable GetAffected(GameModel gameModel) { return from model in Il2CppGenericIEnumerable.AsIEnumerable(gameModel.GetTowersWithBaseId(HeroId, false)).Where(AppliesTo) orderby model.tier select model; } public static string IconForMode(int mode) { if (1 == 0) { } string result = mode switch { 1 => "Ui[RedBtnSquare]", 2 => "Ui[BlueBtnSquare]", _ => "Ui[YellowBtnSquare]", }; if (1 == 0) { } return result; } public override void RegisterText(Dictionary textTable) { textTable[((ModContent)this).Id] = ((NamedModContent)this).DisplayName; int key; string value; foreach (KeyValuePair item in Descriptions1) { item.Deconstruct(out key, out value); int value2 = key; string text = value; textTable[$"{((ModContent)this).Id} Description1 {value2}"] = text; } if (!HasMode2) { return; } foreach (KeyValuePair item2 in Descriptions2) { item2.Deconstruct(out key, out value); int value3 = key; string text2 = value; textTable[$"{((ModContent)this).Id} Description2 {value3}"] = text2; } } } [RegisterTypeInIl2Cpp(false)] public class HeroAbilityChoiceInfo : MonoBehaviour { public HeroAbilityChoice abilityChoice; public Il2CppReferenceArray buttons; public GameObject container; public Image abilityIcon; public Image background; public int index; public HeroAbilityChoiceInfo(IntPtr ptr) : base(ptr) { } public void UpdateIcon() { ImageExt.SetSprite(background, HeroAbilityChoice.IconForMode(abilityChoice?.Mode ?? 0)); if (abilityChoice != null) { container.SetActive(true); SpriteReference icon = abilityChoice.Icon; if (icon != null) { ImageExt.SetSprite(abilityIcon, icon); } } } public void UpdateDescriptions() { foreach (HeroUpgradeButton item in (Il2CppArrayBase)(object)buttons) { UpdateDescription(abilityChoice.HeroId, item); } } public static void UpdateDescription(string heroId, HeroUpgradeButton button) { string text = $"{heroId} Level {button.HeroIndex} Description"; button.descriptions.SetText(LocalizationManager.Instance.GetText(text)); } public static void Setup(string selectedHero, Il2CppReferenceArray buttons) { Il2CppArrayBase source = Enumerable.ToArray(Game.instance.model.GetTowersWithBaseId(selectedHero, false)); List list = (from choice in ModContent.GetContent() where choice.HeroId == selectedHero select choice).ToList(); foreach (HeroUpgradeButton item in (Il2CppArrayBase)(object)buttons) { foreach (HeroAbilityChoiceInfo componentsInChild in ((Component)((Component)item).transform).GetComponentsInChildren(true)) { componentsInChild.abilityChoice = null; if (componentsInChild.index > 0) { componentsInChild.container.SetActive(false); } } } foreach (HeroAbilityChoice abilityChoice in list) { TowerModel towerModel = ((IEnumerable)source).First((TowerModel towerModel2) => abilityChoice.AppliesTo(towerModel2)); HeroUpgradeButton val = ((IEnumerable)buttons).First((HeroUpgradeButton upgradeButton) => upgradeButton.HeroIndex == towerModel.tier); HeroAbilityChoiceInfo heroAbilityChoiceInfo = GameObjectExtensions.GetComponentOrAdd(val.abilityIconContainer); if (heroAbilityChoiceInfo.abilityChoice != null) { Il2CppArrayBase componentsInChildren = ((Component)((Component)val).transform).GetComponentsInChildren(true); if (!Il2CppSystemObjectExt.Is(((IEnumerable)componentsInChildren).FirstOrDefault((HeroAbilityChoiceInfo i) => i.abilityChoice == null), ref heroAbilityChoiceInfo)) { int length = componentsInChildren.Length; GameObject val2 = Object.Instantiate(val.abilityIconContainer, val.abilityIconContainer.transform.parent); ((Object)val2).name = ((Object)val2).name.Replace("(Clone)", length.ToString()); heroAbilityChoiceInfo = val2.GetComponent(); heroAbilityChoiceInfo.container = val2; heroAbilityChoiceInfo.index = length; } } else { heroAbilityChoiceInfo.container = val.abilityIconContainer; } heroAbilityChoiceInfo.container.SetActive(true); heroAbilityChoiceInfo.abilityChoice = abilityChoice; heroAbilityChoiceInfo.buttons = buttons; heroAbilityChoiceInfo.abilityIcon = GameObjectExt.GetComponentInChildrenByName(((Component)heroAbilityChoiceInfo).gameObject, "Icon"); heroAbilityChoiceInfo.background = GameObjectExt.GetComponentInChildrenByName(((Component)heroAbilityChoiceInfo).gameObject, "Bg"); GameObjectExtensions.GetComponentOrAdd(heroAbilityChoiceInfo.container); } foreach (HeroUpgradeButton item2 in (Il2CppArrayBase)(object)buttons) { foreach (HeroAbilityChoiceInfo componentsInChild2 in ((Component)((Component)item2).transform).GetComponentsInChildren()) { componentsInChild2.UpdateIcon(); } } } } internal static class MagusPerfectusManager { [HarmonyPatch(typeof(MagusPerfectusGraveyardStateManager), "TriggerManaExplosion")] internal static class MagusPerfectusGraveyardStateManager_TriggerManaExplosion { [HarmonyPrefix] internal static bool Prefix(MagusPerfectusGraveyardStateManager __instance, ref int __result) { if (activatingPhoenixRebirth) { __instance.explosionRemainingFrames = 450; NecroData paragonNecroData = __instance.ParagonNecroData; if (paragonNecroData != null) { __result = paragonNecroData.RbePool() / 4; if (paragonNecroData.RbePool() - __result < 1000) { __result = paragonNecroData.RbePool(); } __instance.ConsumeMana(__result, false); } return false; } return true; } } [HarmonyPatch(typeof(PhoenixRebirth), "Activate")] internal static class PhoenixRebirth_Activate { [HarmonyPrefix] internal static void Prefix(PhoenixRebirth __instance, ref int __state) { activatingPhoenixRebirth = ((AbilityBehavior)__instance).ability.abilityModel.isHidden; } [HarmonyPostfix] internal static void Postfix(PhoenixRebirth __instance) { activatingPhoenixRebirth = false; } } [HarmonyPatch(typeof(PhoenixRebirth), "SpawnZombieZOMGs")] internal static class PhoenixRebirth_SpawnZombieZOMGs { [HarmonyPostfix] internal static void Postfix(PhoenixRebirth __instance, int manaConsumed) { if (!spawningBfbs) { spawningBfbs = true; int num = manaConsumed % __instance.behaviourModel.manaPerZombieZOMG; ProjectileModel projectileZOMG = __instance.behaviourModel.projectileZOMG; __instance.behaviourModel.projectileZOMG = __instance.behaviourModel.projectileBFB; PhoenixRebirthModel behaviourModel = __instance.behaviourModel; behaviourModel.manaPerZombieZOMG /= 4; __instance.SpawnZombieZOMGs(num); __instance.behaviourModel.projectileZOMG = projectileZOMG; PhoenixRebirthModel behaviourModel2 = __instance.behaviourModel; behaviourModel2.manaPerZombieZOMG *= 4; spawningBfbs = false; } } } [HarmonyPatch(typeof(PhoenixRebirth), "CanUseAbility")] internal static class PhoenixRebirth_CanUseAbility { [HarmonyPrefix] internal static bool Prefix(PhoenixRebirth __instance, ref bool __result) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Invalid comparison between Unknown and I4 if (((AbilityBehavior)__instance).ability.abilityModel.isHidden && (int)((MagusPerfectusAbilityBehavior)__instance).GraveyardManager.graveyardManaState == 1) { __result = false; return false; } return true; } } [HarmonyPatch(typeof(MagusPerfectusGraveyardStateManager), "Process")] internal static class MagusPerfectusGraveyardStateManager_Process { [HarmonyPostfix] internal static void Postfix(MagusPerfectusGraveyardStateManager __instance) { NecroData paragonNecroData = __instance.ParagonNecroData; if (paragonNecroData != null) { int num = paragonNecroData.RbePool(); if (PreviousMana.TryGetValue(__instance.registeredNecroIdx, out var value) && value > ModSettingInt.op_Implicit(AbilityChoiceMod.MagusPerfectusSwitchThreshold) && num <= ModSettingInt.op_Implicit(AbilityChoiceMod.MagusPerfectusSwitchThreshold)) { __instance.SwitchGraveyardManaState((GraveyardManaState)1); } PreviousMana[__instance.registeredNecroIdx] = num; } } } [HarmonyPatch(typeof(ArcaneMetamorphosis), "Process")] internal static class ArcaneMeta_Process { [HarmonyPrefix] internal static void Prefix(ArcaneMetamorphosis __instance) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) if (ModContent.GetInstance().Mode == 1) { __instance.isCurrentlyMorphed = (int)((MagusPerfectusAbilityBehavior)__instance).GraveyardManager.graveyardManaState == 0 && ((IEnumerable>)Il2CppSystemDictionaryExt.GetValues>(((MagusPerfectusAbilityBehavior)__instance).GraveyardManager.graveyardStateAttacks).ToArray()).SelectMany((List list) => (IEnumerable)list.ToArray()).Any((Attack attack) => attack.HasValidTarget()); } } } private static bool activatingPhoenixRebirth; private static bool spawningBfbs; private static readonly Dictionary PreviousMana = new Dictionary(); } internal static class ModHelperData { public const string WorksOnVersion = "55.2"; public const string Version = "4.4.6"; public const string Name = "Ability Choice"; public const string Description = "Adds in new choices for towers with abilities that you can pick instead of having an active ability. Selected in the Upgrades menu for the tower by Right-Clicking on the Upgrade to switch.\r\n\r\nYellow Icon: Default Effect\r\nRed Icon: Permanent but weaker effect of the ability\r\nBlue Icon: A new effect based on the theme of the upgrade path"; public const string RepoOwner = "doombubbles"; public const string PrevRepoName = "ability-choice"; public const string RepoName = "AbilityChoice"; } internal static class OverclockHandler { [HarmonyPatch] internal static class TapTowerAbilityBehavior_Activate { internal static IEnumerable TargetMethods() { return new <>z__ReadOnlyArray(new MethodInfo[2] { AccessTools.Method(typeof(Overclock), "Activate", (Type[])null, (Type[])null), AccessTools.Method(typeof(TakeAim), "Activate", (Type[])null, (Type[])null) }); } [HarmonyPostfix] internal static void Postfix(TapTowerAbilityBehavior __instance) { if (__instance.OverclockAbilityChoice() && __instance.selectedTower != null && !__instance.IsBanned(__instance.selectedTower)) { ApplyOverclock(((TowerBehavior)((AbilityBehavior)__instance).ability).tower, __instance.selectedTower, __instance); } } } [HarmonyPatch(typeof(Ability), "Process")] internal static class Ability_Process { [HarmonyPostfix] internal static void Postfix(Ability __instance) { //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0128: 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) OverclockPermanentModel val = default(OverclockPermanentModel); Overclock val2 = default(Overclock); TimedMutator val3 = default(TimedMutator); OverclockPermanentMutator val4 = default(OverclockPermanentMutator); if (__instance.CooldownRemaining == 0f && __instance.abilityModel.OverclockAbilityChoice() && Il2CppSystemObjectExt.Is(AbilityModelBehaviorExt.GetBehavior(__instance.abilityModel), ref val) && Il2CppSystemObjectExt.Is(((RootBehavior)__instance).entity.GetBehaviorInDependants(), ref val2) && ((TapTowerAbilityBehavior)val2).selectedTower != null && (!Il2CppSystemObjectExt.Is(((Mutable)((TapTowerAbilityBehavior)val2).selectedTower).GetMutatorById(OverclockPermanentModel.MutatorId), ref val3) || !Il2CppSystemObjectExt.Is((Il2CppObjectBase)(object)val3.mutator, ref val4) || val4.stacks < val.maxStacks)) { __instance.Activate(false); __instance.CooldownRemaining = __instance.abilityModel.cooldownFrames; } TapTowerAbilityBehavior val5 = default(TapTowerAbilityBehavior); if (!__instance.abilityModel.OverclockAbilityChoice() || !Il2CppSystemObjectExt.Is(((RootBehavior)__instance).entity.GetBehaviorInDependants(), ref val5)) { return; } TechBotLink fakeTechBotLink = GetFakeTechBotLink(__instance); if (val5.selectedTower != null) { TowerToSimulation selectedTower = TowerSelectionMenuExt.instance.selectedTower; ObjectId? val6 = ((selectedTower != null) ? new ObjectId?(selectedTower.Id) : ((ObjectId?)null)); ObjectId id = ((RootObject)((TowerBehavior)__instance).tower).Id; if (val6.HasValue && val6.GetValueOrDefault() == id) { fakeTechBotLink.PlotPointsToLinkedTower(val5.selectedTower); return; } } fakeTechBotLink.RemoveDots(); } } [HarmonyPatch(typeof(Ability), "OnDestroy")] internal static class Ability_OnDestroy { [HarmonyPrefix] internal static void Prefix(Ability __instance) { if (__instance.abilityModel.OverclockAbilityChoice()) { TechBotLink fakeTechBotLink = GetFakeTechBotLink(__instance); fakeTechBotLink.RemoveDots(); } } } [HarmonyPatch(typeof(OverclockPermanent), "ApplyToTower")] internal static class OverclockPermanent_ApplyToTower { [HarmonyPrefix] internal static bool Prefix(OverclockPermanent __instance) { if (!((AbilityBehavior)__instance).ability.abilityModel.OverclockAbilityChoice()) { return true; } return ((AbilityBehavior)__instance).ability.CooldownRemaining == 0f; } } [HarmonyPatch(typeof(TapTowerAbilityBehavior), "GetCustomInputData")] internal static class TapTowerAbilityBehavior_GetCustomInputData { [HarmonyPostfix] internal static void Postfix(TapTowerAbilityBehavior __instance, ref Object __result) { OverclockCIData val = default(OverclockCIData); if (__instance.OverclockAbilityChoice() && Il2CppSystemObjectExt.Is((Il2CppObjectBase)(object)__result, ref val)) { val.validTowerIds.RemoveAll(Predicate.op_Implicit((Func)delegate(ObjectId id) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) Tower selectedTower = __instance.selectedTower; ObjectId? val2 = ((selectedTower != null) ? new ObjectId?(((RootObject)selectedTower).Id) : ((ObjectId?)null)); return val2.HasValue && id == val2.GetValueOrDefault(); })); } } } [HarmonyPatch(typeof(TapTowerAbilityBehavior), "OnTowerUpgraded")] internal static class TapTowerAbilityBehavior_OnTowerUpgraded { [HarmonyPostfix] internal static void Postfix(TapTowerAbilityBehavior __instance, Tower tower) { //IL_0014: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) if (__instance.OverclockAbilityChoice()) { ObjectId id = ((RootObject)tower).Id; Tower selectedTower = __instance.selectedTower; ObjectId? val = ((selectedTower != null) ? new ObjectId?(((RootObject)selectedTower).Id) : ((ObjectId?)null)); if (val.HasValue && id == val.GetValueOrDefault() && !__instance.IsBanned(tower)) { ApplyOverclock(((TowerBehavior)((AbilityBehavior)__instance).ability).tower, tower, __instance); } if (((RootObject)tower).Id == ((RootObject)((TowerBehavior)((AbilityBehavior)__instance).ability).tower).Id && __instance.selectedTower != null && ((RootBehavior)((AbilityBehavior)__instance).ability).entity.GetBehavior() != null && ((Mutable)__instance.selectedTower).GetMutatorById(OverclockPermanentModel.MutatorId) == null) { ((AbilityBehavior)__instance).ability.ClearCooldown(); ((AbilityBehavior)__instance).ability.Activate(false); } } } } [HarmonyPatch(typeof(TapTowerAbilityBehavior), "OnDestroy")] internal static class TapTowerAbilityBehavior_OnDestroy { [HarmonyPrefix] internal static void Prefix(TapTowerAbilityBehavior __instance) { if (__instance.OverclockAbilityChoice() && __instance.selectedTower != null) { ((Mutable)__instance.selectedTower).RemoveMutatorsById(__instance.MutatorId()); } } } [HarmonyPatch] internal static class TapTowerAbilityBehavior_ApplyCustomInputData { internal static IEnumerable TargetMethods() { return new <>z__ReadOnlyArray(new MethodInfo[2] { AccessTools.Method(typeof(Overclock), "ApplyCustomInputData", (Type[])null, (Type[])null), AccessTools.Method(typeof(TakeAim), "ApplyCustomInputData", (Type[])null, (Type[])null) }); } [HarmonyPrefix] internal static void Prefix(TapTowerAbilityBehavior __instance, CustomInputData data) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (__instance.OverclockAbilityChoice() && __instance.selectedTower != null && ((RootObject)__instance.selectedTower).Id != data.objectIdValue) { ((Mutable)__instance.selectedTower).RemoveMutatorsById(__instance.MutatorId()); } } } [HarmonyPatch(typeof(Ability), "IsReady")] internal static class Ability_IsReady { [HarmonyPrefix] internal static void Prefix(Ability __instance, ref bool ignoreCooldown) { if (__instance.abilityModel.OverclockAbilityChoice()) { ignoreCooldown = true; } } } [HarmonyPatch(typeof(Ability), "Activate")] internal static class Ability_Activate { [HarmonyPrefix] internal static void Prefix(Ability __instance, ref bool ignoreCooldown) { if (__instance.abilityModel.OverclockAbilityChoice()) { ignoreCooldown = true; } } } [HarmonyPatch(typeof(UnityToSimulation), "GetAllAbilities")] internal static class UnityToSimulation_GetAllAbilities { [HarmonyPostfix] internal static void Postfix(ref List __result) { List obj = __result; __result = ((obj != null) ? Il2CppGenerics.Where(obj, (Func)((AbilityToSimulation a) => a == null || !a.model.OverclockAbilityChoice())) : null); } } [HarmonyPatch(typeof(MapSaveLoader), "LoadMapSaveData")] internal static class MapSaveLoader_LoadMapSaveData { [HarmonyPostfix] internal static void Postfix(Simulation sim, MapSaveDataModel mapData) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) if (mapData == null) { return; } Enumerator enumerator = mapData.placedTowers.GetEnumerator(); while (enumerator.MoveNext()) { TowerSaveDataModel current = enumerator.Current; if (current != null) { Tower towerById = sim.towerManager.GetTowerById(current.IdLastSave); ((BloonsTD6Mod)ModHelper.GetMod()).OnTowerLoaded(towerById, current); } } } } [HarmonyPatch(typeof(OverclockMutator), "Mutate")] internal static class OverclockMutator_Mutate { [HarmonyPostfix] internal static void Postfix(OverclockMutator __instance, Model model) { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Expected O, but got Unknown //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Expected O, but got Unknown TowerModel val = default(TowerModel); if (Il2CppSystemObjectExt.Is((Il2CppObjectBase)(object)model, ref val) && ((Model)(object)__instance.overclockModel).OverclockAbilityChoice() && __instance.overclockModel.isParagonMode) { OverclockModel overclockModel = __instance.overclockModel; float uptime = (float)overclockModel.paragonZoneLifespanFrames / (float)overclockModel.lifespanFrames; float multiplier = 1f / AbilityChoice.CalcAvgBonus(uptime, 1f / overclockModel.rateModifier); float additive = AbilityChoice.CalcAvgBonus(uptime, overclockModel.villageRangeModifier); TowerModel obj = val; Args val2 = new Args(); ((ModelArgs)val2).name = "Overclock"; val2.isUnique = true; val2.multiplier = multiplier; val2.additive = additive; val2.mutatorId = overclockModel.mutatorId; val2.buffLocsName = overclockModel.buffLocsName; val2.buffIconName = overclockModel.buffIconName; val2.showBuffIcon = true; val2.isCustomRadius = true; val2.customRadius = overclockModel.paragonZoneRange; TowerModelBehaviorExt.AddBehavior(obj, CreateRangeSupportModelExt.Create(val2)); } } } [HarmonyPatch(typeof(MutatorTower), "Mutate")] internal static class RangeSupport_Mutate { [HarmonyPrefix] internal static bool Prefix(MutatorTower __instance, Model baseModel, Model model, ref bool __result) { //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Expected O, but got Unknown if (((BehaviorMutator)__instance).id != "Overclock") { return true; } OverclockModel val = ModelExt.Duplicate(((Model)Game.instance.model.GetTower(TowerType.EngineerMonkey, 0, 4, 0)).GetDescendant()); val.rateModifier = __instance.multiplier; val.villageRangeModifier = __instance.additive; val.buffIconName = ((BehaviorMutator)__instance).buffIndicator.iconName; val.buffLocsName = ((BehaviorMutator)__instance).buffIndicator.buffName; OverclockMutator val2 = new OverclockMutator(val) { resultCache = ((BehaviorMutator)__instance).resultCache, limiters = ((BehaviorMutator)__instance).limiters, mutated = ((BehaviorMutator)__instance).mutated }; __result = ((BehaviorMutator)val2).Mutate(baseModel, model); return false; } } public const string Enabled = "AbilityChoiceEnabled"; internal static readonly Dictionary> Dots = new Dictionary>(); public static BehaviorMutator GetMutator(TapTowerAbilityBehavior behavior, int tier) { //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Expected O, but got Unknown //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Expected O, but got Unknown Ability ability = ((AbilityBehavior)behavior).ability; float num = (float)ability.abilityModel.cooldownFrames * (1f - ability.abilityModel.CooldownSpeedScale); Overclock val = default(Overclock); if (Il2CppSystemObjectExt.Is((Il2CppObjectBase)(object)behavior, ref val)) { OverclockModel val2 = ModelExt.Duplicate(val.overclockModel); tier = Math.Clamp(tier, 0, ((Il2CppArrayBase)(object)val2.tierBasedDurationMultiplier).Count - 1); float uptime = ((Il2CppArrayBase)(object)val2.tierBasedDurationMultiplier)[tier] * (float)val2.lifespanFrames / num; val2.rateModifier = 1f / AbilityChoice.CalcAvgBonus(uptime, 1f / val2.rateModifier); val2.villageRangeModifier = AbilityChoice.CalcAvgBonus(uptime, val2.villageRangeModifier); return (BehaviorMutator)new OverclockMutator(val2); } TakeAim val3 = default(TakeAim); if (Il2CppSystemObjectExt.Is((Il2CppObjectBase)(object)behavior, ref val3)) { TakeAimModel val4 = ModelExt.Duplicate(val3.takeAimModel); float uptime2 = (float)val4.lifespanFrames / num; val4.rangeModifier = AbilityChoice.CalcAvgBonus(uptime2, val4.rangeModifier); val4.spreadModifier = 1f / AbilityChoice.CalcAvgBonus(uptime2, 1f / val4.spreadModifier); return (BehaviorMutator)new TakeAimMutator(val4); } return null; } public static void ApplyOverclock(Tower from, Tower to, TapTowerAbilityBehavior behavior) { if (((IEnumerable)MonoLinqHelper.ToArray(((RootObject)from).Sim.factory.GetUncast())).Count(delegate(TapTowerAbilityBehavior o) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) Tower selectedTower = o.selectedTower; ObjectId? val = ((selectedTower != null) ? new ObjectId?(((RootObject)selectedTower).Id) : ((ObjectId?)null)); ObjectId id = ((RootObject)to).Id; return val.HasValue && val.GetValueOrDefault() == id; }) <= 1) { ((Mutable)to).RemoveMutatorsById(behavior.MutatorId()); } int num = to.towerModel.tier; if (to.towerModel.IsHero()) { num = (num - 1) / 4; } ((Mutable)to).AddMutator(GetMutator(behavior, num), -1, true, true, false, true, false, false, false, -1, from.IsParagonBased(), true); } internal static bool OverclockAbilityChoice(this TapTowerAbilityBehavior overclock) { return ((RootBehavior)overclock).model.OverclockAbilityChoice(); } internal static bool OverclockAbilityChoice(this AbilityModel abilityModel) { OverclockModel overclockModel = default(OverclockModel); TakeAimModel overclockModel2 = default(TakeAimModel); return (ModelExt.HasDescendant((Model)(object)abilityModel, ref overclockModel) && ((Model)(object)overclockModel).OverclockAbilityChoice()) || (ModelExt.HasDescendant((Model)(object)abilityModel, ref overclockModel2) && ((Model)(object)overclockModel2).OverclockAbilityChoice()); } internal static bool OverclockAbilityChoice(this Model overclockModel) { return overclockModel.name.Contains("AbilityChoiceEnabled"); } private static string MutatorId(this TapTowerAbilityBehavior instance) { return ((MemberInfo)((Object)instance).GetIl2CppType()).Name; } private static TechBotLink GetFakeTechBotLink(Ability __instance) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Expected O, but got Unknown //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) TapTowerAbilityBehavior behaviorInDependants = ((RootBehavior)__instance).entity.GetBehaviorInDependants(); List lineDotDisplays = default(List); if (!Dots.TryGetValue(((RootObject)((TowerBehavior)__instance).tower).Id, ref lineDotDisplays)) { List val = (Dots[((RootObject)((TowerBehavior)__instance).tower).Id] = new List()); lineDotDisplays = val; } TechBotLinkModel descendant = ((Model)Game.instance.model.GetPowerWithId(TowerType.TechBot).tower).GetDescendant(); TechBotLink val3 = new TechBotLink(); ((AbilityBehavior)val3).ability = __instance; ((RootBehavior)val3).entity = ((RootBehavior)__instance).entity; ((RootObject)val3).Sim = ((RootObject)__instance).Sim; Tower selectedTower = behaviorInDependants.selectedTower; val3.selectedTowerId = (ObjectId)((selectedTower != null) ? ((RootObject)selectedTower).Id : default(ObjectId)); val3.linkedTowers = ArrayExt.ToIl2CppList((Tower[])(object)new Tower[1] { behaviorInDependants.selectedTower }); ((RootBehavior)val3).model = (Model)(object)descendant; val3.techBotLinkModel = descendant; val3.lineDotDisplays = lineDotDisplays; return val3; } } public abstract class TowerAbilityChoice : AbilityChoice { public static readonly Dictionary Cache = new Dictionary(); public abstract string Description1 { get; } public virtual string Description2 => ""; public abstract string UpgradeId { get; } protected string DefaultDescription { get; private set; } protected TowerModel BaseTowerModel { get; private set; } protected sealed override bool HasMode2 => !string.IsNullOrEmpty(Description2); public sealed override IEnumerable Load() { yield return (ModContent)(object)this; yield return (ModContent)(object)new TowerAbilityChoiceDescription(this, 1, "[" + ((ModContent)this).Id + " Description1]"); if (HasMode2) { yield return (ModContent)(object)new TowerAbilityChoiceDescription(this, 2, "[" + ((ModContent)this).Id + " Description2]"); } } public override void Register() { base.Register(); BaseTowerModel = GetAffected(Game.instance.model).First(); Cache[UpgradeId] = this; DefaultDescription = LocalizationManager.Instance.textTable[UpgradeId + " Description"]; } public override IEnumerable GetAffected(GameModel gameModel) { return from model in ((IEnumerable)gameModel.towers).Where((TowerModel model) => ((Il2CppArrayBase)(object)model.appliedUpgrades)?.Contains(UpgradeId) ?? false).Where(AppliesTo) orderby ((Il2CppArrayBase)(object)model.appliedUpgrades).Length select model; } public static string IconForMode(int mode) { if (1 == 0) { } string result = mode switch { 1 => "Ui[NotifyRed]", 2 => "Ui[NotifyBlue]", _ => "Ui[NotificationYellow]", }; if (1 == 0) { } return result; } public override void RegisterText(Dictionary textTable) { if (!string.IsNullOrEmpty(((NamedModContent)this).DisplayName)) { textTable[((ModContent)this).Id] = ((NamedModContent)this).DisplayName; } if (!string.IsNullOrEmpty(Description1)) { textTable[((ModContent)this).Id + " Description1"] = Description1; } if (!string.IsNullOrEmpty(Description2)) { textTable[((ModContent)this).Id + " Description2"] = Description2; } } } public class TowerAbilityChoiceDescription : AbilityChoiceDescription { public override string LocalizationKey => abilityChoice.UpgradeId + " Description"; public TowerAbilityChoiceDescription(TowerAbilityChoice abilityChoice, int mode, string description) : base(abilityChoice, mode, description) { } } [RegisterTypeInIl2Cpp(false)] public class TowerAbilityChoiceInfo : MonoBehaviour { public UpgradeDetails upgradeDetails; public TowerAbilityChoice abilityChoice; public TowerAbilityChoiceInfo(IntPtr ptr) : base(ptr) { } public void UpdateIcon() { GameObject abilityObject = upgradeDetails.abilityObject; Image component = abilityObject.GetComponent(); if (abilityChoice != null) { abilityObject.SetActive(true); ImageExt.SetSprite(component, TowerAbilityChoice.IconForMode(abilityChoice.Mode)); } else { ImageExt.SetSprite(component, TowerAbilityChoice.IconForMode(0)); } } public static void Setup(params UpgradeDetails[] pathUpgrades) { foreach (UpgradeDetails val in pathUpgrades) { if (!((Behaviour)val).isActiveAndEnabled) { break; } TowerAbilityChoiceInfo towerAbilityChoiceInfo = ((Component)val.GetButton()).gameObject.GetComponent(); if ((Object)(object)towerAbilityChoiceInfo != (Object)null) { towerAbilityChoiceInfo.abilityChoice = null; } UpgradeModel upgrade = val.upgrade; string key = ((upgrade != null) ? ((Model)upgrade).name : null) ?? ""; if (TowerAbilityChoice.Cache.TryGetValue(key, out var value)) { if ((Object)(object)towerAbilityChoiceInfo == (Object)null) { towerAbilityChoiceInfo = ((Component)val.GetButton()).gameObject.AddComponent(); } towerAbilityChoiceInfo.abilityChoice = value; towerAbilityChoiceInfo.upgradeDetails = val; } if ((Object)(object)towerAbilityChoiceInfo != (Object)null) { towerAbilityChoiceInfo.UpdateIcon(); } } } } } namespace AbilityChoice.Patches { [HarmonyPatch(typeof(MutatorTower), "BuffTowerModel")] internal static class AbilityCooldownScaleSupport_BuffTowerModel { [HarmonyPostfix] internal static void Postfix(MutatorTower __instance, TowerModel towerModel) { Il2CppGenericIEnumerable.ForEach(((Model)towerModel).GetDescendants(), (Action)delegate(ActivateAbilityAfterIntervalModel i) { i.interval /= __instance.abilityCooldownSpeedScale; i.intervalFrames = Math.CeilToInt((float)i.intervalFrames / __instance.abilityCooldownSpeedScale); }); } } [HarmonyPatch(typeof(ActivateAbilityAfterInterval), "Initialise")] internal static class ActivateAbilityAfterInterval_Initialise { [HarmonyPostfix] internal static void Postfix(ActivateAbilityAfterInterval __instance) { if (((RootBehavior)__instance).model.name.Contains("TechBotify")) { Ability ability = __instance.GetAbility(); if (ability != null && !ability.abilityModel.startOffCooldown) { __instance.lastActivatedAt = ((RootObject)__instance).Sim.roundTime.elapsed; } } } } [HarmonyPatch(typeof(ActivateAbilityAfterInterval), "Process")] internal static class ActivateAbilityAfterInterval_Process { [HarmonyPrefix] internal static void Prefix(ActivateAbilityAfterInterval __instance) { if (((EntityBehavior)__instance).Model.name.Contains("TechBotify")) { Ability ability = __instance.GetAbility(); if (ability != null) { float num = ability.abilityModel.Cooldown * (1f - ability.abilityModel.CooldownSpeedScale); ActivateAbilityAfterIntervalModel activateAbilityAfterIntervalModel = __instance.activateAbilityAfterIntervalModel; activateAbilityAfterIntervalModel.interval = Math.Min(activateAbilityAfterIntervalModel.interval, num); activateAbilityAfterIntervalModel.intervalFrames = Math.Min(activateAbilityAfterIntervalModel.intervalFrames, (int)Math.Round(num * 60f)); } } } } [HarmonyPatch(typeof(DarkMutator), "Mutate")] internal static class AdoraSunGodTransformationModel_DarkMutator_Mutate { [HarmonyPostfix] private static void Postfix(Model model) { TowerModel newBall = model.GetDescendant().towerModel; Il2CppGenericIEnumerable.ForEach(model.GetDescendants(), (Action)delegate(TowerCreateTowerModel createTower) { createTower.towerModel = newBall; ((Model)createTower).name = ((Model)createTower).name + "Dark"; }); } } [HarmonyPatch(typeof(Mutator), "Mutate")] internal static class AdoraSunGodTransformationModel_Mutator_Mutate { [HarmonyPostfix] private static void Postfix(Model model) { TowerModel newBall = model.GetDescendant().towerModel; Il2CppGenericIEnumerable.ForEach(model.GetDescendants(), (Action)delegate(TowerCreateTowerModel createTower) { createTower.towerModel = newBall; ((Model)createTower).name = ((Model)createTower).name + "SunGod"; }); } } [HarmonyPatch(typeof(BottleHotSauceBehavior), "Activate")] internal static class BottleHotSauceBehavior_Activate { [HarmonyPrefix] private static bool Prefix(BottleHotSauceBehavior __instance, Vector2 location, int inputId) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) ISelectable selection = ((GeraldoItemBehavior)__instance).sim.Map.GetSelection(location, 20f); Tower val = default(Tower); if (Il2CppSystemObjectExt.Is((Il2CppObjectBase)(object)selection, ref val) && ((Mutable)val).IsMutatedBy("BottleHotSauce")) { ((Mutable)val).RemoveMutatorsById("BottleHotSauce"); Il2CppGenericIEnumerable.ForEach(((GeraldoItemBehavior)__instance).sim.towerManager.GetChildTowers(val), (Action)delegate(Tower t) { if (((EntityModel)t.towerModel).baseId == TowerType.HotSauceCreature) { ((GeraldoItemBehavior)__instance).sim.towerManager.DestroyTower(t, inputId); } }); } return true; } } [HarmonyPatch(typeof(BottleHotSauceBehavior), "IsPositionValid")] internal static class BottleHotSauceBehavior_IsPositionValid { public static bool CurrentlyChecking { get; private set; } [HarmonyPrefix] private static void Prefix(BottleHotSauceBehavior __instance) { CurrentlyChecking = true; } [HarmonyPostfix] private static void Postfix() { CurrentlyChecking = false; } } [HarmonyPatch(typeof(Mutable), "IsMutatedBy", new Type[] { typeof(string) })] internal static class Mutable_IsMutatedBy { [HarmonyPrefix] private static bool Prefix(string id, ref bool __result) { if (BottleHotSauceBehavior_IsPositionValid.CurrentlyChecking && id == "BottleHotSauce") { __result = false; return false; } return true; } } [HarmonyPatch(typeof(MutatorTower), "Mutate")] internal static class DamageSupport_Mutate { [HarmonyPrefix] internal static bool Prefix(MutatorTower __instance, Model model, ref bool __result) { if ((double)__instance.increase < 0.99) { float mult = __instance.increase + 1f; Il2CppGenericIEnumerable.ForEach(model.GetDescendants(), (Action)delegate(DamageModel damageModel) { damageModel.damage = (float)Math.Ceiling(damageModel.damage * mult); }); __result = true; return false; } return true; } } [HarmonyPatch(typeof(HeroInGameScreen), "Open")] internal static class HeroInGameScreen_Open { [HarmonyPostfix] private static void Postfix(HeroInGameScreen __instance) { HeroAbilityChoiceInfo.Setup(__instance.heroId, __instance.heroUpgrades); } } [HarmonyPatch(typeof(HeroUpgradeDetails), "BindHeroDetails")] internal static class HeroUpgradeDetails_BindDetails { [HarmonyPostfix] private static void Postfix(HeroUpgradeDetails __instance) { HeroAbilityChoiceInfo.Setup(__instance.DisplayedHeroId, __instance.heroUpgrades); } } [HarmonyPatch(typeof(SelectPointInput), "IsPositionValid")] internal static class SelectPointInput_IsPositionValid { [HarmonyPostfix] private static void Postfix(SelectPointInput __instance, Vector2 cursorPosWorld, ref bool __result) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_004e: 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_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Invalid comparison between Unknown and I4 SelectTargetCIData cii = __instance.cii; object obj; if (cii == null) { obj = null; } else { PrefabReference targetInvalidImageId = cii.targetInvalidImageId; obj = ((targetInvalidImageId != null) ? targetInvalidImageId.AssetGUID : null); } if ((string?)obj == ModContent.GetDisplayGUID()) { Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(cursorPosWorld); bool num = __result; Area areaAtPoint = InGame.instance.bridge.Simulation.Map.GetAreaAtPoint(val, (Area)null, false, false); int num2; if (areaAtPoint == null) { num2 = 0; } else { AreaModel areaModel = areaAtPoint.areaModel; num2 = (((int)((areaModel != null) ? new AreaType?(areaModel.type) : ((AreaType?)null)).GetValueOrDefault() == 1) ? 1 : 0); } __result = (byte)((num ? 1u : 0u) & (uint)num2) != 0; } } } [HarmonyPatch(typeof(SwordCharge), "HideTower")] internal static class SwordCharge_HideTower { [HarmonyPrefix] private static bool Prefix(SwordCharge __instance) { return __instance.swordChargeModel.effectAtEndModel != null; } } [HarmonyPatch(typeof(Syphon), "OnBloonCreate")] internal static class Syphon_OnBloonCreate { public static int counter; [HarmonyPrefix] private static void Prefix(Syphon __instance, Bloon bloon) { SyphonFunding behavior = ((RootBehavior)__instance).entity.GetBehavior(); if (behavior != null && !((IEnumerable)__instance.syphonModel.ignoreTags).Any((Func)bloon.HasTag)) { int num = (int)Math.Round(1f / behavior.syphonFundingModel.lifespan); __instance.syphonFunding = behavior; behavior.active = counter % num == 0; counter++; } } } [HarmonyPatch(typeof(TargetSelectedPoint), "Initialise")] internal static class TargetSelectedPoint_Initialise { [HarmonyPostfix] private static void Postfix(TargetSelectedPoint __instance, Entity target) { //IL_006c: Unknown result type (might be due to invalid IL or missing references) PrefabReference displayInvalid = __instance.targetSelectedPointModel.displayInvalid; if (!(((displayInvalid != null) ? displayInvalid.AssetGUID : null) != ModContent.GetDisplayGUID())) { Tower val = Il2CppGenericIEnumerableExt.ToList(InGame.instance.bridge.Simulation.towerManager.GetTowers()).First((Tower tower) => ((RootObject)((RootBehavior)tower).entity).Id == ((RootObject)target.Parent).Id); __instance.SetTargetPosition(Vector3Boxed.op_Implicit(((CommonBehaviorProxy)(object)val).Position), true); } } } [HarmonyPatch(typeof(UpgradeScreen), "PopulateParagon")] internal static class UpgradeScreen_PopulateParagon { [HarmonyPostfix] private static void Postfix(UpgradeScreen __instance) { string tower = __instance.currTowerId; if (((Behaviour)__instance.paragonUpgradeDetails).isActiveAndEnabled) { TowerAbilityChoiceInfo.Setup(__instance.paragonUpgradeDetails); return; } TaskScheduler.ScheduleTask((Action)delegate { TowerAbilityChoiceInfo.Setup(__instance.paragonUpgradeDetails); }, (Func)(() => ((Behaviour)__instance.paragonUpgradeDetails).isActiveAndEnabled), (Func)(() => (Object)(object)__instance == (Object)null || __instance.currTowerId != tower)); } } [HarmonyPatch(typeof(UpgradeScreen), "PopulatePath")] internal static class UpgradeScreen_PopulatePath { [HarmonyPostfix] private static void Postfix(Il2CppReferenceArray pathUpgrades) { TowerAbilityChoiceInfo.Setup(Il2CppArrayBase.op_Implicit((Il2CppArrayBase)(object)pathUpgrades)); } } } namespace AbilityChoice.Displays { public class BuffIconQuincy : ModBuffIcon { } public class ElectricShock : ModBloonOverlay { public override string BaseOverlay => "LaserShock"; public override void ModifyDisplayNode(UnityDisplayNode node) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) SpriteRenderer val = default(SpriteRenderer); MeshRenderer val2 = default(MeshRenderer); foreach (Renderer item in (Il2CppArrayBase)(object)node.genericRenderers) { if (Il2CppSystemObjectExt.Is((Il2CppObjectBase)(object)item, ref val)) { val.color = Color.yellow; } else if (Il2CppSystemObjectExt.Is((Il2CppObjectBase)(object)item, ref val2)) { RendererExt.SetMainTexture((Renderer)(object)val2, ((ModContent)this).GetTexture("ElectricShock")); } } } } public class MegaMineInvalid : ModDisplay { public override PrefabReference BaseDisplayReference => ((Model)Game.instance.model.GetTower(TowerType.WizardMonkey, 1, 2, 0)).GetDescendant().displayInvalid; } public class ParagonBomber : ModDisplay { public override string BaseDisplay => "6fb19edd78320c34caffdad31ce623cb"; public override void ModifyDisplayNode(UnityDisplayNode node) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) Animator componentInChildren = ((Component)node).GetComponentInChildren(); GameObject gameObject = ((Component)componentInChildren).gameObject; gameObject.transform.localPosition = new Vector3(0f, 0f, -25f); gameObject.AddComponent(); } } [RegisterTypeInIl2Cpp(false)] public class AnimationPauser : MonoBehaviour { public float time = 0.2f; public string animation = ""; public Animator animator; public AnimationPauser(IntPtr ptr) : base(ptr) { } private void Update() { if (animator == null) { animator = ((Component)this).GetComponent(); } animator.Play(animation, 0, time); animator.speed = 0f; } } public class ZomgTrojan : ModDisplay { public override string BaseDisplay => "0e3f0a7aad0778f41b70496a96589153"; public override float Scale => 1.2f; public override void Register() { ((ModDisplay)this).Register(); if (ModBloonOverlay.WorksOnCurrentMelonLoader) { GameData.Instance.bloonOverlays.overlayTypes["BenjaminTrojan"].assets[(BloonOverlayClass)14] = ModContent.CreatePrefabReference(); } } public override void ModifyDisplayNode(UnityDisplayNode node) { foreach (Renderer item in (Il2CppArrayBase)(object)node.genericRenderers) { item.sortingLayerName = "ZomgMoab"; } } } public class ZomgTrojanSushiBento : ModDisplay { public override string BaseDisplay => "708ed3d201495e847a0fba2b2b1e4aed"; public override float Scale => 1.2f; public override void Register() { ((ModDisplay)this).Register(); if (ModBloonOverlay.WorksOnCurrentMelonLoader) { GameData.Instance.bloonOverlays.overlayTypes["BenjaminTrojanSushiBento"].assets[(BloonOverlayClass)14] = ModContent.CreatePrefabReference(); } } public override void ModifyDisplayNode(UnityDisplayNode node) { foreach (Renderer item in (Il2CppArrayBase)(object)node.genericRenderers) { item.sortingLayerName = "ZomgMoab"; } } } } namespace AbilityChoice.Descriptions { public abstract class AbilityChoiceDescription : ModTextOverride where T : AbilityChoice { protected readonly T abilityChoice; protected readonly int mode; public sealed override string Name => ((ModContent)abilityChoice).Name; public sealed override string TextValue { get; } public override bool Active => abilityChoice.Mode == mode; protected AbilityChoiceDescription(T abilityChoice, int mode, string description) { this.abilityChoice = abilityChoice; this.mode = mode; TextValue = description; } } public class CorvusAbilityChoiceDescription : AbilityChoiceDescription { private bool lvl20; public override string LocalizationKey => ((ModContent)abilityChoice).Name + " description" + (lvl20 ? " level 20" : ""); public CorvusAbilityChoiceDescription(CorvusAbilityChoice abilityChoice, int mode, string description, bool lvl20 = false) : base(abilityChoice, mode, description) { this.lvl20 = lvl20; } } public class GeraldoAbilityChoiceDescription : AbilityChoiceDescription { private readonly int level; public override string LocalizationKey => ((TowerBasedShopItemModel)abilityChoice.GeraldoItem()).locsId + " description" + ((level > 0) ? $" level {level}" : ""); public GeraldoAbilityChoiceDescription(GeraldoAbilityChioce abilityChoice, int level, string description) : base(abilityChoice, 1, description) { this.level = level; } } public class HeroAbilityChoiceDescription : AbilityChoiceDescription { private readonly int level; public override string LocalizationKey => $"{abilityChoice.HeroId} Level {level} Description"; public HeroAbilityChoiceDescription(HeroAbilityChoice abilityChoice, int level, int mode, string description) : base(abilityChoice, mode, description) { this.level = level; } } } namespace AbilityChoice.AbilityChoices.Support.SpikeFactory { public class CarpetOfSpikes : SpikeStorm { public override string UpgradeId => "Carpet of Spikes"; public override string AbilityName => "Spike Storm"; public override string Description1 => "Regularly sets a carpet of spikes over the whole track alongside the stream."; public override string Description2 => "Regularly sets a carpet of spikes over the whole track alongside the accelerated production."; protected override void ApplyBoth(TowerModel model) { AbilityModel val = AbilityModel(model); val.isHidden = true; } } public class Spikeageddon : TowerAbilityChoice { private const float Factor = 5f; public override string UpgradeId => "SpikeFactory Paragon"; public override string Description1 => "A factory of explosive spike Bloon annihilation. Gets a 10s rate boost once per round, and occasionally creates Spikeageddons across the track."; public override string Description2 => "A factory of explosive spike Bloon annihilation. Gets a 10s rate boost once per round, and ejects a continuous stream of Spikeageddon mines along the track."; public override void Apply1(TowerModel model) { AbilityModel val = AbilityModel(model); SpikeaggedonModel behavior = AbilityModelBehaviorExt.GetBehavior(val); ProjectileModel projectileModel = behavior.projectileModel; val.Cooldown /= 5f; Il2CppGenericIEnumerable.ForEach(((Model)projectileModel).GetDescendants(), (Action)delegate(DamageModel damageModel) { damageModel.damage /= 5f; }); Il2CppGenericIEnumerable.ForEach(((Model)projectileModel).GetDescendants(), (Action)delegate(DamageModifierForTagModel tagModel) { tagModel.damageAddative /= 5f; }); TechBotify(model); } public override void Apply2(TowerModel model) { AbilityModel val = AbilityModel(model); SpikeaggedonModel behavior = AbilityModelBehaviorExt.GetBehavior(val); CreateProjectilesAlongPathWhenCloseModel descendant = ((Model)behavior).GetDescendant(); ProjectileModel descendant2 = ((Model)behavior.projectileModel).GetDescendant(); AttackModel val2 = ModelExt.Duplicate(((Il2CppArrayBase)(object)((Model)TowerModelExt.GetAbility(Game.instance.model.GetTower(TowerType.SpikeFactory, 0, 4, 0))).GetDescendant().attacks)[0], "Spikestorm"); WeaponModel val3 = ((Il2CppArrayBase)(object)val2.weapons)[0]; val3.projectile = descendant2; val3.Rate = val.Cooldown / (float)descendant.amountOfProjectilesPerPath; val3.animation = 3; TowerModelBehaviorExt.AddBehavior(model, val2); } protected override void ApplyBoth(TowerModel model) { AbilityModel ability = TowerModelExt.GetAbilities(model).First((AbilityModel a) => a.displayName == "Controlled Burst"); TechBotify(model, ability); } } public class SpikeStorm : TowerAbilityChoice { public override string UpgradeId => "Spike Storm"; public override string Description1 => "Continuously shoots out a stream of spikes over the entire track."; public override string Description2 => "Gains extremely accelerated production for the first few seconds of each round."; public override void Apply1(TowerModel model) { AbilityModel val = AbilityModel(model); Il2CppReferenceArray attacks = AbilityModelBehaviorExt.GetBehavior(val).attacks; AttackModel val2 = ModelExt.Duplicate(((Il2CppArrayBase)(object)attacks)[0]); WeaponModel val3 = ((Il2CppArrayBase)(object)val2.weapons)[0]; val3.fireBetweenRounds = false; val3.rate *= val.Cooldown / (float)((Il2CppArrayBase)(object)attacks).Length; TowerModelBehaviorExt.AddBehavior(model, val2); } public override void Apply2(TowerModel model) { StartOfRoundRateBuffModel val = default(StartOfRoundRateBuffModel); if (!TowerModelBehaviorExt.HasBehavior(model, ref val)) { val = ModelExt.Duplicate(TowerModelBehaviorExt.GetBehavior(Game.instance.model.GetTower(TowerType.SpikeFactory, 0, 0, 2))); val.modifier = 0.3f; TowerModelBehaviorExt.AddBehavior(model, val); } StartOfRoundRateBuffModel obj = val; obj.modifier /= 10f; } protected override void RemoveAbility(TowerModel model) { if (!((Il2CppArrayBase)(object)model.appliedUpgrades).Contains("Carpet of Spikes")) { base.RemoveAbility(model); } } } } namespace AbilityChoice.AbilityChoices.Support.MonkeyVillage { public class CallToArms : TowerAbilityChoice { public override string AbilityName => "Call to Arms"; public override string UpgradeId => "Call to Arms"; public override string Description1 => "Permanent weaker nearby attack speed / pierce buff."; public override string Description2 => "Permanent moderate nearby attack speed."; protected virtual bool IsGlobal => true; public override void Apply1(TowerModel model) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0055: 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_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Expected O, but got Unknown //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Expected O, but got Unknown //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Expected O, but got Unknown AbilityModel val = AbilityModel(model); CallToArmsModel behavior = AbilityModelBehaviorExt.GetBehavior(val); BuffIndicatorModel buffIndicator = ((BehaviorMutator)behavior.Mutator).buffIndicator; float num = AbilityChoice.CalcAvgBonus(behavior.Lifespan / val.Cooldown, behavior.multiplier); Args val2 = new Args(); ((ModelArgs)val2).name = ((ModContent)this).Name; val2.multiplier = 1f / num; val2.isUnique = true; val2.mutatorId = "Village:" + ((ModContent)this).Name; val2.isGlobal = IsGlobal; val2.priority = 1; val2.filters = Il2CppArrayBase.op_Implicit((Il2CppArrayBase)(object)new Il2CppReferenceArray(0L)); val2.buffLocsName = buffIndicator.buffName; val2.buffIconName = buffIndicator.iconName; val2.onlyShowBuffIfMutated = true; RateSupportModel val3 = CreateRateSupportModelExt.Create(val2); Args val4 = new Args(); ((ModelArgs)val4).name = ((ModContent)this).Name; val4.isUnique = true; val4.percentIncrease = num; val4.mutatorId = "Village:" + ((ModContent)this).Name + "2"; val4.filters = Il2CppArrayBase.op_Implicit((Il2CppArrayBase)(object)new Il2CppReferenceArray(0L)); val4.isGlobal = IsGlobal; val4.buffLocsName = buffIndicator.buffName; val4.buffIconName = buffIndicator.iconName; val4.priority = 1; val4.onlyShowBuffIfMutated = true; val4.showBuffIcon = false; PiercePercentageSupportModel val5 = CreatePiercePercentageSupportModelExt.Create(val4); TowerModelBehaviorExt.AddBehavior(model, val3); TowerModelBehaviorExt.AddBehavior(model, val5); } public override void Apply2(TowerModel model) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Expected O, but got Unknown //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Expected O, but got Unknown AbilityModel val = AbilityModel(model); CallToArmsModel behavior = AbilityModelBehaviorExt.GetBehavior(val); BuffIndicatorModel buffIndicator = ((BehaviorMutator)behavior.Mutator).buffIndicator; double num = Math.Pow(behavior.multiplier, ModSettingBool.op_Implicit(AbilityChoiceMod.MoreBalanced) ? 1.5 : 2.0); float num2 = AbilityChoice.CalcAvgBonus(behavior.Lifespan / val.Cooldown, (float)num); Args val2 = new Args(); ((ModelArgs)val2).name = "RateSupportModel_" + ((ModContent)this).Name; val2.multiplier = 1f / num2; val2.isUnique = true; val2.mutatorId = "Village:" + ((ModContent)this).Name; val2.isGlobal = IsGlobal; val2.priority = 1; val2.filters = Il2CppArrayBase.op_Implicit((Il2CppArrayBase)(object)new Il2CppReferenceArray(0L)); val2.buffLocsName = buffIndicator.buffName; val2.buffIconName = buffIndicator.iconName; val2.onlyShowBuffIfMutated = true; RateSupportModel val3 = CreateRateSupportModelExt.Create(val2); TowerModelBehaviorExt.AddBehavior(model, val3); } } public class HomelandDefense : CallToArms { public override string UpgradeId => "Homeland Defense"; public override string AbilityName => "Homeland Defense"; public override string Description1 => "Permanent global moderate attack speed / pierce buff."; public override string Description2 => "Permanent global strong attack speed buff."; protected override bool IsGlobal => true; } } namespace AbilityChoice.AbilityChoices.Support.EngineerMonkey { public class Overclock : TowerAbilityChoice { public override string UpgradeId => "Overclock"; public override string Description1 => "Modified Ability: Permanently boost (based on tier) one tower at a time."; public override string Description2 => "All towers in range are partially overclocked."; protected virtual float Multiplier => 0.3f; public override void Apply1(TowerModel model) { ModelExt.SetName(((Model)model).GetDescendant(), "AbilityChoiceEnabled"); } public override void Apply2(TowerModel model) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Expected O, but got Unknown OverclockModel behavior = AbilityModelBehaviorExt.GetBehavior(AbilityModel(model)); Args val = new Args(); ((ModelArgs)val).name = "Overclock"; val.isUnique = true; val.multiplier = 1f / AbilityChoice.CalcAvgBonus(Multiplier, 1f / behavior.rateModifier); val.additive = AbilityChoice.CalcAvgBonus(Multiplier, behavior.villageRangeModifier); val.mutatorId = behavior.mutatorId; val.buffLocsName = behavior.buffLocsName; val.buffIconName = behavior.buffIconName; val.appliesToOwningTower = true; val.showBuffIcon = true; TowerModelBehaviorExt.AddBehavior(model, CreateRangeSupportModelExt.Create(val)); } protected override void RemoveAbility(TowerModel model) { if (base.Mode2) { base.RemoveAbility(model); } } } public class ParagonOverclock : Ultraboost { private const float ParagonMultiplier = 0.3f; private const int Factor = 10; public override string UpgradeId => "EngineerMonkey Paragon"; public override string Description1 => "Monkey engineering developed to perfection. Can Overclock other Paragons (permanently, one at a time), and creates three Mega Sentries that can build their own sentries. Mega Sentries create small explosions periodically instead of on death."; public override string Description2 => "Monkey engineering developed to perfection. Nearby Paragons are partially overclocked, and creates three Mega Sentries that can build their own sentries. Mega Sentries create small explosions periodically instead of on death."; public override void Apply2(TowerModel model) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0091: 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_00a6: Expected O, but got Unknown base.Apply2(model); OverclockModel behavior = AbilityModelBehaviorExt.GetBehavior(AbilityModel(model)); Args val = new Args(); ((ModelArgs)val).name = "ParagonOverclock"; val.isUnique = true; val.multiplier = 1f / AbilityChoice.CalcAvgBonus(0.3f, 1f / behavior.rateModifier); val.additive = AbilityChoice.CalcAvgBonus(0.3f, behavior.villageRangeModifier); val.mutatorId = behavior.mutatorId; val.buffLocsName = behavior.buffLocsName; val.buffIconName = behavior.buffIconName; val.showBuffIcon = true; val.onlyAffectParagon = true; TowerModelBehaviorExt.AddBehavior(model, CreateRangeSupportModelExt.Create(val)); } protected override void ApplyBoth(TowerModel model) { //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Expected O, but got Unknown //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Expected O, but got Unknown //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Expected O, but got Unknown //IL_011c: Expected O, but got Unknown base.ApplyBoth(model); AbilityModel val = TowerModelBehaviorExt.GetBehaviors(model).First((AbilityModel a) => a.displayName == "SentryParagonSpawner"); foreach (TowerModel item in (Il2CppArrayBase)(object)((WeaponCreateTowerModel)((Model)model).GetDescendant()).towers) { ProjectileModel projectileModel = TowerModelBehaviorExt.GetBehavior(item).projectileModel; ProjectileModelBehaviorExt.GetBehavior(projectileModel).Lifespan = 0.02f; ProjectileModel projectile = ((Model)projectileModel).GetDescendant().projectile; DamageModel damageModel = ProjectileModelExt.GetDamageModel(projectile); damageModel.damage /= 10f; TowerModelBehaviorExt.RemoveBehavior(item); TowerModelBehaviorExt.RemoveBehavior(item); Args val2 = new Args(); ((ModelArgs)val2).name = "Explosion"; val2.CanSeeCamo = true; val2.range = projectile.radius; val2.weapon = CreateWeaponModelExt.Create(new Args { projectile = projectileModel, rate = val.Cooldown * 3f / 10f }); val2.targetProvider = (TargetSupplierModel)(object)CreateTargetCloseModelExt.Create(new Args { isOnSubTower = true }); TowerModelBehaviorExt.AddBehavior(item, CreateAttackModelExt.Create(val2)); } } } public class Ultraboost : Overclock { public override string UpgradeId => "Ultraboost"; public override string Description2 => "All towers in range are fully overclocked."; protected override float Multiplier => 1f; } } namespace AbilityChoice.AbilityChoices.Support.BeastHandler { public class GigaStomp : TRexStomp { public override string AbilityName => "Giga STOMP "; public override string UpgradeId => "Giganotosaurus"; public override string Description1 => "The biggest and most fierce dinosaur of them all, Giganotosaurus can shred almost any Bloon instantly and with ease. Stuns from stomping last longer. Requires 3 additional Tyrannosaurus Handlers to control."; public override string Description2 => "The biggest and most fierce dinosaur of them all, Giganotosaurus can shred almost any Bloon instantly and with ease. Stuns last longer. Requires 3 additional Tyrannosaurus Handlers to control."; } public class TRexStomp : TowerAbilityChoice { public override string AbilityName => "T Rex STOMP"; public override string UpgradeId => "Tyrannosaurus Rex"; public override string Description1 => "The Tyrannosaurus Rex's huge jaw and sharp teeth deal a ton of damage with each bite. T Rex occasionally stomps, stunning Bloons."; public override string Description2 => "The Tyrannosaurus Rex's huge jaw and sharp teeth deal a ton of damage and briefly stun bloons with each bite."; protected virtual float Factor => 5f; public override void Apply1(TowerModel model) { //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011b: 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_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Expected O, but got Unknown TowerModel towerModel = TowerModelBehaviorExt.GetBehavior(model).towerModel; AbilityModel val = AbilityModel(model); AttackModel val2 = ModelExt.Duplicate(((Il2CppArrayBase)(object)AbilityModelBehaviorExt.GetBehavior(val).attacks)[0]); ((Model)val2).name = ((Model)val2).name + "Stomp"; WeaponModel val3 = ((Il2CppArrayBase)(object)val2.weapons)[0]; val3.Rate = val.Cooldown / Factor; ProjectileModel projectile = val3.projectile; projectile.radius = Math.Min(projectile.radius, 200f); DamageModel damageModel = ProjectileModelExt.GetDamageModel(projectile); damageModel.damage /= Factor; SlowModel behavior = ProjectileModelBehaviorExt.GetBehavior(projectile); behavior.Lifespan /= Factor; foreach (SlowModifierForTagModel behavior2 in ProjectileModelBehaviorExt.GetBehaviors(projectile)) { behavior2.lifespanOverride /= Factor; } EffectModel effectModel = ModelExt.Duplicate(AbilityModelBehaviorExt.GetBehavior(val).effectModel); CreateEffectOnExhaustFractionModel val4 = CreateCreateEffectOnExhaustFractionModelExt.Create(new Args { effectModel = effectModel, fraction = 1f, durationFraction = -1f }); ProjectileModelBehaviorExt.AddBehavior(projectile, val4); TowerModelBehaviorExt.AddBehavior(towerModel, val2); } public override void Apply2(TowerModel model) { TowerModel towerModel = TowerModelBehaviorExt.GetBehavior(model).towerModel; AbilityModel val = AbilityModel(model); ProjectileModel val2 = ModelExt.Duplicate(((Model)val).GetDescendant().projectile); AttackModel attackModel = TowerModelExt.GetAttackModel(towerModel); ProjectileModel descendant = ((Model)((Il2CppArrayBase)(object)attackModel.weapons)[0].projectile).GetDescendant(); SlowModel behavior = ProjectileModelBehaviorExt.GetBehavior(val2); behavior.Lifespan /= Factor * 2f; ProjectileModelBehaviorExt.AddBehavior(descendant, behavior); foreach (SlowModifierForTagModel behavior2 in ProjectileModelBehaviorExt.GetBehaviors(val2)) { behavior2.lifespanOverride /= Factor * 2f; ProjectileModelBehaviorExt.AddBehavior(descendant, behavior2); } descendant.UpdateCollisionPassList(); } protected override AbilityModel AbilityModel(TowerModel model) { return base.AbilityModel(ModelExt.FindDescendant((Model)(object)model, TowerType.Microraptor) ?? model); } protected override void RemoveAbility(TowerModel model) { base.RemoveAbility(ModelExt.FindDescendant((Model)(object)model, TowerType.Microraptor) ?? model); } } } namespace AbilityChoice.AbilityChoices.Support.BananaFarm { public class IMFLoan : TowerAbilityChoice { public override string UpgradeId => "IMF loan"; public override string AbilityName => UpgradeId; public override string Description1 => "Periodically gives you $10,000 that has to be paid back over time."; public override string Description2 => "Bank capacity is increased to ~$20,000"; public override void Apply1(TowerModel model) { TechBotify(model); } public override void Apply2(TowerModel model) { BankModel behavior = TowerModelBehaviorExt.GetBehavior(model); behavior.capacity += 7500f; } protected override void RemoveAbility(TowerModel model) { if (base.Mode2) { base.RemoveAbility(model); } } } public class MonkeyNomics : TowerAbilityChoice { public override string UpgradeId => "Monkey-Nomics"; public override string AbilityName => UpgradeId; public override string Description1 => "For when you're too big to fail... such that you periodically get $10,000."; public override string Description2 => "For when you're too big to fail... such that Bank Capacity becomes ~$100,000"; public override void Apply1(TowerModel model) { TechBotify(model); } public override void Apply2(TowerModel model) { BankModel behavior = TowerModelBehaviorExt.GetBehavior(model); behavior.capacity += 87500f; } protected override void RemoveAbility(TowerModel model) { if (base.Mode2) { base.RemoveAbility(model); } } } } namespace AbilityChoice.AbilityChoices.Primary.TackShooter { public class BladeMaelstrom : TowerAbilityChoice { public override string UpgradeId => "Blade Maelstrom"; public override string Description1 => "Shoots out a slow swirl of global, high pierce blades."; public override string Description2 => "Blades have additional range and pierce, and seek out Bloons on their own."; protected virtual int Pierce => 6; protected virtual float Lifespan => 4f; public override void Apply1(TowerModel model) { AbilityModel val = AbilityModel(model); ActivateAttackModel behavior = AbilityModelBehaviorExt.GetBehavior(val); AttackModel val2 = ModelExt.Duplicate(((Il2CppArrayBase)(object)behavior.attacks)[0]); float num = behavior.Lifespan / val.Cooldown; WeaponModel obj = ((Il2CppArrayBase)(object)val2.weapons)[0]; obj.Rate /= num; SpinModel descendant = ((Model)val2).GetDescendant(); descendant.rotationPerFrame *= num; SpinModel descendant2 = ((Model)val2).GetDescendant(); descendant2.rotationPerSecond *= num; TowerModelBehaviorExt.AddBehavior(model, val2); } public override void Apply2(TowerModel model) { model.range += 9f; AttackModel attackModel = TowerModelExt.GetAttackModel(model); attackModel.range += 9f; TowerModel tower = Game.instance.model.GetTower(TowerType.MonkeyAce, 0, 0, 3); AdoraTrackTargetModel val = ModelExt.Duplicate(((Model)tower).GetDescendant()); ProjectileModel projectile = TowerModelExt.GetWeapon(model).projectile; ProjectileModelBehaviorExt.AddBehavior(projectile, val); projectile.pierce += (float)Pierce; TravelStraitModel behavior = ProjectileModelBehaviorExt.GetBehavior(projectile); behavior.Lifespan *= Lifespan; } } public class MeteorImpact : TowerAbilityChoice { private const int Factor = 5; public override string UpgradeId => "TackShooter Paragon"; public override string Description1 => "Spinning blades of Bloon immolation! Occasionally launches a Meteor at the strongest Bloon, sometimes shoots jets of flame with increased projectile lifespan."; public override string Description2 => "Spinning blades of Bloon immolation! Constantly shoots homing fireballs, sometimes shoots jets of flame with increased projectile lifespan."; public override void Apply1(TowerModel model) { AbilityModel val = AbilityModel(model); AttackModel descendant = ((Model)val).GetDescendant(); Il2CppGenericIEnumerable.ForEach(((Model)descendant).GetDescendants(), (Action)delegate(DamageModel damageModel) { damageModel.damage /= 5f; }); val.Cooldown /= 5f; EffectModel effectModel = ((Model)descendant).GetDescendant().effectModel; effectModel.scale /= 2f; ProjectileModel projectile = ((Model)descendant).GetDescendant().projectile; projectile.radius /= 2f; ((Il2CppArrayBase)(object)descendant.weapons)[0].Rate = val.Cooldown; TowerModelBehaviorExt.AddBehavior(model, descendant); } public override void Apply2(TowerModel model) { //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Expected O, but got Unknown //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Expected O, but got Unknown AbilityModel val = AbilityModel(model); AttackModel descendant = ((Model)val).GetDescendant(); Il2CppGenericIEnumerable.ForEach(((Model)descendant).GetDescendants(), (Action)delegate(DamageModel damageModel) { damageModel.damage /= 5f; }); CreateProjectileOnExhaustFractionModel descendant2 = ((Model)descendant).GetDescendant(); ProjectileModel val2 = ModelExt.Duplicate(descendant2.projectile); ProjectileModelBehaviorExt.RemoveBehavior(descendant2.projectile); val2.pierce *= 100f; DamageModel descendant3 = ((Model)val2).GetDescendant(); descendant3.damage /= 2f; AttackModel attackModel = TowerModelExt.GetAttackModel(model); Args val3 = new Args(); ((ModelArgs)(object)val3).name = "Fireballs"; val3.animation = -1; val3.eject = new Vector3(0f, 0f, 23f); val3.rate = val.Cooldown / 25f; val3.emission = ModelExt.Duplicate(descendant2.emission); val3.projectile = descendant2.projectile; val3.behaviors = (Model[])(object)new Model[1] { (Model)CreateAlternateProjectileModelExt.Create(new Args { projectile = val2, emissionModel = ModelExt.Duplicate(descendant2.emission), interval = 5 }) }; AttackModelExt.AddWeapon(attackModel, CreateWeaponModelExt.Create(val3)); } protected override void ApplyBoth(TowerModel model) { AbilityModel val = TowerModelExt.GetAbilities(model).First((AbilityModel a) => a.displayName == "Eruption"); AbilityModelBehaviorExt.RemoveBehavior(val); val.Cooldown /= 5f; ActivateAttackModel descendant = ((Model)val).GetDescendant(); descendant.Lifespan /= 5f; TechBotify(model, val); } } public class SuperMaelstrom : BladeMaelstrom { public override string UpgradeId => "Super Maelstrom"; public override string Description1 => "Shoots out a faster and larger swirl of global, high pierce blades."; public override string Description2 => "Shoots out more homing blades with increased range and pierce."; protected override int Pierce => 9; protected override float Lifespan => 16f; public override void Apply1(TowerModel model) { base.Apply1(model); if (base.Mode2) { ArcEmissionModel descendant = ((Model)model).GetDescendant(); descendant.count *= 2; model.range += 11f; AttackModel attackModel = TowerModelExt.GetAttackModel(model); attackModel.range += 11f; } } } } namespace AbilityChoice.AbilityChoices.Primary.IceMonkey { public class AbsoluteZero : Snowstorm { public override string UpgradeId => "Absolute Zero"; public override string Description1 => "Periodically freezes all Bloons on screen for 2s. Also globally buffs the attack speed of Ice Monkeys."; public override string Description2 => "Cold Aura slows MOABs even further. Also globally buffs the attack speed of Ice Monkeys."; protected override int Factor => 5; public override void Apply2(TowerModel model) { base.Apply2(model); SlowBloonsZoneModel obj = TowerModelBehaviorExt.GetBehaviors(model).Last(); obj.speedScale -= 0.1f; } protected override void ApplyBoth(TowerModel model) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008b: 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 AbilityModel val = AbilityModel(model); ActivateRateSupportZoneModel behavior = AbilityModelBehaviorExt.GetBehavior(val); float num = AbilityChoice.CalcAvgBonus(behavior.lifespan / val.Cooldown, 1f / behavior.rateModifier); Args val2 = new Args(); ((ModelArgs)(object)val2).name = "AbilityChoice"; val2.multiplier = 1f / num; val2.isUnique = true; val2.mutatorId = "AbsoluteZeroRateBuff2"; val2.isGlobal = true; val2.priority = 1; TowerFilterModel[] array = new TowerFilterModel[1]; Args val3 = new Args(); val3.baseIds = Il2CppArrayBase.op_Implicit((Il2CppArrayBase)new Il2CppStringArray(new string[1] { TowerType.IceMonkey })); array[0] = (TowerFilterModel)CreateFilterInBaseTowerIdModelExt.Create(val3); val2.filters = Il2CppArrayBase.op_Implicit((Il2CppArrayBase)(object)new Il2CppReferenceArray((TowerFilterModel[])(object)array)); val2.buffLocsName = ((AbilityBehaviorBuffModel)behavior).buffLocsName; val2.buffIconName = ((AbilityBehaviorBuffModel)behavior).buffIconName; val2.maxStackSize = 2; val2.appliesToOwningTower = true; RateSupportModel val4 = CreateRateSupportModelExt.Create(val2); TowerModelBehaviorExt.AddBehavior(model, val4); } } public class EclipseOfFimbulwinter : TowerAbilityChoice { public const int Factor = 5; public override string UpgradeId => "IceMonkey Paragon"; public override string AbilityName => "Eclipse of Fimbulwinter"; public override string Description1 => "As the eternal frost descends and cold reigns supreme, even the baddest of Bloons are helpless against its icy grasp. Periodically freezes and slows all Bloons, even BADs and Bosses somewhat, and the first Boss skull each tier is nullified."; public override string Description2 => "As the eternal frost descends and cold reigns supreme, even the baddest of Bloons are helpless against its icy grasp. All Bloons are permanently slowed, even BADs and Bosses somewhat."; public override void Apply1(TowerModel model) { AbilityModel val = AbilityModel(model); val.maxActivationsPerRound = -1; AbilityModelBehaviorExt.RemoveBehavior(val); AbilityModelBehaviorExt.RemoveBehavior(val); AbilityModelBehaviorExt.RemoveBehavior(val); CreateProjectileOnAbilityActivateModel behavior = AbilityModelBehaviorExt.GetBehavior(val); ProjectileModel descendant = ((Model)behavior.projectile).GetDescendant(); ((Model)behavior).RemoveChildDependant(behavior.projectile); ((Model)behavior).AddChildDependant(descendant); behavior.projectile = descendant; ProjectileModelBehaviorExt.RemoveBehavior(descendant); Il2CppGenericIEnumerable.ForEach(((Model)val).GetDescendants(), (Action)delegate(ActivateSlowZoneOnAbilityModel slow) { slow.lifetime /= 5f; }); Il2CppGenericIEnumerable.ForEach(((Model)val).GetDescendants(), (Action)delegate(FreezeModel freeze) { freeze.Lifespan /= 5f; }); Il2CppGenericIEnumerable.ForEach(((Model)val).GetDescendants(), (Action)delegate(SlowModel slow) { slow.Lifespan /= 5f; }); val.Cooldown /= 5f; Il2CppGenericIEnumerable.ForEach(((Model)model).GetDescendants(), (Action)delegate(AddHeatToBloonModel heat) { heat.heatAmount *= 2f; }); } public override void Apply2(TowerModel model) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008c: 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_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Expected O, but got Unknown AbilityModel val = AbilityModel(model); foreach (ActivateSlowZoneOnAbilityModel behavior in AbilityModelBehaviorExt.GetBehaviors(val)) { Args val2 = new Args(); ((ModelArgs)val2).name = ((Model)behavior).name.Replace("ActivateSlowZoneOnAbilityModel", "SlowBloonsZoneModel"); val2.zoneRadius = behavior.zoneRadius; val2.mutationId = behavior.mutationId; val2.isUnique = behavior.isUnique; val2.filters = Il2CppArrayBase.op_Implicit((Il2CppArrayBase)(object)behavior.filters); val2.speedScale = behavior.speedScale; val2.speedChange = behavior.speedChange; val2.bindRadiusToTowerRange = behavior.bindRadiusToTowerRange; val2.radiusOffset = behavior.radiusOffset; val2.bloonTag = behavior.bloonTag; val2.bloonTags = Il2CppArrayBase.op_Implicit((Il2CppArrayBase)(object)behavior.bloonTags); val2.inclusive = behavior.inclusive; TowerModelBehaviorExt.AddBehavior(model, CreateSlowBloonsZoneModelExt.Create(val2)); } } protected override void RemoveAbility(TowerModel model) { if (base.Mode2) { base.RemoveAbility(model); } else { TechBotify(model); } } } public class Snowstorm : TowerAbilityChoice { public override string UpgradeId => "Snowstorm"; public override string Description1 => "Periodically freezes all Bloons on screen for 1s."; public override string Description2 => "Cold aura can partially slows MOAB class bloons."; protected virtual int Factor => 6; public override void Apply1(TowerModel model) { AbilityModel val = AbilityModel(model); ActivateAttackModel behavior = AbilityModelBehaviorExt.GetBehavior(val); AttackModel val2 = ModelExt.Duplicate(((Il2CppArrayBase)(object)behavior.attacks)[0]); WeaponModel val3 = ((Il2CppArrayBase)(object)val2.weapons)[0]; val3.Rate = val.Cooldown / (float)Factor; ProjectileModel projectile = val3.projectile; FreezeModel behavior2 = ProjectileModelBehaviorExt.GetBehavior(projectile); behavior2.Lifespan /= (float)Factor; TowerModelBehaviorExt.AddBehavior(model, val2); } public override void Apply2(TowerModel model) { SlowBloonsZoneModel behavior = TowerModelBehaviorExt.GetBehavior(model); TowerModel towerFromId = Game.instance.model.GetTowerFromId("NaturesWardTotem"); SlowBloonsZoneModel val = ModelExt.Duplicate(TowerModelBehaviorExt.GetBehaviors(towerFromId).First((SlowBloonsZoneModel b) => !((Model)b).name.Contains("NonMoabs"))); val.zoneRadius = behavior.zoneRadius; val.bindRadiusToTowerRange = true; val.radiusOffset = behavior.radiusOffset; TowerModelBehaviorExt.AddBehavior(model, val); } } } namespace AbilityChoice.AbilityChoices.Primary.GlueGunner { public class GlueStorm : GlueStrike { public override string UpgradeId => "Glue Storm"; public override string Description1 => "Frequently glues all bloons on screen, making them take increased damage."; public override string Description2 => "Glue weakens and slows Bloons further. Range is increased."; protected override float Factor => 7.5f; public override void Apply2(TowerModel model) { base.Apply2(model); model.range *= 1.5f; AttackModel attackModel = TowerModelExt.GetAttackModel(model); attackModel.range *= 1.5f; WeaponModel weapon = TowerModelExt.GetWeapon(model); weapon.rate /= 1.5f; } } public class GlueStrike : TowerAbilityChoice { public override string UpgradeId => "Glue Strike"; public override string Description1 => "Periodically glues all bloons on screen for a short duration, making them take increased damage."; public override string Description2 => "Glue weakens Bloons, making them take increased damage and be vulnerable to Sharp sources."; protected virtual float Factor => 5f; public override void Apply1(TowerModel model) { AbilityModel val = AbilityModel(model); ActivateAttackModel behavior = AbilityModelBehaviorExt.GetBehavior(val); AttackModel val2 = ModelExt.Duplicate(((Il2CppArrayBase)(object)behavior.attacks)[0]); WeaponModel val3 = ((Il2CppArrayBase)(object)val2.weapons)[0]; val3.Rate = val.Cooldown / Factor; ProjectileModel projectile = val3.projectile; SlowModel behavior2 = ProjectileModelBehaviorExt.GetBehavior(projectile); behavior2.Lifespan /= Factor; RemoveDamageTypeModifierModel behavior3 = ProjectileModelBehaviorExt.GetBehavior(projectile); behavior3.lifespan /= Factor; AddBonusDamagePerHitToBloonModel behavior4 = ProjectileModelBehaviorExt.GetBehavior(projectile); behavior4.lifespan /= Factor; TowerModelBehaviorExt.AddBehavior(model, val2); } public override void Apply2(TowerModel model) { AbilityModel val = AbilityModel(model); AddBonusDamagePerHitToBloonModel descendant = ((Model)val).GetDescendant(); RemoveDamageTypeModifierModel descendant2 = ((Model)val).GetDescendant(); SlowModel descendant3 = ((Model)val).GetDescendant(); foreach (ProjectileModel item in Il2CppGenericIEnumerableExt.ToList(((Model)TowerModelExt.GetWeapon(model)).GetDescendants())) { if (descendant != null) { AddBonusDamagePerHitToBloonModel val2 = ModelExt.Duplicate(descendant); if (model.tier < 5 && ModSettingBool.op_Implicit(AbilityChoiceMod.MoreBalanced)) { val2.perHitDamageAddition = Math.Min(1f, val2.perHitDamageAddition); } ProjectileModelBehaviorExt.AddBehavior(item, val2); } if (descendant2 != null) { ProjectileModelBehaviorExt.AddBehavior(item, ModelExt.Duplicate(descendant2)); } SlowModel behavior = ProjectileModelBehaviorExt.GetBehavior(item); if (behavior != null) { behavior.lifespan = descendant3.lifespan; behavior.layers = descendant3.layers; behavior.multiplier = descendant3.multiplier; } } } } } namespace AbilityChoice.AbilityChoices.Primary.Desperado { public class MarkedToPop : TowerAbilityChoice { private const float Chance = 0.5f; public override string UpgradeId => "Bounty Hunter"; public override string Description1 => "Periodically Mark Bloons and make extra Execute attacks against Marked Bloons. Marked Bloons take more damage and give more cash. All Desperados can target Marked Bloons. "; public override string Description2 => "Desperado's main attacks have a chance to Mark Bloons for Execution. Marked Bloons take more damage and give more cash. All Desperados can target Marked Bloons. "; public override void Apply1(TowerModel model) { AbilityModel val = AbilityModel(model); MarkedToPopModel behavior = AbilityModelBehaviorExt.GetBehavior(val); AttackModel val2 = ModelExt.Duplicate(behavior.markingAttackModel); ((Il2CppArrayBase)(object)val2.weapons)[0].Rate = val.Cooldown / ((float)behavior.markingTimeFrames / (((Il2CppArrayBase)(object)behavior.markingAttackModel.weapons)[0].Rate * 60f)); TowerModelBehaviorExt.AddBehavior(model, val2); AttackModel val3 = ModelExt.Duplicate(behavior.executionAttackModel); ((Il2CppArrayBase)(object)val3.weapons)[0].Rate = val.Cooldown / ((float)behavior.executionTimeMaxFrames / (((Il2CppArrayBase)(object)behavior.executionAttackModel.weapons)[0].Rate * 60f)); TowerModelBehaviorExt.AddBehavior(model, val3); } public override void Apply2(TowerModel model) { AbilityModel val = AbilityModel(model); MarkedToPopModel behavior = AbilityModelBehaviorExt.GetBehavior(val); foreach (AttackModel attackModel in TowerModelExt.GetAttackModels(model)) { foreach (ProjectileModel item in ((IEnumerable)MonoLinqHelper.ToArray(((Model)attackModel).GetDescendants())).Where((ProjectileModel p) => ProjectileModelExt.GetDamageModel(p) != null)) { AddBehaviorToBloonModel val2 = ModelExt.Duplicate(((Model)behavior.markingAttackModel).GetDescendant()); val2.chance = 0.5f; ProjectileModelBehaviorExt.AddBehavior(item, val2); } } } } public class MarkedToPop2 : MarkedToPop { public override string UpgradeId => "Golden Justice"; public override string Description1 => "They say Desperado's longarm can hit clean through an army of Bloons. Still periodically Marks Bloons and makes extra Execute attacks against Marked Bloons."; public override string Description2 => "They say Desperado's longarm can hit clean through an army of Bloons. Desperado's main attacks still have a chance to Mark Bloons for Execution. "; } public class TakeAim : TowerAbilityChoice { public override string UpgradeId => "Deadeye"; public override string Description1 => "Modified Ability: Permanently boost one tower at a time. Desperado gains a long range rifle to use against distant targets. Rifle shots excel against Fortified targets and can pop Lead Bloons. "; public override string Description2 => "All towers in range have camo detection and slightly increased attack range. Desperado gains a long range rifle to use against distant targets. Rifle shots excel against Fortified targets and can pop Lead Bloons. "; protected virtual float Multiplier => 0.05f; public override string BackUpAbilityName => "TakeAim2"; public override void Apply1(TowerModel model) { ModelExt.SetName(((Model)model).GetDescendant(), "AbilityChoiceEnabled"); } public override void Apply2(TowerModel model) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Expected O, but got Unknown //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Expected O, but got Unknown TakeAimModel behavior = AbilityModelBehaviorExt.GetBehavior(AbilityModel(model)); float range = TowerModelExt.GetAttackModel(model, "Rifle").range; TowerModelBehaviorExt.AddBehavior(model, CreateRangeSupportModelExt.Create(new Args { isUnique = true, multiplier = Multiplier, mutatorId = ((BehaviorMutator)behavior.Mutator).saveId, buffLocsName = behavior.buffLocsName, buffIconName = behavior.buffIconName, appliesToOwningTower = true, showBuffIcon = true, isCustomRadius = true, customRadius = range })); TowerModelBehaviorExt.AddBehavior(model, CreateVisibilitySupportModelExt.Create(new Args { isUnique = true, mutatorId = ((BehaviorMutator)behavior.Mutator).saveId + "2", buffLocsName = behavior.buffLocsName, buffIconName = behavior.buffIconName, showBuffIcon = true, isCustomRadius = true, customRadius = range })); } protected override void RemoveAbility(TowerModel model) { if (base.Mode2) { base.RemoveAbility(model); } } } } namespace AbilityChoice.AbilityChoices.Primary.DartMonkey { public class PlasmaMonkeyFanClub : SuperMonkeyFanClub { public override string UpgradeId => "Plasma Monkey Fan Club"; public override string Description1 => "5+ nearby Dart Monkeys including itself are permanently Plasma Monkey Fans."; public override string Description2 => "Permanently shoots powerful plasma blasts itself."; protected override float SuperMonkeyAttackSpeed => 0.03f; public override void Apply2(TowerModel model) { base.Apply2(model); if (!base.Mode2) { return; } ProjectileModel projectile = TowerModelExt.GetWeapon(Game.instance.model.GetTower(TowerType.SuperMonkey, 2, 0, 0)).projectile; foreach (ProjectileModel item in from weaponProjectile in Il2CppGenericIEnumerableExt.ToList(((Model)model).GetDescendants()) where !string.IsNullOrEmpty(weaponProjectile.display.AssetGUID) select weaponProjectile) { item.display = projectile.display; ProjectileModelBehaviorExt.GetBehavior(item).display = projectile.display; DamageModel damageModel = ProjectileModelExt.GetDamageModel(item); damageModel.damage += 2f; ProjectileModelExt.GetDamageModel(item).immuneBloonProperties = (BloonProperties)8; ProjectileModelExt.GetDamageModel(item).immuneBloonPropertiesOriginal = (BloonProperties)8; item.pierce += 5f; } } } public class SuperMonkeyFanClub : TowerAbilityChoice { [HarmonyPatch(typeof(MonkeyFanClub), "UpdatedModel")] internal static class MonkeyFanClub_UpdatedModel { [HarmonyPrefix] internal static void Prefix(MonkeyFanClub __instance, Model modelToUse) { SuperMonkeyFanClub superMonkeyFanClub = (__instance.isPlasma ? ModContent.GetInstance() : ModContent.GetInstance()); if (superMonkeyFanClub.Mode == 1) { MonkeyFanClubModel model = ((Il2CppObjectBase)modelToUse).Cast(); AbilityModel abilityModel = ((Model)((TowerBehavior)((AbilityBehavior)__instance).ability).tower.towerModel).GetDescendant().abilityModel; superMonkeyFanClub.ModifyModel(model, abilityModel); } } } [HarmonyPatch(typeof(MonkeyFanClub), "Activate")] internal static class MonkeyFanClub_Activate { [HarmonyPrefix] internal static bool Prefix(MonkeyFanClub __instance) { SuperMonkeyFanClub superMonkeyFanClub = (__instance.isPlasma ? ModContent.GetInstance() : ModContent.GetInstance()); if (superMonkeyFanClub.Mode != 1) { return true; } MonkeyFanClubModel fanClubModel = __instance.monkeyFanClubModel; AbilityModel abilityModel = ((Model)((TowerBehavior)((AbilityBehavior)__instance).ability).tower.towerModel).GetDescendant().abilityModel; superMonkeyFanClub.ModifyModel(fanClubModel, abilityModel); Tower[] array = ((IEnumerable)MonoLinqHelper.ToArray(((RootObject)__instance).Sim.towerManager.GetClosestTowers(((CommonBehaviorProxy)(object)((TowerBehavior)((AbilityBehavior)__instance).ability).tower).Position, -1, (TowerFilter)null))).Where((Tower tower) => tower != ((TowerBehavior)((AbilityBehavior)__instance).ability).tower && !((CommonBehaviorProxy)(object)tower).IsSuspended && ((EntityModel)tower.towerModel).baseId == ((EntityModel)((TowerBehavior)((AbilityBehavior)__instance).ability).tower.towerModel).baseId && ((Il2CppArrayBase)(object)tower.towerModel.tiers)[0] <= fanClubModel.maxTier && ((Il2CppArrayBase)(object)tower.towerModel.tiers)[1] <= 4 && ((Il2CppArrayBase)(object)tower.towerModel.tiers)[2] <= fanClubModel.maxTier && !((IEnumerable)fanClubModel.ignoreWithMutatorsList).Any((Func)((Mutable)tower).IsMutatedBy) && (__instance.isPlasma || ((Mutable)tower).GetMutatorById("MonkeyFanClubPlasma") == null)).Prepend(((TowerBehavior)((AbilityBehavior)__instance).ability).tower).ToArray(); TimedMutator[] array2 = (from tower in array.Take(fanClubModel.towerCount) select ((Mutable)tower).GetMutatorById(__instance.mutatorId) into mutator where mutator != null select mutator).ToArray(); if ((array2.Length == fanClubModel.towerCount || array2.Length == array.Length) && array2.Skip(1).All((TimedMutator mutator) => mutator.mutator == __instance.mutator)) { TimedMutator[] array3 = array2; foreach (TimedMutator val in array3) { val.totalDuration = fanClubModel.lifespanFrames; val.removeAt = fanClubModel.lifespanFrames; } return false; } Tower[] array4 = array; foreach (Tower val2 in array4) { TimedMutator mutatorById = ((Mutable)val2).GetMutatorById(__instance.mutatorId); if (mutatorById != null && (mutatorById.mutator == __instance.mutator || val2 == ((TowerBehavior)((AbilityBehavior)__instance).ability).tower)) { ((Mutable)val2).RemoveMutator(mutatorById.mutator); } } return true; } } private const int Factor = 10; private MonkeyFanClubModel baseModel; public override string UpgradeId => "Super Monkey Fan Club"; public override string Description1 => "3+ nearby Dart Monkeys including itself are permanently Super Monkey fans."; public override string Description2 => "Gains permanent Super attack speed and range itself."; protected virtual float SuperMonkeyAttackSpeed => 0.06f; public MonkeyFanClubModel BaseModel => baseModel ?? (baseModel = AbilityModelBehaviorExt.GetBehavior(AbilityModel(GetAffected(Game.instance.model).MinBy((TowerModel model) => ((IEnumerable)model.tiers).Sum())))); public override void Apply1(TowerModel model) { AbilityModel val = AbilityModel(model); MonkeyFanClubModel behavior = AbilityModelBehaviorExt.GetBehavior(val); val.Cooldown /= 10f; ModifyModel(behavior, val); behavior.effectOnOtherId = ModContent.CreatePrefabReference(""); behavior.effectModel.assetId = ModContent.CreatePrefabReference(""); behavior.otherDisplayModel.display = ModContent.CreatePrefabReference(""); behavior.endDisplayModel.effectModel.assetId = ModContent.CreatePrefabReference(""); AbilityModelBehaviorExt.RemoveBehavior(val); AbilityModelBehaviorExt.RemoveBehavior(val); } public override void Apply2(TowerModel model) { float rate = TowerModelExt.GetWeapon(base.BaseTowerModel).Rate; WeaponModel weapon = TowerModelExt.GetWeapon(model); weapon.rate *= SuperMonkeyAttackSpeed / rate; model.range += 8f; AttackModel obj = TowerModelExt.GetAttackModels(model)[0]; obj.range += 8f; foreach (ProjectileModel item in from projectileModel in Il2CppGenericIEnumerableExt.ToList(((Model)model).GetDescendants()) where !string.IsNullOrEmpty(projectileModel.display.AssetGUID) select projectileModel) { TravelStraitModel behavior = ProjectileModelBehaviorExt.GetBehavior(item); behavior.lifespan *= 2f; TravelStraitModel behavior2 = ProjectileModelBehaviorExt.GetBehavior(item); behavior2.lifespanFrames *= 2; } } protected override void RemoveAbility(TowerModel model) { if (base.Mode2) { base.RemoveAbility(model); } else { TechBotify(model); } } public void ModifyModel(MonkeyFanClubModel model, AbilityModel ability) { model.lifespanFrames = (int)Math.Round((float)AbilityModelExt.EffectiveCooldownFrames(ability)) + 2; model.lifespan = (float)model.lifespanFrames / 60f; model.towerCount = Math.RoundToNearestInt((float)BaseModel.towerCount * BaseModel.lifespan / (AbilityModelExt.EffectiveCooldown(ability) * 10f), 1); } } } namespace AbilityChoice.AbilityChoices.Primary.BoomerangMonkey { public class Overcharge : TowerAbilityChoice { private const int Factor = 3; public override string UpgradeId => "BoomerangMonkey Paragon"; public override string Description1 => "The Bloons will look upon my Glaives, and they will know fear. Periodically overcharges its own attack speed, with the bonus tapering off over 10 seconds."; public override string Description2 => "The Bloons will look upon my Glaives, and they will know fear. Buffs the attack speed of all primary towers, including itself and other paragons, by 25% instead of 11%."; public override void Apply1(TowerModel model) { AbilityModel val = AbilityModel(model); val.Cooldown /= 3f; AbilityModelBehaviorExt.RemoveBehavior(val); OverchargeModel behavior = AbilityModelBehaviorExt.GetBehavior(val); behavior.durationPerStack /= 3f; TechBotify(model); } public override void Apply2(TowerModel model) { foreach (RateSupportModel behavior in TowerModelBehaviorExt.GetBehaviors(model)) { ((SupportModel)behavior).appliesToOwningTower = true; behavior.multiplier = 0.8f; } } } public class PermaCharge : TowerAbilityChoice { public override string UpgradeId => "Perma Charge"; public override string Description1 => "Perma Charge has permanent super fast attack speed, and a moderate damage increase."; public override string Description2 => "Perma Charge has permanent super fast attack speed, and an even more powerful shock effect."; public override void Apply1(TowerModel model) { AbilityModel val = AbilityModel(model); DamageUpModel behavior = AbilityModelBehaviorExt.GetBehavior(val); DamageModel damageModel = ProjectileModelExt.GetDamageModel(TowerModelExt.GetWeapon(model).projectile); float num = AbilityChoice.CalcAvgBonus((float)behavior.lifespanFrames / (float)val.cooldownFrames, ((float)behavior.additionalDamage + damageModel.damage) / damageModel.damage); damageModel.damage += num; } public override void Apply2(TowerModel model) { AbilityModel val = AbilityModel(model); DamageUpModel behavior = AbilityModelBehaviorExt.GetBehavior(val); DamageModel damageModel = ProjectileModelExt.GetDamageModel(TowerModelExt.GetWeapon(model).projectile); float num = AbilityChoice.CalcAvgBonus((float)behavior.lifespanFrames / (float)val.cooldownFrames, ((float)behavior.additionalDamage + damageModel.damage) / damageModel.damage); ProjectileModel projectile = TowerModelExt.GetWeapon(model).projectile; TowerModel tower = Game.instance.model.GetTower(TowerType.DartlingGunner, 2, 0, 0); ProjectileModel projectile2 = TowerModelExt.GetWeapon(tower).projectile; AddBehaviorToBloonModel val2 = ModelExt.Duplicate(ProjectileModelBehaviorExt.GetBehavior(projectile2)); MiscModelExt.ApplyOverlay((ProjectileBehaviorWithOverlayModel)(object)val2); val2.mutationId = "ElectricShock"; val2.lifespan = 5f; ProjectileModelBehaviorExt.AddBehavior(projectile, val2); DamageModifierForBloonStateModel val3 = ModelExt.Duplicate(ProjectileModelBehaviorExt.GetBehavior(projectile2)); val3.bloonState = "ElectricShock"; val3.bloonStates = Il2CppStringArray.op_Implicit(new string[1] { "ElectricShock" }); val3.damageAdditive += num - 1f; ProjectileModelBehaviorExt.AddBehavior(projectile, val3); projectile.collisionPasses = Il2CppStructArray.op_Implicit(new int[2] { 0, 1 }); } } public class TurboCharge : TowerAbilityChoice { public override string UpgradeId => "Turbo Charge"; public override string Description1 => "Significantly increased attack speed."; public override string Description2 => "Moderate attack speed increase, and boomerangs shock Bloons."; public override void Apply1(TowerModel model) { AbilityModel val = AbilityModel(model); TurboModel behavior = AbilityModelBehaviorExt.GetBehavior(val); float damage = ProjectileModelExt.GetDamageModel(TowerModelExt.GetWeapon(model).projectile).damage; float num = AbilityChoice.CalcAvgBonus(behavior.Lifespan / val.Cooldown, (damage + (float)behavior.extraDamage + 1f) / (damage + 1f) / behavior.multiplier); WeaponModel weapon = TowerModelExt.GetWeapon(model); weapon.Rate /= num; } public override void Apply2(TowerModel model) { AbilityModel val = AbilityModel(model); TurboModel behavior = AbilityModelBehaviorExt.GetBehavior(val); ProjectileModel projectile = TowerModelExt.GetWeapon(model).projectile; DamageModel damageModel = ProjectileModelExt.GetDamageModel(projectile); float damage = damageModel.damage; float num = (damage + (float)behavior.extraDamage) / damage; float num2 = AbilityChoice.CalcAvgBonus(behavior.Lifespan / val.Cooldown, (damage + (float)behavior.extraDamage + 1f) / (damage + 1f) / behavior.multiplier); float num3 = num2 / num; WeaponModel weapon = TowerModelExt.GetWeapon(model); weapon.Rate /= num3; TowerModel tower = Game.instance.model.GetTower(TowerType.DartlingGunner, 2, 0, 0); ProjectileModel projectile2 = TowerModelExt.GetWeapon(tower).projectile; AddBehaviorToBloonModel val2 = ModelExt.Duplicate(ProjectileModelBehaviorExt.GetBehavior(projectile2)); MiscModelExt.ApplyOverlay((ProjectileBehaviorWithOverlayModel)(object)val2); val2.mutationId = "ElectricShock"; ProjectileModelBehaviorExt.AddBehavior(projectile, val2); DamageModifierForBloonStateModel val3 = ModelExt.Duplicate(ProjectileModelBehaviorExt.GetBehavior(projectile2)); val3.bloonState = "ElectricShock"; val3.bloonStates = Il2CppStringArray.op_Implicit(new string[1] { "ElectricShock" }); ProjectileModelBehaviorExt.AddBehavior(projectile, val3); projectile.collisionPasses = Il2CppStructArray.op_Implicit(new int[2] { 0, 1 }); } } } namespace AbilityChoice.AbilityChoices.Primary.BombShooter { public class AssassinateMOAB : TowerAbilityChoice { private const float ExpectedPierce = 4f; private const float Factor = 10f; public override string UpgradeId => "MOAB Assassin"; public override string Description1 => "Frequently shoots out mini Moab Assassin missiles at the strongest Moab on screen."; public override string Description2 => "Main attacks do further increased MOAB damage with more range."; public override void Apply1(TowerModel model) { AbilityModel val = AbilityModel(model); AttackModel val2 = ModelExt.Duplicate(((Model)val).GetDescendant()); WeaponModel val3 = ((Il2CppArrayBase)(object)val2.weapons)[0]; DamageModel damageModel = ProjectileModelExt.GetDamageModel(val3.projectile); damageModel.damage /= 10f; val3.Rate = val.Cooldown / 10f; val3.projectile.scale = 0.5f; Il2CppGenericIEnumerable.ForEach(((Model)val2).GetDescendants(), (Action)delegate(CreateProjectileOnContactModel m) { ProjectileModelExt.GetDamageModel(m.projectile).damage = 1f; ProjectileModelBehaviorExt.GetBehavior(m.projectile).damageAddative = 1f; }); ProjectileModelExt.GetDamageModel(((Model)val2).GetDescendant().projectile).damage = 1f; TowerModelBehaviorExt.AddBehavior(model, val2); } public override void Apply2(TowerModel model) { AbilityModel val = AbilityModel(model); float rate = TowerModelExt.GetWeapon(base.BaseTowerModel).Rate; ProjectileModel projectile = ((Model)TowerModelExt.GetWeapon(model)).GetDescendant().projectile; DamageModel damageModel = ProjectileModelExt.GetDamageModel(((Model)val).GetDescendant().projectile); float num = damageModel.damage / val.Cooldown; DamageModifierForTagModel[] array = ModelExt.FindDescendants((Model)(object)model, (Predicate)((DamageModifierForTagModel tag) => tag.tag == "Moabs")); foreach (DamageModifierForTagModel val2 in array) { val2.damageAddative += num * rate / 4f; } ProjectileModel projectile2 = ((Model)val).GetDescendant().projectile; float num3 = projectile2.pierce * ProjectileModelExt.GetDamageModel(projectile2).damage / val.Cooldown; DamageModel damageModel2 = ProjectileModelExt.GetDamageModel(projectile); damageModel2.damage += num3 * rate / 4f; model.range += 5f; Il2CppGenericIEnumerable.ForEach(((Model)model).GetDescendants(), (Action)delegate(AttackModel attackModel) { attackModel.range += 5f; }); } } public class ISABMissile : TowerAbilityChoice { public const int Factor = 3; public override string AbilityName => "Indomitable Surface-to-Air Ballistic Missile"; public override string UpgradeId => "BombShooter Paragon"; public override string Description1 => "Cluster explosions, anti-MOAB explosions, Bloon stunning explosions, knockback explosions. Automatic frequent ISAB Missiles! BOMB has it all!"; public override void Apply1(TowerModel model) { AbilityModel val = AbilityModel(model); AttackModel val2 = ModelExt.Duplicate(((Model)val).GetDescendant()); WeaponModel val3 = ((Il2CppArrayBase)(object)val2.weapons)[0]; Il2CppGenericIEnumerable.ForEach(((Model)val3.projectile).GetDescendants(), (Action)delegate(DamageModel damage) { damage.damage /= 3f; }); val3.Rate = val.Cooldown / 3f; TowerModelBehaviorExt.AddBehavior(model, val2); } } public class MoabEliminator : AssassinateMOAB { public override string UpgradeId => "MOAB Eliminator"; public override string Description1 => "Frequently shoots out mini Moab Eliminator missiles at the strongest Moab on screen."; public override string Description2 => "Does extremely further increased MOAB damage."; } } namespace AbilityChoice.AbilityChoices.Military.SniperMonkey { public class EliteSupplyDrop : SupplyDrop { public override string UpgradeId => "Elite Sniper"; public override string AbilityName => "Supply Drop"; public override string Description1 => "Occasionally drops more cash. Grants Elite targeting prio and faster reload to all snipers."; public override string Description2 => "Bullets bounce even more, and can bounce back to the same target. Grants Elite targeting prio and faster reload to all snipers."; public override void Apply2(TowerModel model) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown base.Apply2(model); ProjectileModel projectile = TowerModelExt.GetWeapon(model).projectile; if (!ModSettingBool.op_Implicit(AbilityChoiceMod.MoreBalanced)) { projectile.pierce *= 2f; } float delay = ProjectileModelBehaviorExt.GetBehavior(projectile).delay; Args val = new Args(); ((ModelArgs)val).name = "ClearHitBloonsModel_"; val.interval = delay; ProjectileModelBehaviorExt.AddBehavior(projectile, CreateClearHitBloonsModelExt.Create(val)); } } public class SpecialPoperations : TowerAbilityChoice { public override string UpgradeId => "Special Poperations"; public override string Description1 => "Occasionally deploys a powerful special Monkey Marine with machine gun."; public override string Description2 => "A Monkey Marine attacks from inside the Heli with a machine gun."; public override void Apply1(TowerModel model) { TechBotify(model); } public override void Apply2(TowerModel model) { AbilityModel val = AbilityModel(model); ((EntityModel)model).behaviors = Il2CppReferenceArrayExt.RemoveItem(((EntityModel)model).behaviors, val); TowerModel towerModel = AbilityModelBehaviorExt.GetBehavior(val).towerModel; WeaponModel val2 = ModelExt.Duplicate(((Il2CppArrayBase)(object)TowerModelExt.GetAttackModels(towerModel)[0].weapons)[0]); FireFromAirUnitModel behavior = WeaponModelBehaviorExt.GetBehavior(((Il2CppArrayBase)(object)TowerModelExt.GetAttackModels(model)[0].weapons)[0]); val2.behaviors = Il2CppReferenceArray.op_Implicit((Model[])(object)new Model[1] { (Model)behavior }); float num = (val2.ejectZ = 0f); float ejectX = (val2.ejectY = num); val2.ejectX = ejectX; val2.emission = ModelExt.Duplicate(TowerModelExt.GetWeapon(model).emission); ((Il2CppObjectBase)val2.emission).Cast().throwMarkerOffsetModels = new Il2CppReferenceArray((ThrowMarkerOffsetModel[])(object)new ThrowMarkerOffsetModel[1] { ((Il2CppArrayBase)(object)((Il2CppObjectBase)val2.emission).Cast().throwMarkerOffsetModels)[0] }); ((Il2CppArrayBase)(object)((Il2CppObjectBase)val2.emission).Cast().throwMarkerOffsetModels)[0].ejectX = 0f; ((Il2CppObjectBase)val2.emission).Cast().projectileCount = 1; AttackModelExt.AddWeapon(TowerModelExt.GetAttackModels(model)[0], val2); } protected override void RemoveAbility(TowerModel model) { if (base.Mode2) { base.RemoveAbility(model); } } } public class SupplyDrop : TowerAbilityChoice { public override string UpgradeId => "Supply Drop"; public override string Description1 => "Occasionally drops crates of cash. Regular attack also damages Lead Bloons and increases Shrapnel popping power."; public override string Description2 => "Bullets can bounce twice as much. Regular attack also damages Lead Bloons and increases Shrapnel popping power."; public override void Apply1(TowerModel model) { TechBotify(model); } public override void Apply2(TowerModel model) { ProjectileModel projectile = TowerModelExt.GetWeapon(model).projectile; projectile.pierce *= 2f; } protected override void RemoveAbility(TowerModel model) { if (base.Mode2) { base.RemoveAbility(model); } } } } namespace AbilityChoice.AbilityChoices.Military.MortarMonkey { public class Bombardment : TowerAbilityChoice { public override string UpgradeId => "Artillery Battery"; public override string Description1 => "Main attack upgrades to 3+ barrels for extremely fast attacks."; public override string Description2 => "Main attack upgrades to 3+ barrels for incredibly fast attacks with expanded radius."; public override void Apply1(TowerModel model) { AbilityModel val = AbilityModel(model); TurboModel behavior = AbilityModelBehaviorExt.GetBehavior(val); float num = AbilityChoice.CalcAvgBonus(behavior.Lifespan / val.Cooldown, 1f / behavior.multiplier); WeaponModel weapon = TowerModelExt.GetWeapon(model); weapon.Rate /= num; } public override void Apply2(TowerModel model) { AbilityModel val = AbilityModel(model); TurboModel behavior = AbilityModelBehaviorExt.GetBehavior(val); float bonus = behavior.projectileRadiusScaleBonus; Il2CppGenericIEnumerable.ForEach(((Model)model).GetDescendants(), (Action)delegate(ProjectileModel projectileModel) { DisplayModel val2 = default(DisplayModel); if (ProjectileModelBehaviorExt.HasBehavior(projectileModel, ref val2)) { DisplayModel obj = val2; obj.scale *= 1f + bonus; } projectileModel.radius *= 1f + bonus; }); } } public class PopAndAwe : TowerAbilityChoice { public override string UpgradeId => "Pop and Awe"; public override string Description1 => "Main attack gains additional bonus damage to stunned Bloons. Occasionally causes mini-Pop and Awe effects on target."; public override string Description2 => "Main attack gains additional bonus damage to stunned Bloons, and has turbo attack speed permanently"; public override void Apply1(TowerModel model) { WeaponModel weapon = TowerModelExt.GetWeapon(model); AbilityModel val = AbilityModel(model); AttackModel val2 = ModelExt.Duplicate(((Il2CppArrayBase)(object)AbilityModelBehaviorExt.GetBehavior(val).attacks)[0]); WeaponModel val3 = ((Il2CppArrayBase)(object)val2.weapons)[0]; EffectModel val4 = ModelExt.Duplicate(AbilityModelBehaviorExt.GetBehavior(val).effectModel); val4.lifespan /= 8f; WeaponModel val5 = ModelExt.Duplicate(weapon); CreateEffectOnExpireModel behavior = ProjectileModelBehaviorExt.GetBehavior(val5.projectile); behavior.assetId = ModContent.CreatePrefabReference(""); behavior.effectModel = val4; EffectModel effectModel = behavior.effectModel; effectModel.scale /= 3f; behavior.effectModel.useCenterPosition = false; EffectModel effectModel2 = behavior.effectModel; effectModel2.lifespan /= 2f; val5.rate = 4f; ProjectileModel projectile = val3.projectile; ProjectileModelBehaviorExt.GetBehavior(projectile).lifespanFrames = 1; projectile.radius = weapon.projectile.radius * 2f; projectile.behaviors = Il2CppReferenceArrayExt.RemoveItemOfType(projectile.behaviors); ProjectileModelBehaviorExt.GetBehavior(val5.projectile).projectile = projectile; val5.projectile.behaviors = Il2CppReferenceArrayExt.RemoveItemOfType(val5.projectile.behaviors); CreateSoundOnProjectileExhaustModel behavior2 = ProjectileModelBehaviorExt.GetBehavior(TowerModelExt.GetWeapon(Game.instance.model.GetTower(TowerType.MortarMonkey, 5, 0, 0)).projectile); val5.projectile.behaviors = Il2CppReferenceArrayExt.RemoveItemOfType(val5.projectile.behaviors); ProjectileModelBehaviorExt.AddBehavior(val5.projectile, behavior2); AttackModelExt.AddWeapon(TowerModelExt.GetAttackModels(model)[0], val5); } public override void Apply2(TowerModel model) { float multiplier = ((Model)Game.instance.model.GetTower(TowerType.MortarMonkey, 0, 4, 0)).GetDescendant().multiplier; WeaponModel weapon = TowerModelExt.GetWeapon(model); weapon.Rate *= multiplier; } } } namespace AbilityChoice.AbilityChoices.Military.MonkeySub { public class FinalStrike : TowerAbilityChoice { private const float Factor = 10f; public override string UpgradeId => "MonkeySub Paragon"; public override string Description1 => "Unfathomable range, power, and synergies with other Monkey Towers and Heroes put all Bloons under assault. Occasionally fires a devastating radioactive missile at the strongest Bloon."; public override string Description2 => "Unfathomable range, power, and synergies with other Monkey Towers and Heroes put all Bloons under assault. Attacks leave behind radioactive fallout."; public override void Apply1(TowerModel model) { //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Expected O, but got Unknown //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Expected O, but got Unknown //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Expected O, but got Unknown //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Expected O, but got Unknown //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Expected O, but got Unknown AbilityModel val = AbilityModel(model); FinalStrikeModel behavior = AbilityModelBehaviorExt.GetBehavior(val); ProjectileModel projectileModel = behavior.projectileModel; Il2CppGenericIEnumerable.ForEach(((Model)projectileModel).GetDescendants(), (Action)delegate(DamageModel damageModel) { damageModel.damage /= 10f; }); Il2CppGenericIEnumerable.ForEach(((Model)projectileModel).GetDescendants(), (Action)delegate(SlowModel slowModel) { slowModel.Lifespan /= 10f; }); Il2CppGenericIEnumerable.ForEach(((Model)projectileModel).GetDescendants(), (Action)delegate(DamageModifierForTagModel tagModel) { tagModel.damageAddative /= 10f; }); Il2CppGenericIEnumerable.ForEach(((Model)projectileModel).GetDescendants(), (Action)delegate(AgeModel ageModel) { if (ageModel.Lifespan > 10f) { ageModel.Lifespan /= 10f; } }); ProjectileModelBehaviorExt.AddBehavior(projectileModel, CreateCreateSoundOnProjectileExpireModelExt.Create(new Args { sound = behavior.nukeLaunchSoundModel })); Args val2 = new Args(); ((ModelArgs)(object)val2).name = "FinalStrike"; val2.CanSeeCamo = true; val2.range = 2000f; val2.attackThroughWalls = true; val2.addsToSharedGrid = false; val2.targetProvider = (TargetSupplierModel)(object)CreateTargetStrongModelExt.Create(); Args val3 = new Args(); val3.projectile = ModelExt.Duplicate(projectileModel); val3.rate = val.Cooldown / 10f / 3f; val3.eject = new Vector3(behavior.throwOffsetX, behavior.throwOffsetY, behavior.throwOffsetZ); val3.emission = behavior.emissionModel; val3.behaviors = (Model[])(object)new Model[2] { (Model)CreateEjectEffectModelExt.Create(new Args { effectModel = behavior.launchEffectModel, lifespan = 1f }), (Model)CreateEjectEffectModelExt.Create(new Args { effectModel = behavior.launchEjectEffectModel, lifespan = 1f, useEjectPoint = true }) }; val2.weapon = CreateWeaponModelExt.Create(val3); TowerModelBehaviorExt.AddBehavior(model, CreateAttackModelExt.Create(val2)); } public override void Apply2(TowerModel model) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006b: 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_0084: Expected O, but got Unknown //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Expected O, but got Unknown AbilityModel val = AbilityModel(model); FinalStrikeModel behavior = AbilityModelBehaviorExt.GetBehavior(val); ProjectileModel projectile = ((Model)behavior).GetDescendant().projectile; SingleEmissionModel emission = CreateSingleEmissionModelExt.Create(); AgeModel descendant = ((Model)projectile).GetDescendant(); descendant.Lifespan /= 10f; ProjectileModelBehaviorExt.AddBehavior(((Il2CppArrayBase)(object)TowerModelExt.GetAttackModel(model, 1).weapons)[0].projectile, CreateCreateProjectilesOnTrackOnExpireModelExt.Create(new Args { projectile = ModelExt.Duplicate(projectile), emission = (EmissionModel)(object)emission, count = 1, range = 60f })); ClearHitBloonsModel descendant2 = ((Model)projectile).GetDescendant(); descendant2.interval *= 5f; ProjectileModelBehaviorExt.AddBehavior(((Il2CppArrayBase)(object)TowerModelExt.GetAttackModel(model).weapons)[0].projectile, CreateCreateProjectileOnExhaustFractionModelExt.Create(new Args { projectile = ModelExt.Duplicate(projectile), emission = (EmissionModel)(object)emission, fraction = 1f, durationfraction = -1f })); } } public class FirstStrikeCapability : TowerAbilityChoice { private const float ExpectedPierce = 10f; private const float Factor = 50f; public override string UpgradeId => "First Strike Capability"; public override string Description1 => "Gains frequent First Strike style missile attacks."; public override string Description2 => "Ballistic missiles do more damage, further increased against MOABs and Ceramics"; public override void Apply1(TowerModel model) { //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Expected O, but got Unknown //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Expected O, but got Unknown AbilityModel val = AbilityModel(model); AttackModel val2 = ModelExt.Duplicate(((Il2CppArrayBase)(object)AbilityModelBehaviorExt.GetBehavior(val).attacks)[0], ((ModContent)this).Name); WeaponModel val3 = ((Il2CppArrayBase)(object)val2.weapons)[0]; val3.Rate = val.Cooldown / 50f; foreach (CreateProjectileOnExpireModel behavior2 in ProjectileModelBehaviorExt.GetBehaviors(val3.projectile)) { DamageModel damageModel = ProjectileModelExt.GetDamageModel(behavior2.projectile); damageModel.damage /= 50f; if (behavior2.projectile.radius > 10f) { ProjectileModel projectile = behavior2.projectile; projectile.radius /= 2f; } } CreateEffectOnExpireModel behavior = ProjectileModelBehaviorExt.GetBehavior(val3.projectile); Args val4 = new Args(); ((ModelArgs)val4).name = ((Model)behavior).name; val4.assetId = behavior.assetId; val4.scale = 0.5f; val4.lifespan = behavior.lifespan; behavior.effectModel = CreateEffectModelExt.Create(val4); TowerModelBehaviorExt.AddBehavior(model, val2); } public override void Apply2(TowerModel model) { AbilityModel val = AbilityModel(model); DamageModel descendant = ((Model)TowerModelExt.GetAttackModel(model, "BallisticMissile")).GetDescendant(); float baseWeaponRate = ((Il2CppArrayBase)(object)TowerModelExt.GetAttackModel(model, "BallisticMissile").weapons)[0].Rate; List source = Il2CppGenericIEnumerableExt.ToList(((Model)val).GetDescendants()); DamageModel damageModel = ProjectileModelExt.GetDamageModel(source.First((CreateProjectileOnExpireModel expireModel) => ((Model)expireModel).name.Contains("SingleTarget")).projectile); float addedMoabDps = damageModel.damage / val.Cooldown; Il2CppGenericIEnumerable.ForEach(((Model)TowerModelExt.GetAttackModel(model, 1)).GetDescendants(), (Action)delegate(DamageModifierForTagModel tagModel) { float num3 = addedMoabDps * baseWeaponRate / 10f; tagModel.damageAddative += num3; }); ProjectileModel projectile = source.First((CreateProjectileOnExpireModel expireModel) => ((Model)expireModel).name.Contains("Explosion")).projectile; float num = projectile.pierce * ProjectileModelExt.GetDamageModel(projectile).damage / val.Cooldown; float num2 = num * baseWeaponRate / 10f; descendant.damage += num2; } } public class PreemptiveStrike : FirstStrikeCapability { public override string UpgradeId => "Pre-emptive Strike"; public override string AbilityName => "First Strike Capability"; public override string Description1 => base.DefaultDescription + " (" + base.Description1 + ")"; public override string Description2 => base.DefaultDescription + " (" + base.Description2 + ")"; } } namespace AbilityChoice.AbilityChoices.Military.MonkeyBuccaneer { public class LargeBADHarpoon : TowerAbilityChoice { public override string UpgradeId => "MonkeyBuccaneer Paragon"; public override string Description1 => "The greatest thing ever to float on water. Occasionally uses a mega hook to destroy the strongest non-Boss Bloon on screen."; public override string Description2 => "The greatest thing ever to float on water. Can use nearly all of its hooks in order to destroy a BAD Bloon."; public override void Apply1(TowerModel model) { AbilityModel val = AbilityModel(model); AttackModel descendant = ((Model)val).GetDescendant(); ((Il2CppArrayBase)(object)descendant.weapons)[0].Rate = val.Cooldown; TowerModelBehaviorExt.AddBehavior(model, descendant); } public override void Apply2(TowerModel model) { Il2CppGenericIEnumerable.ForEach(((Model)model).GetDescendants(), (Action)delegate(TargetGrapplableModel grapplableModel) { grapplableModel.badHooksRequired = 8; }); } } public class MOABTakedown : TowerAbilityChoice { public override string UpgradeId => "Buccaneer-Monkey Pirates"; public override string Description1 => "Adds 2 new cannons to the ship and cannons attacks do more damage. Also gains a hook attack which periodically harpoons a MOAB class Bloon and brings it down."; public override string Description2 => "Adds 2 new cannons to the ship and cannons attacks do more damage. Damage bonuses to MOABs and Ceramics increased."; public override void Apply1(TowerModel model) { AbilityModel val = AbilityModel(model); AttackModel val2 = ModelExt.Duplicate(((Model)val).GetDescendant()); ((Il2CppArrayBase)(object)val2.weapons)[0].Rate = val.Cooldown; TowerModelBehaviorExt.AddBehavior(model, val2); } public override void Apply2(TowerModel model) { //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Expected O, but got Unknown //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Expected O, but got Unknown //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Expected O, but got Unknown //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Expected O, but got Unknown if (ModSettingBool.op_Implicit(AbilityChoiceMod.MoreBalanced)) { Il2CppGenericIEnumerable.ForEach(((Model)model).GetDescendants(), (Action)delegate(DamageModifierForTagModel modifier) { if (modifier.tag == "Moabs") { modifier.damageAddative *= 1.5f; } }); return; } foreach (ProjectileModel item in from projectileModel in Il2CppGenericIEnumerableExt.ToList(((Model)model).GetDescendants()) where projectileModel.id == "Explosion" select projectileModel) { Args val = new Args(); ((ModelArgs)val).name = "MoabDamage"; val.tag = "Moabs"; val.damageAddative = 20f; ProjectileModelBehaviorExt.AddBehavior(item, CreateDamageModifierForTagModelExt.Create(val)); Args val2 = new Args(); ((ModelArgs)val2).name = "MoabDamage"; val2.tag = "Ceramic"; val2.damageAddative = 10f; ProjectileModelBehaviorExt.AddBehavior(item, CreateDamageModifierForTagModelExt.Create(val2)); item.hasDamageModifiers = true; } } } public class ZOMGTakedown : MOABTakedown { public override string UpgradeId => "Buccaneer-Pirate Lord"; public override string Description1 => "Greatly improved power and can shoot many grappling hooks at once, plundering extra cash from each MOAB-class Bloon taken down."; public override string Description2 => "Greatly increased attack speed for all attacks, with further increased MOAB damage."; public override void Apply1(TowerModel model) { AbilityModel val = AbilityModel(model); AttackModel val2 = ModelExt.Duplicate(((Model)val).GetDescendant()); ((Il2CppArrayBase)(object)val2.weapons)[0].Rate = val.Cooldown / 2f; Il2CppGenericIEnumerable.ForEach(((Model)val2).GetDescendants(), (Action)delegate(TargetGrapplableModel grapplableModel) { grapplableModel.hooks /= 2; }); TowerModelBehaviorExt.AddBehavior(model, val2); } public override void Apply2(TowerModel model) { //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Expected O, but got Unknown //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Expected O, but got Unknown //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Expected O, but got Unknown //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Expected O, but got Unknown base.Apply2(model); if (ModSettingBool.op_Implicit(AbilityChoiceMod.MoreBalanced)) { return; } foreach (ProjectileModel item in Il2CppGenericIEnumerableExt.ToList(((Model)model).GetDescendants())) { if (item.id == "Explosion") { foreach (DamageModifierForTagModel behavior in ProjectileModelBehaviorExt.GetBehaviors(item)) { behavior.damageAddative *= 2f; } } else if (ProjectileModelExt.GetDamageModel(item) != null) { Args val = new Args(); ((ModelArgs)val).name = "MoabDamage"; val.tag = "Moabs"; val.damageAddative = 20f; ProjectileModelBehaviorExt.AddBehavior(item, CreateDamageModifierForTagModelExt.Create(val)); Args val2 = new Args(); ((ModelArgs)val2).name = "MoabDamage"; val2.tag = "Ceramic"; val2.damageAddative = 5f; ProjectileModelBehaviorExt.AddBehavior(item, CreateDamageModifierForTagModelExt.Create(val2)); item.hasDamageModifiers = true; } } } } } namespace AbilityChoice.AbilityChoices.Military.MonkeyAce { public class CarpetBomb : TowerAbilityChoice { [HarmonyPatch(typeof(FighterMovement), "Process")] internal static class FighterMovement_Process { [HarmonyPrefix] private static void Prefix(FighterMovement __instance) { if (__instance.currentPathSupplier == null) { ((RootBehavior)__instance).Attatched(); } } } private const int Factor = 4; public override string UpgradeId => "MonkeyAce Paragon"; public override string Description1 => "A flying shadow of darkness spells Bloon obliteration. Occasionally drops carpet bombs along a selected path."; public override string Description2 => "A flying shadow of darkness spells Bloon obliteration. Joined by 3 bomber planes that launch homing bombs at the strongest Bloon."; public override void Apply1(TowerModel model) { AbilityModel val = AbilityModel(model); CarpetBombAbilityModel behavior = AbilityModelBehaviorExt.GetBehavior(val); ProjectileModel projectileModel = behavior.projectileModel; val.Cooldown /= 4f; Il2CppGenericIEnumerable.ForEach(((Model)projectileModel).GetDescendants(), (Action)delegate(DamageModel damageModel) { damageModel.damage /= 4f; }); Il2CppGenericIEnumerable.ForEach(((Model)projectileModel).GetDescendants(), (Action)delegate(DamageModifierForTagModel tagModel) { tagModel.damageAddative /= 4f; }); Il2CppGenericIEnumerable.ForEach(((Model)projectileModel).GetDescendants(), (Action)delegate(SlowModel slowModel) { slowModel.Lifespan /= 4f; }); TechBotify(model); } public override void Apply2(TowerModel model) { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Expected O, but got Unknown //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Expected O, but got Unknown //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Expected O, but got Unknown //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Expected O, but got Unknown //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Expected O, but got Unknown //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_024b: Expected O, but got Unknown //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_0262: Expected O, but got Unknown AbilityModel val = AbilityModel(model); CarpetBombAbilityModel behavior = AbilityModelBehaviorExt.GetBehavior(val); ProjectileModel val2 = ModelExt.Duplicate(behavior.projectileModel); Il2CppGenericIEnumerable.ForEach(((Model)val2).GetDescendants(), (Action)delegate(SlowModel slowModel) { slowModel.Lifespan /= 3f; }); CreateEffectOnExhaustFractionModel behavior2 = ProjectileModelBehaviorExt.GetBehavior(val2); ProjectileModelBehaviorExt.RemoveBehavior(val2, behavior2); ProjectileModelExt.SetDisplay(val2, behavior2.effectModel.assetId); Args val3 = new Args(); val3.curveSamples = new float[2] { 0f, 0.9f }; val3.filterCollisionWhileMoving = true; val3.altSpeed = 500f; val3.keepUpdatingTargetPos = true; val3.maxTurnAngle = 360f; val3.positionAboveMoabTypes = true; ProjectileModelBehaviorExt.AddBehavior(val2, CreateArriveAtTargetModelExt.Create(val3)); float num = val.Cooldown / behavior.numProjectiles; TowerModel descendant = ((Model)Game.instance.model.GetTower(TowerType.MonkeyBuccaneer, 4, 0, 0)).GetDescendant(); for (int num2 = 0; num2 < 3; num2++) { TowerModel val4 = ModelExt.Duplicate(descendant, "ParagonBomber"); ((EntityModel)val4).baseId = "ParagonBomber"; TowerModelBehaviorExt.RemoveBehaviors(val4); TowerModelBehaviorExt.RemoveBehavior(val4); TowerModelBehaviorExt.GetBehavior(val4).display = new PrefabReference(ModContent.GetDisplayGUID()); Args val5 = new Args(); val5.range = 2000f; val5.attackThroughWalls = true; val5.CanSeeCamo = true; val5.targetProvider = (TargetSupplierModel)(object)CreateFighterPilotPatternStrongModelExt.Create(new Args { offsetDistance = 40f, isOnSubTower = true }); Args val6 = new Args(); val6.emission = (EmissionModel)(object)ModelExt.Duplicate(behavior.singleEmissionModel); val6.rate = num * 3f; val6.customStartCooldown = num * (float)num2; val6.startInCooldown = true; val6.projectile = ModelExt.Duplicate(val2); val6.behaviors = (Model[])(object)new Model[1] { (Model)CreateFireFromAirUnitModelExt.Create() }; val5.weapon = CreateWeaponModelExt.Create(val6); TowerModelBehaviorExt.AddBehavior(val4, CreateAttackAirUnitModelExt.Create(val5)); FighterMovementModel descendant2 = ((Model)val4).GetDescendant(); descendant2.maxSpeed += (float)num2; val4.UpdateTargetProviders(); Args val7 = new Args(); ((ModelArgs)val7).name = "Plane" + num2; val7.towerModel = val4; val7.isAirBasedTower = true; TowerModelBehaviorExt.AddBehavior(model, CreateTowerCreateTowerModelExt.Create(val7)); } } } public class GroundZero : TowerAbilityChoice { protected const int Factor = 7; public override string UpgradeId => "Ground Zero"; public override string Description1 => "Bomb damage increased significantly. Occasionally drops mini Ground Zeros."; public override string Description2 => "Bomb damage increased significantly. Shoots a continuous stream of bombs."; public override void Apply1(TowerModel model) { //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Expected O, but got Unknown //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Expected O, but got Unknown AttackModel attackModel = TowerModelExt.GetAttackModel(model, "Pineapple"); AbilityModel val = AbilityModel(model); AttackModel val2 = ModelExt.Duplicate(((Model)val).GetDescendant()); WeaponModel val3 = ((Il2CppArrayBase)(object)val2.weapons)[0]; EffectModel val4 = ModelExt.Duplicate(AbilityModelBehaviorExt.GetBehavior(val).effectModel); val4.scale = 0.5f; val4.useCenterPosition = false; SoundModel sound = AbilityModelBehaviorExt.GetBehavior(val).sound; AttackModel val5 = ModelExt.Duplicate(attackModel); ((Model)val5).name = "AttackModel_GroundZero"; WeaponModel val6 = ((Il2CppArrayBase)(object)val5.weapons)[0]; val6.emission = val3.emission; val6.Rate = val.Cooldown / 7f; DamageModel descendant = ((Model)val3.projectile).GetDescendant(); descendant.damage /= 7f; val3.projectile.radius = 100f; SlowModel val7 = default(SlowModel); if (ProjectileModelBehaviorExt.HasBehavior(val3.projectile, ref val7)) { SlowModel obj = val7; obj.lifespan /= 7f; } val6.ejectY = 0f; WeaponModelBehaviorExt.AddBehavior(val6, CreateEjectEffectModelExt.Create(new Args { effectModel = val4, lifespan = -1f, useEjectPoint = true })); ProjectileModel projectile = val6.projectile; ProjectileModelBehaviorExt.GetBehavior(projectile).projectile = val3.projectile; ProjectileModelBehaviorExt.RemoveBehavior(projectile); ProjectileModelBehaviorExt.GetBehavior(projectile).display = ModContent.CreatePrefabReference(""); WeaponModelBehaviorExt.AddBehavior(val6, CreateCreateSoundOnProjectileCreatedModelExt.Create(new Args { sound1 = sound, sound2 = sound, sound3 = sound, sound4 = sound, sound5 = sound })); TowerModelBehaviorExt.AddBehavior(model, val5); } public override void Apply2(TowerModel model) { AttackModel attackModel = TowerModelExt.GetAttackModel(model, "Pineapple"); EmissionOverTimeModel descendant = ((Model)attackModel).GetDescendant(); WeaponModel val = ((Il2CppArrayBase)(object)attackModel.weapons)[0]; val.Rate = (float)descendant.count * descendant.timeBetween; WeaponModelBehaviorExt.RemoveBehavior(val); } } public class TsarBomba : GroundZero { public override string UpgradeId => "Tsar Bomba"; public override string Description1 => "Occasionally drops mini Tsar Bombs."; public override string Description2 => "Drops a continuous stream of larger, more powerful bombs that stun bloons."; public override void Apply2(TowerModel model) { base.Apply2(model); SlowModel val = ModelExt.Duplicate(((Model)AbilityModel(model)).GetDescendant()); AttackModel attackModel = TowerModelExt.GetAttackModel(model, "Pineapple"); val.Lifespan /= 7f; ProjectileModel projectile = ((Model)attackModel).GetDescendant().projectile; ProjectileModelBehaviorExt.AddBehavior(projectile, val); DamageModel damageModel = ProjectileModelExt.GetDamageModel(projectile); damageModel.damage *= 7f; projectile.radius *= 2f; EffectModel effectModel = ((Model)attackModel).GetDescendant().effectModel; effectModel.scale /= 2f; } } } namespace AbilityChoice.AbilityChoices.Military.HeliPilot { public class SupportDrop : TowerAbilityChoice { public override string UpgradeId => "Support Chinook"; public override string Description1 => "Occasionally drops lives and cash crates. Can pick up and redeploy most Monkey types."; public override string Description2 => "Downdraft attack is stronger and damages Moab class bloons. Can pick up and redeploy most Monkey types."; public override void Apply1(TowerModel model) { TechBotify(model); } public override void Apply2(TowerModel model) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Expected O, but got Unknown //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Expected O, but got Unknown AttackModel attackModel = TowerModelExt.GetAttackModel(model, "Downdraft"); ProjectileModel descendant = ((Model)attackModel).GetDescendant(); WindModel behavior = ProjectileModelBehaviorExt.GetBehavior(descendant); behavior.distanceMin = behavior.distanceMax; Args val = new Args(); ((ModelArgs)val).name = "DamageModel_"; val.damage = 1f; val.immuneBloonProperties = (BloonProperties)0; val.immuneBloonPropertiesOriginal = (BloonProperties)0; ProjectileModelBehaviorExt.AddBehavior(descendant, CreateDamageModelExt.Create(val)); Args val2 = new Args(); ((ModelArgs)val2).name = "DamageModifierForTagModel_"; val2.tag = "Moabs"; val2.damageAddative = 9f; val2.applyOverMaxDamage = true; ProjectileModelBehaviorExt.AddBehavior(descendant, CreateDamageModifierForTagModelExt.Create(val2)); descendant.hasDamageModifiers = true; ProjectileFilterModel behavior2 = ProjectileModelBehaviorExt.GetBehavior(descendant); FilterOutTagModel val3 = default(FilterOutTagModel); behavior2.filters = IEnumerableExt.ToIl2CppReferenceArray(((IEnumerable)behavior2.filters).Where((FilterModel filterModel) => !Il2CppSystemObjectExt.Is((Il2CppObjectBase)(object)filterModel, ref val3) || !(val3.tag == "Moabs"))); } protected override void RemoveAbility(TowerModel model) { if (base.Mode2) { base.RemoveAbility(model); } } } } namespace AbilityChoice.AbilityChoices.Military.DartlingGunner { public class RocketStorm : TowerAbilityChoice { public override string AbilityName => ((ModContent)this).Name; public override string UpgradeId => "Rocket Storm"; public override string Description1 => "Occasionally shoots a wave of Rocket Storm missiles."; public override string Description2 => "Shoots a single stream of Rocket Storm missiles with the same accuracy of its main attack."; public override void Apply1(TowerModel model) { AbilityModel val = AbilityModel(model); ActivateAttackModel behavior = AbilityModelBehaviorExt.GetBehavior(val); AttackModel val2 = ModelExt.Duplicate(((Il2CppArrayBase)(object)behavior.attacks)[0]); float num = behavior.Lifespan / val.Cooldown; WeaponModel val3 = ((Il2CppArrayBase)(object)val2.weapons)[0]; val3.rate /= num; AttackModelExt.AddWeapon(TowerModelExt.GetAttackModels(model)[0], val3); } public override void Apply2(TowerModel model) { AbilityModel val = AbilityModel(model); ActivateAttackModel behavior = AbilityModelBehaviorExt.GetBehavior(val); AttackModel val2 = ModelExt.Duplicate(((Il2CppArrayBase)(object)behavior.attacks)[0]); float num = behavior.Lifespan / val.Cooldown; WeaponModel val3 = ((Il2CppArrayBase)(object)val2.weapons)[0]; WeaponModel weapon = TowerModelExt.GetWeapon(model); int num2 = 1; RandomEmissionModel val4 = default(RandomEmissionModel); EmissionWithOffsetsModel val5 = default(EmissionWithOffsetsModel); if (Il2CppSystemObjectExt.IsType((Object)(object)val3.emission, ref val4)) { num2 = val4.count; } else if (Il2CppSystemObjectExt.IsType((Object)(object)val3.emission, ref val5)) { num2 = val5.projectileCount; } else { MelonLogger.Msg("Couldn't find count ?"); } val3.emission = weapon.emission; val3.Rate /= num * (float)num2 / 2f; Il2CppGenericIEnumerable.ForEach(((Model)val3).GetDescendants(), (Action)delegate(SlowModel slowModel) { slowModel.dontRefreshDuration = true; }); EffectModel effectModel = WeaponModelBehaviorExt.GetBehavior(val3).effectModel; effectModel.lifespan *= num; AttackModelExt.AddWeapon(TowerModelExt.GetAttackModels(model)[0], val3); } } public class RocketStormMAD : RocketStorm { public override string UpgradeId => "M.A.D"; public override string Description1 => "Occasionally shoots a wave of MAD Rocket Storm missiles."; public override string Description2 => "Shoots a single stream of MAD Rocket Storm missiles with the same accuracy of its main attack."; } } namespace AbilityChoice.AbilityChoices.Magic.WizardMonkey { public class ArcaneMetamorphosis : TowerAbilityChoice { internal const int Factor = 4; private const int Factor2 = 5; public override string UpgradeId => "WizardMonkey Paragon"; public override string Description1 => "Only the most perfect Wizard can channel the ancient powers of the beyond. Spends 1000 mana/s on flame thrower + wall of fire attacks, and 25% current mana on occasional Phoenix explosions that create zombie ZOMGs/BFBs."; public override string Description2 => "Only the most perfect Wizard can channel the ancient powers of the beyond. Foregoes necromancy and mana to permanently use all attacks at once."; public override void Apply1(TowerModel model) { //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Expected O, but got Unknown AbilityModel val = AbilityModel(model); ArcaneMetamorphosisModel behavior = AbilityModelBehaviorExt.GetBehavior(val); behavior.manaPerSecond /= 4; WeaponModel obj = ((Il2CppArrayBase)(object)TowerModelExt.GetAttackModel(model, "Flamethrower").weapons)[0]; obj.Rate *= 4f; Il2CppGenericIEnumerable.ForEach(((Model)TowerModelExt.GetAttackModel(model, "Walls of Fire")).GetDescendants(), (Action)delegate(DamageModel d) { d.damage /= 4f; }); MagusPerfectusGraveyardStateManagerModel behavior2 = TowerModelBehaviorExt.GetBehavior(model); Il2CppStringArray second = behavior2.attackManagerStates[MagusPerfectusGraveyardStateManagerModel.StateDrainingOverTime]; behavior2.attackManagerStates[MagusPerfectusGraveyardStateManagerModel.StateConsuming] = Il2CppStringArray.op_Implicit(((IEnumerable)behavior2.attackManagerStates[MagusPerfectusGraveyardStateManagerModel.StateConsuming]).Concat((IEnumerable)second).ToArray()); behavior2.attackManagerStates[MagusPerfectusGraveyardStateManagerModel.StateDrainingOverTime] = new Il2CppStringArray(0L); AbilityModel val2 = TowerModelExt.GetAbilities(model).First((AbilityModel a) => a.displayName == "Phoenix Rebirth"); PhoenixRebirthModel behavior3 = AbilityModelBehaviorExt.GetBehavior(val2); val2.Cooldown /= 4f; AbilityModelBehaviorExt.RemoveBehavior(val2); behavior3.duration = 0f; AddBehaviorToBloonModel descendant = ((Model)behavior3.projectileExplosionModel).GetDescendant(); descendant.lifespan /= 4f; DamageOverTimeModel descendant2 = ((Model)behavior3.projectileExplosionModel).GetDescendant(); descendant2.damage /= 4f; behavior3.effectEndSubtowerModel.assetId.guidRef = ""; behavior3.disabledSubTowers = Il2CppReferenceArray.op_Implicit(Array.Empty()); TechBotify(model, val2); } public override void Apply2(TowerModel model) { //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Expected O, but got Unknown //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Expected O, but got Unknown //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Expected O, but got Unknown model.towerSelectionMenuThemeId = "Camo"; WeaponModel obj = ((Il2CppArrayBase)(object)TowerModelExt.GetAttackModel(model, "Flamethrower").weapons)[0]; obj.Rate *= 5f; Il2CppGenericIEnumerable.ForEach(((Model)TowerModelExt.GetAttackModel(model, "Walls of Fire")).GetDescendants(), (Action)delegate(DamageModel d) { d.damage /= 5f; }); TowerModelBehaviorExt.RemoveBehavior(model); ArrayExt.ForEach(((IEnumerable)MonoLinqHelper.ToArray(((Model)model).GetDescendants())).Concat(((IEnumerable)MonoLinqHelper.ToArray(((Model)model).GetDescendants())).SelectMany((TowerModel m) => (IEnumerable)MonoLinqHelper.ToArray(((Model)m).GetDescendants()))).ToArray(), (Action)delegate(WeaponModel w) { WeaponModelBehaviorExt.RemoveBehavior(w); }); Il2CppGenericIEnumerable.ForEach(((Model)model).GetDescendants(), (Action)delegate(ProjectileModel p) { ProjectileModelBehaviorExt.RemoveBehavior(p); }); AbilityModel val = TowerModelExt.GetAbilities(model).First((AbilityModel a) => a.displayName == "Phoenix Rebirth"); PhoenixRebirthModel behavior = AbilityModelBehaviorExt.GetBehavior(val); AddBehaviorToBloonModel descendant = ((Model)behavior.projectileExplosionModel).GetDescendant(); descendant.lifespan /= 5f; DamageOverTimeModel descendant2 = ((Model)behavior.projectileExplosionModel).GetDescendant(); descendant2.damage /= 5f; foreach (TowerModel item in (Il2CppArrayBase)(object)TowerModelBehaviorExt.GetBehavior(model).towerModels) { Args val2 = new Args(); ((ModelArgs)(object)val2).name = "Explosion"; val2.range = 2000f; val2.addsToSharedGrid = false; val2.CanSeeCamo = true; val2.fireWithoutTarget = true; val2.attackThroughWalls = true; Args val3 = new Args(); val3.rate = val.Cooldown / 4f; val3.fireWithoutTarget = true; val3.projectile = ModelExt.Duplicate(behavior.projectileExplosionModel); val3.behaviors = (Model[])(object)new Model[1] { (Model)CreateEjectEffectModelExt.Create(new Args { effectModel = behavior.effectSubtowerModel, lifespan = 2f }) }; val2.weapon = CreateWeaponModelExt.Create(val3); TowerModelBehaviorExt.AddBehavior(item, CreateAttackModelExt.Create(val2)); item.UpdateTargetProviders(); } } protected override void RemoveAbility(TowerModel model) { if (base.Mode2) { TowerModelBehaviorExt.RemoveBehaviors(model); } else { AbilityModel(model).isHidden = true; } } } public class SummonLordPhoenix : SummonPheonix { public override string UpgradeId => "Wizard Lord Phoenix"; public override string Description1 => "Summons a somewhat powerful Lava Phoenix."; public override string Description2 => "Wizard gains the attacks of both Phoenixes itself (non-globally)."; public override void Apply1(TowerModel model) { TowerCreateTowerModel val = ModelExt.Duplicate(TowerModelBehaviorExt.GetBehavior(model)); AbilityModel val2 = AbilityModel(model); float num = TowerModelBehaviorExt.GetBehavior(((Model)val2).GetDescendant()).Lifespan / val2.Cooldown; TowerModel descendant = ((Model)val2).GetDescendant(); ((EntityModel)descendant).behaviors = Il2CppReferenceArrayExt.RemoveItemOfType(((EntityModel)descendant).behaviors); foreach (WeaponModel weapon in TowerModelExt.GetWeapons(descendant)) { weapon.Rate /= num; } val.towerModel = descendant; TowerModelBehaviorExt.AddBehavior(model, val); } public override void Apply2(TowerModel model) { base.Apply2(model); TowerCreateTowerModel behavior = TowerModelBehaviorExt.GetBehavior(model); TowerModelBehaviorExt.RemoveBehavior(model, behavior); SummonPheonix.AddAttacksFromSubTower(model, behavior.towerModel); } } public class SummonPheonix : TowerAbilityChoice { public override string UpgradeId => "Summon Phoenix"; public override string Description1 => "Summons a Phoenix which wreaks a moderate amount of bloon havoc."; public override string Description2 => "Wizard gains the attacks of the Phoenix itself (non-globally)."; public override void Apply1(TowerModel model) { AbilityModel val = AbilityModel(model); float num = TowerModelBehaviorExt.GetBehavior(((Model)val).GetDescendant()).Lifespan / val.Cooldown; TowerModel tower = Game.instance.model.GetTower(TowerType.WizardMonkey, ((Il2CppArrayBase)(object)model.tiers)[0], 5, ((Il2CppArrayBase)(object)model.tiers)[2]); TowerCreateTowerModel val2 = ModelExt.Duplicate(TowerModelBehaviorExt.GetBehavior(tower)); WeaponModel weapon = TowerModelExt.GetWeapon(val2.towerModel); weapon.Rate /= num; TowerModelBehaviorExt.AddBehavior(model, val2); } public override void Apply2(TowerModel model) { model.range = TowerModelBehaviorExt.GetBehaviors(model).Max((AttackModel attackModel) => attackModel.range); AbilityModel val = AbilityModel(model); TowerModel descendant = ((Model)val).GetDescendant(); AddAttacksFromSubTower(model, descendant); } protected static void AddAttacksFromSubTower(TowerModel model, TowerModel subTowerModel) { foreach (AttackModel attackModel in TowerModelExt.GetAttackModels(subTowerModel)) { attackModel.range = model.range; attackModel.targetProvider = null; AttackModelBehaviorExt.RemoveBehavior(attackModel); AttackModelBehaviorExt.RemoveBehavior(attackModel); foreach (TargetSupplierModel behavior in AttackModelBehaviorExt.GetBehaviors(TowerModelExt.GetAttackModel(model))) { AttackModelBehaviorExt.AddBehavior(attackModel, behavior); attackModel.fireWithoutTarget = false; } ((Il2CppArrayBase)(object)attackModel.weapons)[0].ejectZ = 0f; TowerModelBehaviorExt.AddBehavior(model, attackModel); } } } } namespace AbilityChoice.AbilityChoices.Magic.SuperMonkey { public class AntiBloon : TechTerror { public override string UpgradeId => "The Anti-Bloon"; public override string AbilityName => "The Anti-Bloon"; public override string BackUpAbilityName => ""; public override string Description1 => "Frequently eradicates nearby Bloons."; public override string Description2 => "Nanobot plasma seeks out and destroys Bloons with strong Crits"; } public class ChampionDarkshift : TowerAbilityChoice { public override string UpgradeId => "Dark Champion"; public override string AbilityName => ((ModContent)this).Name; public override string Description1 => "Champion's dark blades excel at puncturing and ruining all Bloon types. Further increased range."; public override void Apply1(TowerModel model) { TowerModelExt.IncreaseRange(model, 20f); } } public class Darkshift : TowerAbilityChoice { public override string UpgradeId => "Dark Knight"; public override string Description1 => "Dark blades increase knockback and pierce and deal extra damage to MOAB-class Bloons. Increased range."; public override void Apply1(TowerModel model) { TowerModelExt.IncreaseRange(model, 10f); } } public class LegendDarkshift : TowerAbilityChoice { public override string UpgradeId => "Legend of the Night"; public override string AbilityName => "ChampionDarkshift"; public override string Description1 => "We turn to him, when all hope is lost... and he's got a bit more range"; protected override int Order => -1; public override void Apply1(TowerModel model) { TowerModelExt.IncreaseRange(model, 30f); } } public class TechTerror : TowerAbilityChoice { private const int Factor = 10; public override string UpgradeId => "Tech Terror"; public override string Description1 => "Frequently annihilates nearby Bloons."; public override string Description2 => "Nanobot plasma seeks out and destroys Bloons with strong Crits"; public override void Apply1(TowerModel model) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0046: 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_0063: Expected O, but got Unknown AbilityModel val = AbilityModel(model); AttackModel val2 = ModelExt.Duplicate(((Il2CppArrayBase)(object)AbilityModelBehaviorExt.GetBehavior(val).attacks)[0]); WeaponModel val3 = ((Il2CppArrayBase)(object)val2.weapons)[0]; EffectModel effectModel = AbilityModelBehaviorExt.GetBehavior(val).effectModel; CreateEffectOnExhaustFractionModel val4 = CreateCreateEffectOnExhaustFractionModelExt.Create(new Args { effectModel = effectModel, fraction = 1f, durationFraction = -1f }); ProjectileModelBehaviorExt.AddBehavior(val3.projectile, val4); DamageModel damageModel = ProjectileModelExt.GetDamageModel(val3.projectile); damageModel.damage /= 10f; val3.rate = val.Cooldown / 10f; CritMultiplierModel descendant = ((Model)val3).GetDescendant(); descendant.damage /= 10f; KnockbackModel val5 = default(KnockbackModel); if (ModelExt.HasDescendant((Model)(object)val3, ref val5)) { KnockbackModel obj = val5; obj.lightMultiplier /= 10f; KnockbackModel obj2 = val5; obj2.heavyMultiplier /= 10f; KnockbackModel obj3 = val5; obj3.moabMultiplier /= 10f; } val2.range = val3.projectile.radius - 10f; val2.fireWithoutTarget = false; TowerModelBehaviorExt.AddBehavior(model, val2); } public override void Apply2(TowerModel model) { Il2CppGenericIEnumerable.ForEach(((Model)model).GetDescendants(), (Action)delegate(CritMultiplierModel multiplierModel) { multiplierModel.damage *= (ModSettingBool.op_Implicit(AbilityChoiceMod.MoreBalanced) ? 1.5f : 5f); }); RetargetOnContactModel retarget = ModelExt.Duplicate(((Model)Game.instance.model.GetTower(TowerType.BoomerangMonkey, 4, 0, 0)).GetDescendant()); retarget.expireIfNoTargetFound = false; CollectionExtensions.Do(from projectileModel in Il2CppGenericIEnumerableExt.ToList(((Model)model).GetDescendants()) where ProjectileModelBehaviorExt.HasBehavior(projectileModel) select projectileModel, (Action)delegate(ProjectileModel projectileModel) { ProjectileModelBehaviorExt.AddBehavior(projectileModel, ModelExt.Duplicate(retarget)); }); } } } namespace AbilityChoice.AbilityChoices.Magic.NinjaMonkey { public class GrandSabotage : Sabotage { public override string UpgradeId => "Grand Saboteur"; public override string Description1 => "All Bloons move at further reduced speed. MOAB-Class Bloons spawn with slightly reduced health. Permanent Shinobi buff."; public override string Description2 => "Ninja's attack have further increased range and pierce, and do more damage to stronger Bloon types. Permanent Shinobi buff."; public override void Apply1(TowerModel model) { base.Apply1(model); AbilityModel val = AbilityModel(model); float uptime = ((Model)val).GetDescendant().Lifespan / val.Cooldown; Il2CppGenericIEnumerable.ForEach(((Model)model).GetDescendants(), (Action)delegate(DamagePercentOfMaxModel maxModel) { float percent = AbilityChoice.CalcAvgBonus(uptime, 1f + maxModel.percent) - 1f; maxModel.percent = percent; }); } public override void Apply2(TowerModel model) { //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Expected O, but got Unknown base.Apply2(model); TowerModelExt.IncreaseRange(model, 10f); List list = new List { "Moab", "Bfb", "Zomg", "Ddt", "Bad" }; DamageModel val = default(DamageModel); foreach (WeaponModel weapon in TowerModelExt.GetWeapons(model)) { for (int i = 0; i < list.Count; i++) { if (Il2CppSystemObjectExt.IsType((Object)(object)ProjectileModelExt.GetDamageModel(weapon.projectile), ref val)) { Args val2 = new Args(); ((ModelArgs)(object)val2).name = "DamageModifierForTagModel_" + i; val2.tag = list[i]; val2.damageAddative = 10 * (i + 1); val2.tags = new string[1] { list[i] }; DamageModifierForTagModel val3 = CreateDamageModifierForTagModelExt.Create(val2); ProjectileModelBehaviorExt.AddBehavior(weapon.projectile, val3); ProjectileModel projectile = weapon.projectile; projectile.pierce += 10f; val.immuneBloonProperties = (BloonProperties)0; } } } } protected override void ApplyBoth(TowerModel model) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0056: 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_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Expected O, but got Unknown //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Expected O, but got Unknown //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Expected O, but got Unknown AbilityModel val = AbilityModel(model); ActivateRangeSupportZoneModel descendant = ((Model)val).GetDescendant(); Args val2 = new Args(); ((ModelArgs)val2).name = "RangeSupportModel_"; val2.isUnique = true; val2.multiplier = descendant.multiplier; val2.additive = descendant.additive / 2f; val2.mutatorId = descendant.mutatorId; val2.filters = Il2CppArrayBase.op_Implicit((Il2CppArrayBase)(object)descendant.filters); val2.isGlobal = ((AbilityBehaviorBuffModel)descendant).isGlobal; val2.buffLocsName = ((AbilityBehaviorBuffModel)descendant).buffLocsName; val2.buffIconName = ((AbilityBehaviorBuffModel)descendant).buffIconName; RangeSupportModel val3 = CreateRangeSupportModelExt.Create(val2); TowerModelBehaviorExt.AddBehavior(model, val3); ActivateDamageModifierSupportZoneModel descendant2 = ((Model)val).GetDescendant(); Args val4 = new Args(); ((ModelArgs)val4).name = "DamageSupportModel_"; val4.isUnique = descendant2.isUnique; val4.mutatorId = descendant2.mutatorId; val4.filters = Il2CppArrayBase.op_Implicit((Il2CppArrayBase)(object)descendant2.filters); val4.isGlobal = ((AbilityBehaviorBuffModel)descendant2).isGlobal; val4.damageModifierModel = descendant2.damageModifierModel; DamageModifierSupportModel val5 = CreateDamageModifierSupportModelExt.Create(val4); TowerModelBehaviorExt.AddBehavior(model, val5); } } public class Sabotage : TowerAbilityChoice { public override string UpgradeId => "Bloon Sabotage"; public override string Description1 => "All Bloons move at partially reduced speed."; public override string Description2 => "Ninja’s attacks have more range and slow Bloons to half speed."; public override void Apply1(TowerModel model) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Expected O, but got Unknown //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Expected O, but got Unknown AbilityModel val = AbilityModel(model); SlowMinusAbilityDurationModel descendant = ((Model)val).GetDescendant(); float multiplier = AbilityChoice.CalcAvgBonus(((SlowModel)descendant).Lifespan / val.Cooldown, ((SlowModel)descendant).multiplier); AttackModel val2 = ModelExt.Duplicate(((Model)val).GetDescendant()); WeaponModel val3 = ((Il2CppArrayBase)(object)val2.weapons)[0]; val3.fireBetweenRounds = false; WeaponModelBehaviorExt.AddBehavior(val3, CreateWeaponRateMinModelExt.Create(new Args { min = 2f })); ProjectileModel projectile = ((Il2CppArrayBase)(object)val2.weapons)[0].projectile; ProjectileModelBehaviorExt.RemoveBehavior(projectile); ProjectileModelBehaviorExt.GetBehavior(projectile).Lifespan = 2f; Args val4 = new Args(); ((ModelArgs)val4).name = "Sabotage"; val4.multiplier = multiplier; val4.lifespan = 2f; val4.mutationId = ((SlowModel)descendant).mutationId; val4.layers = 999; val4.isUnique = true; SlowModel val5 = CreateSlowModelExt.Create(val4); ProjectileModelBehaviorExt.AddBehavior(projectile, val5); TowerModelBehaviorExt.AddBehavior(model, val2); } public override void Apply2(TowerModel model) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_008d: 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_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Expected O, but got Unknown TowerModelExt.IncreaseRange(model, 10f); AbilityModel val = AbilityModel(model); AttackModel val2 = ModelExt.Duplicate(((Il2CppArrayBase)(object)AbilityModelBehaviorExt.GetBehavior(val).attacks)[0]); WeaponModel val3 = ((Il2CppArrayBase)(object)val2.weapons)[0]; SlowMutator mutator = ((SlowModel)ProjectileModelBehaviorExt.GetBehavior(val3.projectile)).Mutator; SlowModifierForTagModel behavior = ProjectileModelBehaviorExt.GetBehavior(val3.projectile); Args val4 = new Args(); ((ModelArgs)val4).name = "Sabotage"; val4.multiplier = 0.5f; val4.lifespan = 2f; val4.mutationId = mutator.mutationId; val4.layers = 999; val4.isUnique = true; val4.mutator = mutator; SlowModel val5 = CreateSlowModelExt.Create(val4); DamageModel val6 = default(DamageModel); foreach (WeaponModel weapon in TowerModelExt.GetWeapons(model)) { if (Il2CppSystemObjectExt.IsType((Object)(object)ProjectileModelExt.GetDamageModel(weapon.projectile), ref val6)) { ProjectileModelBehaviorExt.AddBehavior(weapon.projectile, val5); ProjectileModelBehaviorExt.AddBehavior(weapon.projectile, behavior); ProjectileModel projectile = weapon.projectile; projectile.pierce += 5f; val6.immuneBloonProperties = (BloonProperties)0; } } } } } namespace AbilityChoice.AbilityChoices.Magic.Mermonkey { public class IceJet : TowerAbilityChoice { public override string AbilityName => "MermonkyAbility"; public override string UpgradeId => "Arctic Knight"; public override string Description1 => "Tridents can pop Lead Bloons and grow in power faster. Also launches bouncing ice balls following target priority, or targeted point."; public override void Apply1(TowerModel model) { AbilityModel val = AbilityModel(model); ActivateAttackModel behavior = AbilityModelBehaviorExt.GetBehavior(val); AttackModel val2 = ModelExt.Duplicate(((Il2CppArrayBase)(object)behavior.attacks)[0]); ((Model)val2).name = "AttackModel_Attack_IceBalls"; val2.range = model.range; float num = behavior.Lifespan / val.Cooldown; EffectModel effectModel = AttackModelBehaviorExt.GetBehavior(val2).effectModel; effectModel.lifespan /= 3f; WeaponModel val3 = ((Il2CppArrayBase)(object)val2.weapons)[0]; val3.rate /= num; TowerModelBehaviorExt.AddBehavior(model, val2); } } public class IceJetBig : IceJet { private const int Factor = 3; public override string AbilityName => "MermonkyAbilityBig"; public override string UpgradeId => "Popseidon"; public override string Description1 => "Popseidon draws such power that a rogue wave periodically floods the map with supercooled water, freezing all Bloons and reclaiming the weak for the sea."; public override void Apply1(TowerModel model) { //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Expected O, but got Unknown //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Expected O, but got Unknown base.Apply1(model); AbilityModel val = AbilityModel(model); AttackModel attackModel = TowerModelExt.GetAttackModel(model, "IceBalls"); WeaponModel val2 = ((Il2CppArrayBase)(object)attackModel.weapons)[1]; val2.Rate = val.Cooldown / 3f; DamageModel descendant = ((Model)val2).GetDescendant(); descendant.damage /= 3f; SlowModel descendant2 = ((Model)val2).GetDescendant(); descendant2.Lifespan /= 3f; EffectModel effectModel = AbilityModelBehaviorExt.GetBehavior(val).effectModel; CreateSoundOnAbilityModel behavior = AbilityModelBehaviorExt.GetBehavior(val); effectModel.useCenterPosition = true; WeaponModelBehaviorExt.AddBehavior(val2, CreateEjectEffectModelExt.Create(new Args { effectModel = effectModel, lifespan = effectModel.lifespan, fullscreen = effectModel.fullscreen })); WeaponModelBehaviorExt.AddBehavior(val2, CreateCreateSoundOnProjectileCreatedModelExt.Create(new Args { sound1 = behavior.sound, sound2 = behavior.sound, sound3 = behavior.sound, sound4 = behavior.sound, sound5 = behavior.sound })); } } } namespace AbilityChoice.AbilityChoices.Magic.Druid { public class PrimordialWrath : TowerAbilityChoice { [HarmonyPatch(typeof(PrimordialWrath), "AddDebuff")] internal static class PrimordialWrathSim_AddDebuff { [HarmonyPrefix] internal static bool Prefix(PrimordialWrath __instance, Tower tower) { return !ModContent.GetInstance().Enabled || ((TowerBehavior)((AbilityBehavior)__instance).ability).tower == tower; } } private const float Factor1 = 0.25f; private const float Factor2 = 0.3f; public override string UpgradeId => "Druid Paragon"; public override string Description1 => "That from which all life branches. " + $"Toggle to forego its own income generation to go into a {0.25f:P0} effectiveness Wrathful state."; public override string Description2 => "That from which all life branches. " + $"Permanently foregoes all of its own income generation to always be in a {0.3f:P0} effectiveness Wrathful state."; public override void Apply1(TowerModel model) { AbilityModel val = AbilityModel(model); AbilityModelBehaviorExt.RemoveBehavior(val); PrimordialWrathModel behavior = AbilityModelBehaviorExt.GetBehavior(val); int num = (behavior.cashPerSecondMax = 0); int num3 = (behavior.cashPerSecondMin = num); float depletionPercent = (behavior.depletionAsMultiplier = num3); behavior.depletionPercent = depletionPercent; behavior.maxMultiplier = 1f + (behavior.maxMultiplier - 1f) * 0.25f; behavior.damageMultiplierPerThreshold *= 0.25f; behavior.rangeMultiplier = 1f + (behavior.rangeMultiplier - 1f) * 0.25f; behavior.attackSpreadMultiplier = 1f - (1f - behavior.attackSpreadMultiplier) * 0.25f; behavior.wrathActiveSound = null; behavior.wrathInactiveSound = null; } public override void Apply2(TowerModel model) { TowerModelBehaviorExt.RemoveBehavior(model, "Passive"); TowerModelBehaviorExt.RemoveBehavior(model); AbilityModel val = AbilityModel(model); PrimordialWrathModel primordialWrath = AbilityModelBehaviorExt.GetBehavior(val); ParagonTowerModel behavior = TowerModelBehaviorExt.GetBehavior(model); ModelExt.RemoveChildDependants((Model)(object)behavior, (IEnumerable)behavior.displayDegreePaths); behavior.displayDegreePaths = primordialWrath.displayDegreePaths; ModelExt.AddChildDependants((Model)(object)behavior, (IEnumerable)behavior.displayDegreePaths); ProjectileModelExt.SetDisplay(((Model)TowerModelExt.GetAttackModel(model)).GetDescendant(), primordialWrath.wrathProjectileDisplay.assetPath); ProjectileModelExt.SetDisplay(((Model)((Model)TowerModelExt.GetAttackModel(model, "Spawner")).GetDescendant()).GetDescendant(), primordialWrath.wrathSubtowerProjectileDisplay.assetPath); Il2CppGenericIEnumerable.ForEach(((Model)model).GetDescendants(), (Action)delegate(DamageModifierPrimordialWrathModel wrath) { wrath.active = true; wrath.damageMultiplier *= 0.3f; wrath.maxDamageMultiplier = 1f + (wrath.maxDamageMultiplier - 1f) * 0.3f; }); model.range *= 1f + (primordialWrath.rangeMultiplier - 1f) * 0.3f; foreach (AttackModel attackModel in TowerModelExt.GetAttackModels(model)) { attackModel.range *= 1f + (primordialWrath.rangeMultiplier - 1f) * 0.3f; } Il2CppGenericIEnumerable.ForEach(((Model)model).GetDescendants(), (Action)delegate(ArcEmissionModel emissionModel) { emissionModel.angle *= 1f - (1f - primordialWrath.attackSpreadMultiplier) * 0.3f; }); } protected override void RemoveAbility(TowerModel model) { if (base.Mode2) { base.RemoveAbility(model); } } } public class VineCrush2 : VineCrush { public override string UpgradeId => "Spirit of the Forest"; public override string Description1 => "Grows thorned vines along the path that deal constant damage and bonus damage to ceramics. Vines nearest the Spirit of the Forest do more damage. Crushing vines grab more Bloons."; public override string AbilityName => "Vine Crush"; protected override int Order => -1; protected override void ApplyBoth(TowerModel model) { AbilityModel val = ((IEnumerable)TowerModelBehaviorExt.GetBehaviors(model)).FirstOrDefault((Func)((AbilityModel ability) => ability.displayName == "Vine Rupture")); if (val != null) { float damage = ProjectileModelExt.GetDamageModel(AbilityModelBehaviorExt.GetBehavior(val).projectileModel).damage; float cooldown = val.Cooldown; SpiritOfTheForestModel behavior = TowerModelBehaviorExt.GetBehavior(model); DamageOverTimeModel behaviorModel = behavior.damageOverTimeZoneModelFar.behaviorModel; behaviorModel.damage += behaviorModel.Interval * damage / cooldown; TowerModelBehaviorExt.RemoveBehavior(model, val); } } } public class VineCrush : TowerAbilityChoice { public override string UpgradeId => "Jungle's Bounty"; public override string Description1 => "Vines create stronger thorn piles. Druid generates cash and lives at the end of each round, plus extra cash per Banana Farm near the Druid. Periodically crushes multiple Bloons at once."; public virtual int Factor => 5; public override void Apply1(TowerModel model) { AbilityModel val = AbilityModel(model); AttackModel descendant = ((Model)val).GetDescendant(); ((Il2CppArrayBase)(object)descendant.weapons)[0].Rate = val.Cooldown / (float)Factor; MultiInstantEmissionModel descendant2 = ((Model)descendant).GetDescendant(); descendant2.amount /= Factor; JungleVineLimitProjectileModel descendant3 = ((Model)descendant).GetDescendant(); descendant3.limit /= Factor; TowerModelBehaviorExt.AddBehavior(model, descendant); } } } namespace AbilityChoice.AbilityChoices.Magic.Alchemist { public class TotalTransformingTonic : TransformingTonic { [HarmonyPatch(typeof(MorphTower), "UpdatedModel")] internal static class MorphTower_UpdatedModel { [HarmonyPrefix] internal static void Prefix(MorphTower __instance, Model modelToUse) { if (!(((EntityModel)((TowerBehavior)((AbilityBehavior)__instance).ability).tower.towerModel).baseId != TowerType.Alchemist)) { TotalTransformingTonic instance = ModContent.GetInstance(); if (instance != null && instance.Mode == 1) { MorphTowerModel model = ((Il2CppObjectBase)modelToUse).Cast(); AbilityModel abilityModel = ((Model)((TowerBehavior)((AbilityBehavior)__instance).ability).tower.towerModel).GetDescendant().abilityModel; instance.ModifyModel(model, abilityModel); } } } } [HarmonyPatch(typeof(MorphTower), "Activate")] internal static class MorphTower_Activate { [HarmonyPrefix] internal static void Prefix(MorphTower __instance) { if (!(((EntityModel)((TowerBehavior)((AbilityBehavior)__instance).ability).tower.towerModel).baseId != TowerType.Alchemist)) { TotalTransformingTonic instance = ModContent.GetInstance(); if (instance != null && instance.Mode == 1) { MorphTowerModel morphTowerModel = __instance.morphTowerModel; AbilityModel abilityModel = ((Model)((TowerBehavior)((AbilityBehavior)__instance).ability).tower.towerModel).GetDescendant().abilityModel; instance.ModifyModel(morphTowerModel, abilityModel); } } } } [CompilerGenerated] [DebuggerBrowsable(DebuggerBrowsableState.Never)] private MorphTowerModel k__BackingField; private const int Factor = 8; public override string UpgradeId => "Total Transformation"; public override string Description1 => "Has a monstrous laser attack, and 3+ nearby Monkeys are constantly transformed into monsters."; public override string Description2 => "Transforms just itself permanently into an even more powerful monster!"; public MorphTowerModel BaseModel => k__BackingField ?? (k__BackingField = AbilityModelBehaviorExt.GetBehavior(AbilityModel(GetAffected(Game.instance.model).MinBy((TowerModel model) => ((IEnumerable)model.tiers).Sum())))); public override void Apply1(TowerModel model) { base.Apply1(model); AbilityModel val = AbilityModel(model); MorphTowerModel behavior = AbilityModelBehaviorExt.GetBehavior(val); val.Cooldown /= 8f; ModifyModel(behavior, val); behavior.effectModel.assetId = ModContent.CreatePrefabReference(""); behavior.effectOnTransitionBackModel.assetId = ModContent.CreatePrefabReference(""); AbilityModelBehaviorExt.RemoveBehavior(val); AbilityModelBehaviorExt.RemoveBehavior(val); AbilityModelBehaviorExt.RemoveBehavior(val); AbilityModelBehaviorExt.RemoveBehavior(val); AbilityModelBehaviorExt.RemoveBehavior(val); } public override void Apply2(TowerModel model) { AbilityModel val = AbilityModel(model); AttackModel val2 = ModelExt.Duplicate(((Il2CppArrayBase)(object)AbilityModelBehaviorExt.GetBehavior(val).attacks)[0]); WeaponModel val3 = ((Il2CppArrayBase)(object)val2.weapons)[0]; val3.Rate /= 2f; ProjectileModel projectile = val3.projectile; projectile.pierce *= 3f; DamageModel damageModel = ProjectileModelExt.GetDamageModel(val3.projectile); damageModel.damage *= 2f; val2.range = model.range; TowerModelBehaviorExt.AddBehavior(model, val2); TowerModelExt.IncreaseRange(model, AbilityModelBehaviorExt.GetBehavior(val).addative); PrefabReference display = AbilityModelBehaviorExt.GetBehavior(val).display; PrefabReference display2 = (TowerModelBehaviorExt.GetBehavior(model).display = display); ((EntityModel)model).display = display2; } protected override void RemoveAbility(TowerModel model) { if (base.Mode2) { base.RemoveAbility(model); } else { TechBotify(model); } } public void ModifyModel(MorphTowerModel model, AbilityModel ability) { model.lifespanFrames = (int)Math.Round((float)AbilityModelExt.EffectiveCooldownFrames(ability)) + 2; model.lifespan = (float)model.lifespanFrames / 60f; model.maxTowers = Math.CeilToInt((float)BaseModel.maxTowers * BaseModel.lifespan / (AbilityModelExt.EffectiveCooldown(ability) * 8f)); } } public class TransformingTonic : TowerAbilityChoice { public override string UpgradeId => "Transforming Tonic"; public override string Description1 => "Gains a monstrous laser beam attack."; public override string Description2 => "Gains a monstrous laser beam attack (with the looks to match it)."; public override void Apply1(TowerModel model) { AbilityModel val = AbilityModel(model); ActivateAttackModel behavior = AbilityModelBehaviorExt.GetBehavior(val); AttackModel val2 = ModelExt.Duplicate(((Il2CppArrayBase)(object)behavior.attacks)[0]); WeaponModel val3 = ((Il2CppArrayBase)(object)val2.weapons)[0]; float num = behavior.Lifespan / val.Cooldown; val2.range = model.range; val3.rate /= num; TowerModelBehaviorExt.AddBehavior(model, val2); TowerModelExt.IncreaseRange(model, AbilityModelBehaviorExt.GetBehavior(val).addative * num); } public override void Apply2(TowerModel model) { Apply1(model); AbilityModel val = AbilityModel(model); PrefabReference display = AbilityModelBehaviorExt.GetBehavior(val).display; PrefabReference display2 = (TowerModelBehaviorExt.GetBehavior(model).display = display); ((EntityModel)model).display = display2; } } } namespace AbilityChoice.AbilityChoices.Hero.StrikerJones { public class ArtilleryCommand : HeroAbilityChoice { public override string HeroId => TowerType.StrikerJones; public override Dictionary Descriptions1 => new Dictionary { { 10, "All Bomb Shooters and Mortar Monkeys have 50% reduced ability cooldowns." }, { 20, "All Bomb Shooters and Mortar Monkeys have increased damage and pops per shot." } }; public override Dictionary Descriptions2 => new Dictionary { { 10, "All Bomb Shooters and Mortar Monkeys deal 25% increased damage to Stunned bloons." }, { 20, "All Bomb Shooters and Mortar Monkeys have increased damage and pops per shot." } }; private static TowerFilterModel[] Filters { get { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Expected O, but got Unknown TowerFilterModel[] array = new TowerFilterModel[1]; Args val = new Args(); val.baseIds = new string[2] { TowerType.BombShooter, TowerType.MortarMonkey }; array[0] = (TowerFilterModel)CreateFilterInBaseTowerIdModelExt.Create(val); return (TowerFilterModel[])(object)array; } } public override void Apply1(TowerModel model) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown TowerModelBehaviorExt.AddBehavior(model, CreateAbilityCooldownScaleSupportModelExt.Create(new Args { abilityCooldownSpeedScale = 2f, isGlobal = true, filters = Filters, buffLocsName = "ArtilleryCommanderBuff", buffIconName = "BuffIconStrikerJones", onlyShowBuffIfMutated = true })); } public override void Apply2(TowerModel model) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown //IL_0068: Expected O, but got Unknown TowerModelBehaviorExt.AddBehavior(model, CreateDamageModifierSupportModelExt.Create(new Args { isUnique = true, mutatorId = ((ModContent)this).Name + "StunDamage", filters = Filters, isGlobal = true, damageModifierModel = (DamageModifierModel)(object)CreateDamageModifierForBloonStateModelExt.Create(new Args { bloonState = "Stun", damageMultiplier = 1.25f }) })); } protected override void ApplyBoth(TowerModel model) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0055: 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_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected O, but got Unknown //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Expected O, but got Unknown if (model.tier >= 20) { AbilityModel val = AbilityModel(model); float num = AbilityChoice.CalcAvgBonus((float)((Model)val).GetDescendant().buffFrames / (float)val.cooldownFrames, 2f); Args val2 = new Args(); ((ModelArgs)val2).name = "MULT"; val2.isUnique = true; val2.pierce = num; val2.mutatorId = ((ModContent)this).Name + "Pierce"; val2.filters = Filters; val2.isGlobal = true; val2.buffLocsName = "ArtilleryCommanderBuff"; val2.buffIconName = "BuffIconStrikerJones"; TowerModelBehaviorExt.AddBehavior(model, CreatePierceSupportModelExt.Create(val2)); TowerModelBehaviorExt.AddBehavior(model, CreateDamageSupportModelExt.Create(new Args { isUnique = true, increase = num - 1f, mutatorId = ((ModContent)this).Name + "Damage", filters = Filters, isGlobal = true, buffLocsName = "ArtilleryCommanderBuff", buffIconName = "BuffIconStrikerJones" })); } } } public class ConcussiveShell : HeroAbilityChoice { private const int Factor = 2; private const int Factor2 = 10; public override string HeroId => TowerType.StrikerJones; public override Dictionary Descriptions1 => new Dictionary { { 3, "Occasionally shoots a shell at the strongest Bloon on screen, stunning and damaging it." }, { 15, "Concussive Shells are fired more frequently." } }; public override Dictionary Descriptions2 => new Dictionary { { 3, "Normal attacks will briefly stuns Bloons." }, { 9, "Increased attack speed and attack stun duration." }, { 14, "Increased blast radius and stun duration." }, { 15, "Increased pierce." } }; public override void Apply1(TowerModel model) { AbilityModel val = AbilityModel(model); AttackModel val2 = ModelExt.Duplicate(((Model)val).GetDescendant(), "ConcussiveShell"); WeaponModel val3 = ((Il2CppArrayBase)(object)val2.weapons)[0]; Il2CppGenericIEnumerable.ForEach(((Model)val3).GetDescendants(), (Action)delegate(DamageModel damageModel) { damageModel.damage /= 2f; }); Il2CppGenericIEnumerable.ForEach(((Model)val3).GetDescendants(), (Action)delegate(SlowModel slowModel) { slowModel.Lifespan /= 2f; slowModel.dontRefreshDuration = true; }); Il2CppGenericIEnumerable.ForEach(((Model)val3).GetDescendants(), (Action)delegate(SlowModifierForTagModel slowModel) { slowModel.lifespanOverride /= 2f; }); val3.rate = val.Cooldown / 2f; TowerModelBehaviorExt.AddBehavior(model, val2); } public override void Apply2(TowerModel model) { AbilityModel val = AbilityModel(model); SlowModel val2 = ModelExt.Duplicate(((Model)val).GetDescendant()); IEnumerable enumerable = from modifier in Il2CppGenericIEnumerableExt.ToList(((Model)val).GetDescendants()) select ModelExt.Duplicate(modifier); ProjectileModel val3 = Il2CppGenericIEnumerableExt.ToList(((Model)TowerModelExt.GetAttackModel(model)).GetDescendants()).First((ProjectileModel projectileModel) => ProjectileModelExt.GetDamageModel(projectileModel) != null); val2.Lifespan /= 10f; val2.dontRefreshDuration = true; ProjectileModelBehaviorExt.AddBehavior(val3, val2); foreach (SlowModifierForTagModel item in enumerable) { item.lifespanOverride /= 10f; ProjectileModelBehaviorExt.AddBehavior(val3, item); } val3.UpdateCollisionPassList(); if (model.tier >= 15) { DamageModel damageModel = ProjectileModelExt.GetDamageModel(val3); float damage = damageModel.damage; damageModel.damage = damage + 1f; val3.pierce += 12f; } } } public class TargetFocus : HeroAbilityChoice { [HarmonyPatch(typeof(MutatorTower), "Mutate")] internal static class ProjectileRadiusSupport_MutatorTower_Mutate { [HarmonyPrefix] private static void Prefix(MutatorTower __instance, Model model) { TowerModel val = default(TowerModel); if (!(((BehaviorMutator)__instance).id != "StrikerJonesProjectileRadiusBuff") && Il2CppSystemObjectExt.Is((Il2CppObjectBase)(object)model, ref val) && !(((EntityModel)val).baseId != TowerType.MortarMonkey) && ModContent.GetInstance().Enabled) { Il2CppGenericIEnumerable.ForEach(model.GetDescendants(), (Action)delegate(RandomTargetSpreadModel spreadModel) { spreadModel.spread *= 0.75f; }); } } } public override string HeroId => TowerType.StrikerJones; public override Dictionary Descriptions1 => new Dictionary { { 7, "Pops 2 layers per shot and Mortar Monkeys blast radius increased by 10% and accuracy increased by 25%." } }; } } namespace AbilityChoice.AbilityChoices.Hero.Silas { public class Frostbite : HeroAbilityChoice { private const int Factor = 3; public override string HeroId => TowerType.Silas; public override Dictionary Descriptions1 => new Dictionary { { 3, "Periodically Silas can hit all Bloons types for a short duration, doing extra damage to Frozen Bloons based on remaining freeze time." }, { 9, "Frozen Bloons take more damage from Frostbite attacks. Ice Fragment damage & pierce increased." }, { 15, "Frozen Bloons take more damage from all special attacks, and special attacks are more frequent." }, { 20, "Frozen Bloons take even more damage from Frostbite attacks. Silas creates Ice Walls more often. Monkeys that freeze Bloons freeze them yet longer again." } }; public override Dictionary Descriptions2 => new Dictionary { { 3, "Every 4th attack can hit all Bloons types and does extra damage to Frozen Bloons based on remaining freeze time." }, { 9, "Frozen Bloons take more damage from Frostbite attacks. Ice Fragment damage & pierce increased." }, { 15, "Frozen Bloons take more damage from all special attacks, and special attacks are more frequent." }, { 20, "Frozen Bloons take even more damage from Frostbite attacks. Silas creates Ice Walls more often. Monkeys that freeze Bloons freeze them yet longer again." } }; public override void Apply1(TowerModel model) { AbilityModel val = AbilityModel(model); val.Cooldown /= 3f; AbilityModelBehaviorExt.RemoveBehavior(val); ChangeDamageTypeModel behavior = AbilityModelBehaviorExt.GetBehavior(val); behavior.lifespanFrames /= 3; MutateProjectileOnAbilityModel behavior2 = AbilityModelBehaviorExt.GetBehavior(val); behavior2.lifespanFrames /= 3; } public override void Apply2(TowerModel model) { //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Expected O, but got Unknown AbilityModel val = AbilityModel(model); int interval = ((model.tier >= 15) ? 3 : 4); WeaponModel child = ((Model)TowerModelExt.GetAttackModel(model)).GetChild(); ProjectileModel projectile = ModelExt.Duplicate(child.projectile); Il2CppGenericIEnumerable.ForEach(((Model)projectile).GetDescendants(), (Action)delegate(DamageModel damageModel) { damageModel.immuneBloonProperties = (BloonProperties)0; }); AbilityModelBehaviorExt.GetBehaviors(val).ForEach(delegate(MutateProjectileOnAbilityModel mutate) { DamageModel damageModel = ProjectileModelExt.GetDamageModel(projectile); damageModel.damage += (float)mutate.damageIncrease; ProjectileModelBehaviorExt.AddBehavior(projectile, mutate.projectileBehaviorModel); projectile.hasDamageModifiers = true; }); AlternateProjectileModel val2 = CreateAlternateProjectileModelExt.Create(new Args { projectile = projectile, interval = interval }); WeaponModelBehaviorExt.AddBehavior(child, val2); } protected override void RemoveAbility(TowerModel model) { if (base.Mode2) { base.RemoveAbility(model); } else { TechBotify(model); } } } public class FrozenBurial : HeroAbilityChoice { private const int Factor = 6; public override string HeroId => TowerType.Silas; public override Dictionary Descriptions1 => new Dictionary { { 10, "Periodically freezes and damages all Bloons, dealing more damage to already frozen Bloons, then fills the track with mini Ice Walls." } }; public override Dictionary Descriptions2 => new Dictionary { { 10, "Silas creates more Ice Walls, and Ice Walls now deal damage to Bloons." } }; public override void Apply1(TowerModel model) { AbilityModel val = AbilityModel(model); val.Cooldown /= 6f; AbilityModelBehaviorExt.RemoveBehavior(val); AbilityModelBehaviorExt.RemoveBehavior(val, "CornerFX"); AbilityModelBehaviorExt.RemoveBehavior(val, "Snow"); ProjectileModel projectile = AbilityModelBehaviorExt.GetBehavior(val).projectile; Il2CppGenericIEnumerable.ForEach(((Model)projectile).GetDescendants(), (Action)delegate(DamageModel damage) { damage.damage /= 6f; }); Il2CppGenericIEnumerable.ForEach(((Model)projectile).GetDescendants(), (Action)delegate(DamageModifierForBloonStateModel state) { state.damageAdditive /= 6f; }); Il2CppGenericIEnumerable.ForEach(((Model)projectile).GetDescendants(), (Action)delegate(FreezeModel freeze) { freeze.Lifespan /= 6f; }); Il2CppGenericIEnumerable.ForEach(((Model)projectile).GetDescendants(), (Action)delegate(AddHeatToBloonModel heat) { heat.heatAmount /= 6f; }); FrozenBurialModel behavior = AbilityModelBehaviorExt.GetBehavior(val); behavior.icewallDelay /= 3; behavior.timePerIcewall /= 3; ProjectileModel icewallProjectile = behavior.icewallProjectile; icewallProjectile.scale = 0.67f; icewallProjectile.radius = 2f; Il2CppGenericIEnumerable.ForEach(((Model)icewallProjectile).GetDescendants(), (Action)delegate(AgeModel age) { age.Lifespan /= 2f; }); Il2CppGenericIEnumerable.ForEach(((Model)icewallProjectile).GetDescendants(), (Action)delegate(DamageModel damage) { damage.damage /= 3f; }); Il2CppGenericIEnumerable.ForEach(((Model)icewallProjectile).GetDescendants(), (Action)delegate(FreezeModel freeze) { freeze.Lifespan /= 3f; }); } public override void Apply2(TowerModel model) { //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Expected O, but got Unknown AbilityModel val = AbilityModel(model); ProjectileModel projectile = AbilityModelBehaviorExt.GetBehavior(val).projectile; AttackModel attackModel = TowerModelExt.GetAttackModel(model, "Icewall"); WeaponModel val2 = ((Il2CppArrayBase)(object)attackModel.weapons)[0]; ProjectileModel projectile2 = val2.projectile; attackModel.range = model.range; val2.Rate *= val.Cooldown / 180f; DamageModel val3 = ModelExt.Duplicate(ProjectileModelBehaviorExt.GetBehavior(projectile)); val3.damage = 2f; ProjectileModelBehaviorExt.AddBehavior(projectile2, val3); foreach (CollideExtraPierceReductionModel behavior in ProjectileModelBehaviorExt.GetBehaviors(projectile2)) { ProjectileModelBehaviorExt.AddBehavior(projectile2, CreateDamageModifierForTagModelExt.Create(new Args { tag = behavior.bloonTag, damageAddative = behavior.extraAmount * 2 })); } } protected override void RemoveAbility(TowerModel model) { if (base.Mode2) { base.RemoveAbility(model); } else { TechBotify(model); } } } public class FrozenCascade : HeroAbilityChoice { private const int Factor = 5; public override string HeroId => TowerType.Silas; public override Dictionary Descriptions1 => new Dictionary { { 7, "Occasionally creates shattering blasts of ice around Silas then other Ice Monkeys spreading out from Silas. Frozen Bloons take extra damage." } }; public override Dictionary Descriptions2 => new Dictionary { { 7, "The Ice Fragments of nearby Ice Monkey can hit all Bloon types and do more damage, further increased against Frozen Bloons." } }; public override void Apply1(TowerModel model) { AbilityModel val = AbilityModel(model); val.Cooldown /= 5f; AbilityModelBehaviorExt.RemoveBehavior(val); Il2CppGenericIEnumerable.ForEach(((Model)val).GetDescendants(), (Action)delegate(DamageModel damage) { damage.damage /= 5f; }); Il2CppGenericIEnumerable.ForEach(((Model)val).GetDescendants(), (Action)delegate(DamageModifierForTagModel modifier) { modifier.damageAddative /= 5f; }); Il2CppGenericIEnumerable.ForEach(((Model)val).GetDescendants(), (Action)delegate(FreezeModel freeze) { freeze.Lifespan /= 5f; }); Il2CppGenericIEnumerable.ForEach(((Model)val).GetDescendants(), (Action)delegate(AddHeatToBloonModel heat) { heat.heatAmount /= 5f; }); } public override void Apply2(TowerModel model) { AbilityModel ability = AbilityModel(model); ProjectileModel iceFragmentProjectileModel = TowerModelBehaviorExt.GetBehavior(model).iceFragmentProjectileModel; Il2CppGenericIEnumerable.ForEach(((Model)iceFragmentProjectileModel).GetDescendants(), (Action)delegate(DamageModel damage) { damage.damage *= 120f / ability.Cooldown; damage.immuneBloonProperties = (BloonProperties)0; damage.immuneBloonPropertiesOriginal = (BloonProperties)0; }); Il2CppGenericIEnumerable.ForEach(((Model)iceFragmentProjectileModel).GetDescendants(), (Action)delegate(DamageModifierForBloonStateModel state) { state.damageAdditive *= 120f / ability.Cooldown; }); } protected override void RemoveAbility(TowerModel model) { if (base.Mode2) { base.RemoveAbility(model); } else { TechBotify(model); } } } } namespace AbilityChoice.AbilityChoices.Hero.Sauda { public class LeapingSwordAttack : HeroAbilityChoice { private const int Factor = 5; public override string HeroId => TowerType.Sauda; public override Dictionary Descriptions1 => new Dictionary { { 3, "Sauda can throw blades on her targeted Bloons that stick in the track and can pop Lead Bloons." } }; public override Dictionary Descriptions2 => new Dictionary { { 3, "Saudas swords leap out to nearby enemies beyond her range." } }; public override void Apply1(TowerModel model) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Expected O, but got Unknown //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Expected O, but got Unknown //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Expected O, but got Unknown //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Expected O, but got Unknown AbilityModel val = AbilityModel(model); LeapingSwordModel behavior = AbilityModelBehaviorExt.GetBehavior(val); ProjectileModel impactProjectileModel = behavior.impactProjectileModel; ProjectileModel dotProjectileModel = behavior.dotProjectileModel; float num = 0.2f; PrefabReference display = (ProjectileModelBehaviorExt.GetBehavior(impactProjectileModel).display = dotProjectileModel.display); impactProjectileModel.display = display; Args val2 = new Args(); val2.timeToTake = num; val2.curveSamples = new float[2] { 0.95f, 1f }; val2.filterCollisionWhileMoving = true; val2.stopOnTargetReached = true; val2.keepUpdatingTargetPos = true; val2.positionAboveMoabTypes = true; ProjectileModelBehaviorExt.AddBehavior(impactProjectileModel, CreateArriveAtTargetModelExt.Create(val2)); AgeModel behavior2 = ProjectileModelBehaviorExt.GetBehavior(impactProjectileModel); behavior2.Lifespan += num; DamageModel behavior3 = ProjectileModelBehaviorExt.GetBehavior(impactProjectileModel); behavior3.damage /= 5f; ProjectileModelBehaviorExt.GetBehaviors(impactProjectileModel).ForEach(delegate(DamageModifierForTagModel modifier) { modifier.damageAddative /= 5f; }); Il2CppGenericIEnumerable.ForEach(((Model)impactProjectileModel).GetDescendants(), (Action)delegate(SaudaAfflictionDamageModifierModel saudaDamage) { saudaDamage.lv7MoabBonus /= 5f; saudaDamage.lv11MoabBonus /= 5f; saudaDamage.lv19MoabBonus /= 5f; saudaDamage.lv7NonMoabBonus /= 5f; saudaDamage.lv11NonMoabBonus /= 5f; saudaDamage.lv19NonMoabBonus /= 5f; }); AgeModel behavior4 = ProjectileModelBehaviorExt.GetBehavior(dotProjectileModel); behavior4.Lifespan /= 5f; ProjectileModelBehaviorExt.AddBehavior(impactProjectileModel, CreateCreateProjectileOnExpireModelExt.Create(new Args { projectile = dotProjectileModel, emission = (EmissionModel)(object)CreateSingleEmissionModelExt.Create(), useRotation = true })); AttackModel attackModel = TowerModelExt.GetAttackModel(model); Args val3 = new Args(); ((ModelArgs)(object)val3).name = ((ModContent)this).Name; val3.range = 9999f; val3.behaviors = Il2CppArrayBase.op_Implicit((Il2CppArrayBase)(object)attackModel.behaviors); val3.attackThroughWalls = true; Args val4 = new Args(); val4.animation = -1; val4.rate = val.Cooldown / 5f; val4.eject = new Vector3(0f, 0f, 9999f); Args val5 = new Args(); val5.behaviors = (EmissionBehaviorModel[])(object)new EmissionBehaviorModel[1] { (EmissionBehaviorModel)CreateEmissionRotationZeroModelExt.Create() }; val4.emission = (EmissionModel)(object)CreateSingleEmissionModelExt.Create(val5); val4.projectile = impactProjectileModel; val3.weapon = CreateWeaponModelExt.Create(val4); AttackModel val6 = CreateAttackModelExt.Create(val3); TowerModelBehaviorExt.AddBehavior(model, val6); } public override void Apply2(TowerModel model) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected O, but got Unknown //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Expected O, but got Unknown //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Expected O, but got Unknown //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Expected O, but got Unknown //IL_01e0: Expected O, but got Unknown AbilityModel val = AbilityModel(model); LeapingSwordModel behavior = AbilityModelBehaviorExt.GetBehavior(val); ProjectileModel dotProjectileModel = behavior.dotProjectileModel; WeaponModel descendant = ((Model)model).GetDescendant(); ProjectileModelBehaviorExt.RemoveBehavior(dotProjectileModel); ProjectileModelBehaviorExt.RemoveBehavior(dotProjectileModel); ProjectileModelBehaviorExt.RemoveBehavior(dotProjectileModel); dotProjectileModel.pierce = descendant.projectile.pierce * 2f; dotProjectileModel.ignorePierceExhaustion = false; ProjectileModelBehaviorExt.AddBehavior(dotProjectileModel, CreateTravelStraitModelExt.Create(new Args { speed = 150f, lifespan = 0.5f })); ProjectileModelBehaviorExt.AddBehavior(dotProjectileModel, CreateTrackTargetModelExt.Create(new Args { distance = 999f, trackNewTargets = true, maxSeekAngle = 180f, turnRate = 1000f, useLifetimeAsDistance = true })); DamageModel damageModel = ProjectileModelExt.GetDamageModel(dotProjectileModel); damageModel.damage /= 5f; SaudaAfflictionDamageModifierModel val2 = default(SaudaAfflictionDamageModifierModel); if (ProjectileModelBehaviorExt.HasBehavior(dotProjectileModel, ref val2)) { SaudaAfflictionDamageModifierModel obj = val2; obj.lv7MoabBonus /= 5f; SaudaAfflictionDamageModifierModel obj2 = val2; obj2.lv11MoabBonus /= 5f; SaudaAfflictionDamageModifierModel obj3 = val2; obj3.lv19MoabBonus /= 5f; SaudaAfflictionDamageModifierModel obj4 = val2; obj4.lv7NonMoabBonus /= 5f; SaudaAfflictionDamageModifierModel obj5 = val2; obj5.lv11NonMoabBonus /= 5f; SaudaAfflictionDamageModifierModel obj6 = val2; obj6.lv19NonMoabBonus /= 5f; } Args val3 = new Args(); ((ModelArgs)val3).name = ((ModContent)this).Name; val3.range = model.range; val3.CanSeeCamo = true; val3.weapon = CreateWeaponModelExt.Create(new Args { animation = -1, rate = descendant.Rate * 2f, emission = (EmissionModel)(object)CreateSingleEmissionModelExt.Create(), eject = WeaponModelExt.GetEject(descendant), projectile = dotProjectileModel }); TowerModelBehaviorExt.AddBehavior(model, CreateAttackModelExt.Create(val3)); } } public class SwordCharge : HeroAbilityChoice { public const float Factor = 5f; public override string HeroId => TowerType.Sauda; public override Dictionary Descriptions1 => new Dictionary { { 10, "Sauda sends mirages of herself along the track, devastating Bloons as she goes." }, { 14, "Sauda attacks even faster, and Sword Charge mirages are sent twice as often!" }, { 20, "Sword Charge and Leaping Sword power greatly increased." } }; public override Dictionary Descriptions2 => new Dictionary { { 10, "Sauda sends mirages of herself forward towards Bloons." }, { 14, "Sauda attacks even faster, and Sword Charge mirages are sent twice as often!" }, { 20, "Sword Charge and Leaping Sword power greatly increased." } }; public override void Apply1(TowerModel model) { AbilityModel val = AbilityModel(model); SwordChargeModel behavior = AbilityModelBehaviorExt.GetBehavior(val); AbilityModelBehaviorExt.RemoveBehavior(val); AbilityModelBehaviorExt.RemoveBehavior(val); behavior.landingSound = null; behavior.spawnSound = null; behavior.effectAtEndModel = null; val.Cooldown /= 5f; float factor = (float)behavior.iterations / 5f; Il2CppGenericIEnumerable.ForEach(((Model)behavior).GetDescendants(), (Action)delegate(DamageModel damage) { damage.damage *= factor; }); Il2CppGenericIEnumerable.ForEach(((Model)behavior).GetDescendants(), (Action)delegate(DamageModifierForTagModel modifier) { modifier.damageAddative *= factor; }); Il2CppGenericIEnumerable.ForEach(((Model)behavior).GetDescendants(), (Action)delegate(SaudaAfflictionDamageModifierModel modifier) { modifier.lv7NonMoabBonus *= factor; modifier.lv7MoabBonus *= factor; modifier.lv11NonMoabBonus *= factor; modifier.lv11MoabBonus *= factor; modifier.lv19NonMoabBonus *= factor; modifier.lv19MoabBonus *= factor; }); behavior.iterations = 1; } public override void Apply2(TowerModel model) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0046: 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_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0066: 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_007e: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Expected O, but got Unknown //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Expected O, but got Unknown //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Expected O, but got Unknown //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Expected O, but got Unknown AbilityModel val = AbilityModel(model); SwordChargeModel behavior = AbilityModelBehaviorExt.GetBehavior(val); ProjectileModel projectileModel = behavior.projectileModel; ProjectileModelBehaviorExt.AddBehavior(projectileModel, CreateTravelStraitModelExt.Create(new Args { lifespan = 1f, speed = ProjectileModelBehaviorExt.GetBehavior(projectileModel).speedFrames * 60f })); ProjectileModelBehaviorExt.AddBehavior(projectileModel, CreateTrackTargetModelExt.Create(new Args { distance = 999f, trackNewTargets = true, maxSeekAngle = 360f, turnRate = 1000f, useLifetimeAsDistance = true })); ProjectileModelBehaviorExt.RemoveBehavior(projectileModel); ProjectileModelBehaviorExt.RemoveBehavior(projectileModel); Il2CppGenericIEnumerable.ForEach(((Model)behavior).GetDescendants(), (Action)delegate(DamageModel damage) { damage.damage /= 5f; }); Il2CppGenericIEnumerable.ForEach(((Model)behavior).GetDescendants(), (Action)delegate(DamageModifierForTagModel modifier) { modifier.damageAddative /= 5f; }); Il2CppGenericIEnumerable.ForEach(((Model)behavior).GetDescendants(), (Action)delegate(SaudaAfflictionDamageModifierModel modifier) { modifier.lv7NonMoabBonus /= 5f; modifier.lv7MoabBonus /= 5f; modifier.lv11NonMoabBonus /= 5f; modifier.lv11MoabBonus /= 5f; modifier.lv19NonMoabBonus /= 5f; modifier.lv19MoabBonus /= 5f; }); float rate = val.Cooldown / 5f / (float)behavior.iterations; Args val2 = new Args(); ((ModelArgs)(object)val2).name = ((ModContent)this).Name; val2.range = 9999f; val2.addsToSharedGrid = false; val2.CanSeeCamo = true; val2.behaviors = (Model[])(object)new Model[1] { (Model)CreateRotateToTargetModelExt.Create(new Args { onlyRotateDuringThrow = true, rotateTower = true }) }; val2.weapon = CreateWeaponModelExt.Create(new Args { animation = -1, rate = rate, projectile = projectileModel }); TowerModelBehaviorExt.AddBehavior(model, CreateAttackModelExt.Create(val2)); } protected override void RemoveAbility(TowerModel model) { if (base.Mode2) { base.RemoveAbility(model); } else { TechBotify(model); } } } } namespace AbilityChoice.AbilityChoices.Hero.Rosalia { public class FlightBoost : HeroAbilityChoice { [HarmonyPatch(typeof(RosaliaMovement), "Process")] internal static class RosaliaMovement_Process { [HarmonyPrefix] internal static void Prefix(RosaliaMovement __instance) { if (((Model)__instance.rosaliaMovementModel).name.Contains("Pursuit")) { __instance.TogglePursuit(true); } } } [HarmonyPatch(typeof(RateSupportMutator), "Mutate")] internal static class RateSupportModel_RateSupportMutator_Mutate { [HarmonyPrefix] internal static bool Prefix(RateSupportMutator __instance, Model model, ref bool __result) { if (((BehaviorMutator)__instance).id != "FlightBoost") { return true; } float mult = __instance.multiplier; Il2CppGenericIEnumerable.ForEach(model.GetDescendants(), (Action)delegate(HeliMovementModel movementModel) { movementModel.maxSpeed *= mult; movementModel.movementForceStart *= mult; movementModel.movementForceEnd *= mult; movementModel.brakeForce *= mult; movementModel.otherHeliRepulsonForce *= mult; }); Il2CppGenericIEnumerable.ForEach(model.GetDescendants(), (Action)delegate(PathMovementModel movementModel) { movementModel.speed *= mult; movementModel.rotation *= mult; movementModel.bankRotation *= mult; }); __result = true; return false; } } public override string HeroId => TowerType.Rosalia; public override Dictionary Descriptions1 => new Dictionary { { 7, "Upgraded Jetpack! Nearby aircraft fly faster & Rosalia pursues Bloons over the whole map! " }, { 18, "Upgraded Weapons! Rosalia always attacks using both weapons!" } }; public override Dictionary Descriptions2 => new Dictionary { { 7, "Upgraded Weapons! Rosalia always attacks using both weapons!" }, { 18, "Upgraded Jetpack! Nearby aircraft fly faster & Rosalia pursues Bloons over the whole map!" } }; public override void Apply1(TowerModel model) { AlwaysPursuit(model); if (model.tier >= 18) { BothWeapons(model); } } public override void Apply2(TowerModel model) { BothWeapons(model); if (model.tier >= 18) { AlwaysPursuit(model); } } private void AlwaysPursuit(TowerModel model) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_004a: 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_005e: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Expected O, but got Unknown RosaliaMovementModel descendant = ((Model)model).GetDescendant(); ((Model)descendant).name = ((Model)descendant).name + "Pursuit"; FlightBoostAbilityModel descendant2 = ((Model)model).GetDescendant(); AirUnitMutator mutator = descendant2.Mutator; Args val = new Args(); ((ModelArgs)val).name = "FlightBoost"; val.multiplier = descendant2.moveSpeedMultiplier; val.isUnique = true; val.mutatorId = "FlightBoost"; val.priority = ((BehaviorMutator)mutator).priority; val.buffLocsName = ((BehaviorMutator)mutator).buffIndicator.buffName; val.buffIconName = ((BehaviorMutator)mutator).buffIndicator.iconName; TowerModelBehaviorExt.AddBehavior(model, CreateRateSupportModelExt.Create(val)); } private void BothWeapons(TowerModel model) { ((Model)model).GetDescendant().emitBoth = true; } } public class KineticCharge : HeroAbilityChoice { private const int Factor = 5; public override string HeroId => TowerType.Rosalia; public override Dictionary Descriptions1 => new Dictionary { { 10, "Workshop emits Kinetic Charges that attach to Bloons, harnessing energy when the target takes damage. They then release the accumulated energy in a huge detonation." }, { 16, "More frequent Kinetic Charge and Scatter Missile." } }; public override void Apply1(TowerModel model) { //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Expected O, but got Unknown //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Expected O, but got Unknown AbilityModel val = AbilityModel(model); ActivateAttackModel behavior = AbilityModelBehaviorExt.GetBehavior(val); AttackModel val2 = ModelExt.Duplicate(((Il2CppArrayBase)(object)behavior.attacks)[0]); ((Model)val2).name = "AttackModel_Attack_ScatterMissile"; val2.range = model.range; WeaponModel val3 = ((Il2CppArrayBase)(object)val2.weapons)[0]; val3.rate = val.Cooldown / 5f; Il2CppGenericIEnumerable.ForEach(((Model)val3).GetDescendants(), (Action)delegate(KineticChargeProjectileModel kc) { kc.duration /= 5f; kc.durationFrames /= 5; kc.maxAdditionalDamageAmount /= 5; kc.damageTakenMaxAmount /= 5; }); Il2CppGenericIEnumerable.ForEach(((Model)val3).GetDescendants(), (Action)delegate(DamageModel damageModel) { damageModel.damage /= 5f; }); EffectModel effectModel = AbilityModelBehaviorExt.GetBehavior(val).effectModel; CreateSoundOnAbilityModel behavior2 = AbilityModelBehaviorExt.GetBehavior(val); WeaponModelBehaviorExt.AddBehavior(val3, CreateEjectEffectModelExt.Create(new Args { effectModel = effectModel, lifespan = effectModel.lifespan, fullscreen = effectModel.fullscreen })); WeaponModelBehaviorExt.AddBehavior(val3, CreateCreateSoundOnProjectileCreatedModelExt.Create(new Args { sound1 = behavior2.sound, sound2 = behavior2.sound, sound3 = behavior2.sound, sound4 = behavior2.sound, sound5 = behavior2.sound })); TowerModelBehaviorExt.AddBehavior(model, val2); } } public class ScatterMissile : HeroAbilityChoice { private const int Factor = 5; public override string HeroId => TowerType.Rosalia; public override Dictionary Descriptions1 => new Dictionary { { 3, "Rosalia's Workshop periodically launches a missile that scatters into many somewhat destructive explosions." }, { 9, "Scatter Missile releases more mini-missiles when fired." }, { 16, "More frequent Kinetic Charge and Scatter Missile." } }; public override Dictionary Descriptions2 => new Dictionary { { 3, "Rosalia's Workshop periodically launches a missile that scatters into a few highly destructive explosions." }, { 9, "Scatter Missile releases more mini-missiles when fired." }, { 16, "More frequent Kinetic Charge and Scatter Missile." } }; public override void Apply1(TowerModel model) { //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Expected O, but got Unknown AbilityModel val = AbilityModel(model); ActivateAttackModel behavior = AbilityModelBehaviorExt.GetBehavior(val); AttackModel val2 = ModelExt.Duplicate(((Il2CppArrayBase)(object)behavior.attacks)[0]); ((Model)val2).name = "AttackModel_Attack_ScatterMissile"; WeaponModel val3 = ((Il2CppArrayBase)(object)val2.weapons)[0]; val3.rate = val.Cooldown / 5f; Il2CppGenericIEnumerable.ForEach(((Model)val3).GetDescendants(), (Action)delegate(DamageModel damageModel) { damageModel.damage /= 5f; }); Il2CppGenericIEnumerable.ForEach(((Model)val3).GetDescendants(), (Action)delegate(SlowModel slowModel) { slowModel.Lifespan /= 5f; }); Il2CppGenericIEnumerable.ForEach(((Model)val3).GetDescendants(), (Action)delegate(DamageModifierForTagModel tagModel) { tagModel.damageAddative /= 5f; }); EffectModel effectModel = AbilityModelBehaviorExt.GetBehavior(val).effectModel; WeaponModelBehaviorExt.AddBehavior(val3, CreateEjectEffectModelExt.Create(new Args { effectModel = effectModel, lifespan = effectModel.lifespan, fullscreen = effectModel.fullscreen })); TowerModelBehaviorExt.AddBehavior(model, val2); } public override void Apply2(TowerModel model) { //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Expected O, but got Unknown AbilityModel val = AbilityModel(model); ActivateAttackModel behavior = AbilityModelBehaviorExt.GetBehavior(val); AttackModel val2 = ModelExt.Duplicate(((Il2CppArrayBase)(object)behavior.attacks)[0]); ((Model)val2).name = "AttackModel_Attack_ScatterMissile"; WeaponModel val3 = ((Il2CppArrayBase)(object)val2.weapons)[0]; val3.rate = val.Cooldown / 5f; CreateProjectilesInAreaModel descendant = ((Model)val3).GetDescendant(); descendant.maxProjectileCount /= 5; EffectModel effectModel = AbilityModelBehaviorExt.GetBehavior(val).effectModel; WeaponModelBehaviorExt.AddBehavior(val3, CreateEjectEffectModelExt.Create(new Args { effectModel = effectModel, lifespan = effectModel.lifespan, fullscreen = effectModel.fullscreen })); TowerModelBehaviorExt.AddBehavior(model, val2); } } } namespace AbilityChoice.AbilityChoices.Hero.Quincy { public class RapidShot : HeroAbilityChoice { public override string HeroId => TowerType.Quincy; public override Dictionary Descriptions1 => new Dictionary { { 3, "Increased attack speed." }, { 13, "Small range and attack speed increase increase." }, { 15, "Further increased attack speed." } }; public override Dictionary Descriptions2 => new Dictionary { { 3, "Quincy's attacks now ACTUALLY never miss. Slightly increased attack speed." }, { 13, "Small range and attack speed increase increase." }, { 15, "Further increased attack speed." } }; public override void Apply1(TowerModel model) { AbilityModel val = AbilityModel(model); TurboModel descendant = ((Model)val).GetDescendant(); float bonus = AbilityChoice.CalcAvgBonus(descendant.Lifespan / val.Cooldown, 1f / descendant.multiplier); Il2CppGenericIEnumerable.ForEach(((Model)model).GetDescendants(), (Action)delegate(WeaponModel weaponModel) { weaponModel.Rate /= bonus; }); } public override void Apply2(TowerModel model) { //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Expected O, but got Unknown AbilityModel val = AbilityModel(model); TurboModel descendant = ((Model)val).GetDescendant(); float bonus = AbilityChoice.CalcAvgBonus(0.5f * descendant.Lifespan / val.Cooldown, 1f / descendant.multiplier); Il2CppGenericIEnumerable.ForEach(((Model)model).GetDescendants(), (Action)delegate(WeaponModel weaponModel) { weaponModel.Rate /= bonus; }); foreach (ProjectileModel item in from proj in Il2CppGenericIEnumerableExt.ToList(((Model)TowerModelExt.GetAttackModel(model)).GetDescendants()) where ProjectileModelBehaviorExt.HasBehavior(proj) select proj) { ProjectileModelBehaviorExt.RemoveBehavior(item); ProjectileModelBehaviorExt.AddBehavior(item, CreateTrackTargetModelExt.Create(new Args { distance = 100f, trackNewTargets = true, constantlyAquireNewTarget = true, maxSeekAngle = 360f, turnRate = 99999f })); } } } public class StormOfArrows : HeroAbilityChoice { public override string AbilityName => "Storm of Arrows"; public override string HeroId => TowerType.Quincy; public override Dictionary Descriptions1 => new Dictionary { { 10, "Quincy occasionally fires a barrage of arrows at Bloons anywhere on screen." }, { 18, "Quincy attacks faster and barrages are more frequent with 50% more arrows." }, { 20, "Quincy attacks even faster. Arrow barrages deal more damage and fire even more arrows." } }; public override Dictionary Descriptions2 => new Dictionary { { 10, "Quincy's attacks do increased damage. 15% increased attack speed and range for all Crossbow Monkeys." }, { 18, "Quincy attacks faster. 30% increased attack speed and range for all Crossbow Monkeys." }, { 20, "Quincy attacks even faster. Crossbow Monkeys deal 30% more damage to MOAB-Class Bloons and can damage all Bloon types." } }; public override void Apply1(TowerModel model) { AbilityModel val = AbilityModel(model); AttackModel val2 = ModelExt.Duplicate(((Model)val).GetDescendant()); WeaponModel val3 = ((Il2CppArrayBase)(object)val2.weapons)[0]; ProjectileModel descendant = ((Model)val2).GetDescendant(); ProjectileModel descendant2 = ((Model)descendant).GetDescendant(); DamageModel behavior = ProjectileModelBehaviorExt.GetBehavior(descendant2); AgeModel behavior2 = ProjectileModelBehaviorExt.GetBehavior(descendant2); EffectModel effectModel = ((Model)descendant).GetDescendant().effectModel; float num = behavior2.Lifespan * 2f; float lifespan = (behavior2.Lifespan = 1f); effectModel.lifespan = lifespan; behavior.damage /= 2f; val3.Rate = val.Cooldown / num; lifespan = (effectModel.scale = 0.5f); descendant2.scale = lifespan; TowerModelBehaviorExt.AddBehavior(model, val2); } public override void Apply2(TowerModel model) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: 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) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Expected O, but got Unknown //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Expected O, but got Unknown //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Expected O, but got Unknown //IL_01ab: Expected O, but got Unknown //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Expected O, but got Unknown float num = ((model.tier >= 18) ? 0.3f : 0.15f); BuffIconQuincy instance = ModContent.GetInstance(); TowerFilterModel[] array = new TowerFilterModel[2]; Args val = new Args(); val.baseIds = new string[1] { TowerType.DartMonkey }; array[0] = (TowerFilterModel)CreateFilterInBaseTowerIdModelExt.Create(val); array[1] = (TowerFilterModel)CreateFilterInTowerTiersModelExt.Create(new Args { path1MinTier = 0, path1MaxTier = 5, path2MinTier = 0, path2MaxTier = 5, path3MinTier = 3, path3MaxTier = 5 }); TowerFilterModel[] filters = (TowerFilterModel[])(object)array; TowerModelBehaviorExt.AddBehavior(model, CreateRateSupportModelExt.Create(new Args { multiplier = 1f - num, isUnique = true, mutatorId = "QuincyRateBuff", isGlobal = true, filters = filters, buffLocsName = ((ModBuffIcon)instance).BuffLocsName, buffIconName = ((ModBuffIcon)instance).BuffIconName })); TowerModelBehaviorExt.AddBehavior(model, CreateRangeSupportModelExt.Create(new Args { isUnique = true, multiplier = num, mutatorId = "QuincyRangeBuff", filters = filters, isGlobal = true, buffLocsName = ((ModBuffIcon)instance).BuffLocsName, buffIconName = ((ModBuffIcon)instance).BuffIconName })); if (model.tier >= 20) { TowerModelBehaviorExt.AddBehavior(model, CreateDamageModifierSupportModelExt.Create(new Args { isUnique = true, mutatorId = "QuincyDamageBuff", filters = filters, isGlobal = true, damageModifierModel = (DamageModifierModel)(object)CreateDamageModifierForTagModelExt.Create(new Args { tag = "Moabs", damageMultiplier = 1f + num }) })); TowerModelBehaviorExt.AddBehavior(model, CreateDamageTypeSupportModelExt.Create(new Args { isUnique = true, mutatorId = "QuincyDamageTypeBuff", immuneBloonProperties = (BloonProperties)0, filters = filters, buffLocsName = ((ModBuffIcon)instance).BuffLocsName, buffIconName = ((ModBuffIcon)instance).BuffIconName })); } } } } namespace AbilityChoice.AbilityChoices.Hero.Psi { public class PsionicScream : HeroAbilityChoice { private const int Factor = 6; public override string HeroId => TowerType.Psi; public override Dictionary Descriptions1 => new Dictionary { { 10, "Psi unleashes silent screams that throw some Bloons into utter chaos." }, { 20, "Psionic Screams hold and damage mores Bloons on screen. Psi can now target DDTs and ZOMGs." } }; public override Dictionary Descriptions2 => new Dictionary { { 10, "Targeted Bloons sometimes let out psionic screams that throw some nearby Bloons into utter chaos" }, { 20, "Psionic Screams hold and damage mores Bloons. Psi can now target DDTs and ZOMGs." } }; public override void Apply1(TowerModel model) { //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Expected O, but got Unknown //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Expected O, but got Unknown AbilityModel val = AbilityModel(model); ActivateAttackModel behavior = AbilityModelBehaviorExt.GetBehavior(val); AttackModel child = ((Model)behavior).GetChild(); child.fireWithoutTarget = false; child.range = 2000f; WeaponModel child2 = ((Model)child).GetChild(); child2.Rate = val.Cooldown / 6f; EffectModel val2 = (from e in AbilityModelBehaviorExt.GetBehaviors(val) select e.effectModel).First((EffectModel e) => (int)e.fullscreen == 0); WeaponModelBehaviorExt.AddBehavior(child2, CreateEjectEffectModelExt.Create(new Args { effectModel = val2, lifespan = val2.lifespan, fullscreen = val2.fullscreen })); ProjectileModel projectile = child2.projectile; projectile.pierce /= 6f; ProjectileFilterModel behavior2 = ProjectileModelBehaviorExt.GetBehavior(projectile); Il2CppReferenceArray filters = (projectile.filters = Il2CppReferenceArrayExt.AddTo(projectile.filters, (FilterModel)(object)CreateFilterWithChanceModelExt.Create(new Args { filterChance = 1f / 6f }))); behavior2.filters = filters; TowerModelBehaviorExt.AddBehavior(model, child); } public override void Apply2(TowerModel model) { AbilityModel val = AbilityModel(model); EffectModel effect = ModelExt.FindDescendant((Model)(object)val, "PsiFX").effectModel; effect.scale = 0.5f; ProjectileModel projectile = ((Model)val).GetDescendant(); projectile.radius = 40f; ProjectileModel obj = projectile; obj.pierce /= val.Cooldown; Il2CppGenericIEnumerable.ForEach(((Model)model).GetDescendants(), (Action)delegate(WeaponModel weapon) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected O, but got Unknown //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Expected O, but got Unknown ProjectileModel val2 = ModelExt.Duplicate(weapon.projectile); Args val3 = new Args(); ((ModelArgs)val3).name = ((ModContent)this).Name; val3.projectile = ModelExt.Duplicate(projectile); val3.emission = (EmissionModel)(object)CreateSingleEmissionModelExt.Create(); ProjectileModelBehaviorExt.AddBehavior(val2, CreateCreateProjectileOnContactModelExt.Create(val3)); Args val4 = new Args(); ((ModelArgs)val4).name = ((ModContent)this).Name; val4.effectModel = ModelExt.Duplicate(effect); ProjectileModelBehaviorExt.AddBehavior(val2, CreateCreateEffectOnContactModelExt.Create(val4)); WeaponModelBehaviorExt.AddBehavior(weapon, CreateAlternateProjectileModelExt.Create(new Args { projectile = val2, emissionModel = (EmissionModel)(object)CreateInstantDamageEmissionModelExt.Create(), interval = 6, alternateAnimation = 3 })); }); } } public class PsychicBlast : HeroAbilityChoice { private const int Factor = 4; public override string HeroId => TowerType.Psi; public override Dictionary Descriptions1 => new Dictionary { { 3, "Psi unleashes waves of power that stuns nearby Bloons for a short time." }, { 7, "Psychic Blast pulses more often. Psi can now destroy Ceramic Bloons." }, { 12, "Psychic Blast pulses even more often." } }; public override Dictionary Descriptions2 => new Dictionary { { 3, "Emits small waves of power around Psi's targets, briefly stunning nearby Bloons." }, { 7, "Psychic Blasts hit more Bloons. Psi can now destroy Ceramic Bloons." }, { 12, "Psychic Blasts hit even more Bloons." } }; public override void Apply1(TowerModel model) { AbilityModel val = AbilityModel(model); ActivateAttackModel behavior = AbilityModelBehaviorExt.GetBehavior(val); float num = (behavior.Lifespan + 1.95f) / 2f; AttackModel child = ((Model)behavior).GetChild(); child.fireWithoutTarget = false; WeaponModel child2 = ((Model)child).GetChild(); child2.Rate = val.Cooldown / 4f / num; WeaponModelBehaviorExt.RemoveBehavior(child2); ProjectileModel projectile = child2.projectile; SlowModel behavior2 = ProjectileModelBehaviorExt.GetBehavior(projectile); behavior2.Lifespan /= 4f; SlowModifierForTagModel behavior3 = ProjectileModelBehaviorExt.GetBehavior(projectile); behavior3.lifespanOverride /= 4f; child.range = child2.projectile.radius; TowerModelBehaviorExt.AddBehavior(model, child); } public override void Apply2(TowerModel model) { AbilityModel val = AbilityModel(model); ActivateAttackModel behavior = AbilityModelBehaviorExt.GetBehavior(val); float num = (behavior.Lifespan + 1.95f) / 2f; float num2 = 0.2f + num * 0.1f; EffectModel effect = ((Model)val).GetDescendant().effectModel; EffectModel obj = effect; obj.scale *= num2; EffectModel obj2 = effect; obj2.lifespan /= 4f; ProjectileModel projectile = ((Model)val).GetDescendant(); ProjectileModel obj3 = projectile; obj3.pierce *= num2; ProjectileModel obj4 = projectile; obj4.radius /= 4f; SlowModel behavior2 = ProjectileModelBehaviorExt.GetBehavior(projectile); behavior2.Lifespan /= 4f; SlowModifierForTagModel behavior3 = ProjectileModelBehaviorExt.GetBehavior(projectile); behavior3.lifespanOverride /= 4f; Il2CppGenericIEnumerable.ForEach(((Model)model).GetDescendants(), (Action)delegate(ProjectileModel proj) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected O, but got Unknown //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Expected O, but got Unknown if (!(proj.id != "BaseProjectile")) { Args val2 = new Args(); ((ModelArgs)val2).name = ((ModContent)this).Name; val2.projectile = ModelExt.Duplicate(projectile); val2.emission = (EmissionModel)(object)CreateSingleEmissionModelExt.Create(); ProjectileModelBehaviorExt.AddBehavior(proj, CreateCreateProjectileOnContactModelExt.Create(val2)); Args val3 = new Args(); ((ModelArgs)val3).name = ((ModContent)this).Name; val3.effectModel = ModelExt.Duplicate(effect); ProjectileModelBehaviorExt.AddBehavior(proj, CreateCreateEffectOnContactModelExt.Create(val3)); } }); } } } namespace AbilityChoice.AbilityChoices.Hero.PatFusty { public class BigSqueeze : HeroAbilityChoice { private static readonly List NonBADs = new List { "Moab", "Bfb", "Zomg", "Ddt" }; public override string HeroId => TowerType.PatFusty; public override Dictionary Descriptions1 => new Dictionary { { 10, "Pat can grab MOAB-Class Bloons below ZOMGs and crush them to bits while still continuing his other attacks." } }; public override Dictionary Descriptions2 => new Dictionary { { 10, "Main attack does bonus % health damage to MOAB-class Bloons." }, { 20, "Main attack slam now does AOE bonus % health damage to MOAB-class Bloons." } }; public override void Apply1(TowerModel model) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown AbilityModel val = AbilityModel(model); AttackModel val2 = ModelExt.Duplicate(((Model)val).GetDescendant()); Args val3 = new Args(); ((ModelArgs)val3).name = "Zomg"; val3.tag = "Zomg"; val3.disableWhenSupportMutatorIDs = Array.Empty(); FilterOutTagModel val4 = CreateFilterOutTagModelExt.Create(val3); AttackFilterModel behavior = AttackModelBehaviorExt.GetBehavior(val2); if (model.tier < 20) { behavior.filters = Il2CppReferenceArrayExt.AddTo(behavior.filters, (FilterModel)(object)val4); } WeaponModel child = ((Model)val2).GetChild(); child.Rate = val.Cooldown; ProjectileModel projectile = child.projectile; ProjectileFilterModel behavior2 = ProjectileModelBehaviorExt.GetBehavior(projectile); if (model.tier < 20) { behavior2.filters = Il2CppReferenceArrayExt.AddTo(behavior2.filters, (FilterModel)(object)val4); } TowerModelBehaviorExt.AddBehavior(model, val2); } public override void Apply2(TowerModel model) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown AbilityModel val = AbilityModel(model); float percent = 0.5f / val.Cooldown; ProjectileModel val2 = ((model.tier < 20) ? ((Model)((Model)model).GetDescendant()).GetDescendant() : ((Model)model).GetDescendant()); foreach (string nonBAD in NonBADs) { Args val3 = new Args(); ((ModelArgs)(object)val3).name = nonBAD; val3.percent = percent; val3.tags = new string[1] { nonBAD }; ProjectileModelBehaviorExt.AddBehavior(val2, CreateDamagePercentOfMaxModelExt.Create(val3)); } } } public class RallyingRoar : HeroAbilityChoice { private const int Factor = 3; public override string HeroId => TowerType.PatFusty; public override Dictionary Descriptions1 => new Dictionary { { 3, "Occasionally lets out a roar, rallying nearby Monkeys to pop +1 layer for a short time." } }; public override Dictionary Descriptions2 => new Dictionary { { 3, "Occasionally lets out a roar, weakening nearby Bloons such that they take +1 damage for a short time." }, { 14, "Weakening Roar increased radius and duration and increased damage Bloons take." } }; public override void Apply1(TowerModel model) { AbilityModel val = AbilityModel(model); AbilityModelBehaviorExt.RemoveBehavior(val); AbilityModelBehaviorExt.GetBehavior(val).effectModel.scale = 0.5f; val.Cooldown /= 3f; ActivateTowerDamageSupportZoneModel behavior = AbilityModelBehaviorExt.GetBehavior(val); behavior.lifespan /= 3f; behavior.lifespanFrames /= 3f; } public override void Apply2(TowerModel model) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Expected O, but got Unknown //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Expected O, but got Unknown //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Expected O, but got Unknown //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Expected O, but got Unknown AbilityModel val = AbilityModel(model); EffectModel effectModel = AbilityModelBehaviorExt.GetBehavior(val).effectModel; ActivateTowerDamageSupportZoneModel behavior = AbilityModelBehaviorExt.GetBehavior(val); Args val2 = new Args(); ((ModelArgs)(object)val2).name = "WeakeningRoar"; val2.range = behavior.range; val2.attackThroughWalls = true; val2.CanSeeCamo = true; Args val3 = new Args(); ((ModelArgs)(object)val3).name = "WeakeningRoar"; val3.animation = 3; val3.rate = val.Cooldown / 3f; val3.behaviors = (Model[])(object)new Model[1] { (Model)CreateEjectEffectModelExt.Create(new Args { effectModel = effectModel }) }; Args val4 = new Args(); val4.id = "WeakeningRoar"; val4.radius = behavior.range; val4.pierce = 1000f; val4.CanHitCamo = true; val4.behaviors = (Model[])(object)new Model[2] { (Model)CreateAgeModelExt.Create(new Args { lifespan = 0.05f }), (Model)CreateAddBonusDamagePerHitToBloonModelExt.Create(new Args { mutationId = "WeakeningRoar", lifespan = behavior.lifespan / 3f, perHitDamageAddition = behavior.damageIncrease, isUnique = true }) }; val3.projectile = CreateProjectileModelExt.Create(val4); val2.weapon = CreateWeaponModelExt.Create(val3); TowerModelBehaviorExt.AddBehavior(model, CreateAttackModelExt.Create(val2)); TowerModelBehaviorExt.RemoveBehavior(model); } protected override void RemoveAbility(TowerModel model) { if (base.Mode2) { base.RemoveAbility(model); } else { TechBotify(model); } } } } namespace AbilityChoice.AbilityChoices.Hero.ObynGreenfoot { public class Brambles : HeroAbilityChoice { private const int Factor = 5; public override string HeroId => TowerType.ObynGreenfoot; public override Dictionary Descriptions1 => new Dictionary { { 3, "Creates spiked bushes on the track that can pop 50 bloons." } }; public override Dictionary Descriptions2 => new Dictionary { { 3, $"Frequently creates small spiked bushes on the track that can pop {10} Bloons each." }, { 7, $"Brambles can pop {20} Bloons." }, { 16, $"Brambles pop {100} bloons each and can damage all Bloon types." } }; public override void Apply1(TowerModel model) { AbilityModel val = AbilityModel(model); AttackModel val2 = ModelExt.Duplicate(((Model)val).GetDescendant()); WeaponModel val3 = ((Il2CppArrayBase)(object)val2.weapons)[0]; val3.Rate = val.Cooldown; val3.fireBetweenRounds = false; TowerModelBehaviorExt.AddBehavior(model, val2); } public override void Apply2(TowerModel model) { AbilityModel val = AbilityModel(model); AttackModel val2 = ModelExt.Duplicate(((Model)val).GetDescendant()); WeaponModel val3 = ((Il2CppArrayBase)(object)val2.weapons)[0]; ProjectileModel projectile = val3.projectile; val3.Rate = val.Cooldown / 5f; val3.fireBetweenRounds = false; projectile.pierce /= 5f; projectile.scale = 0.7f; ProjectileModelBehaviorExt.RemoveBehavior(projectile); TowerModelBehaviorExt.AddBehavior(model, val2); } } public class WallOfTrees : HeroAbilityChoice { public override string HeroId => TowerType.ObynGreenfoot; public override string AbilityName => "Wall of Trees"; public override Dictionary Descriptions1 => new Dictionary { { 10, "Summons walls of trees across the track that destroy all Bloons that enter. When full, the trees burst into money." } }; public override Dictionary Descriptions2 => new Dictionary { { 10, "Obyn sends out 3 Wolf Spirits at a time with increased cash per pop." }, { 20, "Obyn sends out 6 Wolf Spirits at a time with increased cash per pop." } }; public override void Apply1(TowerModel model) { AbilityModel val = AbilityModel(model); AttackModel val2 = ModelExt.Duplicate(((Model)val).GetDescendant()); WeaponModel val3 = ((Il2CppArrayBase)(object)val2.weapons)[0]; LimitProjectileModel behavior = WeaponModelBehaviorExt.GetBehavior(val3); val3.Rate = val.Cooldown; behavior.limitByDestroyedPriorProjectile = false; TowerModelBehaviorExt.AddBehavior(model, val2); } public override void Apply2(TowerModel model) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown WeaponModelExt.SetEmission(((Model)TowerModelExt.GetAttackModel(model)).GetChild(), (EmissionModel)(object)CreateArcEmissionModelExt.Create(new Args { Count = ((model.tier < 20) ? 3 : 6), offset = -25f, angle = 50f })); TowerModelBehaviorExt.AddBehavior(model, CreateCashIncreaseModelExt.Create(new Args { multiplier = ((model.tier < 20) ? 1.5f : 2f) })); } } } namespace AbilityChoice.AbilityChoices.Hero.Gwendolin { public class CocktailOfFire : HeroAbilityChoice { private const int Factor = 2; public override string AbilityName => "Cocktail of Fire"; public override string HeroId => TowerType.Gwendolin; public override Dictionary Descriptions1 => new Dictionary { { 3, "Frequently hurls a flask of flammable liquid, with a chance of burning Bloons that pass through the fire." } }; public override Dictionary Descriptions2 => new Dictionary { { 3, "Fire blasts leave behind pools of liquid fire on the track." }, { 7, "Heat it up has increased radius, pools of fire are more effective." }, { 14, "Pools of Fire do extra damage and set MOAB class Bloons alight." } }; public override void Apply1(TowerModel model) { //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Expected O, but got Unknown AbilityModel val = AbilityModel(model); AttackModel val2 = ModelExt.Duplicate(((Model)val).GetDescendant()); WeaponModel val3 = ((Il2CppArrayBase)(object)val2.weapons)[0]; ProjectileModelBehaviorExt.RemoveBehavior(val3.projectile); ProjectileModel descendant = ((Model)val3.projectile).GetDescendant(); AgeModel behavior = ProjectileModelBehaviorExt.GetBehavior(descendant); float num = behavior.Lifespan / val.Cooldown; behavior.Lifespan /= 2f; val3.Rate = behavior.Lifespan / num; AddBehaviorToBloonModel descendant2 = ((Model)descendant).GetDescendant(); if (descendant2 != null) { descendant2.lifespan /= 2f; descendant2.lifespanFrames /= 2; } val3.Rate /= 2f; ProjectileFilterModel val4 = ProjectileModelBehaviorExt.GetBehavior(descendant); if (val4 == null) { val4 = CreateProjectileFilterModelExt.Create(); ProjectileModelBehaviorExt.AddBehavior(descendant, val4); } val4.filters = Il2CppReferenceArrayExt.AddTo(val4.filters ?? new Il2CppReferenceArray(0L), (FilterModel)(object)CreateFilterWithChanceModelExt.Create(new Args { filterChance = 0.5f })); descendant.UpdateCollisionPassList(); TowerModelBehaviorExt.AddBehavior(model, val2); } public override void Apply2(TowerModel model) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Expected O, but got Unknown //IL_0100: Expected O, but got Unknown //IL_0128: 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_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Expected O, but got Unknown AbilityModel val = AbilityModel(model); ProjectileModel val2 = ModelExt.Duplicate(((Model)((Model)val).GetDescendant()).GetDescendant()); ProjectileModelExt.AddFilter(val2, (FilterModel)(object)CreateFilterWithChanceModelExt.Create(new Args { filterChance = 0.2f })); AgeModel behavior = ProjectileModelBehaviorExt.GetBehavior(val2); behavior.Lifespan /= 5f; val2.UpdateCollisionPassList(); AddBehaviorToBloonModel descendant = ((Model)val2).GetDescendant(); if (descendant != null) { descendant.lifespan /= 5f; descendant.lifespanFrames /= 5; } AttackModel val3 = ModelExt.Duplicate(TowerModelExt.GetAttackModel(model), "PoolsOfFire"); WeaponModel child = ((Model)val3).GetChild(); ProjectileModel projectile = child.projectile; child.Rate *= 10f; WeaponModelExt.SetEmission(child, (EmissionModel)(object)CreateSingleEmissionModelExt.Create()); WeaponModelBehaviorExt.RemoveBehavior(child); WeaponModelBehaviorExt.RemoveBehavior(child); DisplayModel behavior2 = ProjectileModelBehaviorExt.GetBehavior(projectile); PrefabReference val4 = new PrefabReference { guidRef = "" }; PrefabReference display = val4; behavior2.display = val4; projectile.display = display; projectile.pierce = 9999f; ProjectileModelBehaviorExt.RemoveBehavior(projectile); ProjectileModelBehaviorExt.RemoveBehavior(projectile); ProjectileModelBehaviorExt.AddBehavior(projectile, CreateCreateProjectileOnExhaustPierceModelExt.Create(new Args { projectile = val2, emission = (EmissionModel)(object)CreateSingleEmissionModelExt.Create(), pierceInterval = 1f, count = 5, minimumTimeDifferenceInFrames = 5, destroyProjectile = true, displayLifetime = 1f })); TowerModelBehaviorExt.AddBehavior(model, val3); } } public class Firestorm : HeroAbilityChoice { private const int Factor = 6; public override string HeroId => TowerType.Gwendolin; public override Dictionary Descriptions1 => new Dictionary { { 10, "Periodically emits storms of fire, burning nearby Bloons. Duration of Heat it Up is increased." }, { 16, "Firestorms have increased duration and do more damage. Purple Bloons are no longer immune to Gwendolin's attacks." }, { 20, "Firestorms does hugely increased damage." } }; public override Dictionary Descriptions2 => new Dictionary { { 10, "Range and duration of heat it up increased, and its blast wave deals much more damage." }, { 16, "Blast wave burn damage and duration increased. Purple Bloons are no longer immune to Gwendolin's attacks." }, { 20, "Blast wave does hugely increased damage." } }; public override void Apply1(TowerModel model) { AbilityModel ability = AbilityModel(model); Il2CppGenericIEnumerable.ForEach(((Model)ability).GetDescendants(), (Action)delegate(AttackModel attackModel) { //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Expected O, but got Unknown AttackModel val = ModelExt.Duplicate(attackModel); WeaponModel val2 = ((Il2CppArrayBase)(object)val.weapons)[0]; ProjectileModel projectile = val2.projectile; val2.Rate = ability.Cooldown / 6f; val.fireWithoutTarget = false; DamageModel damageModel = ProjectileModelExt.GetDamageModel(projectile); damageModel.damage /= 6f; AddBehaviorToBloonModel behavior = ProjectileModelBehaviorExt.GetBehavior(projectile); behavior.lifespan /= 6f; ProjectileModelBehaviorExt.RemoveBehavior(projectile); ProjectileModelBehaviorExt.RemoveBehavior(projectile); projectile.radius = 70f; val.range = model.range; EffectModel effectModel = AbilityModelBehaviorExt.GetBehavior(ability).effectModel; effectModel.scale = 0.6f; WeaponModelBehaviorExt.AddBehavior(val2, CreateEjectEffectModelExt.Create(new Args { effectModel = effectModel, lifespan = effectModel.lifespan })); ((Model)val).name = ((Model)val).name + "Firestorm"; TowerModelBehaviorExt.AddBehavior(model, val); }); } public override void Apply2(TowerModel model) { //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Expected O, but got Unknown AbilityModel val = AbilityModel(model); BonusProjectileAfterIntervalModel descendant = ((Model)model).GetDescendant(); float num = (float)descendant.interval * TowerModelExt.GetWeapon(model).Rate; float num2 = num / val.Cooldown; descendant.projectileModel.scale = 2f; ProjectileModel projectileModel = descendant.projectileModel; projectileModel.radius *= 1.5f; foreach (ProjectileModel item in Il2CppGenericIEnumerableExt.ToList(((Model)val).GetDescendants())) { ProjectileModel val2 = ModelExt.Duplicate(item); ProjectileModelBehaviorExt.RemoveBehavior(val2); ProjectileModelBehaviorExt.RemoveBehavior(val2); DamageModel damageModel = ProjectileModelExt.GetDamageModel(val2); damageModel.damage *= num2; AddBehaviorToBloonModel behavior = ProjectileModelBehaviorExt.GetBehavior(val2); behavior.lifespan *= num2; val2.radius = descendant.projectileModel.radius; ProjectileModelBehaviorExt.AddBehavior(descendant.projectileModel, CreateCreateProjectileOnExhaustFractionModelExt.Create(new Args { projectile = val2, emission = (EmissionModel)(object)CreateSingleEmissionModelExt.Create(), fraction = 1f, durationfraction = -1f })); } } protected override void ApplyBoth(TowerModel towerModel) { AbilityModel val = AbilityModel(towerModel); BonusProjectileAfterIntervalModel descendant = ((Model)towerModel).GetDescendant(); float increase = 1f + ((Model)val).GetDescendant().lifespan / val.Cooldown; Il2CppGenericIEnumerable.ForEach(((Model)descendant).GetDescendants(), (Action)delegate(HeatItUpDamageBuffModel model) { model.lifespan *= increase; }); Il2CppGenericIEnumerable.ForEach(((Model)descendant).GetDescendants(), (Action)delegate(PierceUpTowersModel model) { model.lifespan *= increase; }); Il2CppGenericIEnumerable.ForEach(((Model)descendant).GetDescendants(), (Action)delegate(DamageUpTowersModel model) { model.lifespan *= increase; }); Il2CppGenericIEnumerable.ForEach(((Model)descendant).GetDescendants(), (Action)delegate(DamageUpTagTowersModel model) { model.lifespan *= increase; }); } } } namespace AbilityChoice.AbilityChoices.Hero.Geraldo { public class BottleHotSauce : GeraldoAbilityChioce { public override Dictionary Descriptions1 => new Dictionary { { 8, "New Item! Bottle of 'Gerry's Fire' - 2.8 million Bloonville units of pure hot sauce fire! Gives a Monkey, Hero, or minion a fiery attack permanently." }, { 16, "Stack of Old Nails becomes a Nail Mine, Jar of Pickles grants additional bonus damage vs. Fortified Bloons, and Gerry's Fire gains bonus burny damage." } }; public override Dictionary Descriptions2 => new Dictionary { { 0, "2.8 million Bloonville units. Whoever tastes this special sauce will be spewing fire permanently!" }, { 16, "2.8 million Bloonville units. Whoever tastes this special sauce will be spewing fire permanently! Now with extra burny-ness." } }; protected override int CostMult => 5; protected override void Apply(GeraldoItemModel geraldoItem) { } public override void Apply(GameModel gameModel) { base.Apply(gameModel); foreach (TowerModel item in Il2CppGenericIEnumerable.AsIEnumerable(gameModel.GetTowersWithBaseId(TowerType.HotSauceCreature, false))) { ((Model)item).GetDescendant().rounds = -1; } } } public class CreepyIdol : GeraldoAbilityChioce { public override Dictionary Descriptions1 => new Dictionary { { 18, "Genie gains a second close-target attack and does bonus damage to MOAB-class Bloons. Creepy Idol occasionally covers nearby MOAB-class Bloons with a Mystical Shroud, causing damage when popped." } }; public override Dictionary Descriptions2 => new Dictionary(); protected override int CostMult => 15; protected override void Apply(GeraldoItemModel geraldoItem) { } public override void Apply(GameModel gameModel) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: 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_006a: 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_007e: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Expected O, but got Unknown base.Apply(gameModel); foreach (TowerModel item in Il2CppGenericIEnumerable.AsIEnumerable(gameModel.GetTowersWithBaseId(TowerType.CreepyIdol, false))) { ((Model)item).GetDescendant().rounds = -1; CreateProjectileOnTowerDestroyModel descendant = ((Model)item).GetDescendant(); if (descendant != null) { WeaponModel val = CreateWeaponModelExt.Create(new Args { projectile = descendant.projectileModel, emission = descendant.emissionModel, fireWithoutTarget = true, rate = 30f, startInCooldown = true }); AttackModelExt.AddWeapon(TowerModelExt.GetAttackModel(item), val); } } } } public class Fertilizer : GeraldoAbilityChioce { public override Dictionary Descriptions1 => new Dictionary { { 9, "New Item! Fertilizer - targeted Banana Farms that produce visible bananas increase production and get a cash bonus. Geraldo's main attack blast radius increases." } }; public override Dictionary Descriptions2 => new Dictionary(); protected override int CostMult => 15; protected override void Apply(GeraldoItemModel geraldoItem) { ((Model)geraldoItem).GetDescendant().rounds = -1; } } public class GenieBottle : GeraldoAbilityChioce { public override Dictionary Descriptions1 => new Dictionary { { 12, "New Item! Genie Bottle - summons a plasma-powered Genie Monkey. Creepy Idol can now apply an occasional short stun to passing visible MOAB-class Bloons." } }; public override Dictionary Descriptions2 => new Dictionary { { 0, "Summon a Genie Monkey from this brilliant blue bottle and rejoice, it lasts forever! (no wishes included with purchase)." }, { 18, "Summon a Genie Monkey from this brilliant gold bottle and rejoice, it lasts forever! (no wishes included with purchase). Extra attack and more damage to MOABs now included." } }; protected override int CostMult => 15; protected override void Apply(GeraldoItemModel geraldoItem) { } public override void Apply(GameModel gameModel) { base.Apply(gameModel); foreach (TowerModel item in Il2CppGenericIEnumerable.AsIEnumerable(gameModel.GetTowersWithBaseId(TowerType.GenieBottle, false))) { ((Model)item).GetDescendant().rounds = -1; } } } public class JarOfPickles : GeraldoAbilityChioce { public override Dictionary Descriptions1 => new Dictionary(); public override Dictionary Descriptions2 => new Dictionary { { 0, "Try these pickles on one of your Monkey Towers and it will hit harder, but shoot slower, permanently." }, { 11, "Try these pickles on one of your Monkey Towers and it will hit harder, but shoot slower, permanently. Now with increased damage to Fortified Bloons!" }, { 16, "Try these pickles on one of your Monkey Towers and it will hit harder, but shoot slower, permanently. Now with EVEN MORE increased damage to Fortified Bloons!" } }; protected override int CostMult => 10; protected override void Apply(GeraldoItemModel geraldoItem) { ((Model)geraldoItem).GetDescendant().rounds = -1; } } public class SeeInvisibilityPotion : GeraldoAbilityChioce { public override Dictionary Descriptions1 => new Dictionary { { 3, "New Item! See Invisibility Potion - grants permanent camo detection to a Monkey Tower or Hero. Geraldo's attack range increases." }, { 14, "See Invisibility Potion grants additional range." } }; public override Dictionary Descriptions2 => new Dictionary { { 0, "Whatever Monkey you gift with this extremely efficacious elixir will be able to see Camo Bloons with ease! Effects will not wear off." }, { 14, "Whatever Monkey you gift with this extremely efficacious elixir will be able to see Camo Bloons with ease! Effects will not wear off. Now gives increased range!" }, { 19, "Whatever Monkey you gift with this extremely efficacious elixir will be able to see Camo Bloons with ease and do more damage to them! Effects will not wear off." } }; protected override int CostMult => 5; protected override void Apply(GeraldoItemModel geraldoItem) { SeeInvisibilityPotionBehaviorModel descendant = ((Model)geraldoItem).GetDescendant(); descendant.rounds = -1; descendant.upgradedRangeScale += 0.1f; descendant.roundsUpgradedTo = -1; } } public class SharpeningStone : GeraldoAbilityChioce { public override Dictionary Descriptions1 => new Dictionary(); public override Dictionary Descriptions2 => new Dictionary { { 0, "Sharpen those darts, friend! Apply this to your darts and blades and they'll be sharper than ever before. Does not run out." } }; protected override int CostMult => 5; protected override void Apply(GeraldoItemModel geraldoItem) { ((Model)geraldoItem).GetDescendant().rounds = -1; } } public class TubeOfAmazoGlue : GeraldoAbilityChioce { public override Dictionary Descriptions1 => new Dictionary(); public override Dictionary Descriptions2 => new Dictionary { { 0, "Truly amazing! Apply a tube of this modern marvel anywhere on the track and watch the next bunch of Bloons slow right down. Lasts until used up." } }; protected override int CostMult => 2; protected override void Apply(GeraldoItemModel geraldoItem) { ((Model)geraldoItem).GetDescendant().rounds = 0; } } } namespace AbilityChoice.AbilityChoices.Hero.Ezili { public class Heartstopper : HeroAbilityChoice { public override string HeroId => TowerType.Ezili; public override Dictionary Descriptions1 => new Dictionary { { 3, "Blocks regrow for Bloons within range. All Purple Bloons are less resistant to damage." }, { 12, "Deals increased damage to MOABs. Purple Bloons are fully susceptible to all damage." } }; public override void Apply1(TowerModel model) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Expected O, but got Unknown AbilityModel val = AbilityModel(model); GrowBlockModel descendant = ((Model)val).GetDescendant(); IgnoreDmgImmunityModel descendant2 = ((Model)val).GetDescendant(); descendant2.chance = ((model.tier >= 12) ? 1f : 0.5f); Args val2 = new Args(); ((ModelArgs)(object)val2).name = "GrowBlock"; val2.zoneRadius = model.range; val2.mutationId = "Heartstopper"; val2.isUnique = true; val2.behaviors = (BloonBehaviorModel[])(object)new BloonBehaviorModel[1] { (BloonBehaviorModel)descendant }; val2.overlayType = "GrowBlock"; TowerModelBehaviorExt.AddBehavior(model, CreateAddBehaviorToBloonInZoneModelExt.Create(val2)); val2 = new Args(); ((ModelArgs)(object)val2).name = "Purple"; val2.zoneRadius = 999999f; val2.mutationId = "HeartstopperBreakPurple"; val2.isUnique = true; val2.behaviors = (BloonBehaviorModel[])(object)new BloonBehaviorModel[1] { (BloonBehaviorModel)descendant2 }; TowerModelBehaviorExt.AddBehavior(model, CreateAddBehaviorToBloonInZoneModelExt.Create(val2)); } } public class MOABHex : HeroAbilityChoice { private const int Factor = 5; private static readonly List NonBADs = new List(4) { "Moab", "Bfb", "Zomg", "Ddt" }; public override string HeroId => TowerType.Ezili; public override Dictionary Descriptions1 => new Dictionary { { 10, "Periodically places a hex on a MOAB-CLass Bloon, dealing massive % damage to it." } }; public override Dictionary Descriptions2 => new Dictionary { { 10, "Main attack now does bonus % health damage to MOABs. Range increased." }, { 20, "Main attack % damage increased, and can now affect BAD Bloons. Range increased." } }; public override void Apply1(TowerModel model) { AbilityModel val = AbilityModel(model); AbilityModelBehaviorExt.RemoveBehaviors(val); AbilityModelBehaviorExt.RemoveBehaviors(val); HexManagerModel behavior = TowerModelBehaviorExt.GetBehavior(model); HexModel hex = behavior.hex; hex.totalDuration /= 5f; HexModel hex2 = behavior.hex; hex2.totalIntervalFrames /= 5; AddBehaviorToBloonModel descendant = ((Model)val).GetDescendant(); descendant.lifespan /= 5f; descendant.lifespanFrames /= 5; HexModel descendant2 = ((Model)val).GetDescendant(); descendant2.totalDuration /= 5f; descendant2.totalIntervalFrames /= 5; val.Cooldown /= 5f; } public override void Apply2(TowerModel model) { //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Expected O, but got Unknown //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Expected O, but got Unknown AbilityModel val = AbilityModel(model); HexModel descendant = ((Model)model).GetDescendant(); float num = descendant.totalDuration / val.Cooldown; ProjectileModel projectile = ((Il2CppArrayBase)(object)TowerModelExt.GetAttackModel(model).weapons)[0].projectile; float percent = descendant.damagePercentOfMax * num; if (model.tier < 20) { foreach (string nonBAD in NonBADs) { Args val2 = new Args(); ((ModelArgs)(object)val2).name = nonBAD; val2.percent = percent; val2.tags = new string[1] { nonBAD }; ProjectileModelBehaviorExt.AddBehavior(projectile, CreateDamagePercentOfMaxModelExt.Create(val2)); } model.range += 10f; } else { Args val2 = new Args(); val2.percent = percent; val2.tags = new string[1] { "Moabs" }; ProjectileModelBehaviorExt.AddBehavior(projectile, CreateDamagePercentOfMaxModelExt.Create(val2)); model.range += 20f; } projectile.hasDamageModifiers = true; } protected override void RemoveAbility(TowerModel model) { if (base.Mode2) { base.RemoveAbility(model); } else { TechBotify(model); } } } public class SacrificialTotem : HeroAbilityChoice { public override string HeroId => TowerType.Ezili; public override Dictionary Descriptions1 => new Dictionary { { 7, "Summons a totem that grants camo detection and pierce to nearby Monkeys, especially Wizard Monkeys." }, { 16, "Totem now has increased uptime." } }; public override Dictionary Descriptions2 => new Dictionary { { 7, "Summons a totem that grants attack speed to nearby Monkeys, especially Wizard Monkeys." }, { 16, "Totem now has increased uptime" } }; protected override void ApplyBoth(TowerModel model) { AbilityModel val = AbilityModel(model); AttackModel val2 = ModelExt.Duplicate(((Model)val).GetDescendant()); WeaponModel child = ((Model)val2).GetChild(); child.Rate = val.Cooldown / 3f; TowerModel descendant = ((Model)child).GetDescendant(); TowerModelBehaviorExt.RemoveBehaviors(descendant); if (base.Mode2) { TowerModelBehaviorExt.RemoveBehaviors(descendant); TowerModelBehaviorExt.RemoveBehaviors(descendant); } else { TowerModelBehaviorExt.RemoveBehaviors(descendant); TowerModelBehaviorExt.RemoveBehaviors(descendant); } TowerExpireModel behavior = TowerModelBehaviorExt.GetBehavior(descendant); behavior.Lifespan /= 3f; TowerModelBehaviorExt.AddBehavior(model, val2); } } } namespace AbilityChoice.AbilityChoices.Hero.Etienne { public class DroneSwarm : HeroAbilityChoice { public override string HeroId => TowerType.Etienne; public override Dictionary Descriptions1 => new Dictionary { { 3, "Etienne launches an additional permanent drone." }, { 6, "Etienne now controls 3 drones at once." }, { 7, "Drone pierce increased." }, { 9, "Drones pop an extra Bloon layer. Adds a fourth drone." }, { 11, "Etienne gains a fifth drone to control." }, { 16, "Etienne's range and drone popping power both improved." }, { 19, "Etienne now controls six drones all the time!" } }; public override void Apply1(TowerModel model) { //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Expected O, but got Unknown AbilityModel val = AbilityModel(model); DroneSupportModel behavior = TowerModelBehaviorExt.GetBehavior(model); int count = behavior.count; int count2 = ((Model)val).GetDescendant().count; float duration = ((Model)val).GetDescendant().duration; float cooldown = val.Cooldown; float num = (float)count * AbilityChoice.CalcAvgBonus(duration / cooldown, (float)(count + count2) / (float)count); int count3 = behavior.count; behavior.count = count3 + 1; count3 = model.tier; if ((count3 >= 9 || count3 == 6) ? true : false) { count3 = behavior.count; behavior.count = count3 + 1; } int count4 = behavior.count; float num2 = num / (float)count4; ProjectileModel descendant = ((Model)behavior.droneModel).GetDescendant(); float num3 = Math.Max(num2 * descendant.pierce, 1f); descendant.pierce += num3; AttackModel attackModel = TowerModelExt.GetAttackModel(model); if (!AttackModelBehaviorExt.HasBehavior(attackModel)) { AttackModelBehaviorExt.AddBehavior(attackModel, CreateTargetDivideAndConquerModelExt.Create(new Args { isSelectable = true })); model.UpdateTargetProviders(); } } } public class UCAV : HeroAbilityChoice { public override string HeroId => TowerType.Etienne; public override Dictionary Descriptions1 => new Dictionary { { 10, "A devastating combat drone circles the map at high altitude." }, { 13, "UCAV attack speed increased." }, { 15, "UCAV damage output increased." }, { 17, "UCAV damage output increased again!" }, { 20, "UCAV becomes even more powerful and can pop all Bloon types." } }; protected override void ApplyBoth(TowerModel model) { //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Expected O, but got Unknown AbilityModel val = AbilityModel(model); UCAVModel behavior = AbilityModelBehaviorExt.GetBehavior(val); float num = behavior.duration / val.Cooldown; CreateTowerModel descendant = ((Model)model).GetDescendant(); ((Model)descendant).RemoveChildDependant(descendant.tower); TowerModel val2 = (descendant.tower = behavior.ucavTowerModel); TowerModel val3 = val2; ((Model)descendant).AddChildDependant(val3); if (model.tier < 20) { WeaponModel descendant2 = ((Model)val3).GetDescendant(); descendant2.Rate /= num; } else { DamageModel descendant3 = ((Model)behavior.uavTowerModel).GetDescendant(); DamageModel descendant4 = ((Model)val3).GetDescendant(); float num2 = descendant3.damage * AbilityChoice.CalcAvgBonus(num, descendant4.damage / descendant3.damage); if (base.Mode2) { descendant4.damage = num2; } else { WeaponModel descendant5 = ((Model)val3).GetDescendant(); descendant5.Rate *= descendant4.damage / num2; } TowerModelBehaviorExt.GetBehavior(model).towerId = "UCAV"; } if (model.tier == 10) { TowerModelBehaviorExt.AddBehavior(model, CreateDestroyChildTowersOnUpgradeModelExt.Create(new Args { towerId = "UAV" })); } } } } namespace AbilityChoice.AbilityChoices.Hero.Corvus { public class Aggression : CorvusAbilityChoice { protected override int Order => 1; public override void Apply1(TowerModel model) { CorvusContinuousSpellModel val = ContinuousSpell(model); val.ongoingManaCost += ((CorvusSpellModel)val).initialManaCost / 20; ((CorvusSpellModel)val).initialManaCost = val.ongoingManaCost; } public override void Apply2(TowerModel model) { CorvusContinuousSpellModel val = ContinuousSpell(model); float num = ((float)val.ongoingManaCost + (float)((CorvusSpellModel)val).initialManaCost / 20f) / (float)val.ongoingManaCost; ((CorvusSpellModel)val).initialManaCost = val.ongoingManaCost; AggressionModel val2 = ((Il2CppObjectBase)val).Cast(); val2.sizeMultiplier = AbilityChoice.CalcAvgBonus(1f / num, val2.sizeMultiplier); val2.rehitCooldownMultiplier = 1f / AbilityChoice.CalcAvgBonus(1f / num, 1f / val2.rehitCooldownMultiplier); } } public class AncestralMight : CorvusAbilityChoice { protected override int Order => 0; public override void Apply1(TowerModel model) { CorvusInstantSpellModel val = InstantSpell(model); ((CorvusSpellModel)val).initialManaCost = (int)((float)((CorvusSpellModel)val).initialManaCost / val.duration); val.duration = 1f; val.cooldown = 0f; } public override void Apply2(TowerModel model) { AncestralMightModel val = ((Il2CppObjectBase)InstantSpell(model)).Cast(); float num = ((CorvusInstantSpellModel)val).duration / (((CorvusInstantSpellModel)val).duration + ((CorvusInstantSpellModel)val).cooldown); ((CorvusSpellModel)val).initialManaCost = (int)(num * ((float)((CorvusSpellModel)val).initialManaCost / ((CorvusInstantSpellModel)val).duration)); ((CorvusInstantSpellModel)val).duration = 1f; ((CorvusInstantSpellModel)val).cooldown = 0f; WeaponModel obj = ((Il2CppArrayBase)(object)val.attack.weapons)[0]; obj.Rate /= num; } } public class DarkRitual : HeroAbilityChoice { private const int Factor = 6; public override string HeroId => TowerType.Corvus; public override Dictionary Descriptions1 => new Dictionary { { 10, "Performs Dark Rituals that harvest a huge number of Bloons near Corvus. Trample does more damage to more Bloons. Learns: Recovery" } }; public override Dictionary Descriptions2 => new Dictionary { { 10, "Constantly performs a Dark Ritual that harvests Bloons near Corvus. Trample does more damage to more Bloons. Learns: Recovery" } }; public override void Apply1(TowerModel model) { AbilityModel val = AbilityModel(model); AttackModel val2 = ModelExt.Duplicate(((Model)val).GetDescendant()); ((Il2CppArrayBase)(object)val2.weapons)[0].Rate = val.Cooldown / 6f; AgeModel descendant = ((Model)val2).GetDescendant(); descendant.Lifespan /= 6f; TowerModelBehaviorExt.AddBehavior(model, val2); } public override void Apply2(TowerModel model) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown AbilityModel val = AbilityModel(model); AttackModel val2 = ModelExt.Duplicate(((Model)val).GetDescendant()); float lifespan = ((Model)val2).GetDescendant().Lifespan; WeaponModel val3 = ((Il2CppArrayBase)(object)val2.weapons)[0]; val3.Rate = lifespan; WeaponModelBehaviorExt.AddBehavior(val3, CreateWeaponRateMinModelExt.Create(new Args { min = lifespan })); val3.animation = -1; ClearHitBloonsModel descendant = ((Model)val2).GetDescendant(); descendant.interval *= val.Cooldown / lifespan; descendant.intervalFrames = (int)(descendant.interval * 60f); RefreshPierceModel descendant2 = ((Model)val2).GetDescendant(); descendant2.interval *= val.Cooldown / lifespan; descendant2.intervalFrames = (int)(descendant2.interval * 60f); TowerModelBehaviorExt.AddBehavior(model, val2); } } public class Echo : CorvusAbilityChoice { public override string Description2 => "The Spirit splits itself in two. Commands sent to one are sent to both. The Echo always targets first, but has reduced attack speed."; protected override int Order => 0; public override void Apply1(TowerModel model) { CorvusInstantSpellModel val = InstantSpell(model); ((CorvusSpellModel)val).initialManaCost = (int)((float)((CorvusSpellModel)val).initialManaCost / val.duration); val.duration = 1f; val.cooldown = 0f; } public override void Apply2(TowerModel model) { EchoModel val = ((Il2CppObjectBase)InstantSpell(model)).Cast(); float factor = ((CorvusInstantSpellModel)val).duration / (((CorvusInstantSpellModel)val).duration + ((CorvusInstantSpellModel)val).cooldown); ((CorvusSpellModel)val).initialManaCost = (int)(factor * ((float)((CorvusSpellModel)val).initialManaCost / ((CorvusInstantSpellModel)val).duration)); ((CorvusInstantSpellModel)val).duration = 1f; ((CorvusInstantSpellModel)val).cooldown = 0f; TowerModel duplicateSpiritModel = val.duplicateSpiritModel; Il2CppGenericIEnumerable.ForEach(((Model)duplicateSpiritModel).GetDescendants(), (Action)delegate(WeaponModel weaponModel) { weaponModel.Rate /= factor; }); } } public class Ember : CorvusAbilityChoice { protected override int Order => 0; public override void Apply1(TowerModel model) { CorvusInstantSpellModel val = InstantSpell(model); ((CorvusSpellModel)val).initialManaCost = (int)((float)((CorvusSpellModel)val).initialManaCost / val.duration); val.duration = 1f; val.cooldown = 0f; } public override void Apply2(TowerModel model) { EmberModel val = ((Il2CppObjectBase)InstantSpell(model)).Cast(); float num = ((CorvusInstantSpellModel)val).duration / (((CorvusInstantSpellModel)val).duration + ((CorvusInstantSpellModel)val).cooldown); ((CorvusSpellModel)val).initialManaCost = (int)(num * ((float)((CorvusSpellModel)val).initialManaCost / ((CorvusInstantSpellModel)val).duration)); ((CorvusInstantSpellModel)val).duration = 1f; ((CorvusInstantSpellModel)val).cooldown = 0f; WeaponModel obj = ((Il2CppArrayBase)(object)val.attack.weapons)[0]; obj.Rate /= num; } } public class Frostbound : CorvusAbilityChoice { protected override int Order => 0; public override void Apply1(TowerModel model) { CorvusInstantSpellModel val = InstantSpell(model); ((CorvusSpellModel)val).initialManaCost = (int)((float)((CorvusSpellModel)val).initialManaCost / val.duration); val.duration = 1f; val.cooldown = 0f; } public override void Apply2(TowerModel model) { FrostboundModel val = ((Il2CppObjectBase)InstantSpell(model)).Cast(); float num = ((CorvusInstantSpellModel)val).duration / (((CorvusInstantSpellModel)val).duration + ((CorvusInstantSpellModel)val).cooldown); ((CorvusSpellModel)val).initialManaCost = (int)(num * ((float)((CorvusSpellModel)val).initialManaCost / ((CorvusInstantSpellModel)val).duration)); ((CorvusInstantSpellModel)val).duration = 1f; ((CorvusInstantSpellModel)val).cooldown = 0f; ClearHitBloonsModel descendant = ((Model)val.projectile).GetDescendant(); descendant.interval /= num; descendant.intervalFrames = (int)((float)descendant.intervalFrames / num); RefreshPierceModel descendant2 = ((Model)val.projectile).GetDescendant(); descendant2.interval /= num; descendant2.intervalFrames = (int)((float)descendant2.intervalFrames / num); } } public class Haste : CorvusAbilityChoice { protected override int Order => 1; public override void Apply1(TowerModel model) { CorvusInstantSpellModel val = InstantSpell(model); ((CorvusSpellModel)val).initialManaCost = (int)Math.Round((float)((CorvusSpellModel)val).initialManaCost / val.duration); val.duration = 1f; val.cooldown = 0f; } public override void Apply2(TowerModel model) { CorvusInstantSpellModel val = InstantSpell(model); float num = val.duration / (val.duration + val.cooldown); ((CorvusSpellModel)val).initialManaCost = (int)(num * ((float)((CorvusSpellModel)val).initialManaCost / val.duration)); val.duration = 1f; val.cooldown = 0f; HasteModel val2 = ((Il2CppObjectBase)val).Cast(); val2.orbitSpeedMultiplier = AbilityChoice.CalcAvgBonus(num, val2.orbitSpeedMultiplier); val2.turnSpeedMultiplier = AbilityChoice.CalcAvgBonus(num, val2.turnSpeedMultiplier); } } public class Malevolence : CorvusAbilityChoice { protected override int Order => 1; public override void Apply1(TowerModel model) { CorvusContinuousSpellModel val = ContinuousSpell(model); val.ongoingManaCost += ((CorvusSpellModel)val).initialManaCost / 20; ((CorvusSpellModel)val).initialManaCost = val.ongoingManaCost; } public override void Apply2(TowerModel model) { MalevolenceModel val = ((Il2CppObjectBase)ContinuousSpell(model)).Cast(); float num = ((float)((CorvusContinuousSpellModel)val).ongoingManaCost + (float)((CorvusSpellModel)val).initialManaCost / 20f) / (float)((CorvusContinuousSpellModel)val).ongoingManaCost; ((CorvusSpellModel)val).initialManaCost = ((CorvusContinuousSpellModel)val).ongoingManaCost; WeaponModel obj = ((Il2CppArrayBase)(object)val.attack.weapons)[0]; obj.Rate *= num; } } public class Nourishment : CorvusAbilityChoice { [HarmonyPatch(typeof(Nourishment), "Cast", new Type[] { })] internal static class Nourishment_Cast { [HarmonyPrefix] internal static bool Prefix(Nourishment __instance) { if (!CorvusAbilityChoice.EnabledForSpell((CorvusSpellType)14)) { return true; } Tower tower = ((TowerBehavior)__instance).tower; Hero behaviorInDependants = ((RootBehavior)tower).entity.GetBehaviorInDependants(); int initialManaCost = ((CorvusSpellModel)((CorvusInstantSpell)__instance).SpellModel).initialManaCost; if (behaviorInDependants.GetHeroLevel() < behaviorInDependants.maxLevel) { behaviorInDependants.AddXp((float)initialManaCost * __instance.spellModel.xpPerMana); } else if (((RootObject)__instance).Sim.model.gameMode != "Clicks" && ((RootObject)__instance).Sim.model.gameMode != "Deflation") { ((RootObject)__instance).Sim.AddCash((double)((float)initialManaCost * __instance.spellModel.cashPerManaAtMaxLevel), (CashType)2, tower.owner, (CashSource)11, (Tower)null, false); } return false; } } [HarmonyPatch(typeof(CorvusManager), "HasEnoughManaForSpell")] internal static class CorvusManager_HasEnoughManaForSpell { [HarmonyPostfix] internal static void Postfix(CorvusManager __instance, CorvusSpell spell, ref bool __result) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 if ((int)spell.SpellType == 14) { __result &= __instance.AvailableMana >= spell.corvusSpellModel.initialManaCost; } } } [HarmonyPatch(typeof(CorvusSpellbookSpellUi), "UpdateUi")] internal static class CorvusSpellbookSpellUi_UpdateUi { [HarmonyPostfix] internal static void Postfix(CorvusSpellbookSpellUi __instance) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 if ((int)__instance.corvusSpellModel.spellType == 14) { __instance.manaCost.SetText(__instance.corvusSpellModel.initialManaCost.ToString()); } } } [HarmonyPatch(typeof(Nourishment), "Expire")] internal static class Nourishment_Expire { [HarmonyPrefix] internal static bool Prefix(Nourishment __instance) { return false; } } protected override int Order => 1; public override string Description1 => "Sacrifices Mana and converts it into Hero XP."; public override string Description1Lvl20 => "Consumes Mana and converts it into cash."; protected override bool HasMode2 => false; public override void Apply1(TowerModel model) { CorvusInstantSpellModel val = InstantSpell(model); ((CorvusSpellModel)val).initialManaCost = (int)(800f / val.cooldown); val.duration = 1f; val.cooldown = 0f; } public override void Apply2(TowerModel model) { CorvusInstantSpellModel val = InstantSpell(model); ((CorvusSpellModel)val).initialManaCost = (int)(800f / val.cooldown); val.duration = 1f; val.cooldown = 0f; } } public class Overload : CorvusAbilityChoice { [HarmonyPatch(typeof(Overload), "Cast")] internal static class Overload_Cast { [HarmonyPrefix] internal static bool Prefix(Overload __instance) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) if (!CorvusAbilityChoice.EnabledForSpell((CorvusSpellType)9)) { return true; } OverloadModel spellModel = __instance.spellModel; ((CorvusSpell)__instance).CreateProjectileAtSpirit(__instance.emission, spellModel.projectile); CorvusManager corvusManager = ((RootObject)__instance).Sim.GetCorvusManager(((TowerBehavior)__instance).tower.owner); if (corvusManager.duplicateSpiritSubTower != null) { corvusManager.CreateProjectileAtDuplicate(((CorvusSpell)__instance).SpellType, __instance.emission, spellModel.projectile); } return false; } } [HarmonyPatch(typeof(CorvusManager), "IsSpellActive", new Type[] { typeof(CorvusSpellType) })] internal static class CorvusManager_IsSpellActive { [HarmonyPrefix] internal static bool Prefix(CorvusSpellType spellType, ref bool __result) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 if (!CorvusHandler.CorvusManager_TriggerCorvusToReleaseSpirit.releasing || (int)spellType != 9 || !CorvusAbilityChoice.EnabledForSpell((CorvusSpellType)9)) { return true; } __result = false; return false; } } private const int Period = 10; public override string Description1 => $"Every {10} seconds, the Spirit spends mana to emit a detonation of overwhelming energy."; public override string Description2 => "The Spirit constantly emits detonations of energy."; public override void Apply1(TowerModel model) { CorvusInstantSpellModel val = InstantSpell(model); ((CorvusSpellModel)val).initialManaCost = (int)((float)(10 * ((CorvusSpellModel)val).initialManaCost) / (val.cooldown + val.duration)); float num = (val.cooldown + val.duration) / 10f; val.duration = 10f; val.cooldown = 0f; OverloadModel val2 = ((Il2CppObjectBase)val).Cast(); DamageModel descendant = ((Model)val2.projectile).GetDescendant(); descendant.damage /= num; } public override void Apply2(TowerModel model) { CorvusInstantSpellModel val = InstantSpell(model); ((CorvusSpellModel)val).initialManaCost = (int)((float)((CorvusSpellModel)val).initialManaCost / (val.cooldown + val.duration)); val.duration = 1f; val.cooldown = 0f; OverloadModel val2 = ((Il2CppObjectBase)val).Cast(); DamageModel descendant = ((Model)val2.projectile).GetDescendant(); descendant.damage /= val.cooldown + val.duration; } } public class Repel : CorvusAbilityChoice { protected override int Order => 2; public override void Apply1(TowerModel model) { CorvusInstantSpellModel val = InstantSpell(model); ((CorvusSpellModel)val).initialManaCost = (int)((float)((CorvusSpellModel)val).initialManaCost / val.duration); val.duration = 1f; val.cooldown = 0f; } public override void Apply2(TowerModel model) { RepelModel val = ((Il2CppObjectBase)InstantSpell(model)).Cast(); float num = ((CorvusInstantSpellModel)val).duration / (((CorvusInstantSpellModel)val).duration + ((CorvusInstantSpellModel)val).cooldown); ((CorvusSpellModel)val).initialManaCost = (int)(num * ((float)((CorvusSpellModel)val).initialManaCost / ((CorvusInstantSpellModel)val).duration)); ((CorvusInstantSpellModel)val).duration = 1f; ((CorvusInstantSpellModel)val).cooldown = 0f; ClearHitBloonsModel descendant = ((Model)val.projectile).GetDescendant(); descendant.interval /= num; descendant.intervalFrames = (int)((float)descendant.intervalFrames / num); RefreshPierceModel descendant2 = ((Model)val.projectile).GetDescendant(); descendant2.interval /= num; descendant2.intervalFrames = (int)((float)descendant2.intervalFrames / num); } } public class SoulBarrier : CorvusAbilityChoice { protected override int Order => 0; public override string Description1 => "If a Bloon gets past your defenses, Temporarily use Mana in place of lives."; protected override bool HasMode2 => false; public override void Apply1(TowerModel model) { } } public class SoulHarvest : HeroAbilityChoice { private const int Factor = 5; public override string HeroId => TowerType.Corvus; public override Dictionary Descriptions1 => new Dictionary { { 3, "Corvus periodically harvests nearby Bloons in an instant. Learns: Echo, Haste." } }; public override void Apply1(TowerModel model) { AbilityModel val = AbilityModel(model); AttackModel val2 = ModelExt.Duplicate(((Model)val).GetDescendant()); ((Il2CppArrayBase)(object)val2.weapons)[0].Rate = val.Cooldown / 5f; DamageModel descendant = ((Model)val2).GetDescendant(); descendant.damage /= 5f; Il2CppGenericIEnumerable.ForEach(((Model)val2).GetDescendants(), (Action)delegate(DamageModifierForTagModel tagModel) { tagModel.damageAddative /= 5f; }); AddCorvusManaModel descendant2 = ((Model)val2).GetDescendant(); descendant2.amountOnEmit /= 5; TowerModelBehaviorExt.AddBehavior(model, val2); } } public class Spear : CorvusAbilityChoice { protected override int Order => 0; public override void Apply1(TowerModel model) { CorvusContinuousSpellModel val = ContinuousSpell(model); val.ongoingManaCost += ((CorvusSpellModel)val).initialManaCost / 20; ((CorvusSpellModel)val).initialManaCost = val.ongoingManaCost; } public override void Apply2(TowerModel model) { SpearModel val = ((Il2CppObjectBase)ContinuousSpell(model)).Cast(); float num = ((float)((CorvusContinuousSpellModel)val).ongoingManaCost + (float)((CorvusSpellModel)val).initialManaCost / 20f) / (float)((CorvusContinuousSpellModel)val).ongoingManaCost; ((CorvusSpellModel)val).initialManaCost = ((CorvusContinuousSpellModel)val).ongoingManaCost; WeaponModel obj = ((Il2CppArrayBase)(object)val.attack.weapons)[0]; obj.Rate *= num; } } public class SpiritWalk : HeroAbilityChoice { public override string HeroId => TowerType.Corvus; public override Dictionary Descriptions1 => new Dictionary { { 7, "Corvus gains significantly increased range. Learns: Ancestral Might, Malevolence" } }; protected override int Order => 1; public override void Apply1(TowerModel model) { model.range *= 1.5f; foreach (AttackModel attackModel in TowerModelExt.GetAttackModels(model)) { attackModel.range *= 1.5f; } } } public class Storm : CorvusAbilityChoice { protected override int Order => 0; public override void Apply1(TowerModel model) { CorvusContinuousSpellModel val = ContinuousSpell(model); val.ongoingManaCost += ((CorvusSpellModel)val).initialManaCost / 20; ((CorvusSpellModel)val).initialManaCost = val.ongoingManaCost; } public override void Apply2(TowerModel model) { StormModel val = ((Il2CppObjectBase)ContinuousSpell(model)).Cast(); float num = ((float)((CorvusContinuousSpellModel)val).ongoingManaCost + (float)((CorvusSpellModel)val).initialManaCost / 20f) / (float)((CorvusContinuousSpellModel)val).ongoingManaCost; ((CorvusSpellModel)val).initialManaCost = ((CorvusContinuousSpellModel)val).ongoingManaCost; WeaponModel obj = ((Il2CppArrayBase)(object)val.attack.weapons)[0]; obj.Rate *= num; } } public class Trample : CorvusAbilityChoice { [HarmonyPatch(typeof(Trample), "Cast")] internal static class Trample_Cast { [HarmonyPrefix] internal static bool Prefix(Trample __instance) { //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) if (!CorvusAbilityChoice.EnabledForSpell((CorvusSpellType)13)) { return true; } __instance.ClearProjectiles(); TrampleModel spellModel = __instance.spellModel; ((CorvusSpell)__instance).CreateProjectileAtSpirit(__instance.emission, spellModel.projectileModel); __instance.projectile = Il2CppGenericsExt.Get(((CorvusSpell)__instance).emittedProjectiles, 0); ((RootObject)__instance.projectile).OnDestroyEvent += DestroyedEventHandler.op_Implicit((Action)__instance.OnProjectileDestroy); CorvusManager corvusManager = ((RootObject)__instance).Sim.GetCorvusManager(((TowerBehavior)__instance).tower.owner); if (corvusManager.duplicateSpiritSubTower != null) { corvusManager.CreateProjectileAtDuplicate(((CorvusSpell)__instance).SpellType, __instance.emission, spellModel.projectileModel); __instance.projectileDuplicate = Il2CppGenerics.FirstOrDefault(corvusManager.GetDuplicateProjectilesEmittedBySpell(((CorvusSpellModel)spellModel).spellType)); Projectile projectileDuplicate = __instance.projectileDuplicate; if (projectileDuplicate != null) { ((RootObject)projectileDuplicate).OnDestroyEvent += DestroyedEventHandler.op_Implicit((Action)__instance.OnProjectileDestroy); } } return false; } } [HarmonyPatch(typeof(Trample), "Process")] internal static class Trample_Process { [HarmonyPrefix] internal static bool Prefix(Trample __instance) { if (!CorvusAbilityChoice.EnabledForSpell((CorvusSpellType)13)) { return true; } if (__instance.projectile != null) { ((CommonBehaviorProxy)(object)__instance.projectile).Rotation = ((RootBehavior)((CorvusSpell)__instance).SpiritTower).entity.transformBehaviorCache.rotation.value; } if (__instance.projectileDuplicate != null) { ((CommonBehaviorProxy)(object)__instance.projectileDuplicate).Rotation = ((CorvusSpell)__instance).Corvus.GetDuplicateTowerRotation(); } return false; } } [HarmonyPatch(typeof(CorvusManager), "ExpireInstantSpell")] internal static class CorvusManager_ExpireInstantSpell { [HarmonyPostfix] internal static void Postfix(CorvusInstantSpell spell) { Trample val = default(Trample); if (Il2CppSystemObjectExt.Is((Il2CppObjectBase)(object)spell, ref val)) { val.ClearProjectiles(); } } } private const int Factor = 5; public override string Description1 => "The spirit is joined by a stampede of other spirits, crushing Bloons they pass."; public override void Apply1(TowerModel model) { CorvusInstantSpellModel val = InstantSpell(model); ((CorvusSpellModel)val).initialManaCost = (int)((float)((CorvusSpellModel)val).initialManaCost / val.cooldown); val.duration = 1f; val.cooldown = 0f; TrampleModel val2 = ((Il2CppObjectBase)val).Cast(); DamageModel descendant = ((Model)val2.projectileModel).GetDescendant(); descendant.damage /= 5f; ProjectileModel projectileModel = val2.projectileModel; projectileModel.pierce /= 5f; } } public class Vision : CorvusAbilityChoice { [HarmonyPatch(typeof(VisionMutator), "ChangeTowerModel")] internal static class VisionMutator_ChangeTowerModel { [HarmonyPostfix] internal static void Postfix(TowerModel towerModel) { if (ModContent.GetInstance().Mode2) { Il2CppGenericIEnumerable.ForEach(((Model)towerModel).GetDescendants(), (Action)delegate(RemoveBloonModifiersModel modifiersModel) { modifiersModel.cleanseCamo = false; }); } } } public override string Description1 => "Lets the Spirit see Camo Bloons, and remove Camo property from anything it hits."; public override string Description2 => "Lets the Spirit see Camo Bloons."; protected override int Order => 2; public override void Apply1(TowerModel model) { CorvusInstantSpellModel val = InstantSpell(model); ((CorvusSpellModel)val).initialManaCost = (int)((float)((CorvusSpellModel)val).initialManaCost / val.duration); val.duration = 1f; val.cooldown = 0f; ((CorvusSpellModel)val).soundModel = null; } public override void Apply2(TowerModel model) { CorvusInstantSpellModel val = InstantSpell(model); float num = val.duration / (val.duration + val.cooldown); ((CorvusSpellModel)val).initialManaCost = (int)(num * ((float)((CorvusSpellModel)val).initialManaCost / val.duration)); val.duration = 1f; val.cooldown = 0f; ((CorvusSpellModel)val).soundModel = null; } } } namespace AbilityChoice.AbilityChoices.Hero.CaptainChurchill { public class ArmorPiercingShells : HeroAbilityChoice { private const int Factor = 3; public override string HeroId => TowerType.CaptainChurchill; public override Dictionary Descriptions1 => new Dictionary { { 3, "Periodically Churchill's shots can pop Black Bloons and do extra damage to Ceramic Bloons for a short duration. Duration increases as Churchill levels." } }; public override Dictionary Descriptions2 => new Dictionary { { 3, "Every third shot becomes an Armor Piercing Shell that can pop Black Bloons and does extra damage to Ceramic Bloons." }, { 13, "Armor Piercing Shells happen every other shot, pop 3 layers of Bloon and do extra damage to Ceramic and higher." } }; public override void Apply1(TowerModel model) { AbilityModel val = AbilityModel(model); val.Cooldown /= 3f; AbilityModelBehaviorExt.RemoveBehavior(val); AbilityModelBehaviorExt.GetBehaviors(val).ForEach(delegate(MutateProjectileOnAbilityModel mutate) { mutate.lifespanFrames /= 3; }); AbilityModelBehaviorExt.GetBehaviors(val).ForEach(delegate(MutateCreateProjectileOnExhaustPierceOnAbilityModel mutate) { mutate.lifespanFrames /= 3; }); AbilityModelBehaviorExt.GetBehaviors(val).ForEach(delegate(ChangeDamageTypeModel damage) { damage.lifespanFrames /= 3; }); } public override void Apply2(TowerModel model) { //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Expected O, but got Unknown AbilityModel val = AbilityModel(model); int interval = ((model.tier >= 13) ? 2 : 3); WeaponModel child = ((Model)TowerModelExt.GetAttackModel(model)).GetChild(); ProjectileModel projectile = ModelExt.Duplicate(child.projectile); Il2CppGenericIEnumerable.ForEach(((Model)projectile).GetDescendants(), (Action)delegate(DamageModel damageModel) { damageModel.immuneBloonProperties = (BloonProperties)0; }); AbilityModelBehaviorExt.GetBehaviors(val).ForEach(delegate(MutateProjectileOnAbilityModel mutate) { ProjectileModel val3 = Il2CppGenericIEnumerableExt.ToList(((Model)projectile).GetDescendants()).First((ProjectileModel p) => p.id == mutate.projectileModel.id); DamageModel damageModel = ProjectileModelExt.GetDamageModel(val3); damageModel.damage += (float)mutate.damageIncrease; ProjectileModelBehaviorExt.AddBehavior(val3, mutate.projectileBehaviorModel); val3.hasDamageModifiers = true; }); ProjectileModel obj = projectile; PrefabReference display = (ProjectileModelBehaviorExt.GetBehavior(projectile).display = AbilityModelBehaviorExt.GetBehavior(val).displayPath.assetPath); obj.display = display; CreateProjectileOnExhaustPierceModel descendant = ((Model)projectile).GetDescendant(); descendant.count += AbilityModelBehaviorExt.GetBehavior(val).countIncrease; AlternateProjectileModel val2 = CreateAlternateProjectileModelExt.Create(new Args { projectile = projectile, interval = interval }); WeaponModelBehaviorExt.AddBehavior(child, val2); } protected override void RemoveAbility(TowerModel model) { if (base.Mode2) { base.RemoveAbility(model); } else { TechBotify(model); } } } public class MOABBarrage : HeroAbilityChoice { private const float Factor = 0.5f; public override string HeroId => TowerType.CaptainChurchill; public override Dictionary Descriptions1 => new Dictionary { { 10, "Frequently launches a wave of shells at up to 10 MOAB-class Bloons for massive damage." }, { 20, "MOAB Barrage shells and Main Gun do massively increased damage per hit, and barrages happen more often." } }; public override Dictionary Descriptions2 => new Dictionary { { 10, "Constantly barrages the strongest MOAB-class Bloon on screen with shells that deal massive damage." }, { 20, "MOAB Barrage shells and Main Gun do massively increased damage per hit, and barrages fire even faster." } }; public override void Apply1(TowerModel model) { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected O, but got Unknown //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Expected O, but got Unknown AbilityModel val = AbilityModel(model); MoabBarrageModel behavior = AbilityModelBehaviorExt.GetBehavior(val); MoabBarrageBloonBehaviorModel descendant = ((Model)behavior).GetDescendant(); MoabBarrageBloonBehaviorModel val2 = ModelExt.Duplicate(descendant); val2.numOfMissiles = 1; AttackModel val3 = ModelExt.Duplicate(((Il2CppArrayBase)(object)((Model)TowerModelExt.GetAbility(Game.instance.model.GetHeroWithNameAndLevel(TowerType.Gwendolin, 10, false), 1)).GetDescendant().attacks)[1]); val3.fireWithoutTarget = false; Args val4 = new Args(); val4.filters = (FilterModel[])(object)new FilterModel[1] { (FilterModel)CreateFilterWithTagModelExt.Create(new Args { tag = "Moabs" }) }; AttackModelBehaviorExt.AddBehavior(val3, CreateAttackFilterModelExt.Create(val4)); WeaponModel child = ((Model)val3).GetChild(); child.Rate = val.Cooldown / (float)descendant.numOfMissiles; child.fireWithoutTarget = false; EffectModel effectModel = AbilityModelBehaviorExt.GetBehavior(val).effectModel; effectModel.lifespan = 0.2f; WeaponModelBehaviorExt.AddBehavior(child, CreateEjectEffectModelExt.Create(new Args { effectModel = effectModel, lifespan = 0.2f })); ProjectileModel projectile = child.projectile; projectile.pierce = behavior.targets; Il2CppReferenceArray filters = (ProjectileModelBehaviorExt.GetBehavior(projectile).filters = Il2CppReferenceArray.op_Implicit(((IEnumerable)projectile.filters).Take(1).ToArray())); projectile.filters = filters; ProjectileModelBehaviorExt.RemoveBehavior(projectile); AddBehaviorToBloonModel behavior2 = ProjectileModelBehaviorExt.GetBehavior(projectile); behavior2.mutationId = behavior.mutatorId; ((ProjectileBehaviorWithOverlayModel)behavior2).overlayType = ""; BloonBehaviorModel[] array = (BloonBehaviorModel[])(object)new MoabBarrageBloonBehaviorModel[1] { val2 }; behavior2.behaviors = Il2CppReferenceArray.op_Implicit(array); TowerModelBehaviorExt.AddBehavior(model, val3); } public override void Apply2(TowerModel model) { //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Expected O, but got Unknown //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Expected O, but got Unknown //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Expected O, but got Unknown //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Expected O, but got Unknown //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Expected O, but got Unknown //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Expected O, but got Unknown AbilityModel val = AbilityModel(model); MoabBarrageModel behavior = AbilityModelBehaviorExt.GetBehavior(val); MoabBarrageBloonBehaviorModel descendant = ((Model)behavior).GetDescendant(); EffectModel effectModel = AbilityModelBehaviorExt.GetBehavior(val).effectModel; effectModel.lifespan = 0.2f; float num = 0.5f * (float)descendant.numOfMissiles * (float)behavior.targets / val.Cooldown; descendant.numOfMissiles = 1; descendant.Interval = 0.01f; descendant.InitialDelay = 0f; int num2 = (descendant.randomDelayMaxFrames = 0); descendant.randomDelayMax = num2; Args val2 = new Args(); ((ModelArgs)(object)val2).name = ((ModContent)this).Name; val2.range = 9999f; val2.attackThroughWalls = true; val2.filters = (FilterModel[])(object)new FilterModel[1] { (FilterModel)CreateFilterMoabModelExt.Create() }; val2.behaviors = (Model[])(object)new Model[1] { (Model)CreateTargetStrongModelExt.Create() }; val2.CanSeeCamo = true; Args val3 = new Args(); val3.animation = 3; val3.rate = 1f / num; val3.emission = (EmissionModel)(object)CreateSingleEmissionModelExt.Create(); val3.behaviors = (Model[])(object)new Model[1] { (Model)CreateEjectEffectModelExt.Create(new Args { effectModel = effectModel, lifespan = 0.2f }) }; Args val4 = new Args(); val4.id = ((ModContent)this).Name; val4.maxPierce = 1f; Model[] array = new Model[4]; Args val5 = new Args(); val5.mutationId = behavior.mutatorId; val5.lifespan = 0.05f; val5.layers = 1; val5.behaviors = (BloonBehaviorModel[])(object)new BloonBehaviorModel[1] { (BloonBehaviorModel)descendant }; val5.isUnique = true; array[0] = (Model)CreateAddBehaviorToBloonModelExt.Create(val5); array[1] = (Model)CreateInstantModelExt.Create(); array[2] = (Model)CreateAgeModelExt.Create(new Args { lifespan = 0.05f }); array[3] = (Model)CreateDisplayModelExt.Create(); val4.behaviors = (Model[])(object)array; val4.filters = (FilterModel[])(object)new FilterModel[1] { (FilterModel)CreateFilterAllExceptTargetModelExt.Create() }; val3.projectile = CreateProjectileModelExt.Create(val4); val2.weapon = CreateWeaponModelExt.Create(val3); TowerModelBehaviorExt.AddBehavior(model, CreateAttackModelExt.Create(val2)); } } } namespace AbilityChoice.AbilityChoices.Hero.Benjamin { public class Biohack : HeroAbilityChoice { [HarmonyPatch(typeof(BiohackDamageMutator), "Mutate")] internal static class BiohackDamageMutator_Mutate { [HarmonyPostfix] internal static void Postfix(BiohackDamageMutator __instance, Model model) { if (!Mathf.Approximately(__instance.increase, 1f) || !ModContent.GetInstance().Mode2) { return; } Il2CppGenericIEnumerable.ForEach(model.GetDescendants(), (Action)delegate(WeaponModel weaponModel) { if (ModelExt.HasDescendant((Model)(object)weaponModel)) { weaponModel.Rate *= 1.25f; } }); } } private const int Factor = 5; public override string HeroId => TowerType.Benjamin; public override Dictionary Descriptions1 => new Dictionary { { 3, "Periodically Biohacks the 4 closest Monkeys, making them pop an extra layer for a few attacks but then skipping their next." }, { 13, "Biohack increases bonus damage and affects 6 Monkeys at a time." }, { 19, "Biohack lasts for more attacks and affected Monkeys pop 3 extra layers instead of 2." } }; public override Dictionary Descriptions2 => new Dictionary { { 3, "Biohacks the closest other tower, making it pop an extra layer per attack but have 25% reduced attack speed." }, { 13, "Biohack bonus damage increased to 2 and no longer reduced attack speed." }, { 19, "Biohack makes the affected monkey pop 3 extra layers instead of 2." } }; public override void Apply1(TowerModel model) { AbilityModel val = AbilityModel(model); val.Cooldown /= 5f; BiohackModel descendant = ((Model)val).GetDescendant(); descendant.lifespan /= 5f; descendant.lifespanFrames /= 5; Il2CppGenericIEnumerable.ForEach(((Model)val).GetDescendants(), (Action)delegate(DelayedShutoffModel shutoffModel) { shutoffModel.delay /= 5f; shutoffModel.delayFrames /= 5; shutoffModel.shutoffTime /= 5f; shutoffModel.shutoffTimeFrames /= 5; EffectModel effectModel2 = shutoffModel.effectModel; effectModel2.lifespan /= 5f; }); EffectModel effectModel = descendant.effectModel; effectModel.lifespan /= 5f; } public override void Apply2(TowerModel model) { AbilityModel val = AbilityModel(model); BiohackModel descendant = ((Model)val).GetDescendant(); val.Cooldown = descendant.lifespan; descendant.affectedCount = 1; Il2CppGenericIEnumerable.ForEach(((Model)val).GetDescendants(), (Action)delegate(DelayedShutoffModel shutoffModel) { int num = (shutoffModel.shutoffTimeFrames = 0); shutoffModel.shutoffTime = num; shutoffModel.effectModel = null; }); val.animation = -1; } protected override void ApplyBoth(TowerModel model) { AbilityModel val = AbilityModel(model); AbilityModelBehaviorExt.RemoveBehaviors(val); AbilityModelBehaviorExt.RemoveBehaviors(val); } protected override void RemoveAbility(TowerModel model) { TechBotify(model); } } public class SyphonFunding : HeroAbilityChoice { public override string HeroId => TowerType.Benjamin; public override Dictionary Descriptions1 => new Dictionary { { 10, "Every few bloons each round get downgraded by 1 rank and give double cash per pop." }, { 20, "More Bloons get downgraded, and they now give triple cash per pop." } }; public override Dictionary Descriptions2 => new Dictionary { { 10, "Bloon Trojan gives more cash and has Strong targeting priority instead of random." }, { 16, "Bloon Trojan is sent more often and earns even more cash." }, { 20, "Bloon Trojan can affect ZOMGs, and earns tons of cash." } }; public override void Apply1(TowerModel model) { AbilityModel val = AbilityModel(model); SyphonFundingModel behavior = AbilityModelBehaviorExt.GetBehavior(val); behavior.lifespan /= val.Cooldown; TowerModelBehaviorExt.AddBehavior(model, behavior); } public override void Apply2(TowerModel model) { TowerModelBehaviorExt.RemoveBehavior(model); AttackModel attackModel = TowerModelExt.GetAttackModel(model, "BloonTrojan"); WeaponModel child = ((Model)attackModel).GetChild(); ProjectileModel projectile = child.projectile; IncreaseBloonWorthWithTierModel behavior = ProjectileModelBehaviorExt.GetBehavior(projectile); int tier = model.tier; if (1 == 0) { } int num = ((tier < 16) ? 2 : ((tier >= 20) ? 10 : 5)); if (1 == 0) { } behavior.cashPerTier = num; AttackModelBehaviorExt.RemoveBehavior(attackModel); attackModel.targetProvider = (TargetSupplierModel)(object)CreateTargetStrongModelExt.Create(); AttackModelBehaviorExt.AddBehavior(attackModel, attackModel.targetProvider); if (model.tier >= 20) { AttackFilterModel behavior2 = AttackModelBehaviorExt.GetBehavior(attackModel); behavior2.filters = Il2CppReferenceArrayExt.RemoveItem(behavior2.filters, IEnumerableExt.OfIl2CppType((IEnumerable)behavior2.filters).First((FilterOutTagModel filter) => filter.tag == "Zomg")); ProjectileFilterModel behavior3 = ProjectileModelBehaviorExt.GetBehavior(projectile); behavior3.filters = Il2CppReferenceArrayExt.RemoveItem(behavior3.filters, IEnumerableExt.OfIl2CppType((IEnumerable)behavior3.filters).First((FilterOutTagModel filter) => filter.tag == "Zomg")); projectile.filters = Il2CppReferenceArrayExt.RemoveItem(projectile.filters, IEnumerableExt.OfIl2CppType((IEnumerable)projectile.filters).First((FilterOutTagModel filter) => filter.tag == "Zomg")); } } } } namespace AbilityChoice.AbilityChoices.Hero.Adora { public class BallOfLight : HeroAbilityChoice { public override string AbilityName => "Ball of Light"; public override string HeroId => TowerType.Adora; public override Dictionary Descriptions1 => new Dictionary { { 10, "Brings forth a powerful ball of energy to strike down the Bloons." } }; public override void Apply1(TowerModel model) { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Expected O, but got Unknown //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Expected O, but got Unknown AbilityModel val = AbilityModel(model); AbilityCreateTowerModel behavior = AbilityModelBehaviorExt.GetBehavior(val); TowerModel towerModel = behavior.towerModel; float num = TowerModelBehaviorExt.GetBehavior(towerModel).Lifespan / val.Cooldown; TowerModelBehaviorExt.RemoveBehavior(towerModel); foreach (WeaponModel weapon in TowerModelExt.GetWeapons(towerModel)) { weapon.Rate /= num; } Args val2 = new Args(); ((ModelArgs)val2).name = ((ModContent)this).Name + model.tier; val2.towerModel = towerModel; val2.isAirBasedTower = true; TowerModelBehaviorExt.AddBehavior(model, CreateTowerCreateTowerModelExt.Create(val2)); TowerModelBehaviorExt.AddBehavior(model, behavior); } } public class BloodSacrifice : HeroAbilityChoice { [HarmonyPatch(typeof(MutatorTower), "Mutate")] internal static class SupportStackingRange_MutatorTower_Mutate { [HarmonyPostfix] internal static void Postfix(MutatorTower __instance, Model model) { SupportStackingRangeModel support = __instance.parent.supportStackingRangeModel; TowerModel val = default(TowerModel); if (((Model)support).name.Contains("BloodSacrifice") && Il2CppSystemObjectExt.Is((Il2CppObjectBase)(object)model, ref val)) { Il2CppGenericIEnumerable.ForEach(((Model)val).GetDescendants(), (Action)delegate(WeaponModel weapon) { weapon.Rate *= 1f - support.rangeMultiplier; }); } } } internal static readonly Dictionary NextSacrificeTimes = new Dictionary(); public override string HeroId => TowerType.Adora; public override Dictionary Descriptions1 => new Dictionary { { 7, "You may pay tribute to Adora, passively spending money in order to give bonus XP to Adora and boost her attack range and rate of fire (and also 3+/X/X Super Monkeys')." }, { 20, "Ball of Light is greatly improved, plus increased rate of fire, range, and cost efficiency for paying tribute." } }; public override Dictionary Descriptions2 => new Dictionary { { 7, "Adora get more 10% Hero XP for each 3+/X/X Super Monkey (up to 50%). Each one nearby will buff the range and rate of fire of themselves and Adora by 5%, stacking up to 25%." }, { 20, "Ball of Light is greatly improved, plus increased rate of fire, range. Super Monkey buff is now 10% per stack, up to 50%." } }; public override bool DoesTick => base.Mode == 1; private static TowerFilterModel[] Tier3SuperMonkeys { get { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Expected O, but got Unknown //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Expected O, but got Unknown TowerFilterModel[] array = new TowerFilterModel[2]; Args val = new Args(); val.baseIds = new string[1] { TowerType.SuperMonkey }; array[0] = (TowerFilterModel)CreateFilterInBaseTowerIdModelExt.Create(val); array[1] = (TowerFilterModel)CreateFilterInTowerTiersModelExt.Create(new Args { path1MinTier = 3, path1MaxTier = 999, path2MinTier = 0, path2MaxTier = 999, path3MinTier = 0, path3MaxTier = 999 }); return (TowerFilterModel[])(object)array; } } private static TowerFilterModel[] JustAdora { get { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Expected O, but got Unknown TowerFilterModel[] array = new TowerFilterModel[1]; Args val = new Args(); val.baseIds = new string[1] { TowerType.Adora }; array[0] = (TowerFilterModel)CreateFilterInBaseTowerIdModelExt.Create(val); return (TowerFilterModel[])(object)array; } } private static TowerFilterModel[] AdoraAndSuperMonkeys { get { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Expected O, but got Unknown //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Expected O, but got Unknown TowerFilterModel[] array = new TowerFilterModel[2]; Args val = new Args(); val.baseIds = new string[2] { TowerType.SuperMonkey, TowerType.Adora }; array[0] = (TowerFilterModel)CreateFilterInBaseTowerIdModelExt.Create(val); array[1] = (TowerFilterModel)CreateFilterInTowerTiersModelExt.Create(new Args { path1MinTier = 3, path1MaxTier = 999, path2MinTier = 0, path2MaxTier = 999, path3MinTier = 0, path3MaxTier = 999 }); return (TowerFilterModel[])(object)array; } } public override void Apply1(TowerModel model) { AbilityModel val = AbilityModel(model); BloodSacrificeModel behavior = AbilityModelBehaviorExt.GetBehavior(val); TowerModelBehaviorExt.AddBehavior(model, behavior); model.towerSelectionMenuThemeId = ModContent.GetId(); } protected override void Tick(int ticks, Simulation sim) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) UnityToSimulation bridge = UnityToSimulationExt.Current; IEnumerable enumerable = from tower in Il2CppGenericIEnumerableExt.ToList(sim.towerManager.GetTowersByBaseId(TowerType.Adora)) where tower.owner == bridge.MyPlayerNumber select tower; foreach (Tower item in enumerable) { int valueOrDefault = NextSacrificeTimes.GetValueOrDefault(((RootObject)item).Id, 0); if (sim.roundTime.elapsed < valueOrDefault || AdoraTsmTheme.SacrificeAmount == 0) { continue; } NextSacrificeTimes[((RootObject)item).Id] = sim.roundTime.elapsed + 60; BloodSacrifice behavior = ((RootBehavior)item).entity.GetBehavior(); if (behavior == null) { continue; } BloodSacrificeModel bloodSacrificeModel = behavior.bloodSacrificeModel; float num = (float)Math.Min(AdoraTsmTheme.SacrificeAmount, bridge.GetCash(-1)); ((RootBehavior)item).entity.GetBehavior().AddXp(num * bloodSacrificeModel.xpMultiplier); float num2 = bloodSacrificeModel.bonusSacrificeAmount / bloodSacrificeModel.buffDuration; BloodSacrificeMutator mutator = bloodSacrificeModel.GetMutator((int)Math.Round(num / num2), ""); ((Mutable)item).AddMutator((BehaviorMutator)(object)mutator, 66, true, true, false, true, false, false, false, -1, false, false); List source = Il2CppGenericIEnumerableExt.ToList(sim.towerManager.GetTowersInRange(((CommonBehaviorProxy)(object)item).Position, item.towerModel.range)); foreach (Tower item2 in source.Where((Tower tower) => ((Il2CppArrayBase)(object)tower.towerModel.appliedUpgrades).Contains("Sun Avatar"))) { item2.AddMutatorIncludeSubTowers((BehaviorMutator)(object)mutator, 66, true, true, false, true, -1); } sim.RemoveCash((double)num, (CashType)0, item.owner, (CashSource)3); } } public override void Apply2(TowerModel model) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected O, but got Unknown //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Expected O, but got Unknown Args val = new Args(); ((ModelArgs)val).name = ((ModContent)this).Name; val.towerIds = TowerType.SuperMonkey; val.tier = 3; val.maxPercent = 50; val.percentPerTower = 5; TowerModelBehaviorExt.AddBehavior(model, CreateScaleHeroXpWithTowerCountModelExt.Create(val)); BloodSacrificeModel descendant = ((Model)model).GetDescendant(); Args val2 = new Args(); val2.mutationId = ((ModContent)this).Name + "AddBehavior"; TowerBehaviorModel[] array = new TowerBehaviorModel[1]; Args val3 = new Args(); ((ModelArgs)val3).name = ((ModContent)this).Name; val3.mutatorId = ((ModContent)this).Name; val3.rangeMultiplier = ((model.tier < 20) ? 0.05f : 0.1f); val3.buffIconName = descendant.buffIconName; val3.buffLocsName = descendant.buffLocsName; val3.filters = AdoraAndSuperMonkeys; val3.maxStacks = 5; array[0] = (TowerBehaviorModel)CreateSupportStackingRangeModelExt.Create(val3); val2.behaviors = (TowerBehaviorModel[])(object)array; val2.filters = Tier3SuperMonkeys; TowerModelBehaviorExt.AddBehavior(model, CreateAddBehaviorToTowerSupportModelExt.Create(val2)); } } public class LongArmOfLight : HeroAbilityChoice { private const int Factor = 3; public override string AbilityName => "The Long Arm of Light"; public override string HeroId => TowerType.Adora; public override Dictionary Descriptions1 => new Dictionary { { 3, "Adora occasionally gets greatly increases attack range and power for a short time & damages all Bloon Types." } }; public override Dictionary Descriptions2 => new Dictionary { { 3, "Further increased attack range. Everything third shot has bonus power & damages all Bloon types." }, { 16, "Long Arm of Light projectiles becomes even more deadly, and now happen every other attack." } }; public override void Apply1(TowerModel model) { AbilityModel val = AbilityModel(model); val.Cooldown /= 3f; AbilityModelBehaviorExt.RemoveBehavior(val); LongArmOfLightModel behavior = AbilityModelBehaviorExt.GetBehavior(val); behavior.Lifespan /= 3f; } public override void Apply2(TowerModel model) { //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Expected O, but got Unknown AbilityModel val = AbilityModel(model); LongArmOfLightModel longArmOfLight = AbilityModelBehaviorExt.GetBehavior(val); int interval = ((model.tier >= 16) ? 2 : 3); float uptime = longArmOfLight.Lifespan / val.Cooldown; float num = AbilityChoice.CalcAvgBonus(uptime, longArmOfLight.multiplier); model.range *= num; foreach (AttackModel attackModel in TowerModelExt.GetAttackModels(model)) { attackModel.range *= num; } WeaponModel child = ((Model)TowerModelExt.GetAttackModel(model)).GetChild(); ProjectileModel val2 = ModelExt.Duplicate(child.projectile); PrefabReference display = (ProjectileModelBehaviorExt.GetBehavior(val2).display = longArmOfLight.projectileDisplay.assetPath); val2.display = display; val2.pierce *= longArmOfLight.multiplier; val2.radius *= longArmOfLight.projectileRadiusMultiplier; Il2CppGenericIEnumerable.ForEach(((Model)val2).GetDescendants(), (Action)delegate(DamageModel damageModel) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) damageModel.immuneBloonProperties = longArmOfLight.immuneBloonProperties; damageModel.damage += (float)longArmOfLight.damageIncrease; }); AdoraTrackTargetModel behavior = ProjectileModelBehaviorExt.GetBehavior(val2); behavior.minimumSpeed *= longArmOfLight.multiplier; behavior.minimumSpeedFrames *= longArmOfLight.multiplier; behavior.rotation *= longArmOfLight.multiplier; behavior.maximumSpeed *= longArmOfLight.multiplier; behavior.maximumSpeedFrames *= longArmOfLight.multiplier; behavior.acceleration *= longArmOfLight.multiplier; behavior.accelerationFrames *= longArmOfLight.multiplier; behavior.Lifespan *= longArmOfLight.multiplier; AlternateProjectileModel val3 = CreateAlternateProjectileModelExt.Create(new Args { projectile = val2, interval = interval }); WeaponModelBehaviorExt.AddBehavior(child, val3); } protected override void RemoveAbility(TowerModel model) { if (base.Mode2) { base.RemoveAbility(model); } else { TechBotify(model); } } } } namespace AbilityChoice.AbilityChoices.Hero.AdmiralBrickell { public class BlastChain : HeroAbilityChoice { public override string HeroId => TowerType.AdmiralBrickell; public override string AbilityName => "Blast Chain Ability"; public override Dictionary Descriptions1 => new Dictionary { { 7, "Sea mines fire more frequently. Brickell gains increased attack range and Camo Bloon detection." } }; public override Dictionary Descriptions2 => new Dictionary { { 7, "Sea mines last longer. Brickell gains increased attack range and Camo Bloon detection." } }; public override void Apply1(TowerModel model) { AbilityModel val = AbilityModel(model); BrickellFreezeMinesAbilityBuffModel descendant = ((Model)val).GetDescendant(); float num = AbilityChoice.CalcAvgBonus(descendant.lifespan / val.Cooldown, 1f / descendant.multiplier); WeaponModel descendant2 = ((Model)TowerModelExt.GetAttackModel(model, "SeaMine")).GetDescendant(); descendant2.Rate /= num; } public override void Apply2(TowerModel model) { AbilityModel val = AbilityModel(model); BrickellFreezeMinesAbilityBuffModel descendant = ((Model)val).GetDescendant(); float bonus = AbilityChoice.CalcAvgBonus(descendant.lifespan / val.Cooldown, descendant.projectileSpeedMultiplier); Il2CppGenericIEnumerable.ForEach(((Model)TowerModelExt.GetAttackModel(model, "SeaMine")).GetDescendants(), (Action)delegate(AgeModel ageModel) { if (ageModel.useRoundTime) { ageModel.Lifespan *= bonus; } }); } } public class MegaMine : HeroAbilityChoice { public override string HeroId => TowerType.AdmiralBrickell; public override Dictionary Descriptions1 => new Dictionary { { 10, "Deploys Mega Mines to a targeted water location that trigger on MOABs and stun nearby Bloons. Mega Mines last 3 rounds." }, { 13, "Mega Mines are created more frequently." }, { 18, "Mega Mines are created even more frequently." }, { 20, "Mega Mines do massively increased damage and stun longer." } }; public override Dictionary Descriptions2 => new Dictionary { { 10, "Sea Mine explosions are larger, deal bonus damage to Moabs, and stun Bloons." }, { 13, "Sea Mine pierce and Moab damage increased." }, { 18, "Sea Mine stun duration and Moab Damage increased." }, { 20, "Sea Mines have more pierce, stun for longer, and their Moab damage is massively increased." } }; public override void Apply1(TowerModel model) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Expected O, but got Unknown AbilityModel val = AbilityModel(model); PlaceProjectileAtModel behavior = AbilityModelBehaviorExt.GetBehavior(val); ProjectileModel val2 = ModelExt.Duplicate(behavior.projectileModel); Args val3 = new Args(); val3.timeToTake = 1f; val3.curveSamples = new float[2] { 0f, 1f }; val3.filterCollisionWhileMoving = true; val3.stopOnTargetReached = true; val3.positionAboveMoabTypes = true; ProjectileModelBehaviorExt.AddBehavior(val2, CreateArriveAtTargetModelExt.Create(val3)); AttackModel val4 = ModelExt.Duplicate(TowerModelExt.GetAttackModel(Game.instance.model.GetTower(TowerType.WizardMonkey, 1, 2, 0), "Wall")); ((Model)val4).name = "AttackModel_MegaMine"; AttackModelBehaviorExt.RemoveBehavior(val4); TargetSelectedPointModel val5 = (TargetSelectedPointModel)(object)(val4.targetProvider = (TargetSupplierModel)(object)AttackModelBehaviorExt.GetBehavior(val4)); val5.displayInvalid = ModContent.CreatePrefabReference(); val5.lockToInsideTowerRange = false; val5.startWithClosestTrackPoint = false; val5.projectileToExpireOnTargetChangeModel = null; AttackFilterModel behavior3 = AttackModelBehaviorExt.GetBehavior(val4); FilterOfftrackModel descendant = ((Model)behavior3).GetDescendant(); ((Model)behavior3).RemoveChildDependant(descendant); behavior3.filters = Il2CppReferenceArrayExt.RemoveItem(behavior3.filters, descendant); WeaponModel descendant2 = ((Model)val4).GetDescendant(); descendant2.animation = 3; WeaponModelBehaviorExt.RemoveBehavior(descendant2); ((Model)descendant2).RemoveChildDependant(descendant2.projectile); descendant2.projectile = val2; ((Model)descendant2).AddChildDependant(val2); descendant2.Rate = val.Cooldown; descendant2.startInCooldown = false; descendant2.customStartCooldown = 5f; descendant2.ejectZ = 9999f; EffectModel effectAtTowerModel = behavior.effectAtTowerModel; WeaponModelBehaviorExt.AddBehavior(descendant2, CreateEjectEffectModelExt.Create(new Args { effectModel = effectAtTowerModel, lifespan = effectAtTowerModel.lifespan })); TowerModelBehaviorExt.AddBehavior(model, val4); model.towerSelectionMenuThemeId = "SelectPointInput"; model.UpdateTargetProviders(); } public override void Apply2(TowerModel model) { //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Expected O, but got Unknown AbilityModel val = AbilityModel(model); ProjectileModel val2 = Il2CppGenericIEnumerableExt.ToList(((Model)val).GetDescendants()).First((ProjectileModel projectileModel) => projectileModel.id == "MegaMineExplosion"); AttackModel attackModel = TowerModelExt.GetAttackModel(model, "SeaMine"); ProjectileModel val3 = Il2CppGenericIEnumerableExt.ToList(((Model)attackModel).GetDescendants()).First((ProjectileModel projectileModel) => projectileModel.id == "Explosion"); float cooldown = val.Cooldown; float num = val.Cooldown / 2f; float num2 = val.Cooldown / 5f; int num3 = 10; ProjectileModelBehaviorExt.AddBehavior(val3, CreateDamageModifierForTagModelExt.Create(new Args { tag = "Moabs", damageAddative = ProjectileModelExt.GetDamageModel(val2).damage / cooldown })); val3.pierce += val2.pierce / num; SlowModel val4 = ModelExt.Duplicate(ProjectileModelBehaviorExt.GetBehavior(val2)); val4.Lifespan /= num2; val3.radius += val2.radius / (float)num3; val3.UpdateCollisionPassList(); ProjectileModelBehaviorExt.AddBehavior(val3, val4); val3.hasDamageModifiers = true; } } public class NavalTactics : HeroAbilityChoice { public override string HeroId => TowerType.AdmiralBrickell; public override Dictionary Descriptions1 => new Dictionary { { 3, "Increases attack speed of Brickell and nearby water-based Monkeys." }, { 5, "Nearby water-based Monkeys can hit all Bloon types except Camo." }, { 8, "Water towers in radius gain extra pierce and can hit Camo bloons." }, { 14, "Nearby water-based monkeys have further increased attack speed." }, { 19, "Brickell's buffs affect all water based towers everywhere." } }; public override Dictionary Descriptions2 => new Dictionary { { 3, "Further increased attack speed." }, { 5, "Increased popping power, and attacks can hit all Bloon types except Camo." }, { 8, "Gains extra pierce." }, { 14, "Further increased attack speed and pierce." }, { 19, "Drastically increased attack speed and pierce." } }; public override void Apply1(TowerModel model) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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_006f: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Expected O, but got Unknown //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0120: 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_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Expected O, but got Unknown //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Expected O, but got Unknown AbilityModel val = AbilityModel(model); ActivateRateSupportZoneModel descendant = ((Model)val).GetDescendant(); ActivateVisibilitySupportZoneModel descendant2 = ((Model)val).GetDescendant(); ActivateTowerDamageSupportZoneModel descendant3 = ((Model)val).GetDescendant(); float num = AbilityChoice.CalcAvgBonus(descendant.lifespan / val.Cooldown, 1f / descendant.rateModifier); bool isGlobal = model.tier >= 19; TowerModelBehaviorExt.AddBehavior(model, CreateRateSupportModelExt.Create(new Args { multiplier = 1f / num, isUnique = descendant.isUnique, mutatorId = descendant.mutatorId, isGlobal = isGlobal, filters = Il2CppArrayBase.op_Implicit((Il2CppArrayBase)(object)descendant.filters), buffLocsName = ((AbilityBehaviorBuffModel)descendant).buffLocsName, buffIconName = ((AbilityBehaviorBuffModel)descendant).buffIconName, appliesToOwningTower = descendant.canEffectThisTower })); if (descendant3 != null) { TowerModelBehaviorExt.AddBehavior(model, CreateDamageTypeSupportModelExt.Create(new Args { isUnique = descendant3.isUnique, mutatorId = descendant3.mutatorId, immuneBloonProperties = descendant3.immuneBloonProperties, filters = Il2CppArrayBase.op_Implicit((Il2CppArrayBase)(object)descendant3.filters), buffLocsName = ((AbilityBehaviorBuffModel)descendant3).buffLocsName, buffIconName = ((AbilityBehaviorBuffModel)descendant3).buffIconName, appliesToOwningTower = descendant3.canEffectThisTower, isGlobal = isGlobal })); } if (descendant2 != null) { TowerModelBehaviorExt.AddBehavior(model, CreateVisibilitySupportModelExt.Create(new Args { isUnique = descendant2.isUnique, mutatorId = descendant2.mutatorId, isGlobal = isGlobal, filters = Il2CppArrayBase.op_Implicit((Il2CppArrayBase)(object)descendant2.filters), buffLocsName = ((AbilityBehaviorBuffModel)descendant2).buffLocsName, buffIconName = ((AbilityBehaviorBuffModel)descendant2).buffIconName, appliesToOwningTower = descendant2.canEffectThisTower })); } } public override void Apply2(TowerModel model) { AbilityModel val = AbilityModel(model); ActivateRateSupportZoneModel rateBuff = ((Model)val).GetDescendant(); ActivateTowerDamageSupportZoneModel damageBuff = ((Model)val).GetDescendant(); ActivatePierceSupportZoneModel pierceBuff = ((Model)val).GetDescendant(); float factor = ((model.tier >= 19) ? 2.1f : ((model.tier >= 14) ? 1.1f : 0.6f)); if (rateBuff != null) { Il2CppGenericIEnumerable.ForEach(((Model)model).GetDescendants(), (Action)delegate(WeaponModel weaponModel) { weaponModel.Rate *= (float)Math.Pow(rateBuff.rateModifier, factor); }); } if (damageBuff != null) { Il2CppGenericIEnumerable.ForEach(((Model)val).GetDescendants(), (Action)delegate(DamageModel damageModel) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) damageModel.damage += damageBuff.damageIncrease * factor; BloonProperties immuneBloonProperties = (damageModel.immuneBloonPropertiesOriginal = damageBuff.immuneBloonProperties); damageModel.immuneBloonProperties = immuneBloonProperties; }); } if (pierceBuff != null) { Il2CppGenericIEnumerable.ForEach(((Model)val).GetDescendants(), (Action)delegate(ProjectileModel projectileModel) { projectileModel.pierce += (float)(pierceBuff.pierceIncrease * (int)Math.Ceiling(factor)); }); } } } }