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.Display;
using BTD_Mod_Helper.Extensions;
using HarmonyLib;
using Il2Cpp;
using Il2CppAssets.Scripts.Models;
using Il2CppAssets.Scripts.Models.Bloons.Behaviors;
using Il2CppAssets.Scripts.Models.Entities;
using Il2CppAssets.Scripts.Models.GenericBehaviors;
using Il2CppAssets.Scripts.Models.Towers;
using Il2CppAssets.Scripts.Models.Towers.Behaviors;
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.Weapons;
using Il2CppAssets.Scripts.Models.Towers.Weapons.Behaviors;
using Il2CppAssets.Scripts.Simulation.Bloons;
using Il2CppAssets.Scripts.Simulation.SMath;
using Il2CppAssets.Scripts.Simulation.SimulationBehaviors;
using Il2CppAssets.Scripts.Simulation.Towers;
using Il2CppAssets.Scripts.Simulation.Towers.Projectiles;
using Il2CppAssets.Scripts.Simulation.Towers.Projectiles.Behaviors;
using Il2CppAssets.Scripts.Unity;
using Il2CppAssets.Scripts.Unity.Display;
using Il2CppAssets.Scripts.Unity.Display.Animation;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppNinjaKiwi.Common;
using Il2CppNinjaKiwi.Common.ResourceUtils;
using MelonLoader;
using Microsoft.CodeAnalysis;
using MirrorUniversePaths;
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(MirrorUniversePathsMod), "Mirror Universe Paths", "1.0.2", "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("MirrorUniversePaths")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+9365f45d62d86225f7e885a36651e6162ce24af0")]
[assembly: AssemblyProduct("MirrorUniversePaths")]
[assembly: AssemblyTitle("MirrorUniversePaths")]
[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 MirrorUniversePaths
{
public class MirrorUniversePathsMod : BloonsTD6Mod
{
}
public static class ModHelperData
{
public const string WorksOnVersion = "55.2";
public const string Version = "1.0.2";
public const string Name = "Mirror Universe Paths";
public const string Description = "Adds a number of alternate tower path branches using Paths++.\nMany paths are inspired by features of tier 3 towers that get overlooked/overwritten by the tier 4 and 5 upgrades in their path, but now have a new chance to shine with reimagined upgrades.";
public const string RepoOwner = "doombubbles";
public const string PrevRepoName = "mirror-universe-paths";
public const string RepoName = "MirrorUniversePaths";
public const string Dependencies = "doombubbles/PathsPlusPlus";
}
}
namespace MirrorUniversePaths.TackShooter
{
public class CompleteCombustion : UpgradePlusPlus<TackFireNonRingPath>
{
public override int Cost => 45000;
public override int Tier => 5;
public override string Portrait => "446b34124f7085149b719079c0d7993b";
public override string Description => "Impossibly hot tacks roast Bloons with blazing efficiency.";
public override string DetailedDescription => "Same meteor attack as base 5xx. Tack damage increased to 8 with +4 to MOABs, ranged increased by 11.5, pierce increased by 2x then +3, attack speed is tripled.";
public override void ApplyUpgrade(TowerModel towerModel, int tier)
{
TowerModel tower = GameModelExt.Current.GetTower(TowerType.TackShooter, Math.Clamp(tier, 4, 5), Math.Clamp(((Il2CppArrayBase<int>)(object)towerModel.tiers)[1], 0, 2), Math.Clamp(((Il2CppArrayBase<int>)(object)towerModel.tiers)[2], 0, 2));
towerModel.range = tower.range;
TowerModelExt.GetAttackModel(towerModel).range = TowerModelExt.GetAttackModel(tower).range;
ProjectileModel projectile = TowerModelExt.GetWeapon(towerModel).projectile;
projectile.pierce *= 2f;
ProjectileModel projectile2 = TowerModelExt.GetWeapon(towerModel).projectile;
projectile2.pierce += 3f;
WeaponModel obj = ((Il2CppArrayBase<WeaponModel>)(object)TowerModelExt.GetAttackModel(towerModel).weapons)[0];
obj.Rate /= 3f;
TowerModelBehaviorExt.AddBehavior<AttackModel>(towerModel, ModelExt.Duplicate<AttackModel>(TowerModelExt.GetAttackModel(tower, "Meteor")));
}
}
public class SuperheatedTacks : UpgradePlusPlus<TackFireNonRingPath>
{
public override int Cost => 3500;
public override int Tier => 4;
public override string? Portrait => "95777a58654f7ee428f180492731dd90";
public override string Description => "Shoots superheated tacks that deal immense damage with slightly more pierce.";
public override string DetailedDescription => "Tacks damage is increase to 5, and they have +2 pierce and +2 radius.";
public override void ApplyUpgrade(TowerModel towerModel, int tier)
{
//IL_0114: Unknown result type (might be due to invalid IL or missing references)
TowerModel tower = GameModelExt.Current.GetTower(TowerType.TackShooter, Math.Clamp(tier, 4, 5), Math.Clamp(((Il2CppArrayBase<int>)(object)towerModel.tiers)[1], 0, 2), Math.Clamp(((Il2CppArrayBase<int>)(object)towerModel.tiers)[2], 0, 2));
WeaponModel weapon = TowerModelExt.GetWeapon(tower);
WeaponModel weapon2 = TowerModelExt.GetWeapon(towerModel);
ProjectileModel projectile = weapon2.projectile;
projectile.pierce += 2f;
projectile.radius = 2f;
TowerModel tower2 = GameModelExt.Current.GetTower(TowerType.TackShooter, Math.Clamp(tier, 4, 5), 0, 0);
ProjectileModel descendant = ((Model)tower2).GetDescendant<ProjectileModel>();
ProjectileModelBehaviorExt.GetBehavior<DamageModel>(projectile).damage = ProjectileModelBehaviorExt.GetBehavior<DamageModel>(descendant).damage;
foreach (DamageModifierForTagModel behavior in ProjectileModelBehaviorExt.GetBehaviors<DamageModifierForTagModel>(descendant))
{
ProjectileModelBehaviorExt.AddBehavior<DamageModifierForTagModel>(projectile, ModelExt.Duplicate<DamageModifierForTagModel>(behavior));
projectile.hasDamageModifiers = true;
}
ProjectileModelExt.ApplyDisplay<SuperHotTack>(projectile);
if (((UpgradePlusPlus)this).Tier == tier)
{
WeaponModelExt.SetEject(weapon2, WeaponModelExt.GetEject(weapon), false, false, false);
}
TowerModelExt.SetDisplay(towerModel, ((EntityModel)tower).display);
}
}
public class SuperHotTack : ModDisplay
{
public override PrefabReference BaseDisplayReference => ((Model)Game.instance.model.GetTower(TowerType.TackShooter, 3, 0, 0)).GetDescendant<ProjectileModel>().display;
public override void ModifyDisplayNodeAsync(UnityDisplayNode node, Action onComplete)
{
((ModDisplay)this).UseNode(((Model)TowerModelExt.GetAttackModel(Game.instance.model.GetTower(TowerType.TackShooter, 5, 0, 0), "Meteor")).GetDescendant<ProjectileModel>().display.AssetGUID, (Action<UnityDisplayNode>)delegate(UnityDisplayNode meteor)
{
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
Transform val = Object.Instantiate<Transform>(((Component)meteor).transform.GetChild(0), ((Component)node).transform, false);
OffsetTowardsCamera component = ((Component)val).gameObject.GetComponent<OffsetTowardsCamera>();
component.offset = 0f;
component.Start();
((Behaviour)component).enabled = false;
val.localPosition = new Vector3(0f, 0f, -5f);
((Component)val.GetChild(0)).gameObject.SetActive(false);
((Component)val.GetChild(1)).gameObject.SetActive(false);
ParticleSystem componentInChildren = ((Component)val.GetChild(2)).GetComponentInChildren<ParticleSystem>();
componentInChildren.emissionRate *= 3f;
componentInChildren.maxParticles *= 3;
onComplete();
});
}
}
public class TackFireNonRingPath : PathPlusPlus
{
public override string Tower => TowerType.TackShooter;
public override int ExtendVanillaPath => 0;
public override bool UseUpgradedTowerModels => false;
public override string DisplayName => "Fiery Tacks";
public override string Description => "Continues shooting tacks instead of replacing them with the ring of fire.";
}
}
namespace MirrorUniversePaths.SuperMonkey
{
public class SunDemigod : UpgradePlusPlus<SunNonTemplePath>
{
public override int Cost => 50000;
public override int Tier => 4;
public override string Description => "Ascends further along the path of solar divinity.";
public override string DetailedDescription => "Attack speed is halved, shoots 3 Sun Temple projectiles at 80% scale that have 5 damage and 20 pierce, range increased by +15.";
public override void ApplyUpgrade(TowerModel towerModel, int tier)
{
WeaponModel weapon = TowerModelExt.GetWeapon(towerModel);
TowerModel tower = Game.instance.model.GetTower(TowerType.SuperMonkey, Math.Clamp(tier, 4, 5), Math.Clamp(((Il2CppArrayBase<int>)(object)towerModel.tiers)[1], 0, 2), Math.Clamp(((Il2CppArrayBase<int>)(object)towerModel.tiers)[2], 0, 2));
if (tier == ((UpgradePlusPlus)this).Tier)
{
weapon.Rate *= 2f;
SunDemigodDisplay sunDemigodDisplay = ModContent.GetInstances<SunDemigodDisplay>().FirstOrDefault((SunDemigodDisplay d) => d.Bot == ((Il2CppArrayBase<int>)(object)towerModel.tiers)[2] && d.Mid == ((Il2CppArrayBase<int>)(object)towerModel.tiers)[1]);
if (sunDemigodDisplay != null)
{
((ModDisplay)sunDemigodDisplay).Apply(towerModel);
}
}
towerModel.range = tower.range;
TowerModelExt.GetAttackModel(towerModel).range = TowerModelExt.GetAttackModel(tower).range;
ProjectileModel val = (weapon.projectile = ModelExt.Duplicate<ProjectileModel>(TowerModelExt.GetWeapon(tower).projectile));
ProjectileModel val3 = val;
val3.scale = 0.8f;
val3.radius *= 0.8f;
ProjectileModelExt.SetDisplay<TempleBlastDisplay>(val3);
ModelExt.SetName<CreateSoundOnAttachedModel>(TowerModelBehaviorExt.GetBehavior<CreateSoundOnAttachedModel>(towerModel), ((ModContent)this).Name);
}
}
public class SunDemigodDisplay : ModDisplay
{
public override PrefabReference BaseDisplayReference => ((EntityModel)Game.instance.model.GetTower(TowerType.SuperMonkey, 3, Mid, Bot)).display;
public int Mid { get; init; }
public int Bot { get; init; }
public override string Name => $"{((ModContent)this).Name}4{Mid}{Bot}";
public override IEnumerable<ModContent> Load()
{
yield return (ModContent)(object)this;
yield return (ModContent)(object)new SunDemigodDisplay
{
Mid = 1
};
yield return (ModContent)(object)new SunDemigodDisplay
{
Mid = 2
};
yield return (ModContent)(object)new SunDemigodDisplay
{
Bot = 1
};
yield return (ModContent)(object)new SunDemigodDisplay
{
Bot = 2
};
}
public override void ModifyDisplayNodeAsync(UnityDisplayNode node, Action onComplete)
{
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
RendererExt.AdjustHSV(UnityDisplayNodeExt.GetMeshRenderer(node, 0, true), 0f, -0.5f, 0f, (Color?)new Color(1f, 73f / 85f, 0f), 0.1f);
((ModDisplay)this).UseNode(AttackModelBehaviorExt.GetBehavior<DisplayModel>(TowerModelExt.GetAttackModel(Game.instance.model.GetTower(TowerType.SuperMonkey, 4, Mid, Bot))).display.AssetGUID, (Action<UnityDisplayNode>)delegate(UnityDisplayNode head)
{
//IL_0058: 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_008e: Unknown result type (might be due to invalid IL or missing references)
//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
Transform val = Object.Instantiate<Transform>(((Component)head).transform.GetChild(0), UnityDisplayNodeExt.GetBone(node, "SuperMonkeyRig:MonkeyJnt_Head"), false);
GameObjectExt.RemoveComponent<Animator>(((Component)val).gameObject);
GameObjectExt.RemoveComponent<PlayableAnimator>(((Component)val).gameObject);
GameObjectExt.RemoveComponent<MonkeyAnimationController>(((Component)val).gameObject);
val.localPosition = new Vector3(10f, 0f, 0.15f);
val.localRotation = Quaternion.Euler(0f, 180f, 270f);
val.localScale = new Vector3(0.6f, 0.6f, 0.6f);
RendererExt.AdjustHSV((Renderer)(object)((Component)val).GetComponentInChildren<SkinnedMeshRenderer>(), 0f, -0.5f, 0f, (Color?)new Color(1f, 73f / 85f, 0f), 0.1f);
onComplete();
});
}
}
public class TempleBlastDisplay : ModDisplay
{
public override PrefabReference BaseDisplayReference => TowerModelExt.GetWeapon(Game.instance.model.GetTower(TowerType.SuperMonkey, 4, 0, 0)).projectile.display;
public override void ModifyDisplayNode(UnityDisplayNode node)
{
foreach (OffsetTowardsCamera componentsInChild in ((Component)node).gameObject.GetComponentsInChildren<OffsetTowardsCamera>(true))
{
componentsInChild.offset = 0f;
componentsInChild.Start();
}
}
}
public class SunGod : UpgradePlusPlus<SunNonTemplePath>
{
public override int Cost => 100000;
public override int Tier => 5;
public override string Icon => "a04463dfa8e4c704c8b660dd6e5d64b4";
public override string? Portrait => "df307dbea1cab0e4285be3949c4d949a";
public override string Description => "Tremble before the AWESOME power of the Sun God!! *trueness not guaranteed*";
public override string DetailedDescription => "Attack speed is doubled, shoots 5 True Sun God projectiles at 80% scale that have 15 damage and 20 pierce.";
public override void ApplyUpgrade(TowerModel towerModel)
{
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
TowerModelExt.SetDisplay<SunGodDisplay>(towerModel);
WeaponModel weapon = TowerModelExt.GetWeapon(towerModel);
ProjectileModelExt.SetDisplay<GodBlastDisplay>(weapon.projectile);
WeaponModelExt.SetEject(weapon, new Vector3(2f, 5f, 42f), false, false, false);
((ArcEmissionModel)((Model)weapon).GetDescendant<RandomArcEmissionModel>()).Count = 5;
}
}
public class SunGodDisplay : ModDisplay
{
public override PrefabReference BaseDisplayReference => AttackModelBehaviorExt.GetBehavior<DisplayModel>(TowerModelExt.GetAttackModel(Game.instance.model.GetTower(TowerType.SuperMonkey, 5, 0, 0))).display;
public override float Scale => 0.75f;
}
public class GodBlastDisplay : ModDisplay
{
public override PrefabReference BaseDisplayReference => TowerModelExt.GetWeapon(Game.instance.model.GetTower(TowerType.SuperMonkey, 5, 0, 0)).projectile.display;
public override void ModifyDisplayNode(UnityDisplayNode node)
{
foreach (OffsetTowardsCamera componentsInChild in ((Component)node).gameObject.GetComponentsInChildren<OffsetTowardsCamera>(true))
{
componentsInChild.offset = 0f;
componentsInChild.Start();
}
}
}
public class SunNonTemplePath : PathPlusPlus
{
public override string Tower => TowerType.SuperMonkey;
public override int ExtendVanillaPath => 0;
public override bool UseUpgradedTowerModels => false;
public override string DisplayName => "Non-Temple";
public override string Description => "Doesn't become a Temple or enact sacrifices.";
}
public class VengefulAvatar : UpgradePlusPlus<VengefulNonTemplePath>
{
public override int Cost => 100000;
public override int Tier => 4;
public override string Portrait => "de6fb5caa564ca44eb80cfcbb936554a";
public override string Description => "Walks the path of vengeance to enact untold ruin onto Bloons.";
public override string DetailedDescription => "Projectile damage increased to 13, can hit Purple Bloons, range increased by +15";
public override void ApplyUpgrade(TowerModel towerModel)
{
//IL_0054: 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)
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
TowerModelExt.SetDisplay<VengefulAvatarDisplay>(towerModel);
towerModel.range += 15f;
AttackModel attackModel = TowerModelExt.GetAttackModel(towerModel);
attackModel.range += 15f;
ProjectileModel projectile = TowerModelExt.GetWeapon(towerModel).projectile;
ProjectileModelExt.SetDisplay(projectile, "e4abb3d789fca4747a7459d21c835472");
DamageModel damageModel = ProjectileModelExt.GetDamageModel(projectile);
damageModel.immuneBloonProperties = (BloonProperties)(damageModel.immuneBloonProperties & -9);
damageModel.immuneBloonPropertiesOriginal = (BloonProperties)(damageModel.immuneBloonPropertiesOriginal & -9);
damageModel.damage = 13f;
ModelExt.SetName<CreateSoundOnAttachedModel>(TowerModelBehaviorExt.GetBehavior<CreateSoundOnAttachedModel>(towerModel), ((ModContent)this).Name);
}
}
public class VengefulAvatarDisplay : ModDisplay
{
public override string BaseDisplay => "36d3f05381187cf4da168f4676076159";
public override float Scale => 1.75f;
}
public class VengefulGod : UpgradePlusPlus<VengefulNonTemplePath>
{
public override int Cost => 500000;
public override int Tier => 5;
public override string Portrait => "afd7922791d61014ca6d601526f94c1e";
public override string Description => "There can be only one.";
public override string DetailedDescription => "Attack speed is doubled, shoots 5 Vengeful True Sun God projectiles at 80% scale that have 30 damage and 30 pierce, range increased by +15.";
public override void ApplyUpgrade(TowerModel towerModel)
{
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
TowerModelExt.SetDisplay<VengefulGodDisplay>(towerModel);
WeaponModel weapon = TowerModelExt.GetWeapon(towerModel);
ProjectileModelExt.SetDisplay<VengefulGodBlastDisplay>(weapon.projectile);
WeaponModelExt.SetEject(weapon, new Vector3(2f, 5f, 42f), false, false, false);
((ArcEmissionModel)((Il2CppObjectBase)weapon.emission).Cast<RandomArcEmissionModel>()).Count = 5;
weapon.Rate /= 2f;
ProjectileModel projectile = weapon.projectile;
projectile.pierce += 24f;
weapon.projectile.radius = 8f;
weapon.projectile.scale = 0.8f;
DamageModel damageModel = ProjectileModelExt.GetDamageModel(weapon.projectile);
damageModel.damage += 17f;
BloonProperties immuneBloonProperties = (BloonProperties)0;
damageModel.immuneBloonPropertiesOriginal = (BloonProperties)0;
damageModel.immuneBloonProperties = immuneBloonProperties;
}
}
public class VengefulGodDisplay : ModDisplay
{
public override string BaseDisplay => "45d40b8795fd36c4eadb7856f96a180c";
public override float Scale => 0.75f;
}
public class VengefulGodBlastDisplay : ModDisplay
{
public override string BaseDisplay => "4fb0baaa656410f4ba1f2fd07b37eda4";
public override void ModifyDisplayNode(UnityDisplayNode node)
{
foreach (OffsetTowardsCamera componentsInChild in ((Component)node).gameObject.GetComponentsInChildren<OffsetTowardsCamera>(true))
{
componentsInChild.offset = 0f;
componentsInChild.Start();
}
}
}
public class VengefulNonTemplePath : PathPlusPlus
{
public override string Tower => TowerType.SuperMonkey;
public override int ExtendVanillaPath => 0;
public override bool UseUpgradedTowerModels => false;
public override string DisplayName => "Vengeful Non-Temple";
public override string Description => "Doesn't become a Temple or enact sacrifices, but is vengeful about it.";
}
}
namespace MirrorUniversePaths.SniperMonkey
{
public class AssaultMOAB : UpgradePlusPlus<SniperNonMaimPath>
{
public override int Cost => 6300;
public override int Tier => 4;
public override string DisplayName => "Assault MOAB";
public override string Description => "Deadly Precision's +50 Ceramic damage bonus now also applies to MOAB-class Bloons.";
public override void ApplyUpgrade(TowerModel towerModel, int tier)
{
Il2CppGenericIEnumerable.ForEach<ProjectileModel>(((Model)towerModel).GetDescendants<ProjectileModel>(), (Action<ProjectileModel>)delegate(ProjectileModel proj)
{
if (!ProjectileModelBehaviorExt.HasBehavior<DamageModel>(proj))
{
return;
}
ProjectileModelBehaviorExt.RemoveBehaviors<SlowMaimMoabModel>(proj);
foreach (DamageModifierForTagModel item in from damageModifier in ProjectileModelBehaviorExt.GetBehaviors<DamageModifierForTagModel>(proj)
where damageModifier.tag == "Ceramic"
select damageModifier)
{
item.tag += ",Moabs";
item.tags = StringExtensions.CommaSeperatedListToStringArray(item.tag, true, true);
}
});
if (tier == ((UpgradePlusPlus)this).Tier)
{
AssaultMOABDisplay assaultMOABDisplay = ModContent.GetInstances<AssaultMOABDisplay>().FirstOrDefault((AssaultMOABDisplay d) => d.Bot == ((Il2CppArrayBase<int>)(object)towerModel.tiers)[2] && d.Mid == ((Il2CppArrayBase<int>)(object)towerModel.tiers)[1]);
if (assaultMOABDisplay != null)
{
((ModDisplay)assaultMOABDisplay).Apply(towerModel);
}
}
}
}
public class AssaultMOABDisplay : ModDisplay
{
public override PrefabReference BaseDisplayReference => ((EntityModel)Game.instance.model.GetTower(TowerType.SniperMonkey, 4, Mid, Bot)).display;
public int Mid { get; init; }
public int Bot { get; init; }
public override string Name => $"{((ModContent)this).Name}4{Mid}{Bot}";
public override IEnumerable<ModContent> Load()
{
yield return (ModContent)(object)this;
yield return (ModContent)(object)new AssaultMOABDisplay
{
Mid = 1
};
yield return (ModContent)(object)new AssaultMOABDisplay
{
Mid = 2
};
yield return (ModContent)(object)new AssaultMOABDisplay
{
Bot = 1
};
yield return (ModContent)(object)new AssaultMOABDisplay
{
Bot = 2
};
}
public override void ModifyDisplayNode(UnityDisplayNode node)
{
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
Renderer meshRenderer = UnityDisplayNodeExt.GetMeshRenderer(node, 0, true);
RendererExt.AdjustHSV(meshRenderer, 0f, -1f, 0f, (Color?)new Color(4f / 15f, 0.34901962f, 11f / 85f), 0.25f);
RendererExt.AdjustHSV(meshRenderer, 0f, -1f, 0f, (Color?)new Color(0.16078432f, 0.2f, 0.0627451f), 0.25f);
RendererExt.AdjustHSV(meshRenderer, 0f, -1f, 0f, (Color?)new Color(0.41960785f, 0.49803922f, 0.16078432f), 0.25f);
RendererExt.AdjustHSV(meshRenderer, 0f, -1f, 0f, (Color?)new Color(0.64705884f, 0.75686276f, 0.050980393f), 0.25f);
RendererExt.SetOutlineColor(meshRenderer, new Color(0.24313726f, 0.24313726f, 0.24313726f));
}
}
public class ExecuteMOAB : UpgradePlusPlus<SniperNonMaimPath>
{
public override int Cost => 32000;
public override int Tier => 5;
public override string DisplayName => "Execute MOAB";
public override string Description => "Deals 10x damage to MOAB-class Bloons that are below 25% health.";
public override void ApplyUpgrade(TowerModel towerModel)
{
Il2CppGenericIEnumerable.ForEach<ProjectileModel>(((Model)towerModel).GetDescendants<ProjectileModel>(), (Action<ProjectileModel>)delegate(ProjectileModel proj)
{
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: 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_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Expected O, but got Unknown
//IL_0047: Expected O, but got Unknown
if (ProjectileModelBehaviorExt.HasBehavior<DamageModel>(proj))
{
proj.hasDamageModifiers = true;
Args val = new Args
{
tag = "Moabs",
damageMultiplier = 10f
};
((ModelArgs<DamageModifierForTagModel>)val).name = "EXECUTE_25";
ProjectileModelBehaviorExt.AddBehavior<DamageModifierForTagModel>(proj, CreateDamageModifierForTagModelExt.Create(val));
}
});
TowerModelExt.SetDisplay<ExecuteMOABDisplay>(towerModel);
}
}
[HarmonyPatch(typeof(DamageModifierForTagModel), "DoesApplyBonus")]
internal static class DamageModifierForTagModel_DoesApplyBonus
{
[HarmonyPostfix]
internal static void Postfix(DamageModifierForTagModel __instance, Bloon bloon, ref bool __result)
{
if (((Model)__instance).name.Contains("EXECUTE") && int.TryParse(((Model)__instance).name.Split('_')[^1], out var result) && bloon.Health * 100 > bloon.bloonModel.maxHealth * result)
{
__result = false;
}
}
}
public class ExecuteMOABDisplay : ModDisplay
{
public override PrefabReference BaseDisplayReference => ((EntityModel)Game.instance.model.GetTower(TowerType.SniperMonkey, 5, 0, 0)).display;
public override void ModifyDisplayNode(UnityDisplayNode node)
{
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
Renderer meshRenderer = UnityDisplayNodeExt.GetMeshRenderer(node, 1, true);
RendererExt.AdjustHSV(meshRenderer, 0f, -1f, 0f, (Color?)new Color(4f / 15f, 0.34901962f, 11f / 85f), 0.25f);
RendererExt.AdjustHSV(meshRenderer, 0f, -1f, 0f, (Color?)new Color(0.16078432f, 0.2f, 0.0627451f), 0.25f);
RendererExt.AdjustHSV(meshRenderer, 0f, -1f, 0f, (Color?)new Color(0.41960785f, 0.49803922f, 0.16078432f), 0.25f);
RendererExt.AdjustHSV(meshRenderer, 0f, -1f, 0f, (Color?)new Color(0.64705884f, 0.75686276f, 0.050980393f), 0.25f);
RendererExt.SetOutlineColor(meshRenderer, new Color(0.24313726f, 0.24313726f, 0.24313726f));
}
}
public class SniperNonMaimPath : PathPlusPlus
{
public override string Tower => TowerType.SniperMonkey;
public override int ExtendVanillaPath => 0;
public override bool UseUpgradedTowerModels => true;
public override string DisplayName => "MOAB DPS";
public override string Description => "Focuses on pure MOAB damage rather than stall/support.";
}
}
namespace MirrorUniversePaths.NinjaMonkey
{
public class Boomjitsu : UpgradePlusPlus<NinjaBombPath>
{
public override int Cost => 5000;
public override int Tier => 4;
public override string Description => "All shurikens are now replaced with flash bombs which deal bonus damage to MOAB-Class Bloons. Caltrops explode too.";
public override string DetailedDescription => "Flash bombs are every attack instead of every 4th. Flash bombs deal +4 damage to MOABs. Caltrops create a flash bomb explosion on exhaust.";
public override void ApplyUpgrade(TowerModel towerModel, int tier)
{
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_008d: Expected O, but got Unknown
//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
//IL_0105: Expected O, but got Unknown
//IL_010d: Unknown result type (might be due to invalid IL or missing references)
//IL_0112: Unknown result type (might be due to invalid IL or missing references)
//IL_0124: Unknown result type (might be due to invalid IL or missing references)
//IL_0130: Unknown result type (might be due to invalid IL or missing references)
//IL_0141: Expected O, but got Unknown
//IL_0151: Unknown result type (might be due to invalid IL or missing references)
//IL_0156: 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_0172: Unknown result type (might be due to invalid IL or missing references)
//IL_0180: Unknown result type (might be due to invalid IL or missing references)
//IL_018e: Unknown result type (might be due to invalid IL or missing references)
//IL_01a1: Expected O, but got Unknown
TowerModelBehaviorExt.RemoveBehavior<AttackModel>(towerModel, "StickyBomb");
WeaponModel val = ((Il2CppArrayBase<WeaponModel>)(object)TowerModelExt.GetAttackModel(towerModel).weapons)[0];
ProjectileModel projectile = val.projectile;
ProjectileModel projectile2 = WeaponModelBehaviorExt.GetBehavior<AlternateProjectileModel>(val).projectile;
ProjectileModel descendant = ((Model)projectile2).GetDescendant<ProjectileModel>();
DamageModifierForBloonStateModel behavior = ProjectileModelBehaviorExt.GetBehavior<DamageModifierForBloonStateModel>(projectile);
ProjectileModelBehaviorExt.AddBehavior<DamageModifierForTagModel>(descendant, CreateDamageModifierForTagModelExt.Create(new Args
{
tag = "Moabs",
damageMultiplier = behavior.damageMultiplier,
damageAddative = behavior.damageAdditive
}));
ProjectileModelBehaviorExt.GetBehavior<SlowModel>(descendant).dontRefreshDuration = true;
WeaponModelBehaviorExt.RemoveBehavior<AlternateProjectileModel>(val);
WeaponModelExt.SetProjectile(val, projectile2);
ProjectileModel descendant2 = ((Model)TowerModelExt.GetAttackModel(towerModel, "Caltrops")).GetDescendant<ProjectileModel>();
ProjectileModelBehaviorExt.AddBehavior<CreateProjectileOnExhaustFractionModel>(descendant2, CreateCreateProjectileOnExhaustFractionModelExt.Create(new Args
{
projectile = ModelExt.Duplicate<ProjectileModel>(descendant),
fraction = 1f,
durationfraction = -1f,
emission = (EmissionModel)(object)CreateSingleEmissionModelExt.Create()
}));
ProjectileModelBehaviorExt.AddBehavior<CreateEffectOnExhaustFractionModel>(descendant2, CreateCreateEffectOnExhaustFractionModelExt.Create(new Args
{
effectModel = ProjectileModelBehaviorExt.GetBehavior<CreateEffectOnContactModel>(projectile2).effectModel,
fraction = 1f,
durationFraction = -1f
}));
CreateSoundOnProjectileCollisionModel behavior2 = ProjectileModelBehaviorExt.GetBehavior<CreateSoundOnProjectileCollisionModel>(projectile2);
ProjectileModelBehaviorExt.AddBehavior<CreateSoundOnProjectileExhaustModel>(descendant2, CreateCreateSoundOnProjectileExhaustModelExt.Create(new Args
{
sound1 = behavior2.sound1,
sound2 = behavior2.sound2,
sound3 = behavior2.sound3,
sound4 = behavior2.sound4,
sound5 = behavior2.sound5
}));
if (tier == ((UpgradePlusPlus)this).Tier)
{
BoomjitsuDisplay boomjitsuDisplay = ModContent.GetInstances<BoomjitsuDisplay>().FirstOrDefault((BoomjitsuDisplay d) => d.Top == ((Il2CppArrayBase<int>)(object)towerModel.tiers)[0] && d.Mid == ((Il2CppArrayBase<int>)(object)towerModel.tiers)[1]);
if (boomjitsuDisplay != null)
{
((ModDisplay)boomjitsuDisplay).Apply(towerModel);
}
}
}
}
public class BoomjitsuDisplay : ModDisplay
{
public override PrefabReference BaseDisplayReference => ((EntityModel)Game.instance.model.GetTower(TowerType.NinjaMonkey, Top, Mid, 4)).display;
public int Top { get; init; }
public int Mid { get; init; }
public override string Name => $"{((ModContent)this).Name}{Top}{Mid}{4}";
public override IEnumerable<ModContent> Load()
{
yield return (ModContent)(object)this;
yield return (ModContent)(object)new BoomjitsuDisplay
{
Top = 1
};
yield return (ModContent)(object)new BoomjitsuDisplay
{
Top = 2
};
yield return (ModContent)(object)new BoomjitsuDisplay
{
Mid = 1
};
yield return (ModContent)(object)new BoomjitsuDisplay
{
Mid = 2
};
}
public override void ModifyDisplayNode(UnityDisplayNode node)
{
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
//IL_009b: Unknown result type (might be due to invalid IL or missing references)
UnityDisplayNodeExt.RemoveBone(node, "NinjaMonkeyRig:Dart", false);
int num = -155;
float num2 = -0.57f;
float num3 = -0.44f;
RendererExt.AdjustHSV(UnityDisplayNodeExt.GetMeshRenderer(node, 0, true), (float)num, num2, num3, (Color?)new Color(1f, 0.21960784f, 0f), 0.3f);
RendererExt.AdjustHSV(UnityDisplayNodeExt.GetMeshRenderer(node, 0, true), (float)num, num2, num3, (Color?)new Color(0.5803922f, 0.21960784f, 0f), 0.3f);
RendererExt.AdjustHSV(UnityDisplayNodeExt.GetMeshRenderer(node, 0, true), (float)num, num2, num3, (Color?)new Color(0.32156864f, 0.21960784f, 0f), 0.3f);
}
}
public class GrandBlasterNinja : UpgradePlusPlus<NinjaBombPath>
{
public override int Cost => 40000;
public override int Tier => 5;
public override string DisplayName => "Grand-Blaster Ninja";
public override string Description => "Explosions now stun MOAB-class Bloons and deal way more damage.";
public override string DetailedDescription => "Applies the base xx5 effects of flash bombs stunning MOABs for .325s, flash bombs having 10 base damage, and caltrops having 5 base damage with +5 to ceramic. Flash bomb bonus MOAB damage is now +19.";
public override void ApplyUpgrade(TowerModel towerModel, int tier)
{
if (tier == ((UpgradePlusPlus)this).Tier)
{
((ModDisplay)ModContent.GetInstance<GrandBlasterNinjaDisplay>()).Apply(towerModel);
}
}
}
public class GrandBlasterNinjaDisplay : ModDisplay
{
public override PrefabReference BaseDisplayReference => ((EntityModel)Game.instance.model.GetTower(TowerType.NinjaMonkey, 0, 0, 5)).display;
public override void ModifyDisplayNode(UnityDisplayNode node)
{
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
UnityDisplayNodeExt.RemoveBone(node, "Dart", false);
RendererExt.AdjustHSV(UnityDisplayNodeExt.GetMeshRenderer(node, 0, true), -157f, 0.88f, 0.32f, (Color?)new Color(0.96862745f, 0.21960784f, 0f), 0.5f);
RendererExt.AdjustHSV(UnityDisplayNodeExt.GetMeshRenderer(node, 0, true), -157f, 0.88f, 0.32f, (Color?)new Color(63f / 85f, 14f / 85f, 0f), 0.5f);
}
}
public class NinjaBombPath : PathPlusPlus
{
public override string Tower => TowerType.NinjaMonkey;
public override int ExtendVanillaPath => 2;
public override bool UseUpgradedTowerModels => true;
public override string DisplayName => "Bomb";
public override string Description => "Amplifies Flash Bombs instead of getting Sticky Bombs.";
}
}
namespace MirrorUniversePaths.MonkeySub
{
public class BloontoniumDarts : UpgradePlusPlus<SubNonSubmergePath>
{
public override int Cost => 2400;
public override int Tier => 4;
public override string Description => "Darts do more damage and leave behind radioactive fallout that irradiates Bloons. Twin Guns makes radiation damage faster, Barbed Darts makes it last longer.";
public override string DetailedDescription => "Dart damage increased to 2 like base 4xx, creates Fallout projectiles on first hitting a Bloon that have the same pierce, damage, and damage interval as the base 4xx attack. Lifespan is 2s, or 5s with Barbed Darts.";
public override string Portrait => "dc8d549c38103f54a82f4682608b252a";
public override void ApplyUpgrade(TowerModel towerModel, int tier)
{
//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
//IL_01fa: Expected O, but got Unknown
//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
//IL_0201: Unknown result type (might be due to invalid IL or missing references)
//IL_020e: Expected O, but got Unknown
//IL_0219: Expected O, but got Unknown
TowerModel paragonTower = Game.instance.model.GetParagonTower(TowerType.MonkeySub);
AttackModel attackModel = TowerModelExt.GetAttackModel(GameModelExt.Current.GetTower(TowerType.MonkeySub, Math.Clamp(tier, 4, 5), Math.Clamp(((Il2CppArrayBase<int>)(object)towerModel.tiers)[1], 0, 2), Math.Clamp(((Il2CppArrayBase<int>)(object)towerModel.tiers)[2], 0, 2)), "Submerge");
WeaponModel val = ((Il2CppArrayBase<WeaponModel>)(object)attackModel.weapons)[1];
ProjectileModel val2 = ModelExt.Duplicate<ProjectileModel>(((Model)((Model)paragonTower).GetDescendant<FinalStrikeModel>()).GetDescendant<CreateProjectilesOnTrackOnExpireModel>().projectile);
val2.pierce = val.projectile.pierce;
ProjectileModelBehaviorExt.RemoveBehavior<RefreshPierceModel>(val2);
ProjectileModelBehaviorExt.GetBehavior<AgeModel>(val2).Lifespan = (((Il2CppArrayBase<string>)(object)towerModel.appliedUpgrades).Contains("Barbed Darts") ? 5 : 2);
ProjectileModelBehaviorExt.GetBehavior<DamageModel>(val2).damage = ((Model)val).GetDescendant<DamageModel>().damage;
ProjectileModelBehaviorExt.RemoveBehaviors<DamageModifierModel>(val2);
ProjectileModelBehaviorExt.AddBehavior<AddTagToBloonModel>(val2, ModelExt.Duplicate<AddTagToBloonModel>(((Model)val).GetDescendant<AddTagToBloonModel>()));
foreach (DamageModifierForTagModel behavior2 in ProjectileModelBehaviorExt.GetBehaviors<DamageModifierForTagModel>(val.projectile))
{
ProjectileModelBehaviorExt.AddBehavior<DamageModifierForTagModel>(val2, ModelExt.Duplicate<DamageModifierForTagModel>(behavior2));
val2.hasDamageModifiers = true;
}
ClearHitBloonsModel behavior = ProjectileModelBehaviorExt.GetBehavior<ClearHitBloonsModel>(val2);
behavior.interval = val.rate;
behavior.intervalFrames = (int)(behavior.interval / 60f);
val2.UpdateCollisionPassList();
if (tier == ((UpgradePlusPlus)this).Tier)
{
val2.scale *= 0.75f;
val2.radius *= 0.75f;
}
ProjectileModel projectile = TowerModelExt.GetWeapon(towerModel).projectile;
Il2CppGenericIEnumerable.ForEach<ProjectileModel>(((Model)projectile).GetDescendants<ProjectileModel>(), (Action<ProjectileModel>)delegate(ProjectileModel proj)
{
if (proj.id.Contains("Airburst"))
{
ProjectileModelExt.SetDisplay<GreenAirburstDart>(proj);
}
});
Args val3 = new Args
{
projectile = val2
};
((ModelArgs<CreateProjectileOnContactModel>)val3).name = "FIRST_CONTACT";
val3.emission = (EmissionModel)(object)CreateEmissionAtClosestPathSegmentModelExt.Create(new Args
{
count = 1
});
ProjectileModelBehaviorExt.AddBehavior<CreateProjectileOnContactModel>(projectile, CreateCreateProjectileOnContactModelExt.Create(val3));
}
}
public class GreenAirburstDart : ModDisplay
{
public override string BaseDisplay => "8ac212675d4760541a5f9bcccad5ccf7";
public override void ModifyDisplayNode(UnityDisplayNode node)
{
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
((Renderer)UnityDisplayNodeExt.GetRenderer<ParticleSystemRenderer>(node, true)).material.color = new Color(0f, 1f, 0.5f, 1f);
}
}
[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("FIRST_CONTACT") || ((ProjectileBehavior)__instance).projectile.collidedWith.Count <= 1;
}
}
public class PeriscopeTargeting : UpgradePlusPlus<SubNonSubmergePath>
{
public override int Cost => 700;
public override int Tier => 3;
public override string Description => "Allows Monkey Sub to detect and deal extra damage to Camo Bloons.";
public override string DetailedDescription => "Grants camo detection, all projectiles deal bonus camo damage equal to their base damage.";
public override string Portrait => "4f2d9eddfc769c4409550715b62adfe2";
public override void ApplyUpgrade(TowerModel towerModel)
{
TowerModelBehaviorExt.RemoveBehavior<SubmergeModel>(towerModel);
TowerModelBehaviorExt.RemoveBehavior<SubmergeEffectModel>(towerModel);
TowerModelBehaviorExt.RemoveBehavior<LinkProjectileRadiusToTowerRangeModel>(towerModel);
TowerModelBehaviorExt.RemoveBehavior<AttackModel>(towerModel, "Submerge");
TowerModelBehaviorExt.RemoveBehavior<CreateEffectAfterTimeModel>(towerModel);
AttackModelBehaviorExt.RemoveBehavior<SubmergedTargetModel>(TowerModelExt.GetAttackModel(towerModel));
}
public override void LateApplyUpgrade(TowerModel towerModel)
{
Il2CppGenericIEnumerable.ForEach<FilterInvisibleModel>(((Model)towerModel).GetDescendants<FilterInvisibleModel>(), (Action<FilterInvisibleModel>)delegate(FilterInvisibleModel model)
{
model.isActive = false;
});
Il2CppGenericIEnumerable.ForEach<ProjectileModel>(((Model)towerModel).GetDescendants<ProjectileModel>(), (Action<ProjectileModel>)delegate(ProjectileModel model)
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: 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_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Expected O, but got Unknown
DamageModel val = default(DamageModel);
if (ProjectileModelBehaviorExt.HasBehavior<DamageModel>(model, ref val))
{
ProjectileModelBehaviorExt.AddBehavior<DamageModifierForTagModel>(model, CreateDamageModifierForTagModelExt.Create(new Args
{
tag = "Camo",
damageAddative = val.damage,
damageMultiplier = 1f
}));
model.hasDamageModifiers = true;
}
});
}
}
public class RbmkFallout : UpgradePlusPlus<SubNonSubmergePath>
{
public override int Cost => 28000;
public override int Tier => 5;
public override string DisplayName => "RBMK Fallout";
public override string Description => "Radioactive Bloontonium Molecular Killzone. Darts and radiation tear apart Bloons at an atomic level, inflicting far more than 3.6 Roentgen.";
public override string DetailedDescription => "Dart damage increased to 5 like base 5xx, Fallout projectiles are 33% larger, and have the same pierce, damage and damage interval as the base 5xx attack.";
public override string Portrait => "934eeddc6fcfe8349afa34ad14ae3afc";
public override void ApplyUpgrade(TowerModel towerModel)
{
}
}
public class SubNonSubmergePath : PathPlusPlus
{
public override string Tower => TowerType.MonkeySub;
public override int ExtendVanillaPath => 0;
public override bool UseUpgradedTowerModels => true;
public override string DisplayName => "Non-Submerge";
public override string Description => "Uses radioactive power for extra damage without submerging.";
}
}
namespace MirrorUniversePaths.EngineerMonkey
{
public class EngineerNailPath : PathPlusPlus
{
public override string Tower => TowerType.EngineerMonkey;
public override int ExtendVanillaPath => 2;
public override bool UseUpgradedTowerModels => true;
public override string DisplayName => "Nail Gun";
public override string Description => "Empowers Nail attacks instead of using Traps.";
public static IEnumerable<AttackModel> Attacks(TowerModel towerModel)
{
yield return TowerModelBehaviorExt.GetBehavior<AttackModel>(towerModel);
AttackModel sentrySpawner = default(AttackModel);
if (!TowerModelBehaviorExt.HasBehavior<AttackModel>(towerModel, "Spawner", ref sentrySpawner))
{
yield break;
}
foreach (TowerModel sentry in Il2CppGenericIEnumerable.AsIEnumerable<TowerModel>(((Model)sentrySpawner).GetDescendants<TowerModel>()))
{
yield return TowerModelExt.GetAttackModel(sentry);
}
}
public static IEnumerable<ProjectileModel> Nails(TowerModel towerModel)
{
return Attacks(towerModel).SelectMany((AttackModel attack) => from projectileModel in Il2CppGenericIEnumerable.AsIEnumerable<ProjectileModel>(((Model)attack).GetDescendants<ProjectileModel>())
where ProjectileModelBehaviorExt.HasBehavior<DamageModel>(projectileModel) && ProjectileModelBehaviorExt.HasBehavior<TravelStraitModel>(projectileModel)
select projectileModel);
}
}
public class GalvanizedNail : ModDisplay
{
public override PrefabReference BaseDisplayReference => ((Model)Game.instance.model.GetTower(TowerType.EngineerMonkey, 0, 0, 4)).GetDescendant<ProjectileModel>().display;
public override void ModifyDisplayNode(UnityDisplayNode node)
{
UnityDisplayNodeExt.GetRenderer<SpriteRenderer>(node, true).sprite = ((ModContent)this).GetSprite(((ModContent)this).Name, 10f);
}
}
public class GalvanizedNails : UpgradePlusPlus<EngineerNailPath>
{
public override int Cost => 3600;
public override int Tier => 4;
public override string Description => "Nails deal significantly increased damage, can pop all Bloon types, and give increased cash per pop.";
public override string DetailedDescription => "Nail damage increased by +2, pops all Bloon types, cash per pop is 2x, Deconstruction damage bonus increased by 4";
public override void ApplyUpgrade(TowerModel towerModel, int tier)
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Expected O, but got Unknown
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
int num = 2;
AttackModel val = default(AttackModel);
if (TowerModelBehaviorExt.HasBehavior<AttackModel>(towerModel, "BloonTrap", ref val))
{
EatBloonModel descendant = ((Model)val).GetDescendant<EatBloonModel>();
AttackModelBehaviorExt.AddBehavior<CashIncreaseModel>(val, CreateCashIncreaseModelExt.Create(new Args
{
multiplier = descendant.rbeCashMultiplier
}));
TowerModelBehaviorExt.RemoveBehavior<AttackModel>(towerModel, val);
}
foreach (ProjectileModel item in EngineerNailPath.Nails(towerModel))
{
DamageModel damageModel = ProjectileModelExt.GetDamageModel(item);
BloonProperties immuneBloonProperties = (BloonProperties)0;
damageModel.immuneBloonPropertiesOriginal = (BloonProperties)0;
damageModel.immuneBloonProperties = immuneBloonProperties;
damageModel.damage += (float)num;
ProjectileModelExt.SetDisplay(item, ModContent.CreatePrefabReference<GalvanizedNail>());
if (!((Il2CppArrayBase<string>)(object)towerModel.appliedUpgrades).Contains("Deconstruction"))
{
continue;
}
foreach (DamageModifierForTagModel item2 in from damageModifier in ProjectileModelBehaviorExt.GetBehaviors<DamageModifierForTagModel>(item)
where ((Il2CppArrayBase<string>)(object)damageModifier.tags).Contains("Moabs") || ((Il2CppArrayBase<string>)(object)damageModifier.tags).Contains("Fortified")
select damageModifier)
{
item2.damageAddative += (float)(num * 2);
}
}
TowerModelBehaviorExt.RemoveBehavior<AttackModel>(towerModel, val);
}
}
internal class Nailstorm : UpgradePlusPlus<EngineerNailPath>
{
public override int Cost => 45000;
public override int Tier => 5;
public override string Description => "Unleashes bucket loads of nails at super speed!";
public override string DetailedDescription => "Shoots 3 nails at a time in a 30° cone, attack speed increased 3x, nail pierce increased by 2x, cash per pop now 3x";
public override void ApplyUpgrade(TowerModel towerModel)
{
AttackModel behavior = TowerModelBehaviorExt.GetBehavior<AttackModel>(towerModel);
WeaponModel val = ((Il2CppArrayBase<WeaponModel>)(object)behavior.weapons)[0];
EmissionWithOffsetsModel val2 = ((Il2CppObjectBase)val.emission).Cast<EmissionWithOffsetsModel>();
val2.spreadProjectilesAcrossMarkers = false;
val2.projectileCount = 3;
val2.randomRotationCone = 30f;
foreach (AttackModel item in EngineerNailPath.Attacks(towerModel))
{
WeaponModel obj = ((Il2CppArrayBase<WeaponModel>)(object)item.weapons)[0];
obj.Rate /= 3f;
}
foreach (ProjectileModel item2 in EngineerNailPath.Nails(towerModel))
{
item2.pierce *= 2f;
}
}
}
}
namespace MirrorUniversePaths.DartlingGunner
{
public class DartlingCannonPath : PathPlusPlus
{
public override string Tower => TowerType.DartlingGunner;
public override int ExtendVanillaPath => 0;
public override bool UseUpgradedTowerModels => false;
public override string DisplayName => "Cannon";
public override string Description => "Continues shooting upgraded laser projectiles rather than switching to solid beams.";
}
public class Plasma : ModDisplay
{
public override PrefabReference BaseDisplayReference => ((Il2CppArrayBase<WeaponModel>)(object)TowerModelExt.GetAttackModel(Game.instance.model.GetTower(TowerType.DartlingGunner, 3, 0, 0)).weapons)[0].projectile.display;
public override void ModifyDisplayNode(UnityDisplayNode node)
{
UnityDisplayNodeExt.GetRenderer<SpriteRenderer>(node, true).sprite = ((ModContent)this).GetSprite(((ModContent)this).Name, 10f);
}
}
public class PlasmaCannon : UpgradePlusPlus<DartlingCannonPath>
{
public override int Tier => 4;
public override int Cost => 10000;
public override string Description => "Upgrades to Plasma beams which have extra pierce and even more bonus MOAB damage. Can pop Lead Bloons.";
public override string DetailedDescription => "Pierce increased by 5x, projectile scaled 1.25x, can pop leads, bonus MOAB damage increased to +10, laser shock lifespan to 5s";
public override void ApplyUpgrade(TowerModel towerModel, int tier)
{
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
//IL_0085: Unknown result type (might be due to invalid IL or missing references)
//IL_008c: Unknown result type (might be due to invalid IL or missing references)
//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
//IL_00f0: 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_0101: Unknown result type (might be due to invalid IL or missing references)
ProjectileModel projectile = ((Il2CppArrayBase<WeaponModel>)(object)TowerModelExt.GetAttackModel(towerModel).weapons)[0].projectile;
((ModDisplay)ModContent.GetInstance<Plasma>()).Apply(projectile);
projectile.pierce *= 5f;
float radius = projectile.radius;
projectile.radius = radius + 1f;
projectile.scale = 1.25f;
DamageModel damageModel = ProjectileModelExt.GetDamageModel(projectile);
damageModel.immuneBloonProperties = (BloonProperties)(damageModel.immuneBloonProperties & -2);
damageModel.immuneBloonPropertiesOriginal = (BloonProperties)(damageModel.immuneBloonPropertiesOriginal & -2);
ProjectileModelBehaviorExt.GetBehavior<DamageModifierForTagModel>(projectile).damageAddative = 10f;
AddBehaviorToBloonModel behavior = ProjectileModelBehaviorExt.GetBehavior<AddBehaviorToBloonModel>(projectile);
MiscModelExt.ApplyOverlay<PlasmaShock>((ProjectileBehaviorWithOverlayModel)(object)behavior);
behavior.mutationId = "LaserShock3";
behavior.lifespan = 5f;
behavior.lifespanFrames = (int)(behavior.lifespan * 60f);
DamageOverTimeModel behavior2 = AddBehaviorToBloonModelBehaviorExt.GetBehavior<DamageOverTimeModel>(behavior);
behavior2.immuneBloonProperties = (BloonProperties)(behavior2.immuneBloonProperties & -2);
behavior2.immuneBloonPropertiesOriginal = (BloonProperties)(behavior2.immuneBloonPropertiesOriginal & -2);
if (tier == ((UpgradePlusPlus)this).Tier)
{
PlasmaCannonDisplay plasmaCannonDisplay = ModContent.GetInstances<PlasmaCannonDisplay>().FirstOrDefault((PlasmaCannonDisplay d) => d.Bot == ((Il2CppArrayBase<int>)(object)towerModel.tiers)[2] && d.Mid == ((Il2CppArrayBase<int>)(object)towerModel.tiers)[1]);
if (plasmaCannonDisplay != null)
{
((ModDisplay)plasmaCannonDisplay).Apply(towerModel);
}
}
}
}
public class PlasmaCannonDisplay : ModDisplay
{
public override PrefabReference BaseDisplayReference => ((EntityModel)Game.instance.model.GetTower(TowerType.DartlingGunner, 4, Mid, Bot)).display;
public int Mid { get; init; }
public int Bot { get; init; }
public override string Name => $"{((ModContent)this).Name}4{Mid}{Bot}";
public override IEnumerable<ModContent> Load()
{
yield return (ModContent)(object)this;
yield return (ModContent)(object)new PlasmaCannonDisplay
{
Mid = 1
};
yield return (ModContent)(object)new PlasmaCannonDisplay
{
Mid = 2
};
yield return (ModContent)(object)new PlasmaCannonDisplay
{
Bot = 1
};
yield return (ModContent)(object)new PlasmaCannonDisplay
{
Bot = 2
};
}
public override void ModifyDisplayNode(UnityDisplayNode node)
{
//IL_0029: 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)
Renderer meshRenderer = UnityDisplayNodeExt.GetMeshRenderer(node, 0, true);
RendererExt.AdjustHSV(meshRenderer, -80f, -0.46f, 0f, (Color?)new Color(0.80784315f, 0f, 0f), 0.5f);
RendererExt.SetOutlineColor(meshRenderer, new Color(16f / 85f, 0f, 0.35686275f));
}
}
[HarmonyPatch(typeof(CrossTheStreamsSimBehavior), "GetLineStartAndEndPoints")]
internal static class CrossTheStreamsSimBehavior_GetLineStartAndEndPoints
{
[HarmonyPrefix]
internal static bool Prefix(Tower tower)
{
return !((Il2CppArrayBase<string>)(object)tower.towerModel.appliedUpgrades).Contains(ModContent.GetId<PlasmaCannon>());
}
}
public class PlasmaShock : ModBloonOverlay
{
public override string BaseOverlay => "LaserShock";
public override void ModifyDisplayNode(UnityDisplayNode node)
{
SpriteRenderer val = default(SpriteRenderer);
MeshRenderer val2 = default(MeshRenderer);
foreach (Renderer item in (Il2CppArrayBase<Renderer>)(object)node.genericRenderers)
{
if (Il2CppSystemObjectExt.Is<SpriteRenderer>((Il2CppObjectBase)(object)item, ref val))
{
CustomSpriteFrameAnimator component = ((Component)val).gameObject.GetComponent<CustomSpriteFrameAnimator>();
for (int i = 0; i < component.frames.Count; i++)
{
component.frames[i] = ((ModContent)this).GetSprite(((ModContent)this).Name + (i + 1), 10f);
}
}
else if (Il2CppSystemObjectExt.Is<MeshRenderer>((Il2CppObjectBase)(object)item, ref val2))
{
RendererExt.SetMainTexture((Renderer)(object)val2, ((ModContent)this).GetTexture(((ModContent)this).Name));
}
}
}
}
public class Sun : ModDisplay
{
public override PrefabReference BaseDisplayReference => ((Il2CppArrayBase<WeaponModel>)(object)TowerModelExt.GetAttackModel(Game.instance.model.GetTower(TowerType.DartlingGunner, 3, 0, 0)).weapons)[0].projectile.display;
public override void ModifyDisplayNode(UnityDisplayNode node)
{
UnityDisplayNodeExt.GetRenderer<SpriteRenderer>(node, true).sprite = ((ModContent)this).GetSprite(((ModContent)this).Name, 10f);
}
}
public class SunCannon : UpgradePlusPlus<DartlingCannonPath>
{
public override int Tier => 5;
public override int Cost => 50000;
public override string Description => "Now shoots 3 beams at once of pure solar energy, with massive pierce and damage.";
public override string DetailedDescription => "Shoots 3 projectiles at a time, pierce increased a further 10x, scale now 1.5x total, damage is 30 total with no MOAB bonus, shock life span 30s dealing 20 damage per tick.";
public override void ApplyUpgrade(TowerModel towerModel, int tier)
{
//IL_00ab: 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_0128: Unknown result type (might be due to invalid IL or missing references)
//IL_012d: Unknown result type (might be due to invalid IL or missing references)
//IL_013a: 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_014a: Unknown result type (might be due to invalid IL or missing references)
//IL_0157: Expected O, but got Unknown
//IL_015e: Unknown result type (might be due to invalid IL or missing references)
//IL_0163: Unknown result type (might be due to invalid IL or missing references)
//IL_016e: Expected O, but got Unknown
//IL_016f: Unknown result type (might be due to invalid IL or missing references)
//IL_017b: Unknown result type (might be due to invalid IL or missing references)
//IL_0183: Unknown result type (might be due to invalid IL or missing references)
//IL_0190: Expected O, but got Unknown
AttackModel attackModel = TowerModelExt.GetAttackModel(towerModel);
ProjectileModel projectile = ((Il2CppArrayBase<WeaponModel>)(object)attackModel.weapons)[0].projectile;
((ModDisplay)ModContent.GetInstance<Sun>()).Apply(projectile);
((Model)attackModel).GetDescendant<RandomEmissionModel>().count = 3;
attackModel.offsetZ += 5f;
RotateToPointerModel behavior = AttackModelBehaviorExt.GetBehavior<RotateToPointerModel>(attackModel);
behavior.weaponEjectZ += 5f;
projectile.pierce *= 10f;
float radius = projectile.radius;
projectile.radius = radius + 1f;
projectile.scale = 1.5f;
DamageModel damageModel = ProjectileModelExt.GetDamageModel(projectile);
damageModel.damage = 30f;
BloonProperties immuneBloonProperties = (BloonProperties)0;
damageModel.immuneBloonPropertiesOriginal = (BloonProperties)0;
damageModel.immuneBloonProperties = immuneBloonProperties;
ProjectileModelBehaviorExt.RemoveBehavior<DamageModifierForTagModel>(projectile);
AddBehaviorToBloonModel behavior2 = ProjectileModelBehaviorExt.GetBehavior<AddBehaviorToBloonModel>(projectile);
MiscModelExt.ApplyOverlay<SunShock>((ProjectileBehaviorWithOverlayModel)(object)behavior2);
behavior2.lifespan = 30f;
behavior2.lifespanFrames = (int)(behavior2.lifespan * 60f);
AddBehaviorToBloonModelBehaviorExt.GetBehavior<DamageOverTimeModel>(behavior2).damage = 20f;
if (tier == ((UpgradePlusPlus)this).Tier)
{
((EntityModel)towerModel).display = ModContent.CreatePrefabReference<SunCannonLegsDisplay>();
TowerModelBehaviorExt.RemoveBehavior<DisplayModel>(towerModel);
TowerModelBehaviorExt.AddBehavior<DisplayModel>(towerModel, CreateDisplayModelExt.Create(new Args
{
display = ((EntityModel)towerModel).display,
category = (DisplayCategory)4,
layer = -1,
ignoreRotation = true
}));
Args val = new Args();
((ModelArgs<DisplayModel>)val).name = "AttackDisplay";
val.display = ModContent.CreatePrefabReference<SunCannonDisplay>();
val.layer = -1;
val.category = (DisplayCategory)4;
AttackModelBehaviorExt.AddBehavior<DisplayModel>(attackModel, CreateDisplayModelExt.Create(val));
}
}
}
public class SunCannonDisplay : ModDisplay
{
public override PrefabReference BaseDisplayReference => ((EntityModel)Game.instance.model.GetTower(TowerType.DartlingGunner, 4, 0, 0)).display;
public override void ModifyDisplayNode(UnityDisplayNode node)
{
//IL_0039: 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_00b7: Unknown result type (might be due to invalid IL or missing references)
//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
foreach (Renderer meshRenderer in UnityDisplayNodeExt.GetMeshRenderers(node, true))
{
RendererExt.AdjustHSV(meshRenderer, 60f, 0f, 0.2f, (Color?)new Color(0.80784315f, 0f, 0f), 0.3f);
RendererExt.AdjustHSV(meshRenderer, -15f, 0f, 0.2f, (Color?)new Color(28f / 51f, 38f / 51f, 0f), 0.75f);
}
UnityDisplayNodeExt.GetBone(node, "LOD_1").localPosition = new Vector3(0f, 5f, -10f);
UnityDisplayNodeExt.GetBone(node, "GunRig_Dartling").localScale = new Vector3(2f, 1f, 2f);
}
}
public class SunCannonLegsDisplay : ModDisplay
{
public override PrefabReference BaseDisplayReference => ((EntityModel)Game.instance.model.GetTower(TowerType.DartlingGunner, 5, 0, 0)).display;
public override void ModifyDisplayNode(UnityDisplayNode node)
{
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
//IL_0095: Unknown result type (might be due to invalid IL or missing references)
//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
//IL_00c9: 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_00fd: Unknown result type (might be due to invalid IL or missing references)
//IL_0111: Unknown result type (might be due to invalid IL or missing references)
//IL_0131: Unknown result type (might be due to invalid IL or missing references)
//IL_0145: Unknown result type (might be due to invalid IL or missing references)
//IL_0165: Unknown result type (might be due to invalid IL or missing references)
//IL_0179: Unknown result type (might be due to invalid IL or missing references)
foreach (Renderer meshRenderer in UnityDisplayNodeExt.GetMeshRenderers(node, true))
{
RendererExt.ReplaceColor(meshRenderer, new Color(77f / 85f, 0.8980392f, 77f / 85f), new Color(1f, 1f, 0.8235294f), 0.05f);
RendererExt.ReplaceColor(meshRenderer, new Color(0.80784315f, 41f / 51f, 0.80784315f), new Color(0.99215686f, 1f, 33f / 85f), 0.05f);
RendererExt.ReplaceColor(meshRenderer, new Color(0.69803923f, 0.69803923f, 0.69803923f), new Color(0.96862745f, 72f / 85f, 0.3529412f), 0.05f);
RendererExt.ReplaceColor(meshRenderer, new Color(29f / 51f, 0.57254905f, 0.56078434f), new Color(0.9372549f, 63f / 85f, 7f / 51f), 0.05f);
RendererExt.ReplaceColor(meshRenderer, new Color(41f / 85f, 41f / 85f, 41f / 85f), new Color(63f / 85f, 7f / 15f, 0f), 0.05f);
RendererExt.ReplaceColor(meshRenderer, new Color(0.41960785f, 0.41960785f, 0.41960785f), new Color(63f / 85f, 0.38039216f, 0f), 0.05f);
RendererExt.ReplaceColor(meshRenderer, new Color(31f / 85f, 31f / 85f, 31f / 85f), new Color(52f / 85f, 0.3019608f, 0f), 0.05f);
}
}
}
public class SunShock : ModBloonOverlay
{
public override string BaseOverlay => "LaserShock";
public override void ModifyDisplayNode(UnityDisplayNode node)
{
SpriteRenderer val = default(SpriteRenderer);
MeshRenderer val2 = default(MeshRenderer);
foreach (Renderer item in (Il2CppArrayBase<Renderer>)(object)node.genericRenderers)
{
if (Il2CppSystemObjectExt.Is<SpriteRenderer>((Il2CppObjectBase)(object)item, ref val))
{
CustomSpriteFrameAnimator component = ((Component)val).gameObject.GetComponent<CustomSpriteFrameAnimator>();
for (int i = 0; i < component.frames.Count; i++)
{
component.frames[i] = ((ModContent)this).GetSprite(((ModContent)this).Name + (i + 1), 10f);
}
}
else if (Il2CppSystemObjectExt.Is<MeshRenderer>((Il2CppObjectBase)(object)item, ref val2))
{
RendererExt.SetMainTexture((Renderer)(object)val2, ((ModContent)this).GetTexture(((ModContent)this).Name));
}
}
}
}
}