Decompiled source of AbilityChoice v4.4.6
AbilityChoice.dll
Decompiled 10 hours ago
The result has been truncated due to the large size, download it to view full contents!
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<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T> { int ICollection.Count => _items.Length; bool ICollection.IsSynchronized => false; object ICollection.SyncRoot => this; object? IList.this[int index] { get { return _items[index]; } set { throw new NotSupportedException(); } } bool IList.IsFixedSize => true; bool IList.IsReadOnly => true; int IReadOnlyCollection<T>.Count => _items.Length; T IReadOnlyList<T>.this[int index] => _items[index]; int ICollection<T>.Count => _items.Length; bool ICollection<T>.IsReadOnly => true; T IList<T>.this[int index] { get { return _items[index]; } set { throw new NotSupportedException(); } } public <>z__ReadOnlyArray(T[] items) { _items = items; } IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)_items).GetEnumerator(); } void ICollection.CopyTo(Array array, int index) { ((ICollection)_items).CopyTo(array, index); } int IList.Add(object? value) { throw new NotSupportedException(); } void IList.Clear() { throw new NotSupportedException(); } bool IList.Contains(object? value) { return ((IList)_items).Contains(value); } int IList.IndexOf(object? value) { return ((IList)_items).IndexOf(value); } void IList.Insert(int index, object? value) { throw new NotSupportedException(); } void IList.Remove(object? value) { throw new NotSupportedException(); } void IList.RemoveAt(int index) { throw new NotSupportedException(); } IEnumerator<T> IEnumerable<T>.GetEnumerator() { return ((IEnumerable<T>)_items).GetEnumerator(); } void ICollection<T>.Add(T item) { throw new NotSupportedException(); } void ICollection<T>.Clear() { throw new NotSupportedException(); } bool ICollection<T>.Contains(T item) { return ((ICollection<T>)_items).Contains(item); } void ICollection<T>.CopyTo(T[] array, int arrayIndex) { ((ICollection<T>)_items).CopyTo(array, arrayIndex); } bool ICollection<T>.Remove(T item) { throw new NotSupportedException(); } int IList<T>.IndexOf(T item) { return ((IList<T>)_items).IndexOf(item); } void IList<T>.Insert(int index, T item) { throw new NotSupportedException(); } void IList<T>.RemoveAt(int index) { throw new NotSupportedException(); } } namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace AbilityChoice { public abstract class AbilityChoice : NamedModContent { internal static int? overrideMode; protected MelonPreferences_Entry<int> setting; protected readonly HashSet<string> affectedIds = new HashSet<string>(); protected readonly List<string> affectedOrder = new List<string>(); public virtual string AbilityName => Regex.Replace(((ModContent)this).Name, "(?<!^)([A-Z][a-z]|(?<=[a-z])[A-Z])", " $1", RegexOptions.Compiled).Trim(); public virtual string BackUpAbilityName => 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<int>(((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<int> 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<AbilityModel>)TowerModelBehaviorExt.GetBehaviors<AbilityModel>(model)).FirstOrDefault((Func<AbilityModel, bool>)((AbilityModel abilityModel) => abilityModel.displayName == AbilityName || abilityModel.displayName == BackUpAbilityName)); } protected virtual void RemoveAbility(TowerModel model) { AbilityModel val = AbilityModel(model); if (val != null) { TowerModelBehaviorExt.RemoveBehavior<AbilityModel>(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<TowerModel> GetAffectedCached(GameModel gameModel) { Dictionary<string, TowerModel> towers = ((IEnumerable<TowerModel>)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<TowerModel> 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<ActivateAbilityAfterIntervalModel>((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<ActivateAbilityAfterIntervalModel>)val).name = name; val.abilityModel = ability; val.interval = ability.Cooldown; TowerModelBehaviorExt.AddBehavior<ActivateAbilityAfterIntervalModel>(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<TowerAbilityChoice>().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<TowerAbilityChoice>().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<TowerAbilityChoice>().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<AbilityChoice>()) { 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<EclipseOfFimbulwinter>().Mode == 1 && Il2CppGenericIEnumerable.Any<TowerToSimulation>(UnityToSimulationExt.Current.GetAllTowers(), (Func<TowerToSimulation, bool>)((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<RaycastResult> val = new List<RaycastResult>(); PointerEventData val2 = new PointerEventData(EventSystem.current) { position = Vector2.op_Implicit(Input.mousePosition) }; EventSystem.current.RaycastAll(val2, val); Enumerator<RaycastResult> enumerator = val.GetEnumerator(); TowerAbilityChoiceInfo towerAbilityChoiceInfo = default(TowerAbilityChoiceInfo); HeroAbilityChoiceInfo heroAbilityChoiceInfo = default(HeroAbilityChoiceInfo); while (enumerator.MoveNext()) { RaycastResult current = enumerator.Current; if (GameObjectExt.HasComponent<TowerAbilityChoiceInfo>(current.gameObject, ref towerAbilityChoiceInfo)) { towerAbilityChoiceInfo.abilityChoice.Toggle(); towerAbilityChoiceInfo.UpdateIcon(); towerAbilityChoiceInfo.upgradeDetails.OnPointerExit(val2); towerAbilityChoiceInfo.upgradeDetails.OnPointerEnter(val2); } else { if (!GameObjectExt.HasComponent<HeroAbilityChoiceInfo>(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<AbilityChoice>() where choice.Enabled select choice) { try { item.Apply(gameModel); } catch (Exception ex) { ModHelper.Error<AbilityChoiceMod>((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<BoostArtifactModel> boosts, out List<CountAllCategoriesBehaviorModel> towerSetChanges, out List<AbilityStackingBehaviorModel> abilityStackings) { boosts = new List<BoostArtifactModel>(); towerSetChanges = new List<CountAllCategoriesBehaviorModel>(); abilityStackings = new List<AbilityStackingBehaviorModel>(); 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<ArtifactLoot> 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<BoostArtifactModel>((Il2CppObjectBase)(object)val, ref item)) { boosts.Add(item); } boosts.AddRange((IEnumerable<BoostArtifactModel>)MonoLinqHelper.ToArray<BoostArtifactModel>(val.GetDescendants<BoostArtifactModel>())); towerSetChanges.AddRange((IEnumerable<CountAllCategoriesBehaviorModel>)MonoLinqHelper.ToArray<CountAllCategoriesBehaviorModel>(val.GetDescendants<CountAllCategoriesBehaviorModel>())); abilityStackings.AddRange((IEnumerable<AbilityStackingBehaviorModel>)MonoLinqHelper.ToArray<AbilityStackingBehaviorModel>(val.GetDescendants<AbilityStackingBehaviorModel>())); } } public static void ProcessBoosts(GameModel gameModel, List<BoostArtifactModel> boosts, List<CountAllCategoriesBehaviorModel> towerSetChanges, List<AbilityStackingBehaviorModel> 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<CooldownBoostBehaviorModel> cooldownBehaviors = ArtifactModelBehaviorExt.GetBehaviors<CooldownBoostBehaviorModel>(boost); if (!cooldownBehaviors.Any()) { continue; } foreach (TowerModel tower in (Il2CppArrayBase<TowerModel>)(object)gameModel.towers) { if ((boost.towerTypes != null && ((IEnumerable<string>)boost.towerTypes).Any() && ((Il2CppArrayBase<string>)(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<TowerSet>)(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<AbilityModel>(((Model)tower).GetDescendants<AbilityModel>(), (Action<AbilityModel>)delegate(AbilityModel ability) { using List<CooldownBoostBehaviorModel>.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<TowerModel>)(object)gameModel.towers) { if (abilityStacking.towerTypes != null && ((IEnumerable<string>)abilityStacking.towerTypes).Any() && ((Il2CppArrayBase<string>)(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<TowerSet>)(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<AbilityModel>(((Model)tower2).GetDescendants<AbilityModel>(), (Action<AbilityModel>)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<TimedMutator>(((Mutable)tower).GetMutatorById("Overclock"), ref val) && Il2CppSystemObjectExt.Is<OverclockMutator>((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<TimedMutator>(((Mutable)tower).GetMutatorById("TakeAim"), ref val) && Il2CppSystemObjectExt.Is<TakeAimMutator>((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<TimedMutator>(((Mutable)tower).GetMutatorById("Overclock"), ref val)) { OverclockMutator val2 = ((Il2CppObjectBase)val.mutator).Cast<OverclockMutator>(); 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<TimedMutator>(((Mutable)tower).GetMutatorById("TakeAim"), ref val)) { return; } TakeAimMutator val3 = ((Il2CppObjectBase)val.mutator).Cast<TakeAimMutator>(); 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<long>)val).min = 0L; ((ModSettingNumber<long>)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<AbilityChoice>() where choice.Mode == mode select choice).SelectMany((AbilityChoice abilityChoice) => abilityChoice.GetAffectedCached(((ModTest)this).Bridge.Model)).Distinct()) { TowerToSimulation tower = ((ModTest)this).AssertNotNull<TowerToSimulation>(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<float>.op_Implicit((Action<float>)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<float>.op_Implicit((Action<float>)delegate(float amount) { SacrificeAmount = (int)amount; }), 52f, "$/s"); ((Graphic)GameObjectExt.GetComponentInChildrenByName<Image>(((Component)slider).gameObject, "Fill")).color = new Color(1f, 1f, 0f); ((Graphic)GameObjectExt.GetComponentInChildrenByName<Image>(((Component)slider20).gameObject, "Fill")).color = new Color(1f, 1f, 0.5f); ((Transform)GameObjectExt.GetComponentInChildrenByName<RectTransform>(((Component)slider).gameObject, "Label")).localPosition = new Vector3(0f, -80f, 0f); ((Transform)GameObjectExt.GetComponentInChildrenByName<RectTransform>(((Component)slider20).gameObject, "Label")).localPosition = new Vector3(0f, -80f, 0f); ((TMP_Text)GameObjectExt.GetComponentInChildrenByName<NK_TextMeshProUGUI>(((Component)slider).gameObject, "Label")).fontStyle = (FontStyles)32; ((TMP_Text)GameObjectExt.GetComponentInChildrenByName<NK_TextMeshProUGUI>(((Component)slider20).gameObject, "Label")).fontStyle = (FontStyles)32; ((Component)GameObjectExt.GetComponentInChildrenByName<RectTransform>(((Component)slider).gameObject, "DefaultNotch")).gameObject.SetActive(false); ((Component)GameObjectExt.GetComponentInChildrenByName<RectTransform>(((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<Image>(((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<int, string> Descriptions1 => new Dictionary<int, string>(); public sealed override Dictionary<int, string> Descriptions2 => new Dictionary<int, string>(); 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<CorvusSpellType>(((ModContent)this).Name); public CorvusSpellModel Spell(TowerModel model) { return ((IEnumerable<CorvusSpellModel>)TowerModelBehaviorExt.GetBehaviors<CorvusSpellModel>(model)).FirstOrDefault((Func<CorvusSpellModel, bool>)((CorvusSpellModel spellModel) => ((TowerBasedShopItemModel)spellModel).locsId == ((ModContent)this).Name)); } public CorvusContinuousSpellModel ContinuousSpell(TowerModel model) { return ((IEnumerable<CorvusContinuousSpellModel>)TowerModelBehaviorExt.GetBehaviors<CorvusContinuousSpellModel>(model)).FirstOrDefault((Func<CorvusContinuousSpellModel, bool>)((CorvusContinuousSpellModel spellModel) => ((TowerBasedShopItemModel)spellModel).locsId == ((ModContent)this).Name)); } public CorvusInstantSpellModel InstantSpell(TowerModel model) { return ((IEnumerable<CorvusInstantSpellModel>)TowerModelBehaviorExt.GetBehaviors<CorvusInstantSpellModel>(model)).FirstOrDefault((Func<CorvusInstantSpellModel, bool>)((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<CorvusAbilityChoice>().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<ModContent> 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<CorvusContinuousSpell> __state) { __state = Il2CppSystemDictionaryExt.Keys<CorvusContinuousSpell, CorvusContinuousSpellTiming>(__instance.activeContinuousSpells).ToList(); } [HarmonyPostfix] internal static void Postfix(CorvusManager __instance, CorvusContinuousSpell spell, ref List<CorvusContinuousSpell> __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<CorvusSpellType>()); HashSet<CorvusSpellType> 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>()); CorvusSpellType[] array = (CorvusSpellType[])(object)new CorvusSpellType[2] { (CorvusSpellType)9, (CorvusSpellType)13 }; List<CorvusSpellType> val2 = default(List<CorvusSpellType>); foreach (CorvusSpellType val in array) { if (CorvusAbilityChoice.EnabledForSpell(val) && __instance.spellRestrictions.TryGetValue(val, ref val2)) { val2.Clear(); } } foreach (CorvusInstantSpell item in Il2CppSystemDictionaryExt.Keys<CorvusInstantSpell, CorvusInstantSpellTiming>(__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<CorvusInstantSpell, CorvusInstantSpellTiming>(__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<CorvusInstantSpellModel>((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<CorvusInstantSpellModel>((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<Echo>().CreateDuplicateSpirit(); } } } [HarmonyPatch(typeof(CorvusManager), "GetSaveMetaData")] internal static class CorvusManager_GetSaveMetaData { [HarmonyPostfix] internal unsafe static void Postfix(CorvusManager __instance, Dictionary<string, string> metaData) { if (SpellsToReactivate.TryGetValue(__instance.owner, out var value)) { metaData.Add("CorvusMetadata_SpellsToReactivate" + __instance.owner, GeneralExtensions.Join<string>(value.Select((CorvusSpellType type) => ((object)(*(CorvusSpellType*)(&type))/*cast due to .constrained prefix*/).ToString()), (Func<string, string>)null, ",")); } } } [HarmonyPatch(typeof(CorvusManager), "SetSaveMetaData")] internal static class CorvusManager_SetSaveMetaData { [HarmonyPostfix] internal static void Postfix(CorvusManager __instance, Dictionary<string, string> metaData) { string text = default(string); if (metaData.TryGetValue("CorvusMetadata_SpellsToReactivate" + __instance.owner, ref text)) { SpellsToReactivate[__instance.owner] = text.Split(",", StringSplitOptions.RemoveEmptyEntries).Select(Enum.Parse<CorvusSpellType>).ToHashSet(); } } } public static readonly Dictionary<int, HashSet<CorvusSpellType>> SpellsToReactivate = new Dictionary<int, HashSet<CorvusSpellType>>(); } 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<int, string> 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<ModContent> Load() { yield return (ModContent)(object)this; int key; string value; foreach (KeyValuePair<int, string> 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<int, string> 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<string, AbilityChoice> Cache = new Dictionary<string, AbilityChoice>(); public abstract string HeroId { get; } public sealed override string Description => ((NamedModContent)this).Description; public abstract Dictionary<int, string> Descriptions1 { get; } public virtual Dictionary<int, string> Descriptions2 { get; } protected override bool HasMode2 => Descriptions2 != null; public override IEnumerable<ModContent> 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<TowerModel> GetAffected(GameModel gameModel) { return from model in Il2CppGenericIEnumerable.AsIEnumerable<TowerModel>(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<string, string> textTable) { textTable[((ModContent)this).Id] = ((NamedModContent)this).DisplayName; int key; string value; foreach (KeyValuePair<int, string> 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<int, string> 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<HeroUpgradeButton> 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<HeroUpgradeButton>)(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<HeroUpgradeButton> buttons) { Il2CppArrayBase<TowerModel> source = Enumerable.ToArray<TowerModel>(Game.instance.model.GetTowersWithBaseId(selectedHero, false)); List<HeroAbilityChoice> list = (from choice in ModContent.GetContent<HeroAbilityChoice>() where choice.HeroId == selectedHero select choice).ToList(); foreach (HeroUpgradeButton item in (Il2CppArrayBase<HeroUpgradeButton>)(object)buttons) { foreach (HeroAbilityChoiceInfo componentsInChild in ((Component)((Component)item).transform).GetComponentsInChildren<HeroAbilityChoiceInfo>(true)) { componentsInChild.abilityChoice = null; if (componentsInChild.index > 0) { componentsInChild.container.SetActive(false); } } } foreach (HeroAbilityChoice abilityChoice in list) { TowerModel towerModel = ((IEnumerable<TowerModel>)source).First((TowerModel towerModel2) => abilityChoice.AppliesTo(towerModel2)); HeroUpgradeButton val = ((IEnumerable<HeroUpgradeButton>)buttons).First((HeroUpgradeButton upgradeButton) => upgradeButton.HeroIndex == towerModel.tier); HeroAbilityChoiceInfo heroAbilityChoiceInfo = GameObjectExtensions.GetComponentOrAdd<HeroAbilityChoiceInfo>(val.abilityIconContainer); if (heroAbilityChoiceInfo.abilityChoice != null) { Il2CppArrayBase<HeroAbilityChoiceInfo> componentsInChildren = ((Component)((Component)val).transform).GetComponentsInChildren<HeroAbilityChoiceInfo>(true); if (!Il2CppSystemObjectExt.Is<HeroAbilityChoiceInfo>(((IEnumerable<HeroAbilityChoiceInfo>)componentsInChildren).FirstOrDefault((HeroAbilityChoiceInfo i) => i.abilityChoice == null), ref heroAbilityChoiceInfo)) { int length = componentsInChildren.Length; GameObject val2 = Object.Instantiate<GameObject>(val.abilityIconContainer, val.abilityIconContainer.transform.parent); ((Object)val2).name = ((Object)val2).name.Replace("(Clone)", length.ToString()); heroAbilityChoiceInfo = val2.GetComponent<HeroAbilityChoiceInfo>(); 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<Image>(((Component)heroAbilityChoiceInfo).gameObject, "Icon"); heroAbilityChoiceInfo.background = GameObjectExt.GetComponentInChildrenByName<Image>(((Component)heroAbilityChoiceInfo).gameObject, "Bg"); GameObjectExtensions.GetComponentOrAdd<Text>(heroAbilityChoiceInfo.container); } foreach (HeroUpgradeButton item2 in (Il2CppArrayBase<HeroUpgradeButton>)(object)buttons) { foreach (HeroAbilityChoiceInfo componentsInChild2 in ((Component)((Component)item2).transform).GetComponentsInChildren<HeroAbilityChoiceInfo>()) { 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<ArcaneMetamorphosis>().Mode == 1) { __instance.isCurrentlyMorphed = (int)((MagusPerfectusAbilityBehavior)__instance).GraveyardManager.graveyardManaState == 0 && ((IEnumerable<List<Attack>>)Il2CppSystemDictionaryExt.GetValues<GraveyardManaState, List<Attack>>(((MagusPerfectusAbilityBehavior)__instance).GraveyardManager.graveyardStateAttacks).ToArray()).SelectMany((List<Attack> list) => (IEnumerable<Attack>)list.ToArray()).Any((Attack attack) => attack.HasValidTarget()); } } } private static bool activatingPhoenixRebirth; private static bool spawningBfbs; private static readonly Dictionary<int, int> PreviousMana = new Dictionary<int, int>(); } 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<MethodInfo> TargetMethods() { return new <>z__ReadOnlyArray<MethodInfo>(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<OverclockPermanentModel>(AbilityModelBehaviorExt.GetBehavior<OverclockPermanentModel>(__instance.abilityModel), ref val) && Il2CppSystemObjectExt.Is<Overclock>(((RootBehavior)__instance).entity.GetBehaviorInDependants<Overclock>(), ref val2) && ((TapTowerAbilityBehavior)val2).selectedTower != null && (!Il2CppSystemObjectExt.Is<TimedMutator>(((Mutable)((TapTowerAbilityBehavior)val2).selectedTower).GetMutatorById(OverclockPermanentModel.MutatorId), ref val3) || !Il2CppSystemObjectExt.Is<OverclockPermanentMutator>((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<TapTowerAbilityBehavior>(((RootBehavior)__instance).entity.GetBehaviorInDependants<TapTowerAbilityBehavior>(), 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<OverclockCIData>((Il2CppObjectBase)(object)__result, ref val)) { val.validTowerIds.RemoveAll(Predicate<ObjectId>.op_Implicit((Func<ObjectId, bool>)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<OverclockPermanent>() != 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<MethodInfo> TargetMethods() { return new <>z__ReadOnlyArray<MethodInfo>(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<AbilityToSimulation> __result) { List<AbilityToSimulation> obj = __result; __result = ((obj != null) ? Il2CppGenerics.Where<AbilityToSimulation>(obj, (Func<AbilityToSimulation, bool>)((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<TowerSaveDataModel> enumerator = mapData.placedTowers.GetEnumerator(); while (enumerator.MoveNext()) { TowerSaveDataModel current = enumerator.Current; if (current != null) { Tower towerById = sim.towerManager.GetTowerById(current.IdLastSave); ((BloonsTD6Mod)ModHelper.GetMod<AbilityChoiceMod>()).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<TowerModel>((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<RangeSupportModel>)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<RangeSupportModel>(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<OverclockModel>(((Model)Game.instance.model.GetTower(TowerType.EngineerMonkey, 0, 4, 0)).GetDescendant<OverclockModel>()); 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<ObjectId, List<Entity>> Dots = new Dictionary<ObjectId, List<Entity>>(); 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<Overclock>((Il2CppObjectBase)(object)behavior, ref val)) { OverclockModel val2 = ModelExt.Duplicate<OverclockModel>(val.overclockModel); tier = Math.Clamp(tier, 0, ((Il2CppArrayBase<float>)(object)val2.tierBasedDurationMultiplier).Count - 1); float uptime = ((Il2CppArrayBase<float>)(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<TakeAim>((Il2CppObjectBase)(object)behavior, ref val3)) { TakeAimModel val4 = ModelExt.Duplicate<TakeAimModel>(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<TapTowerAbilityBehavior>)MonoLinqHelper.ToArray<TapTowerAbilityBehavior>(((RootObject)from).Sim.factory.GetUncast<TapTowerAbilityBehavior>())).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<OverclockModel>((Model)(object)abilityModel, ref overclockModel) && ((Model)(object)overclockModel).OverclockAbilityChoice()) || (ModelExt.HasDescendant<TakeAimModel>((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<TapTowerAbilityBehavior>(); List<Entity> lineDotDisplays = default(List<Entity>); if (!Dots.TryGetValue(((RootObject)((TowerBehavior)__instance).tower).Id, ref lineDotDisplays)) { List<Entity> val = (Dots[((RootObject)((TowerBehavior)__instance).tower).Id] = new List<Entity>()); lineDotDisplays = val; } TechBotLinkModel descendant = ((Model)Game.instance.model.GetPowerWithId(TowerType.TechBot).tower).GetDescendant<TechBotLinkModel>(); 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>((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<string, TowerAbilityChoice> Cache = new Dictionary<string, TowerAbilityChoice>(); 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<ModContent> 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<TowerModel> GetAffected(GameModel gameModel) { return from model in ((IEnumerable<TowerModel>)gameModel.towers).Where((TowerModel model) => ((Il2CppArrayBase<string>)(object)model.appliedUpgrades)?.Contains(UpgradeId) ?? false).Where(AppliesTo) orderby ((Il2CppArrayBase<string>)(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<string, string> 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<TowerAbilityChoice> { 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<Image>(); 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<TowerAbilityChoiceInfo>(); 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>(); } 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<ActivateAbilityAfterIntervalModel>(((Model)towerModel).GetDescendants<ActivateAbilityAfterIntervalModel>(), (Action<ActivateAbilityAfterIntervalModel>)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<AbilityCreateTowerModel>().towerModel; Il2CppGenericIEnumerable.ForEach<TowerCreateTowerModel>(model.GetDescendants<TowerCreateTowerModel>(), (Action<TowerCreateTowerModel>)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<AbilityCreateTowerModel>().towerModel; Il2CppGenericIEnumerable.ForEach<TowerCreateTowerModel>(model.GetDescendants<TowerCreateTowerModel>(), (Action<TowerCreateTowerModel>)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<Tower>((Il2CppObjectBase)(object)selection, ref val) && ((Mutable)val).IsMutatedBy("BottleHotSauce")) { ((Mutable)val).RemoveMutatorsById("BottleHotSauce"); Il2CppGenericIEnumerable.ForEach<Tower>(((GeraldoItemBehavior)__instance).sim.towerManager.GetChildTowers(val), (Action<Tower>)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<DamageModel>(model.GetDescendants<DamageModel>(), (Action<DamageModel>)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<MegaMineInvalid>()) { 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<SyphonFunding>(); if (behavior != null && !((IEnumerable<string>)__instance.syphonM