using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BTD_Mod_Helper;
using BTD_Mod_Helper.Api;
using BTD_Mod_Helper.Api.Components;
using BTD_Mod_Helper.Api.Display;
using BTD_Mod_Helper.Api.ModOptions;
using BTD_Mod_Helper.Api.Towers;
using BTD_Mod_Helper.Extensions;
using HarmonyLib;
using Il2Cpp;
using Il2CppAssets.Scripts.Models;
using Il2CppAssets.Scripts.Models.GenericBehaviors;
using Il2CppAssets.Scripts.Models.Towers;
using Il2CppAssets.Scripts.Models.Towers.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.Behaviors.Emissions.Behaviors;
using Il2CppAssets.Scripts.Models.Towers.Projectiles;
using Il2CppAssets.Scripts.Models.Towers.Projectiles.Behaviors;
using Il2CppAssets.Scripts.Models.Towers.Weapons;
using Il2CppAssets.Scripts.Models.Towers.Weapons.Behaviors;
using Il2CppAssets.Scripts.Simulation.Objects;
using Il2CppAssets.Scripts.Simulation.SMath;
using Il2CppAssets.Scripts.Simulation.Towers;
using Il2CppAssets.Scripts.Simulation.Towers.Behaviors.Attack;
using Il2CppAssets.Scripts.Simulation.Towers.Projectiles;
using Il2CppAssets.Scripts.Simulation.Towers.Projectiles.Behaviors;
using Il2CppAssets.Scripts.Simulation.Towers.Weapons;
using Il2CppAssets.Scripts.Unity;
using Il2CppAssets.Scripts.Unity.Bridge;
using Il2CppAssets.Scripts.Unity.Display;
using Il2CppAssets.Scripts.Unity.UI_New.InGame.TowerSelectionMenu.TowerSelectionMenuThemes;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppNinjaKiwi.Common.ResourceUtils;
using Il2CppSystem.IO;
using MelonLoader;
using Microsoft.CodeAnalysis;
using MiniCrosspaths;
using MiniCrosspaths.DoubleRangaBoomers;
using Newtonsoft.Json.Linq;
using PathsPlusPlus;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(MiniCrosspathsMod), "Mini Crosspaths", "1.0.1", "doombubbles", null)]
[assembly: MelonGame("Ninja Kiwi", "BloonsTD6")]
[assembly: MelonGame("Ninja Kiwi", "BloonsTD6-Epic")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("MiniCrosspaths")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+a7b4adbcd1f2cd99c8f71c4efde5806cafe0863a")]
[assembly: AssemblyProduct("MiniCrosspaths")]
[assembly: AssemblyTitle("MiniCrosspaths")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace MiniCrosspaths
{
public class MiniCrosspathsMod : BloonsTD6Mod
{
}
public static class ModHelperData
{
public const string WorksOnVersion = "55.0";
public const string Version = "1.0.1";
public const string Name = "Mini Crosspaths";
public const string Description = "Adds a number of mini two-upgrade Paths++ paths for towers. \nMany are based on old BTD game features / my favorite features that I've implemented in other mods such as Mega Knowledge or Rogue Remix, others are brand new.\nThis makes them available in a balanced way in regular games, making you pay a fair price and consider the crosspathing tradeoffs (unless you have Paths++ Balanced Mode turned off).";
public const string RepoOwner = "doombubbles";
public const string PrevRepoName = "mini-crosspaths";
public const string RepoName = "MiniCrosspaths";
public const string Dependencies = "doombubbles/PathsPlusPlus";
}
}
namespace MiniCrosspaths.SplodeyDartMonkeys
{
public class HeatTippedArrow : HeatTippedDisplay
{
public override int Tier => 3;
}
public class HeatTippedBolt : HeatTippedDisplay
{
public override int Tier => 4;
}
public class HeatTippedDart : HeatTippedDisplay
{
public override int Tier => 0;
}
public class HeatTippedDarts : UpgradePlusPlus<SplodeyDartMonkeysPath>
{
public override int Cost => 125;
public override int Tier => 1;
public override string Description => "Heat tipped darts allow the Dart Monkey to pop Frozen and Lead Bloons.";
public override void ApplyUpgrade(TowerModel towerModel)
{
Il2CppGenericIEnumerable.ForEach<DamageModel>(((Model)towerModel).GetDescendants<DamageModel>(), (Action<DamageModel>)delegate(DamageModel damage)
{
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: 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)
damage.immuneBloonProperties = (BloonProperties)(damage.immuneBloonProperties & -17);
damage.immuneBloonProperties = (BloonProperties)(damage.immuneBloonProperties & -2);
damage.immuneBloonPropertiesOriginal = (BloonProperties)(damage.immuneBloonPropertiesOriginal & -17);
damage.immuneBloonPropertiesOriginal = (BloonProperties)(damage.immuneBloonPropertiesOriginal & -2);
});
ProjectileModel dart = ((Model)towerModel).GetDescendant<ProjectileModel>();
foreach (HeatTippedDisplay item in from heatTippedDisplay in ModContent.GetContent<HeatTippedDisplay>()
where dart.display == ((ModDisplay)heatTippedDisplay).BaseDisplayReference
select heatTippedDisplay)
{
((ModDisplay)item).Apply(dart);
}
}
}
public abstract class HeatTippedDisplay : ModDisplay
{
public abstract int Tier { get; }
public override PrefabReference BaseDisplayReference => ((Model)Game.instance.model.GetTower(TowerType.DartMonkey, 0, 0, Tier)).GetDescendant<ProjectileModel>().display;
public override void ModifyDisplayNode(UnityDisplayNode node)
{
UnityDisplayNodeExt.GetSpriteRenderer(node, 0, true).sprite = ((ModContent)this).GetSprite(((ModContent)this).Name, 10f);
}
}
public class SplodeyDartMonkeysPath : PathPlusPlus
{
public override string Tower => TowerType.DartMonkey;
}
public class SplodeyDarts : UpgradePlusPlus<SplodeyDartMonkeysPath>
{
public override int Cost => 400;
public override int Tier => 2;
public override string Description => "Projectiles will create a small explosion the first time they collide with a Bloon.";
public override string DetailedDescription => "Explosions have the same pierce as the projectile, and the same base damage (but unaffected by damage modifiers).";
public override void ApplyUpgrade(TowerModel towerModel)
{
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Expected O, but got Unknown
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
//IL_0072: Expected O, but got Unknown
//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
//IL_00ea: Expected O, but got Unknown
//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
//IL_0103: Expected O, but got Unknown
//IL_013d: Unknown result type (might be due to invalid IL or missing references)
//IL_0142: Unknown result type (might be due to invalid IL or missing references)
//IL_014d: Expected O, but got Unknown
//IL_014e: Unknown result type (might be due to invalid IL or missing references)
//IL_014f: Unknown result type (might be due to invalid IL or missing references)
//IL_0154: Unknown result type (might be due to invalid IL or missing references)
//IL_015a: Unknown result type (might be due to invalid IL or missing references)
//IL_0164: Expected O, but got Unknown
//IL_0165: Unknown result type (might be due to invalid IL or missing references)
//IL_0176: Expected O, but got Unknown
//IL_0181: Expected O, but got Unknown
//IL_0188: Unknown result type (might be due to invalid IL or missing references)
//IL_018d: Unknown result type (might be due to invalid IL or missing references)
//IL_0198: Expected O, but got Unknown
//IL_0199: Unknown result type (might be due to invalid IL or missing references)
//IL_019a: Unknown result type (might be due to invalid IL or missing references)
//IL_019f: 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_01af: Expected O, but got Unknown
//IL_01b5: Expected O, but got Unknown
//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
//IL_01d1: Expected O, but got Unknown
//IL_01d7: Expected O, but got Unknown
//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
//IL_01de: Unknown result type (might be due to invalid IL or missing references)
//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
//IL_01f3: Expected O, but got Unknown
//IL_01f9: Expected O, but got Unknown
//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
//IL_0200: Unknown result type (might be due to invalid IL or missing references)
//IL_0205: Unknown result type (might be due to invalid IL or missing references)
//IL_020b: Unknown result type (might be due to invalid IL or missing references)
//IL_0215: Expected O, but got Unknown
//IL_021b: Expected O, but got Unknown
//IL_0221: Unknown result type (might be due to invalid IL or missing references)
//IL_0222: Unknown result type (might be due to invalid IL or missing references)
//IL_0227: Unknown result type (might be due to invalid IL or missing references)
//IL_022d: Unknown result type (might be due to invalid IL or missing references)
//IL_0237: Expected O, but got Unknown
//IL_023d: Expected O, but got Unknown
//IL_0248: Expected O, but got Unknown
((UpgradePlusPlus)this).ApplyUpgrade(towerModel);
DamageModel val = default(DamageModel);
foreach (ProjectileModel item in Il2CppGenericIEnumerable.AsIEnumerable<ProjectileModel>(((Model)towerModel).GetDescendants<ProjectileModel>()))
{
if (ProjectileModelBehaviorExt.HasBehavior<TravelStraitModel>(item) && ProjectileModelBehaviorExt.HasBehavior<DamageModel>(item, ref val))
{
Args val2 = new Args();
((ModelArgs<CreateProjectileOnContactModel>)(object)val2).name = "SplodeyDarts";
val2.emission = (EmissionModel)(object)CreateSingleEmissionModelExt.Create();
Args val3 = new Args();
((ModelArgs<ProjectileModel>)(object)val3).name = "Splosion";
val3.pierce = item.pierce;
val3.radius = 10f;
val3.ignoreBlockers = true;
val3.behaviors = (Model[])(object)new Model[2]
{
(Model)CreateDamageModelExt.Create(new Args
{
damage = val.damage,
maxDamage = val.damage,
immuneBloons = (BloonProperties)((towerModel.tier != 5) ? 2 : 0)
}),
(Model)CreateAgeModelExt.Create(new Args
{
lifespan = 0.1f
})
};
val3.CanHitCamo = ((Il2CppArrayBase<string>)(object)towerModel.appliedUpgrades).Contains("Enhanced Eyesight");
val2.projectile = CreateProjectileModelExt.Create(val3);
ProjectileModelBehaviorExt.AddBehavior<CreateProjectileOnContactModel>(item, CreateCreateProjectileOnContactModelExt.Create(val2));
Args val4 = new Args();
((ModelArgs<CreateEffectOnContactModel>)val4).name = "SplodeyDarts";
val4.effectModel = CreateEffectModelExt.Create(new Args
{
assetId = new PrefabReference("6d84b13b7622d2744b8e8369565bc058"),
lifespan = 2f
});
ProjectileModelBehaviorExt.AddBehavior<CreateEffectOnContactModel>(item, CreateCreateEffectOnContactModelExt.Create(val4));
Args val5 = new Args();
((ModelArgs<CreateSoundOnProjectileCollisionModel>)val5).name = "SplodeyDarts";
val5.sound1 = CreateSoundModelExt.Create(new Args
{
assetId = new AudioClipReference("ec9a5a7531a750e4c82bf8429e0812e4")
});
val5.sound2 = CreateSoundModelExt.Create(new Args
{
assetId = new AudioClipReference("57fac571daa668140b0674eb515f9586")
});
val5.sound3 = CreateSoundModelExt.Create(new Args
{
assetId = new AudioClipReference("5b1ee796433122141a0db034af251f15")
});
val5.sound4 = CreateSoundModelExt.Create(new Args
{
assetId = new AudioClipReference("f5f616027b9887c4db5b1341a614b352")
});
val5.sound5 = CreateSoundModelExt.Create(new Args
{
assetId = new AudioClipReference("9a36e64ca09a7ef42bd4af49c1cf4ef6")
});
ProjectileModelBehaviorExt.AddBehavior<CreateSoundOnProjectileCollisionModel>(item, CreateCreateSoundOnProjectileCollisionModelExt.Create(val5));
}
}
}
}
[HarmonyPatch]
internal static class CreateProjectileOnContact_Collide
{
private static IEnumerable<MethodBase> TargetMethods()
{
yield return AccessTools.Method(typeof(CreateProjectileOnContact), "Collide", (Type[])null, (Type[])null);
yield return AccessTools.Method(typeof(CreateProjectileOnContact), "CollideMap", (Type[])null, (Type[])null);
}
[HarmonyPrefix]
internal static bool Prefix(CreateProjectileOnContact __instance)
{
return ((ProjectileBehavior)__instance).projectile == null || !((Model)__instance.createProjectileOnContactModel).name.Contains("SplodeyDarts") || ((ProjectileBehavior)__instance).projectile.collidedWith.Count <= 1;
}
}
[HarmonyPatch]
internal static class CreateEffectOnContact_Collide
{
private static IEnumerable<MethodBase> TargetMethods()
{
yield return AccessTools.Method(typeof(CreateEffectOnContact), "Collide", (Type[])null, (Type[])null);
yield return AccessTools.Method(typeof(CreateEffectOnContact), "CollideMap", (Type[])null, (Type[])null);
}
[HarmonyPrefix]
internal static bool Prefix(CreateEffectOnContact __instance)
{
return ((ProjectileBehavior)__instance).projectile == null || !((Model)__instance.createEffectOnContactModel).name.Contains("SplodeyDarts") || ((ProjectileBehavior)__instance).projectile.collidedWith.Count <= 1;
}
}
[HarmonyPatch]
internal static class CreateSoundOnProjectileCollision_
{
private static IEnumerable<MethodBase> TargetMethods()
{
yield return AccessTools.Method(typeof(CreateSoundOnProjectileCollision), "Collide", (Type[])null, (Type[])null);
yield return AccessTools.Method(typeof(CreateSoundOnProjectileCollision), "CollideMap", (Type[])null, (Type[])null);
}
[HarmonyPrefix]
internal static bool Prefix(CreateSoundOnProjectileCollision __instance)
{
return ((ProjectileBehavior)__instance).projectile == null || !((Model)__instance.createSoundOnProjectileCollisionModel).name.Contains("SplodeyDarts") || ((ProjectileBehavior)__instance).projectile.collidedWith.Count <= 1;
}
}
}
namespace MiniCrosspaths.LaserRangBoomers
{
public class LaserRangBoomersPath : PathPlusPlus
{
public override string Tower => TowerType.BoomerangMonkey;
}
public class LaserRangs : UpgradePlusPlus<LaserRangBoomersPath>
{
public override int Cost => 250;
public override int Tier => 1;
public override string Description => "Now throws Laser-Rangs, gaining increased pierce and projectile speed.";
public override string DetailedDescription => "Projectiles can longer pop Purple Bloons, but travel 25% faster and have pierce increased by +4 or x1.5, whichever is higher, with MOAB press getting a flat +60.";
public override void ApplyUpgrade(TowerModel towerModel)
{
//IL_0099: Unknown result type (might be due to invalid IL or missing references)
//IL_009f: Unknown result type (might be due to invalid IL or missing references)
//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
ProjectileModel descendant = ((Model)TowerModelExt.GetAttackModel(towerModel)).GetDescendant<ProjectileModel>();
foreach (ProjectileModel item in MonoLinqHelper.ToArray<ProjectileModel>(((Model)towerModel).GetDescendants<ProjectileModel>()))
{
if (ProjectileModelBehaviorExt.HasBehavior<DamageModel>(item))
{
item.pierce = Math.Max(item.pierce + 4f, (int)(item.pierce * 1.5f));
}
}
DamageModel damageModel = ProjectileModelExt.GetDamageModel(descendant);
if (towerModel.tier < 5)
{
damageModel.immuneBloonProperties = (BloonProperties)(damageModel.immuneBloonProperties | 8);
damageModel.immuneBloonPropertiesOriginal = (BloonProperties)(damageModel.immuneBloonPropertiesOriginal | 8);
}
FollowPathModel val = default(FollowPathModel);
TravelStraitModel val2 = default(TravelStraitModel);
if (ProjectileModelBehaviorExt.HasBehavior<FollowPathModel>(descendant, ref val))
{
FollowPathModel obj = val;
obj.Speed *= 1.25f;
}
else if (ProjectileModelBehaviorExt.HasBehavior<TravelStraitModel>(descendant, ref val2))
{
TravelStraitModel obj2 = val2;
obj2.Speed *= 1.25f;
}
if (((Il2CppArrayBase<string>)(object)towerModel.appliedUpgrades).Contains("MOAB Press"))
{
ProjectileModel descendant2 = ((Model)TowerModelExt.GetAttackModel(towerModel, "MOABPress")).GetDescendant<ProjectileModel>();
descendant2.pierce += 60f;
}
PrefabReference display = ((Model)TowerModelExt.GetAttackModel(Game.instance.model.GetTower(TowerType.SuperMonkey, 1, 0, ((Il2CppArrayBase<string>)(object)towerModel.appliedUpgrades).Contains("Glaives") ? 4 : 3))).GetDescendant<ProjectileModel>().display;
ProjectileModelExt.SetDisplay(descendant, display);
OrbitModel val3 = default(OrbitModel);
if (TowerModelBehaviorExt.HasBehavior<OrbitModel>(towerModel, ref val3))
{
ProjectileModelExt.ApplyDisplay<LaserOrbit>(val3.projectile);
}
AddBehaviorToBloonModel val4 = default(AddBehaviorToBloonModel);
if (ModelExt.HasDescendant<AddBehaviorToBloonModel>((Model)(object)towerModel, ref val4))
{
val4.parentDamageModel = null;
((Model)val4).RemoveChildDependant<DamageModel>(val4.parentDamageModel);
}
}
}
public class LaserOrbit : ModDisplay
{
private static readonly int TintColor = Shader.PropertyToID("_TintColor");
public override PrefabReference BaseDisplayReference => TowerModelBehaviorExt.GetBehavior<OrbitModel>(Game.instance.model.GetTower(TowerType.BoomerangMonkey, 5, 0, 0)).projectile.display;
public override void ModifyDisplayNodeAsync(UnityDisplayNode node, Action onComplete)
{
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
((Renderer)((Component)node).GetComponentInChildren<ParticleSystemRenderer>()).material.SetColor(TintColor, new Color(1f, 0.10980392f, 0f, 0.5f));
PrefabReference display = ((Model)TowerModelExt.GetAttackModel(Game.instance.model.GetTower(TowerType.SuperMonkey, 1, 0, 4))).GetDescendant<ProjectileModel>().display;
((ModDisplay)this).UseNode(display.AssetGUID, (Action<UnityDisplayNode>)delegate(UnityDisplayNode displayNode)
{
UnityDisplayNodeExt.GetRenderer<SpriteRenderer>(node, true).sprite = UnityDisplayNodeExt.GetRenderer<SpriteRenderer>(displayNode, true).sprite;
node.RecalculateGenericRenderers();
onComplete();
});
}
}
public class PlasmaRangs : UpgradePlusPlus<LaserRangBoomersPath>
{
public override int Cost => 350;
public override int Tier => 2;
public override string Description => "Upgrades to Plasma-Rangs, attacking even faster.";
public override string DetailedDescription => "Can pop Frozen and Lead Bloons. Fire rate for all weapons is 50% faster, including Glaive-Lord orbital damage.";
public override void ApplyUpgrade(TowerModel towerModel)
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0113: 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_0124: Unknown result type (might be due to invalid IL or missing references)
//IL_012b: Unknown result type (might be due to invalid IL or missing references)
ProjectileModel descendant = ((Model)TowerModelExt.GetAttackModel(towerModel)).GetDescendant<ProjectileModel>();
DamageModel damageModel = ProjectileModelExt.GetDamageModel(descendant);
damageModel.immuneBloonProperties = (BloonProperties)(damageModel.immuneBloonProperties & -18);
damageModel.immuneBloonPropertiesOriginal = (BloonProperties)(damageModel.immuneBloonPropertiesOriginal & -18);
foreach (WeaponModel item in DoubleRangaBoomersPath.BoomerAttacks(towerModel).SelectMany((AttackModel attack) => (IEnumerable<WeaponModel>)attack.weapons))
{
item.Rate /= 1.5f;
}
PrefabReference display = ((Model)TowerModelExt.GetAttackModel(Game.instance.model.GetTower(TowerType.SuperMonkey, 2, 0, ((Il2CppArrayBase<string>)(object)towerModel.appliedUpgrades).Contains("Glaives") ? 4 : 3))).GetDescendant<ProjectileModel>().display;
ProjectileModelExt.SetDisplay(descendant, display);
OrbitModel val = default(OrbitModel);
if (TowerModelBehaviorExt.HasBehavior<OrbitModel>(towerModel, ref val))
{
ProjectileModelExt.ApplyDisplay<PlasmaOrbit>(val.projectile);
DamageModel descendant2 = ((Model)TowerModelExt.GetAttackModel(towerModel, "Orbit")).GetDescendant<DamageModel>();
descendant2.immuneBloonProperties = (BloonProperties)(descendant2.immuneBloonProperties & -18);
descendant2.immuneBloonPropertiesOriginal = (BloonProperties)(descendant2.immuneBloonPropertiesOriginal & -18);
}
}
}
public class PlasmaOrbit : ModDisplay
{
private static readonly int TintColor = Shader.PropertyToID("_TintColor");
public override PrefabReference BaseDisplayReference => TowerModelBehaviorExt.GetBehavior<OrbitModel>(Game.instance.model.GetTower(TowerType.BoomerangMonkey, 5, 0, 0)).projectile.display;
public override void ModifyDisplayNodeAsync(UnityDisplayNode node, Action onComplete)
{
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
((Renderer)((Component)node).GetComponentInChildren<ParticleSystemRenderer>()).material.SetColor(TintColor, new Color(77f / 85f, 0f, 1f, 0.5f));
PrefabReference display = ((Model)TowerModelExt.GetAttackModel(Game.instance.model.GetTower(TowerType.SuperMonkey, 2, 0, 4))).GetDescendant<ProjectileModel>().display;
((ModDisplay)this).UseNode(display.AssetGUID, (Action<UnityDisplayNode>)delegate(UnityDisplayNode displayNode)
{
UnityDisplayNodeExt.GetRenderer<SpriteRenderer>(node, true).sprite = UnityDisplayNodeExt.GetRenderer<SpriteRenderer>(displayNode, true).sprite;
node.RecalculateGenericRenderers();
onComplete();
});
}
}
}
namespace MiniCrosspaths.InstantBombShooters
{
public class InstantBombShootersPath : PathPlusPlus
{
public override string Tower => TowerType.BombShooter;
}
public class PrecisionMunition : UpgradePlusPlus<InstantBombShootersPath>
{
[HarmonyPatch(typeof(Weapon), "CalcRateFrames")]
internal static class Weapon_CalcRateFrames
{
[HarmonyPostfix]
internal static void Postfix(Weapon __instance)
{
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
if (!((Model)__instance.weaponModel).name.Contains("PrecisionMunition"))
{
return;
}
Projectile val = Il2CppGenerics.FirstOrDefault<Projectile>(__instance.newProjectiles);
if (val != null && ((CommonBehaviorProxy<IProjectileBehavior>)(object)val).target != null)
{
Vector3 ejectPosition = __instance.GetEjectPosition(true);
float num = ((Vector3)(ref ejectPosition)).Distance(((CommonBehaviorProxy<IProjectileBehavior>)(object)val).target.Position);
if (num / ((TowerBehavior)((AttackBehavior)__instance).attack).tower.towerModel.range > 2f)
{
__instance.rateFrames = (int)((float)__instance.rateFrames * 1.3f);
}
}
}
}
public override int Cost => 500;
public override int Tier => 2;
public override string Description => "Can hit Bloons it can see anywhere on screen. Attacks 30% slower for very far away Bloons.";
public override string DetailedDescription => "Gains global effective range. If Bloons are further than twice the original displayed range, attacks 30% slower.";
public override void ApplyUpgrade(TowerModel towerModel)
{
towerModel.isGlobalRange = true;
}
}
public class QuantumPayload : UpgradePlusPlus<InstantBombShootersPath>
{
public override int Cost => 150;
public override int Tier => 1;
public override string Description => "Bombs explode instantly at the target's location with no travel time.";
public override void ApplyUpgrade(TowerModel towerModel, int tier)
{
//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
//IL_00e2: Expected O, but got Unknown
//IL_014e: Unknown result type (might be due to invalid IL or missing references)
//IL_0153: Unknown result type (might be due to invalid IL or missing references)
//IL_0164: Expected O, but got Unknown
AlternateProjectileModel val3 = default(AlternateProjectileModel);
foreach (AttackModel item in Il2CppGenericIEnumerable.AsIEnumerable<AttackModel>(((Model)towerModel).GetDescendants<AttackModel>()))
{
WeaponModel val = ((Il2CppArrayBase<WeaponModel>)(object)item.weapons)[0];
ProjectileModel val2 = ((val != null) ? val.projectile : null);
if (val != null && val2 != null && Il2CppSystemObjectExt.Is<SingleEmissionModel>((Il2CppObjectBase)(object)val.emission) && ProjectileModelBehaviorExt.HasBehavior<TravelStraitModel>(val2) && Mathf.Approximately(val2.maxPierce, 1f))
{
if (tier > 1)
{
item.range = 999999f;
ModelExt.SetName<WeaponModel>(val, ((Model)val).name + "_PrecisionMunition");
}
WeaponModelExt.SetEmission(val, (EmissionModel)(object)CreateInstantDamageEmissionModelExt.Create());
ProjectileModelBehaviorExt.RemoveBehavior<TravelStraitModel>(val2);
ProjectileModelBehaviorExt.RemoveBehavior<TrackTargetModel>(val2);
ProjectileModelBehaviorExt.AddBehavior<InstantModel>(val2, CreateInstantModelExt.Create());
ProjectileModelBehaviorExt.AddBehavior<AgeModel>(val2, CreateAgeModelExt.Create(new Args
{
lifespan = 0.1f
}));
if (Il2CppSystemObjectExt.Is<AlternateProjectileModel>(WeaponModelBehaviorExt.GetBehavior<AlternateProjectileModel>(val), ref val3))
{
((Model)val3).RemoveChildDependant<EmissionModel>(val3.emissionModel);
val3.emissionModel = (EmissionModel)(object)CreateInstantDamageEmissionModelExt.Create();
((Model)val3).AddChildDependant<EmissionModel>(val3.emissionModel);
ProjectileModelBehaviorExt.RemoveBehavior<TravelStraitModel>(val3.projectile);
ProjectileModelBehaviorExt.RemoveBehavior<TrackTargetModel>(val3.projectile);
ProjectileModelBehaviorExt.AddBehavior<InstantModel>(val2, CreateInstantModelExt.Create());
ProjectileModelBehaviorExt.AddBehavior<AgeModel>(val2, CreateAgeModelExt.Create(new Args
{
lifespan = 0.1f
}));
}
}
}
}
}
}
namespace MiniCrosspaths.HoverPlaneAces
{
public class HoverPlane : UpgradePlusPlus<HoverPlaneAcesPath>
{
public override int Cost => 600;
public override int Tier => 1;
public override string Description => "Now longer flies in paths, instead hovering wherever you direct it.";
public override string DetailedDescription => "Replaces all default movement with Heli Pilot style movement.";
public override void ApplyUpgrade(TowerModel towerModel, int tier)
{
if (ModelExt.HasDescendant<HeliMovementModel>((Model)(object)towerModel))
{
return;
}
TowerModel tower = Game.instance.model.GetTower(TowerType.HeliPilot, 0, 0, 0);
TowerModel tower2 = Game.instance.model.GetTower(TowerType.HeliPilot, 2, 0, 0);
AirUnitModel behavior = TowerModelBehaviorExt.GetBehavior<AirUnitModel>(towerModel);
List<AttackModel> behaviors = TowerModelBehaviorExt.GetBehaviors<AttackModel>(towerModel);
HeliMovementModel val = ModelExt.Duplicate<HeliMovementModel>(((Model)tower).GetDescendant<HeliMovementModel>());
val.maxSpeed = AirUnitModelBehaviorExt.GetBehavior<PathMovementModel>(behavior).speed;
val.tiltAngle = 0f;
AirUnitModelBehaviorExt.RemoveBehavior<PathMovementModel>(behavior);
AirUnitModelBehaviorExt.AddBehavior<HeliMovementModel>(behavior, val);
bool flag = true;
bool flag2 = tier > 1;
PursuitSettingModel val2 = default(PursuitSettingModel);
foreach (AttackModel item in behaviors.OrderBy((AttackModel model) => ((Model)model).name.Length))
{
item.fireWithoutTarget = false;
item.range = 99999f;
foreach (WeaponModel item2 in (Il2CppArrayBase<WeaponModel>)(object)item.weapons)
{
item2.fireWithoutTarget = false;
}
AttackModelBehaviorExt.RemoveBehaviors<CirclePatternModel>(item);
AttackModelBehaviorExt.RemoveBehaviors<FigureEightPatternModel>(item);
AttackModelBehaviorExt.RemoveBehaviors<CenterElipsePatternModel>(item);
AttackModelBehaviorExt.RemoveBehaviors<WingmonkeyPatternModel>(item);
AttackModel attackModel = TowerModelExt.GetAttackModel(flag2 ? tower2 : tower);
AttackModelBehaviorExt.AddBehavior<RotateToTargetAirUnitModel>(item, ModelExt.Duplicate<RotateToTargetAirUnitModel>(AttackModelBehaviorExt.GetBehavior<RotateToTargetAirUnitModel>(attackModel)));
Il2CppGenericIEnumerable.ForEach<ArcEmissionModel>(((Model)item).GetDescendants<ArcEmissionModel>(), (Action<ArcEmissionModel>)delegate(ArcEmissionModel arc)
{
arc.useAirUnitRotation = true;
});
if (!flag)
{
continue;
}
flag = false;
foreach (TargetSupplierModel behavior2 in AttackModelBehaviorExt.GetBehaviors<TargetSupplierModel>(attackModel))
{
AttackModelBehaviorExt.AddBehavior<TargetSupplierModel>(item, ModelExt.Duplicate<TargetSupplierModel>(behavior2, ((ModContent)this).Name));
}
if (AttackModelBehaviorExt.HasBehavior<PursuitSettingModel>(item, ref val2))
{
val2.pursuitDistance = (((Il2CppArrayBase<string>)(object)towerModel.appliedUpgrades).Contains("Spectre") ? 45 : 15);
}
}
towerModel.UpdateTargetProviders();
BloonsMod val3 = default(BloonsMod);
if (ModHelper.HasMod("TacticalTweaks", ref val3) && val3.ModSettings.TryGetValue("PursuitPathPrioritization", out var value))
{
ModSettingBool val4 = (ModSettingBool)(object)((value is ModSettingBool) ? value : null);
if (val4 != null && ModSettingBool.op_Implicit(val4))
{
towerModel.towerSelectionMenuThemeId = "TacticalTweaks-PursuitTsmTheme";
return;
}
}
towerModel.towerSelectionMenuThemeId = "Default";
}
}
public class HoverPlaneAcesPath : PathPlusPlus
{
public override string Tower => TowerType.MonkeyAce;
}
public class Pursuit : UpgradePlusPlus<HoverPlaneAcesPath>
{
public override int Cost => 500;
public override int Tier => 2;
public override string Description => "A new targeting option enables Monkey Ace to seek and pursue the Bloons automatically.";
public override string DetailedDescription => "Gains the Pursuit targeting option like Heli Pilots.";
public override void ApplyUpgrade(TowerModel towerModel)
{
}
}
}
namespace MiniCrosspaths.DreadnoughtBoats
{
public class Dreadnought : UpgradePlusPlus<DreadnoughtBoatsPath>
{
public override int Tier => 1;
public override int Cost => 600;
public override string Description => "Shoots molten cannonballs instead of darts/grapes that deal extra damage and can pop all Bloon types.";
public override string DetailedDescription => "Projectiles can hit all Bloon types, and their base damage and additive bonuses are all increased by +1 or x1.3, whichever is higher.";
public override void ApplyUpgrade(TowerModel towerModel)
{
//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
PrefabReference display = ((Model)TowerModelExt.GetAttackModel(Game.instance.model.GetTower(TowerType.WizardMonkey, 0, 1, 0), "Fireball")).GetDescendant<DisplayModel>().display;
PrefabReference display2 = ((Model)TowerModelExt.GetAttackModel(Game.instance.model.GetTower(TowerType.TackShooter, 5, 0, 0), "Meteor")).GetDescendant<DisplayModel>().display;
PrefabReference display3 = ((Model)Game.instance.model.GetTower(TowerType.BombShooter, 3, 0, 0)).GetDescendant<ProjectileModel>().display;
IEnumerable<TowerModel> source = Il2CppGenericIEnumerable.AsIEnumerable<TowerModel>(((Model)towerModel).GetDescendants<TowerModel>()).Prepend(towerModel);
IEnumerable<ProjectileModel> enumerable = source.SelectMany((TowerModel t) => Il2CppGenericIEnumerable.AsIEnumerable<ProjectileModel>(((Model)t).GetDescendants<ProjectileModel>()));
DamageModel val = default(DamageModel);
foreach (ProjectileModel item in enumerable)
{
if (ProjectileModelBehaviorExt.HasBehavior<DamageModel>(item, ref val))
{
DamageModel obj = val;
DamageModel obj2 = val;
BloonProperties immuneBloonProperties = (BloonProperties)0;
obj2.immuneBloonPropertiesOriginal = (BloonProperties)0;
obj.immuneBloonProperties = immuneBloonProperties;
val.damage = Math.Max(val.damage + 1f, val.damage * 1.3f);
foreach (DamageModifierForTagModel behavior in ProjectileModelBehaviorExt.GetBehaviors<DamageModifierForTagModel>(item))
{
behavior.damageAddative = Math.Max(behavior.damageAddative + 1f, behavior.damageAddative * 1.3f);
}
}
if (!ProjectileModelBehaviorExt.HasBehavior<TravelStraitModel>(item))
{
break;
}
ProjectileModelExt.SetDisplay<MoltenCannonBall>(item);
if (ProjectileModelBehaviorExt.GetBehaviors<CreateProjectileOnContactModel>(item).Count < 1)
{
item.scale = ((item.radius > 3f) ? 0.7f : 0.5f);
}
}
}
}
public class MoltenCannonBall : ModDisplay
{
public override PrefabReference BaseDisplayReference => ((Model)TowerModelExt.GetAttackModel(Game.instance.model.GetTower(TowerType.TackShooter, 5, 0, 0), "Meteor")).GetDescendant<DisplayModel>().display;
public override void ModifyDisplayNode(UnityDisplayNode node)
{
((Component)UnityDisplayNodeExt.GetRenderer<ParticleSystemRenderer>(node, "Head", true)).gameObject.SetActive(false);
((Component)UnityDisplayNodeExt.GetRenderer<ParticleSystemRenderer>(node, "Tail", true)).gameObject.SetActive(false);
}
}
public class DreadnoughtBoatsPath : PathPlusPlus
{
public override string Tower => TowerType.MonkeyBuccaneer;
}
public class Privateer : UpgradePlusPlus<DreadnoughtBoatsPath>
{
public override int Cost => 800;
public override int Tier => 2;
public override string Description => "Earns 50% more cash from Bloons popped / hooked. Merchantman income is increased by 10%.";
public override string DetailedDescription => "Cash from Bloons is 1.5x, Merchantman income is +10% after other additive bonuses like Trade Empire.";
public override void ApplyUpgrade(TowerModel towerModel)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Expected O, but got Unknown
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Expected O, but got Unknown
Args val = new Args();
((ModelArgs<CashIncreaseModel>)val).name = ((ModContent)this).Name;
val.multiplier = 1.5f;
TowerModelBehaviorExt.AddBehavior<CashIncreaseModel>(towerModel, CreateCashIncreaseModelExt.Create(val));
PerRoundCashBonusTowerModel val2 = default(PerRoundCashBonusTowerModel);
if (ModelExt.HasDescendant<PerRoundCashBonusTowerModel>((Model)(object)towerModel, ref val2))
{
PerRoundCashBonusTowerModel obj = val2;
obj.cashRoundBonusMultiplier += 0.1f;
}
}
}
}
namespace MiniCrosspaths.DoubleRangaBoomers
{
public class DoubleRanga : UpgradePlusPlus<DoubleRangaBoomersPath>
{
public override int Cost => 400;
public override int Tier => 2;
public override string Description => "Throws 2 Boomerangs at a time, but not as frequently.";
public override string DetailedDescription => "Main boomerangs, MOAB Press Boomerangs, and orbiting glaives have double projectile count but two thirds attack speed.";
public override void ApplyUpgrade(TowerModel towerModel)
{
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: Expected O, but got Unknown
foreach (WeaponModel item in DoubleRangaBoomersPath.BoomerAttacks(towerModel).SelectMany((AttackModel attack) => (IEnumerable<WeaponModel>)attack.weapons))
{
item.Rate *= 1.5f;
WeaponModelExt.SetEmission(item, (EmissionModel)(object)CreateArcEmissionModelExt.Create(new Args
{
angle = 30f,
count = 2
}));
}
OrbitModel val = default(OrbitModel);
if (TowerModelBehaviorExt.HasBehavior<OrbitModel>(towerModel, ref val))
{
OrbitModel obj = val;
obj.count *= 2;
WeaponModel obj2 = ((Il2CppArrayBase<WeaponModel>)(object)TowerModelExt.GetAttackModel(towerModel, "Orbit").weapons)[0];
obj2.Rate *= 0.75f;
}
}
}
public class DoubleRangaBoomersPath : PathPlusPlus
{
public override string Tower => TowerType.BoomerangMonkey;
public static List<AttackModel> BoomerAttacks(TowerModel towerModel)
{
List<AttackModel> list = new List<AttackModel> { TowerModelExt.GetAttackModel(towerModel) };
if (((Il2CppArrayBase<string>)(object)towerModel.appliedUpgrades).Contains("MOAB Press"))
{
list.Add(TowerModelExt.GetAttackModel(towerModel, "MOABPress"));
}
return list;
}
}
public class SonicBoom : UpgradePlusPlus<DoubleRangaBoomersPath>
{
public override int Cost => 100;
public override int Tier => 1;
public override string Description => "Boomerangs can smash through Frozen Bloons for extra damage.";
public override string DetailedDescription => "All projectiles can pop Frozen bloons, gaining a damage bonus equal to the projectile's base damage.";
public override void ApplyUpgrade(TowerModel towerModel, int tier)
{
Il2CppGenericIEnumerable.ForEach<ProjectileModel>(((Model)towerModel).GetDescendants<ProjectileModel>(), (Action<ProjectileModel>)delegate(ProjectileModel proj)
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: 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_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: Expected O, but got Unknown
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_005c: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_0076: Expected O, but got Unknown
DamageModel val2 = default(DamageModel);
if (ProjectileModelBehaviorExt.HasBehavior<DamageModel>(proj, ref val2))
{
DamageModel obj = val2;
obj.immuneBloonPropertiesOriginal = (BloonProperties)(obj.immuneBloonPropertiesOriginal & -17);
DamageModel obj2 = val2;
obj2.immuneBloonProperties = (BloonProperties)(obj2.immuneBloonProperties & -17);
Args val3 = new Args();
((ModelArgs<DamageModifierForBloonStateModel>)val3).name = "Frozen";
val3.bloonState = "Ice";
val3.damageMultiplier = 1f;
val3.damageAdditive = val2.damage;
val3.mustBeModified = true;
ProjectileModelBehaviorExt.AddBehavior<DamageModifierForBloonStateModel>(proj, CreateDamageModifierForBloonStateModelExt.Create(val3));
proj.hasDamageModifiers = true;
}
});
AddBehaviorToBloonModel val = default(AddBehaviorToBloonModel);
if (ModelExt.HasDescendant<AddBehaviorToBloonModel>((Model)(object)towerModel, ref val))
{
val.parentDamageModel = null;
((Model)val).RemoveChildDependant<DamageModel>(val.parentDamageModel);
}
}
}
}
namespace MiniCrosspaths.CrystalBallWizards
{
public class CrystalBall : UpgradePlusPlus<CrystalBallWizardsPath>
{
public override int Cost => 1000;
public override int Tier => 2;
public override string Description => "Gains a toggle to allow long range targeting of Bloons in radius of your other towers. Loses Guided Magic's obstacle ignoring behavior while active.";
public override string DetailedDescription => "Toggle Advanced Intel style targeting at the cost of giving up Guided Magic ignoring blockers, if you have it. Projectiles will always use Guided Magic homing to hit targets.";
public override void ApplyUpgrade(TowerModel towerModel)
{
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_0055: Expected O, but got Unknown
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
//IL_0089: Expected O, but got Unknown
//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
//IL_00bf: Expected O, but got Unknown
//IL_00db: Unknown result type (might be due to invalid IL or missing references)
//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
//IL_00f5: Expected O, but got Unknown
towerModel.towerSelectionMenuThemeId = ModContent.GetId<CrystalBallTSM>();
foreach (AttackModel attackModel in TowerModelExt.GetAttackModels(towerModel))
{
if (AttackModelBehaviorExt.HasBehavior<TargetFirstPrioCamoModel>(attackModel))
{
AttackModelBehaviorExt.RemoveBehavior<TargetFirstPrioCamoModel>(attackModel);
AttackModelBehaviorExt.AddBehavior<TargetFirstSharedRangeModel>(attackModel, CreateTargetFirstSharedRangeModelExt.Create(new Args
{
isSelectable = true,
isSharedRangeEnabled = false
}));
}
if (AttackModelBehaviorExt.HasBehavior<TargetLastPrioCamoModel>(attackModel))
{
AttackModelBehaviorExt.RemoveBehavior<TargetLastPrioCamoModel>(attackModel);
AttackModelBehaviorExt.AddBehavior<TargetLastSharedRangeModel>(attackModel, CreateTargetLastSharedRangeModelExt.Create(new Args
{
isSelectable = true,
isSharedRangeEnabled = false
}));
}
if (AttackModelBehaviorExt.HasBehavior<TargetClosePrioCamoModel>(attackModel))
{
AttackModelBehaviorExt.RemoveBehavior<TargetClosePrioCamoModel>(attackModel);
AttackModelBehaviorExt.AddBehavior<TargetCloseSharedRangeModel>(attackModel, CreateTargetCloseSharedRangeModelExt.Create(new Args
{
isSelectable = true,
isSharedRangeEnabled = false
}));
}
if (AttackModelBehaviorExt.HasBehavior<TargetStrongPrioCamoModel>(attackModel))
{
AttackModelBehaviorExt.RemoveBehavior<TargetStrongPrioCamoModel>(attackModel);
AttackModelBehaviorExt.AddBehavior<TargetStrongSharedRangeModel>(attackModel, CreateTargetStrongSharedRangeModelExt.Create(new Args
{
isSelectable = true,
isSharedRangeEnabled = false
}));
}
attackModel.attackThroughWalls = false;
}
foreach (WeaponModel weapon in TowerModelExt.GetWeapons(towerModel))
{
EmissionModelBehaviorExt.AddBehavior<EmissionCamoIfTargetIsCamoModel>(weapon.emission, CreateEmissionCamoIfTargetIsCamoModelExt.Create());
}
}
public override void OnUpgraded(Tower tower)
{
MutableExt.AddMutator<CrystalBallMutator>((Mutable)(object)tower, (JToken)null, -1, true, true, false, true, false, false, false, -1, false, false);
}
}
public class CrystalBallMutator : ModMutator
{
public override bool CantBeAbsorbed => true;
public override bool Saved => true;
public override int Priority => 5;
public override bool Mutate(Model baseModel, Model model, JToken data)
{
//IL_010f: Unknown result type (might be due to invalid IL or missing references)
//IL_0114: Unknown result type (might be due to invalid IL or missing references)
//IL_0120: 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_0134: Unknown result type (might be due to invalid IL or missing references)
//IL_0145: Expected O, but got Unknown
TowerModel val = default(TowerModel);
if (!Il2CppSystemObjectExt.Is<TowerModel>((Il2CppObjectBase)(object)model, ref val))
{
return false;
}
val.ignoreBlockers = false;
TargetFirstSharedRangeModel val2 = default(TargetFirstSharedRangeModel);
TargetLastSharedRangeModel val3 = default(TargetLastSharedRangeModel);
TargetCloseSharedRangeModel val4 = default(TargetCloseSharedRangeModel);
TargetStrongSharedRangeModel val5 = default(TargetStrongSharedRangeModel);
foreach (AttackModel attackModel in TowerModelExt.GetAttackModels(val))
{
if (AttackModelBehaviorExt.HasBehavior<TargetFirstSharedRangeModel>(attackModel, ref val2))
{
val2.isSharedRangeEnabled = true;
}
if (AttackModelBehaviorExt.HasBehavior<TargetLastSharedRangeModel>(attackModel, ref val3))
{
val3.isSharedRangeEnabled = true;
}
if (AttackModelBehaviorExt.HasBehavior<TargetCloseSharedRangeModel>(attackModel, ref val4))
{
val4.isSharedRangeEnabled = true;
}
if (AttackModelBehaviorExt.HasBehavior<TargetStrongSharedRangeModel>(attackModel, ref val5))
{
val5.isSharedRangeEnabled = true;
}
attackModel.attackThroughWalls = false;
}
foreach (ProjectileModel item in Il2CppGenericIEnumerable.AsIEnumerable<ProjectileModel>(model.GetDescendants<ProjectileModel>()))
{
TravelStraitModel behavior = ProjectileModelBehaviorExt.GetBehavior<TravelStraitModel>(item);
if (behavior != null)
{
if (ProjectileModelBehaviorExt.GetBehavior<TrackTargetModel>(item) == null)
{
ProjectileModelBehaviorExt.AddBehavior<TrackTargetModel>(item, CreateTrackTargetModelExt.Create(new Args
{
distance = 80f,
trackNewTargets = true,
maxSeekAngle = 360f,
turnRate = 360f
}));
}
item.ignoreBlockers = false;
}
}
return true;
}
}
public class CrystalBallTSM : ModTsmTheme
{
public override string BaseTheme => "SelectPointInput";
public TSMButton ToggleCrystalBall { get; private set; } = null;
public ModHelperImage Icon { get; private set; } = null;
public override void SetupTheme(BaseTSMTheme theme)
{
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
ToggleCrystalBall = GameObjectExt.AddTSMButton(((Component)theme).gameObject, new Info("ToggleCrystalBall", 372f, -428f, 180f), "Ui[TwitchBtnSquare]", "ToggleCrystalBall", (string)null);
Icon = GameObjectExt.AddImage(((Component)ToggleCrystalBall).gameObject, new Info("Icon", 128f), "");
}
public override void TowerChanged(BaseTSMTheme theme, TowerToSimulation tower)
{
//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
ImageExt.SetSprite(Icon.Image, MutableExt.IsMutatedBy<CrystalBallMutator>((Mutable)(object)tower.tower) ? ((ModContent)this).GetSpriteReference("CrystalBall").AssetGUID : "1c4a4709378c343e0a7234bb2faa2d81");
((Component)ToggleCrystalBall).gameObject.SetActive(((Il2CppArrayBase<string>)(object)tower.Def.appliedUpgrades).Contains("Guided Magic"));
RectTransform component = ((Component)ToggleCrystalBall).GetComponent<RectTransform>();
Il2CppStringArray appliedUpgrades = tower.Def.appliedUpgrades;
int num;
if (appliedUpgrades != null && ((Il2CppArrayBase<string>)(object)appliedUpgrades).Contains("Wall of Fire"))
{
Il2CppStringArray appliedUpgrades2 = tower.Def.appliedUpgrades;
if (appliedUpgrades2 != null && ((Il2CppArrayBase<string>)(object)appliedUpgrades2).Contains("Guided Magic"))
{
num = 198;
goto IL_00b5;
}
}
num = 0;
goto IL_00b5;
IL_00b5:
component.anchoredPosition = new Vector2(372f, (float)(-428 + num));
}
public override void OnButtonPressed(BaseTSMTheme theme, TowerToSimulation tower, string buttonId)
{
if (!(buttonId != "ToggleCrystalBall"))
{
if (MutableExt.IsMutatedBy<CrystalBallMutator>((Mutable)(object)tower.tower))
{
MutableExt.RemoveMutator<CrystalBallMutator>((Mutable)(object)tower.tower);
}
else
{
MutableExt.AddMutator<CrystalBallMutator>((Mutable)(object)tower.tower, (JToken)null, -1, true, true, false, true, false, false, false, -1, false, false);
}
}
}
}
public class CrystalBallWizardsPath : PathPlusPlus
{
public override string Tower => TowerType.WizardMonkey;
}
public class MonkeyApprentice : UpgradePlusPlus<CrystalBallWizardsPath>
{
public override int Cost => 75;
public override int Tier => 1;
public override string Description => "Further study makes all Wizard projectiles travel much further.";
public override string DetailedDescription => "All projectiles that travel in a straight line have doubled lifespan.";
public override void ApplyUpgrade(TowerModel towerModel)
{
foreach (TravelStraitModel item in Il2CppGenericIEnumerable.AsIEnumerable<TravelStraitModel>(((Model)towerModel).GetDescendants<TravelStraitModel>()))
{
item.Lifespan *= 2f;
}
}
}
}