Decompiled source of StarshipEnterprise v1.0.12

StarshipEnterprise.dll

Decompiled 4 hours ago
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.Api.ModOptions;
using BTD_Mod_Helper.Api.Towers;
using BTD_Mod_Helper.Extensions;
using HarmonyLib;
using Il2Cpp;
using Il2CppAssets.Scripts.Data;
using Il2CppAssets.Scripts.Models;
using Il2CppAssets.Scripts.Models.Bloons;
using Il2CppAssets.Scripts.Models.Effects;
using Il2CppAssets.Scripts.Models.Entities;
using Il2CppAssets.Scripts.Models.GenericBehaviors;
using Il2CppAssets.Scripts.Models.TowerSets;
using Il2CppAssets.Scripts.Models.Towers;
using Il2CppAssets.Scripts.Models.Towers.Behaviors;
using Il2CppAssets.Scripts.Models.Towers.Behaviors.Abilities;
using Il2CppAssets.Scripts.Models.Towers.Behaviors.Abilities.Behaviors;
using Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack;
using Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.Behaviors;
using Il2CppAssets.Scripts.Models.Towers.Behaviors.Emissions;
using Il2CppAssets.Scripts.Models.Towers.Behaviors.Emissions.Behaviors;
using Il2CppAssets.Scripts.Models.Towers.Filters;
using Il2CppAssets.Scripts.Models.Towers.Projectiles;
using Il2CppAssets.Scripts.Models.Towers.Projectiles.Behaviors;
using Il2CppAssets.Scripts.Models.Towers.TowerFilters;
using Il2CppAssets.Scripts.Models.Towers.Weapons;
using Il2CppAssets.Scripts.Models.Towers.Weapons.Behaviors;
using Il2CppAssets.Scripts.Simulation.Bloons;
using Il2CppAssets.Scripts.Simulation.Input;
using Il2CppAssets.Scripts.Simulation.Objects;
using Il2CppAssets.Scripts.Simulation.SMath;
using Il2CppAssets.Scripts.Simulation.Towers.Behaviors;
using Il2CppAssets.Scripts.Simulation.Towers.Behaviors.Abilities.Behaviors;
using Il2CppAssets.Scripts.Simulation.Towers.Projectiles.Behaviors;
using Il2CppAssets.Scripts.Unity;
using Il2CppAssets.Scripts.Unity.Display;
using Il2CppAssets.Scripts.Unity.UI_New.InGame;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppNinjaKiwi.Common.ResourceUtils;
using MelonLoader;
using Microsoft.CodeAnalysis;
using PathsPlusPlus;
using StarshipEnterprise;
using StarshipEnterprise.Displays;
using StarshipEnterprise.Displays.Ships;
using StarshipEnterprise.Displays.Weapons;
using StarshipEnterprise.Upgrades.Cannons;
using StarshipEnterprise.Upgrades.Phasers;
using StarshipEnterprise.Upgrades.Refit;
using StarshipEnterprise.Upgrades.Torpedoes;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(StarshipEnterpriseMod), "Starship Enterprise", "1.0.12", "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("StarshipEnterprise")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+018108fdd8807448032c41a5f6cf596a0b74fccb")]
[assembly: AssemblyProduct("StarshipEnterprise")]
[assembly: AssemblyTitle("StarshipEnterprise")]
[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 StarshipEnterprise
{
	public static class ModHelperData
	{
		public const string WorksOnVersion = "55.0";

		public const string Version = "1.0.12";

		public const string Name = "Starship Enterprise";

		public const string Description = "Adds in the Starship Enterprise to BloonsTD6 with 7 Upgrade Paths that have 6 Upgrades each.\n\nThe main 3 paths are Enterprise's weapons: Phasers, Photon Torpedoes, and Phase Cannons.\n\nThe next 3 paths are the Career Paths, letting you specialize in Tactical, Science or Engineering, with standard X/2/0 restrictions.\n\nThe final path is the refit model, taking the Enterprise from Constitution Class all the way to Odyssey Class, and always available for upgrading.\n\nRequires Paths++";

		public const string RepoOwner = "doombubbles";

		public const string PrevRepoName = "starship-enterprise";

		public const string RepoName = "StarshipEnterprise";

		public const string Icon = "StarshipEnterprise-Icon.png";

		public const string Dependencies = "doombubbles/paths-plus-plus";
	}
	public class Starfleet : ModTowerSet
	{
		public override int GetTowerStartIndex(List<TowerDetailsModel> towerSet)
		{
			return 0;
		}
	}
	public class StarshipEnterprise : ModTower<Starfleet>
	{
		public override string BaseTower => TowerType.MonkeyAce + "-004";

		public override int Cost => 1701;

		public override int TopPathUpgrades => 5;

		public override int MiddlePathUpgrades => 5;

		public override int BottomPathUpgrades => 5;

		public override int ShopTowerCount => 1;

		public override string DisplayName => "USS Enterprise";

		public override string Description => "Equipped with Phasers, Photon Torpedoes, and Phase Cannons. Upgrade weapons, refit the ship, and choose your career path. Always costs $1,701.";

		public override ModSettingHotkey Hotkey => StarshipEnterpriseMod.EnterpriseHotkey;

		public static Vector3 EjectOffset => new Vector3(0f, 20f, 5f);

		public static float Speed => 60f;

		public override bool IsValidCrosspath(params int[] tiers)
		{
			if (!((ModTower)this).IsValidCrosspath(tiers))
			{
				return ModHelper.HasMod("UltimateCrosspathing");
			}
			return true;
		}

		public override void ModifyBaseTowerModel(TowerModel towerModel)
		{
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Expected O, but got Unknown
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fd: Expected O, but got Unknown
			//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_030f: Unknown result type (might be due to invalid IL or missing references)
			//IL_031c: Unknown result type (might be due to invalid IL or missing references)
			//IL_032e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0339: Unknown result type (might be due to invalid IL or missing references)
			//IL_0345: Expected O, but got Unknown
			//IL_039f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b5: Expected O, but got Unknown
			//IL_03df: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f7: Expected O, but got Unknown
			//IL_0482: Unknown result type (might be due to invalid IL or missing references)
			//IL_0489: Unknown result type (might be due to invalid IL or missing references)
			//IL_052d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0548: Unknown result type (might be due to invalid IL or missing references)
			//IL_054f: Expected O, but got Unknown
			//IL_0561: Unknown result type (might be due to invalid IL or missing references)
			//IL_0566: Unknown result type (might be due to invalid IL or missing references)
			//IL_0572: Expected O, but got Unknown
			//IL_05b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_05bc: Unknown result type (might be due to invalid IL or missing references)
			AirUnitModel obj = ModelExt.SetName<AirUnitModel>(TowerModelBehaviorExt.GetBehavior<AirUnitModel>(towerModel), ((ModContent)this).Name);
			obj.display = ModContent.CreatePrefabReference<ConstitutionDisplay>();
			PathMovementModel behavior = AirUnitModelBehaviorExt.GetBehavior<PathMovementModel>(obj);
			behavior.speed = Speed;
			behavior.takeOffTime = 0f;
			behavior.takeOffAnimTime = 0f;
			behavior.bankRotation = 30f;
			AttackAirUnitModel val = TowerModelBehaviorExt.GetBehaviors<AttackAirUnitModel>(towerModel).MinBy((AttackAirUnitModel model) => ((Model)model).name.Length);
			ModelExt.RemoveChildDependants<Model>((Model)(object)val, (IEnumerable<Model>)((AttackModel)val).behaviors);
			((AttackModel)val).behaviors = Il2CppReferenceArray<Model>.op_Implicit((Model[])(object)new Model[3]
			{
				((Il2CppArrayBase<Model>)(object)((AttackModel)val).behaviors)[3],
				((Il2CppArrayBase<Model>)(object)((AttackModel)val).behaviors)[1],
				((Il2CppArrayBase<Model>)(object)((AttackModel)val).behaviors)[2]
			});
			ModelExt.AddChildDependants<Model>((Model)(object)val, (IEnumerable<Model>)((AttackModel)val).behaviors);
			foreach (FigureEightPatternModel behavior3 in AttackModelBehaviorExt.GetBehaviors<FigureEightPatternModel>((AttackModel)(object)val))
			{
				behavior3.useTowerPosition = false;
			}
			CenterElipsePatternModel behavior2 = AttackModelBehaviorExt.GetBehavior<CenterElipsePatternModel>((AttackModel)(object)val);
			behavior2.canSelectPoint = false;
			float widthRadius = (behavior2.heightRadius = 80f);
			behavior2.widthRadius = widthRadius;
			towerModel.UpdateTargetProviders();
			TowerModelExt.SetDisplay<StarfleetBase>(towerModel);
			TowerModelBehaviorExt.RemoveBehavior<RectangleFootprintModel>(towerModel);
			TowerModelBehaviorExt.AddBehavior<CircleFootprintModel>(towerModel, CreateCircleFootprintModelExt.Create(new Args
			{
				radius = 12f
			}));
			TowerModel towerFromId = Game.instance.model.GetTowerFromId(TowerType.DartMonkey);
			TowerModelBehaviorExt.RemoveBehaviors<CreateSoundOnTowerPlaceModel>(towerModel);
			TowerModelBehaviorExt.AddBehavior<CreateSoundOnTowerPlaceModel>(towerModel, ModelExt.Duplicate<CreateSoundOnTowerPlaceModel>(TowerModelBehaviorExt.GetBehavior<CreateSoundOnTowerPlaceModel>(towerFromId), ((Model)towerModel).name));
			AttackModelExt.RemoveWeapon((AttackModel)(object)val, ((Il2CppArrayBase<WeaponModel>)(object)((AttackModel)val).weapons)[0]);
			TowerModelBehaviorExt.RemoveBehavior<AttackModel>(towerModel, TowerModelExt.GetAttackModel(towerModel, "Spectre"));
			AttackModel val2 = ModelExt.Duplicate<AttackModel>(TowerModelExt.GetAttackModel(((Model)Game.instance.model.GetHeroWithNameAndLevel(TowerType.Adora, 10, false)).GetDescendant<AbilityCreateTowerModel>().towerModel), "Phaser");
			WeaponModel obj2 = ModelExt.SetName<WeaponModel>(((Model)val2).GetChild<WeaponModel>(), "Phaser");
			ProjectileModel val3 = ModelExt.SetName<ProjectileModel>(obj2.projectile, "Phaser");
			DamageModel damageModel = ProjectileModelExt.GetDamageModel(val3);
			LineProjectileEmissionModel child = ((Model)obj2).GetChild<LineProjectileEmissionModel>();
			AttackModelBehaviorExt.RemoveBehaviors<CirclePatternModel>(val2);
			val2.targetProvider = (TargetSupplierModel)(object)CreateTargetFirstAirUnitModelExt.Create();
			AttackModelBehaviorExt.AddBehavior<TargetSupplierModel>(val2, val2.targetProvider);
			val2.offsetY = 0f;
			WeaponModelBehaviorExt.AddBehavior<FireFromAirUnitModel>(obj2, CreateFireFromAirUnitModelExt.Create());
			WeaponModelExt.SetEject(obj2, EjectOffset, false, false, false);
			obj2.Rate = 1f;
			child.dontUseTowerPosition = true;
			ModelExt.SetName<AssetPathModel>(child.displayPath, "Phaser").assetPath = ModContent.CreatePrefabReference<PhaserBeam>();
			child.effectAtEndModel.assetId = ModContent.CreatePrefabReference<PhaserParticles>();
			child.displayLifetime = 0.2f;
			ProjectileModelBehaviorExt.RemoveBehaviors<DamageModifierForTagModel>(val3);
			damageModel.damage = 1f;
			BloonProperties immuneBloonPropertiesOriginal = (BloonProperties)8;
			damageModel.immuneBloonProperties = (BloonProperties)8;
			damageModel.immuneBloonPropertiesOriginal = immuneBloonPropertiesOriginal;
			TowerModelBehaviorExt.AddBehavior<AttackModel>(towerModel, val2);
			AttackModel val4 = ModelExt.Duplicate<AttackModel>(TowerModelExt.GetAttackModel(((Model)Game.instance.model.GetHeroWithNameAndLevel(TowerType.Etienne, 10, false)).GetDescendant<UCAVModel>().ucavTowerModel));
			Args val5 = new Args();
			((ModelArgs<AttackModel>)val5).name = "PhotonTorpedo";
			val5.weapons = Il2CppArrayBase<WeaponModel>.op_Implicit((Il2CppArrayBase<WeaponModel>)(object)val4.weapons);
			val5.range = val4.range;
			val5.behaviors = Il2CppArrayBase<Model>.op_Implicit((Il2CppArrayBase<Model>)(object)val4.behaviors);
			val5.targetProvider = (TargetSupplierModel)(object)CreateTargetStrongAirUnitModelExt.Create();
			val5.attackThroughWalls = true;
			AttackModel val6 = CreateAttackModelExt.Create(val5);
			WeaponModel val7 = ModelExt.SetName<WeaponModel>(((Model)val6).GetChild<WeaponModel>(), "PhotonTorpedo");
			ProjectileModel val8 = ModelExt.SetName<ProjectileModel>(val7.projectile, "PhotonTorpedo");
			ModelExt.SetName<ProjectileModel>(((Model)val8).GetDescendant<ProjectileModel>(), "PhotonTorpedoExplosion");
			DamageModel descendant = ((Model)val8).GetDescendant<DamageModel>();
			AttackModelBehaviorExt.RemoveBehaviors<TargetSupplierModel>(val6);
			AttackModelBehaviorExt.AddBehavior<TargetSupplierModel>(val6, val6.targetProvider);
			WeaponModelExt.SetEject(val7, EjectOffset, false, false, false);
			Args val9 = new Args();
			((ModelArgs<RandomArcEmissionModel>)(object)val9).name = "PhotonTorpedo";
			val9.count = 1;
			val9.randomAngle = 90f;
			val9.behaviors = (EmissionBehaviorModel[])(object)new EmissionBehaviorModel[1] { (EmissionBehaviorModel)CreateEmissionRotationOffBloonDirectionModelExt.Create(new Args
			{
				useAirUnitPosition = true,
				dontSetAfterEmit = true
			}) };
			WeaponModelExt.SetEmission(val7, (EmissionModel)(object)CreateRandomArcEmissionModelExt.Create(val9));
			val7.Rate = 2f;
			ProjectileModelBehaviorExt.GetBehavior<TrackTargetModel>(val8).TurnRate = 180f;
			EffectModel effectModel = ProjectileModelBehaviorExt.GetBehavior<CreateEffectOnContactModel>(val8).effectModel;
			MiscModelExt.ApplyDisplay<PhotonTorpedoExplosion>(effectModel);
			effectModel.lifespan = 0.5f;
			ProjectileModelBehaviorExt.GetBehavior<TravelStraitModel>(val8).Lifespan = 5f;
			ProjectileModelBehaviorExt.GetBehavior<TravelStraitModel>(val8).Speed = 100f;
			ProjectileModelExt.SetDisplay(val8, "187bc7112ccbf6445afc2ef9173b4568");
			descendant.damage = 2f;
			immuneBloonPropertiesOriginal = (BloonProperties)8;
			descendant.immuneBloonProperties = (BloonProperties)8;
			descendant.immuneBloonPropertiesOriginal = immuneBloonPropertiesOriginal;
			TowerModelBehaviorExt.AddBehavior<AttackModel>(towerModel, val6);
			AttackModel val10 = ModelExt.Duplicate<AttackModel>(TowerModelExt.GetAttackModel(((Model)Game.instance.model.GetTower(TowerType.MonkeyBuccaneer, 4, 0, 0)).GetDescendant<CreateTowerModel>().tower), "PhaseCannon");
			WeaponModel val11 = ModelExt.SetName<WeaponModel>(((Model)val10).GetChild<WeaponModel>(), "PhaseCannon");
			ProjectileModel val12 = ModelExt.SetName<ProjectileModel>(val11.projectile, "PhaseCannon");
			DamageModel damageModel2 = ProjectileModelExt.GetDamageModel(val12);
			((Model)val10).GetDescendant<FilterTargetAngleModel>().fieldOfView = 90f;
			AttackModelBehaviorExt.RemoveBehaviors<TargetSupplierModel>(val10);
			val10.targetProvider = (TargetSupplierModel)(object)CreateTargetFirstAirUnitModelExt.Create();
			AttackModelBehaviorExt.AddBehavior<TargetSupplierModel>(val10, val10.targetProvider);
			WeaponModelExt.SetEject(val11, EjectOffset, false, false, false);
			val11.Rate = 0.5f;
			Args val13 = new Args();
			val13.count = 1;
			val13.behaviors = (EmissionBehaviorModel[])(object)new EmissionBehaviorModel[1] { (EmissionBehaviorModel)CreateEmissionRotationOffBloonDirectionModelExt.Create(new Args
			{
				useAirUnitPosition = true
			}) };
			WeaponModelExt.SetEmission(val11, (EmissionModel)(object)CreateParallelEmissionModelExt.Create(val13));
			WeaponModelBehaviorExt.RemoveBehaviors<ThrowMarkerOffsetModel>(val11);
			val12.pierce = 5f;
			val12.scale = 0.5f;
			ProjectileModelExt.SetDisplay(val12, "f54fbbae11116a04dafbcde24ff646d8");
			immuneBloonPropertiesOriginal = (BloonProperties)8;
			damageModel2.immuneBloonProperties = (BloonProperties)8;
			damageModel2.immuneBloonPropertiesOriginal = immuneBloonPropertiesOriginal;
			TowerModelBehaviorExt.AddBehavior<AttackModel>(towerModel, val10);
			Il2CppGenericIEnumerable.ForEach<FilterInvisibleModel>(((Model)towerModel).GetDescendants<FilterInvisibleModel>(), (Action<FilterInvisibleModel>)delegate(FilterInvisibleModel model)
			{
				model.isActive = true;
			});
		}
	}
	public class StarshipEnterpriseMod : BloonsTD6Mod
	{
		[HarmonyPatch(typeof(TowerInventory), "GetTowerCost")]
		internal static class TowerInventory_GetTowerCost
		{
			[HarmonyPostfix]
			private static void Postfix(TowerModel tower, ref float __result)
			{
				if (((EntityModel)tower).baseId == ModContent.TowerID<StarshipEnterprise>(0, 0, 0) && __result > 0f)
				{
					__result = 1701f;
				}
			}
		}

		[HarmonyPatch(typeof(TowerInventory), "IsFreeTowerAvailable")]
		internal static class TowerInventory_IsFreeTowerAvailable
		{
			[HarmonyPostfix]
			private static void Postfix(TowerModel towerModel, bool __result)
			{
				dontRoundNextValue = ((EntityModel)towerModel).baseId == ModContent.TowerID<StarshipEnterprise>(0, 0, 0) && !__result;
			}
		}

		[HarmonyPatch(typeof(Math), "RoundToNearestInt")]
		internal static class Math_RoundToNearestInt
		{
			[HarmonyPrefix]
			private static bool Prefix(ref int __result, int nearestIntValue)
			{
				bool result = true;
				if (dontRoundNextValue && nearestIntValue == 5)
				{
					__result = 1701;
					result = false;
				}
				dontRoundNextValue = false;
				return result;
			}
		}

		public static readonly ModSettingHotkey EnterpriseHotkey = new ModSettingHotkey((KeyCode)101, (HotkeyModifier)1);

		public static readonly ModSettingDouble EnterpriseDisplayScale;

		private static bool dontRoundNextValue;

		public override void OnFixedUpdate()
		{
			dontRoundNextValue = false;
		}

		public override void OnNewGameModel(GameModel result)
		{
			foreach (TowerModel item in Il2CppGenericIEnumerable.AsIEnumerable<TowerModel>(result.GetTowersWithBaseId(ModContent.TowerID<StarshipEnterprise>(0, 0, 0), false)))
			{
				item.cost = 1701f;
			}
		}

		static StarshipEnterpriseMod()
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			//IL_0016: 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_0022: Expected O, but got Unknown
			//IL_0022: 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_003e: Expected O, but got Unknown
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			//IL_0050: Expected O, but got Unknown
			ModSettingDouble val = new ModSettingDouble(1.0);
			((ModSettingNumber<double>)val).slider = true;
			val.stepSize = 0.01f;
			((ModSettingNumber<double>)val).min = 0.5;
			((ModSettingNumber<double>)val).max = 1.0;
			EnterpriseDisplayScale = val;
		}
	}
}
namespace StarshipEnterprise.Upgrades
{
	public abstract class CareerPath : PathPlusPlus<StarshipEnterprise>
	{
		public override bool ValidTiers(int[] tiers)
		{
			return PathPlusPlus.DefaultValidTiers(tiers.Skip(3).Take(3).ToArray());
		}
	}
	public abstract class CareerPathUpgrade<T> : UpgradePlusPlus<T> where T : CareerPath
	{
		public override string Description => ((ModContent)((UpgradePlusPlus)this).Path).Name + " Officer - <b>" + Title + "</b>\n";

		private string Title => ((UpgradePlusPlus)this).Tier switch
		{
			1 => "Ensign", 
			2 => "Lieutenant", 
			3 => "Lt. Commander", 
			4 => "Commander", 
			5 => "Captain", 
			6 => "Admiral", 
			_ => "Cadet", 
		};

		public override string Container => ((ModContent)((UpgradePlusPlus)this).Path).Name + "UpgradeContainer";
	}
}
namespace StarshipEnterprise.Upgrades.Torpedoes
{
	public class ChronitonTorpedoes : ModUpgrade<StarshipEnterprise>
	{
		public override int Path => 1;

		public override int Tier => 4;

		public override int Cost => 12345;

		public override string Description => "Imbue Torpedoes with Chroniton particles, giving them more pierce and making them greatly slow hit Bloons.";

		public override string Icon => ((ModContent)this).Name;

		public override void Register()
		{
			((ModUpgrade)this).Register();
			GameData.Instance.bloonMutatorData.badImmunityIds = Il2CppStringArrayExt.AddTo(GameData.Instance.bloonMutatorData.badImmunityIds, ((ModContent)this).Name);
		}

		public override void ApplyUpgrade(TowerModel towerModel)
		{
			ArrayExt.ForEach<ProjectileModel>(ModelExt.FindDescendants<ProjectileModel>((Model)(object)towerModel, "PhotonTorpedo"), (Action<ProjectileModel>)delegate(ProjectileModel proj)
			{
				//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_0023: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Unknown result type (might be due to invalid IL or missing references)
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0045: Unknown result type (might be due to invalid IL or missing references)
				//IL_0051: Expected O, but got Unknown
				//IL_0057: Unknown result type (might be due to invalid IL or missing references)
				//IL_005c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0067: Expected O, but got Unknown
				//IL_0067: Unknown result type (might be due to invalid IL or missing references)
				//IL_0072: Unknown result type (might be due to invalid IL or missing references)
				//IL_007e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0089: Unknown result type (might be due to invalid IL or missing references)
				//IL_0099: Expected O, but got Unknown
				//IL_009f: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00af: Expected O, but got Unknown
				//IL_00af: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c6: 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_00e1: Expected O, but got Unknown
				//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f7: Expected O, but got Unknown
				//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
				//IL_0102: Unknown result type (might be due to invalid IL or missing references)
				//IL_010e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0119: Unknown result type (might be due to invalid IL or missing references)
				//IL_0129: Expected O, but got Unknown
				//IL_012f: 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_013f: Expected O, but got Unknown
				//IL_013f: 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_0156: Unknown result type (might be due to invalid IL or missing references)
				//IL_0161: Unknown result type (might be due to invalid IL or missing references)
				//IL_0171: Expected O, but got Unknown
				proj.pierce *= 1.5f;
				ProjectileModelBehaviorExt.AddBehavior<SlowModel>(proj, CreateSlowModelExt.Create(new Args
				{
					multiplier = 0.25f,
					lifespan = 5f,
					mutationId = ((ModContent)this).Name,
					layers = 9999,
					isUnique = true
				}));
				Args val = new Args();
				((ModelArgs<SlowModifierForTagModel>)val).name = "Moab";
				val.tag = "Moab";
				val.slowId = ((ModContent)this).Name;
				val.slowMultiplier = 1f;
				val.lifespanOverride = 0.5f;
				ProjectileModelBehaviorExt.AddBehavior<SlowModifierForTagModel>(proj, CreateSlowModifierForTagModelExt.Create(val));
				Args val2 = new Args();
				((ModelArgs<SlowModifierForTagModel>)val2).name = "Bfb";
				val2.tag = "Bfb";
				val2.slowId = ((ModContent)this).Name;
				val2.slowMultiplier = 1f;
				val2.lifespanOverride = 0.3f;
				ProjectileModelBehaviorExt.AddBehavior<SlowModifierForTagModel>(proj, CreateSlowModifierForTagModelExt.Create(val2));
				Args val3 = new Args();
				((ModelArgs<SlowModifierForTagModel>)val3).name = "Ddt";
				val3.tag = "Ddt";
				val3.slowId = ((ModContent)this).Name;
				val3.slowMultiplier = 1f;
				val3.lifespanOverride = 0.3f;
				ProjectileModelBehaviorExt.AddBehavior<SlowModifierForTagModel>(proj, CreateSlowModifierForTagModelExt.Create(val3));
				Args val4 = new Args();
				((ModelArgs<SlowModifierForTagModel>)val4).name = "Zomg";
				val4.tag = "Zomg";
				val4.slowId = ((ModContent)this).Name;
				val4.slowMultiplier = 1f;
				val4.lifespanOverride = 0.1f;
				ProjectileModelBehaviorExt.AddBehavior<SlowModifierForTagModel>(proj, CreateSlowModifierForTagModelExt.Create(val4));
				proj.UpdateCollisionPassList();
			});
		}
	}
	public class FasterArming : ModUpgrade<StarshipEnterprise>
	{
		public override int Path => 1;

		public override int Tier => 1;

		public override int Cost => 800;

		public override string Description => "Torpedo take less time to reload time.";

		public override string Icon => ((ModContent)this).Name;

		public override void ApplyUpgrade(TowerModel towerModel)
		{
			WeaponModel obj = ModelExt.FindDescendant<WeaponModel>((Model)(object)towerModel, "PhotonTorpedo");
			obj.Rate *= 0.8f;
		}
	}
	public class FullSpread : ModUpgrade<StarshipEnterprise>
	{
		public override int Path => 1;

		public override int Tier => 3;

		public override int Cost => 2300;

		public override string Description => "Torpedoes now fire in bursts of 3 in a wide arc.";

		public override string Icon => ((ModContent)this).Name;

		public override void ApplyUpgrade(TowerModel towerModel)
		{
			RandomArcEmissionModel obj = ModelExt.FindDescendant<RandomArcEmissionModel>((Model)(object)towerModel, "PhotonTorpedo");
			((ArcEmissionModel)obj).angle = 90f;
			obj.randomAngle = 15f;
			((ArcEmissionModel)obj).Count = 3;
		}
	}
	public class HighYieldWarheads : ModUpgrade<StarshipEnterprise>
	{
		public override int Path => 1;

		public override int Tier => 2;

		public override int Cost => 1000;

		public override string Description => "Torpedoes deal increased damage, and bonus damage to their primary target.";

		public override string Icon => ((ModContent)this).Name;

		public override void ApplyUpgrade(TowerModel towerModel)
		{
			ProjectileModel obj = ModelExt.FindDescendant<ProjectileModel>((Model)(object)towerModel, "PhotonTorpedo");
			Il2CppGenericIEnumerable.ForEach<DamageModel>(((Model)obj).GetDescendants<DamageModel>(), (Action<DamageModel>)delegate(DamageModel model)
			{
				model.damage *= 2f;
			});
			ProjectileModel descendant = ((Model)obj).GetDescendant<ProjectileModel>();
			ProjectileModelBehaviorExt.AddBehavior<DamageModel>(obj, ModelExt.Duplicate<DamageModel>(ProjectileModelBehaviorExt.GetBehavior<DamageModel>(descendant)));
		}
	}
	public class PhotonTorpedoPath : PathPlusPlus<StarshipEnterprise>
	{
		public override int UpgradeCount => 6;

		public override int ExtendVanillaPath => 1;

		public override bool ValidTiers(int[] tiers)
		{
			return PathPlusPlus.DefaultValidTiers(tiers.Take(3).ToArray());
		}
	}
	public class QuantumTorpedoes : ModUpgrade<StarshipEnterprise>
	{
		public override int Path => 1;

		public override int Tier => 5;

		public override int Cost => 52000;

		public override string Description => "Upgrade Photon Torpedoes to powerful Quantum Torpedoes. Explosion damage, radius and pierce increased.";

		public override string Icon => ((ModContent)this).Name;

		public override void ApplyUpgrade(TowerModel towerModel)
		{
			ArrayExt.ForEach<WeaponModel>(ModelExt.FindDescendants<WeaponModel>((Model)(object)towerModel, "PhotonTorpedo"), (Action<WeaponModel>)delegate(WeaponModel weapon)
			{
				ProjectileModel projectile = weapon.projectile;
				ProjectileModelExt.ApplyDisplay<QuantumTorpedo>(projectile);
				ProjectileModel descendant = ((Model)projectile).GetDescendant<ProjectileModel>();
				Il2CppGenericIEnumerable.ForEach<DamageModel>(((Model)projectile).GetDescendants<DamageModel>(), (Action<DamageModel>)delegate(DamageModel model)
				{
					model.damage *= 5f;
				});
				descendant.radius *= 1.5f;
				descendant.pierce *= 2f;
				MiscModelExt.ApplyDisplay<QuantumTorpedoExplosion>(ProjectileModelBehaviorExt.GetBehavior<CreateEffectOnContactModel>(projectile).effectModel);
			});
		}
	}
	public class TransphasicTorpedoes : UpgradePlusPlus<PhotonTorpedoPath>
	{
		public override int Tier => 6;

		public override int Cost => 275000;

		public override string Description => "Torpedoes now phase through Bloon layers, dealing massive damage to all layers at the same time.";

		public override string Container => UpgradePlusPlus.UpgradeContainerPlatinum;

		public override string Icon => ((ModContent)this).Name;

		public override void ApplyUpgrade(TowerModel towerModel)
		{
			ArrayExt.ForEach<ProjectileModel>(ModelExt.FindDescendants<ProjectileModel>((Model)(object)towerModel, "PhotonTorpedo"), (Action<ProjectileModel>)delegate(ProjectileModel model)
			{
				//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_007b: Expected O, but got Unknown
				//IL_007b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0082: Unknown result type (might be due to invalid IL or missing references)
				//IL_008f: Unknown result type (might be due to invalid IL or missing references)
				//IL_009b: Expected O, but got Unknown
				string text = default(string);
				List<int> list = default(List<int>);
				foreach (IGrouping<string, int> item in from bloonModel in (IEnumerable<BloonModel>)Game.instance.model.bloons
					group bloonModel.layerNumber by bloonModel.baseId)
				{
					IEnumerableExt.Deconstruct<string, int>(item, ref text, ref list);
					string text2 = text;
					List<int> source = list;
					Args val = new Args();
					((ModelArgs<DamageModifierForBloonTypeModel>)val).name = text2;
					val.bloonId = text2;
					val.damageMultiplier = source.First();
					val.includeChildren = true;
					ProjectileModelBehaviorExt.AddBehavior<DamageModifierForBloonTypeModel>(model, CreateDamageModifierForBloonTypeModelExt.Create(val));
				}
				ProjectileModelBehaviorExt.AddBehavior<StripChildrenModel>(model, CreateStripChildrenModelExt.Create());
				model.hasDamageModifiers = true;
			});
		}
	}
}
namespace StarshipEnterprise.Upgrades.Tactical
{
	public class AttackPatternAlpha : CareerPathUpgrade<Tactical>
	{
		public override int Cost => 1000;

		public override int Tier => 1;

		public override string Description => base.Description + "Increase the attack speed of all of Enterprise's weapons.";

		public override void ApplyUpgrade(TowerModel towerModel)
		{
			Il2CppGenericIEnumerable.ForEach<WeaponModel>(((Model)towerModel).GetDescendants<WeaponModel>(), (Action<WeaponModel>)delegate(WeaponModel weapon)
			{
				weapon.Rate *= 0.8f;
			});
		}
	}
	public class AttackPatternOmega : CareerPathUpgrade<Tactical>
	{
		public override int Cost => 240000;

		public override int Tier => 6;

		public override string Description => base.Description + "Enterprise's attacks do bonus damage based on maximum HP of Bloons.";

		public override void ApplyUpgrade(TowerModel towerModel)
		{
			Il2CppGenericIEnumerable.ForEach<ProjectileModel>(((Model)towerModel).GetDescendants<ProjectileModel>(), (Action<ProjectileModel>)delegate(ProjectileModel projectile)
			{
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0026: Expected O, but got Unknown
				//IL_0030: Expected O, but got Unknown
				if (ProjectileModelBehaviorExt.HasBehavior<DamageModel>(projectile))
				{
					ProjectileModelBehaviorExt.AddBehavior<DamagePercentOfMaxModel>(projectile, CreateDamagePercentOfMaxModelExt.Create(new Args
					{
						percent = 0.005f,
						tags = Il2CppArrayBase<string>.op_Implicit((Il2CppArrayBase<string>)new Il2CppStringArray(0L))
					}));
				}
			});
		}
	}
	public class DivertPowerWeapons : CareerPathUpgrade<Tactical>
	{
		public class BuffIconDivertPowerWeapons : ModBuffIcon
		{
		}

		[HarmonyPatch(typeof(RateMutator), "Mutate")]
		internal static class RateMutator_Mutate
		{
			[HarmonyPostfix]
			private static void Postfix(RateMutator __instance, Model model)
			{
				if (!(((BehaviorMutator)__instance).id != "DivertPowerWeapons"))
				{
					Il2CppGenericIEnumerable.ForEach<PathMovementModel>(model.GetDescendants<PathMovementModel>(), (Action<PathMovementModel>)delegate(PathMovementModel movementModel)
					{
						movementModel.speed /= 10f;
					});
					Il2CppGenericIEnumerable.ForEach<FighterMovementModel>(model.GetDescendants<FighterMovementModel>(), (Action<FighterMovementModel>)delegate(FighterMovementModel movementModel)
					{
						movementModel.maxSpeed /= 10f;
					});
				}
			}
		}

		public override int Cost => 10000;

		public override int Tier => 4;

		public override string DisplayName => "Divert Power: Weapons";

		public override string Description => base.Description + "Ability: Divert power from all non essential systems and give it to Weapons.";

		public override bool Ability => true;

		public override void ApplyUpgrade(TowerModel towerModel)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Expected O, but got Unknown
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Expected O, but got Unknown
			//IL_012d: Expected O, but got Unknown
			//IL_0137: Expected O, but got Unknown
			BuffIconDivertPowerWeapons instance = ModContent.GetInstance<BuffIconDivertPowerWeapons>();
			Args val = new Args();
			((ModelArgs<AbilityModel>)(object)val).name = ((ModContent)this).Name;
			val.displayName = ((NamedModContent)this).DisplayName;
			val.description = ((NamedModContent)this).Description;
			val.animation = -1;
			val.icon = ((UpgradePlusPlus)this).IconReference;
			val.Cooldown = 60f;
			Model[] array = new Model[2];
			Args val2 = new Args();
			((ModelArgs<ActivateRateSupportZoneModel>)(object)val2).name = ((ModContent)this).Name;
			val2.mutatorId = ((ModContent)this).Name;
			val2.isUnique = true;
			val2.rateModifier = 0.5f;
			val2.range = ((EntityModel)towerModel).radius;
			val2.maxNumTowersModified = 1f;
			val2.canEffectThisTower = true;
			val2.lifespan = 20f;
			val2.buffLocsName = ((ModBuffIcon)instance).BuffLocsName;
			val2.buffIconName = ((ModBuffIcon)instance).BuffIconName;
			TowerFilterModel[] array2 = new TowerFilterModel[1];
			Args val3 = new Args();
			val3.baseIds = new string[1] { ((UpgradePlusPlus)this).Path.Tower };
			array2[0] = (TowerFilterModel)CreateFilterInBaseTowerIdModelExt.Create(val3);
			val2.filters = (TowerFilterModel[])(object)array2;
			array[0] = (Model)CreateActivateRateSupportZoneModelExt.Create(val2);
			array[1] = (Model)CreateCreateSoundOnAbilityModelExt.Create(new Args
			{
				sound = CreateSoundModelExt.Create(new Args
				{
					assetId = new AudioClipReference
					{
						guidRef = "c72781a0643d41c4b976110d1516fabc"
					}
				})
			});
			val.behaviors = (Model[])(object)array;
			val.addedViaUpgrade = ((ModContent)this).Id;
			TowerModelBehaviorExt.AddBehavior<AbilityModel>(towerModel, CreateAbilityModelExt.Create(val));
		}
	}
	public class ResistanceIsFutile : CareerPathUpgrade<Tactical>
	{
		public override int Cost => 42000;

		public override int Tier => 5;

		public override string Description => base.Description + "Enterprise's attacks do bonus damage to Moab-Class Bloons.";

		public override void ApplyUpgrade(TowerModel towerModel)
		{
			Il2CppGenericIEnumerable.ForEach<ProjectileModel>(((Model)towerModel).GetDescendants<ProjectileModel>(), (Action<ProjectileModel>)delegate(ProjectileModel model)
			{
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Expected O, but got Unknown
				//IL_0019: 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_002f: Unknown result type (might be due to invalid IL or missing references)
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0046: Expected O, but got Unknown
				if (ProjectileModelBehaviorExt.HasBehavior<DamageModel>(model))
				{
					Args val = new Args();
					((ModelArgs<DamageModifierForTagModel>)val).name = "Moabs";
					val.tag = "Moabs";
					val.damageMultiplier = 1.2f;
					val.damageAddative = 2f;
					val.applyOverMaxDamage = true;
					ProjectileModelBehaviorExt.AddBehavior<DamageModifierForTagModel>(model, CreateDamageModifierForTagModelExt.Create(val));
					model.hasDamageModifiers = true;
				}
			});
		}
	}
	public class Tactical : CareerPath
	{
		public override int UpgradeCount => 6;

		protected override int Order => 1;
	}
	public class TacticalInitiative : CareerPathUpgrade<Tactical>
	{
		public override int Cost => 1700;

		public override int Tier => 2;

		public override string Description => base.Description + "Increase the pierce of all of Enterprise's weapons.";

		public override void ApplyUpgrade(TowerModel towerModel)
		{
			Il2CppGenericIEnumerable.ForEach<ProjectileModel>(((Model)towerModel).GetDescendants<ProjectileModel>(), (Action<ProjectileModel>)delegate(ProjectileModel proj)
			{
				if (ProjectileModelBehaviorExt.HasBehavior<DamageModel>(proj))
				{
					proj.pierce += (float)(int)Math.Ceiling((double)proj.pierce * 0.2);
				}
			});
		}
	}
	public class TargetShields : CareerPathUpgrade<Tactical>
	{
		public override int Cost => 2700;

		public override int Tier => 3;

		public override string Description => base.Description + "Enterpise's attacks do bonus damage to Ceramic and Fortified Bloons";

		public override void ApplyUpgrade(TowerModel towerModel)
		{
			Il2CppGenericIEnumerable.ForEach<ProjectileModel>(((Model)towerModel).GetDescendants<ProjectileModel>(), (Action<ProjectileModel>)delegate(ProjectileModel model)
			{
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: Expected O, but got Unknown
				//IL_001c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				//IL_003d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0049: Expected O, but got Unknown
				//IL_004f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0054: Unknown result type (might be due to invalid IL or missing references)
				//IL_005f: Expected O, but got Unknown
				//IL_005f: Unknown result type (might be due to invalid IL or missing references)
				//IL_006a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0075: Unknown result type (might be due to invalid IL or missing references)
				//IL_0080: Unknown result type (might be due to invalid IL or missing references)
				//IL_008c: Expected O, but got Unknown
				if (ProjectileModelBehaviorExt.HasBehavior<DamageModel>(model))
				{
					Args val = new Args();
					((ModelArgs<DamageModifierForTagModel>)val).name = "Fortified";
					val.tag = "Fortified";
					val.damageMultiplier = 1.2f;
					val.damageAddative = 2f;
					val.applyOverMaxDamage = true;
					ProjectileModelBehaviorExt.AddBehavior<DamageModifierForTagModel>(model, CreateDamageModifierForTagModelExt.Create(val));
					Args val2 = new Args();
					((ModelArgs<DamageModifierForTagModel>)val2).name = "Ceramic";
					val2.tag = "Ceramic";
					val2.damageMultiplier = 1.2f;
					val2.damageAddative = 2f;
					val2.applyOverMaxDamage = true;
					ProjectileModelBehaviorExt.AddBehavior<DamageModifierForTagModel>(model, CreateDamageModifierForTagModelExt.Create(val2));
					model.hasDamageModifiers = true;
				}
			});
		}
	}
}
namespace StarshipEnterprise.Upgrades.Science
{
	public class ModulateFrequencies : CareerPathUpgrade<Science>
	{
		public override int Cost => 700;

		public override int Tier => 1;

		public override string Description => base.Description + "All of Enterprise's attacks can pop Purple Bloons.";

		public override string Icon => ((ModContent)this).Name;

		public override void ApplyUpgrade(TowerModel towerModel)
		{
			Il2CppGenericIEnumerable.ForEach<DamageModel>(((Model)towerModel).GetDescendants<DamageModel>(), (Action<DamageModel>)delegate(DamageModel model)
			{
				model.immuneBloonProperties = (BloonProperties)0;
			});
		}
	}
	public class RefuseThePrimeDirective : CareerPathUpgrade<Science>
	{
		public class BuffIconRefuseThePrimeDirective : ModBuffIcon
		{
		}

		[HarmonyPatch(typeof(RateMutator), "Mutate")]
		internal static class RateMutator_Mutate
		{
			[HarmonyPostfix]
			private static void Postfix(RateSupportMutator __instance, Model model, ref bool __result)
			{
				TowerModel val = default(TowerModel);
				if (!(((BehaviorMutator)__instance).id != "RefuseThePrimeDirective") && Il2CppSystemObjectExt.Is<TowerModel>((Il2CppObjectBase)(object)model, ref val))
				{
					__result = Science.PrimeDirectiveTech(val, Math.Clamp(val.tier, 0, 4));
				}
			}
		}

		public override int Cost => 17770;

		public override int Tier => 4;

		public override bool Ability => true;

		public override string Description => base.Description + "Ability: Grant all Monkeys temporary access to advanced Starfleet technology.";

		public override void ApplyUpgrade(TowerModel towerModel, int tier)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Expected O, but got Unknown
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Expected O, but got Unknown
			//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_0115: 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_011b: 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_0130: Expected O, but got Unknown
			//IL_0135: Expected O, but got Unknown
			//IL_013f: Expected O, but got Unknown
			BuffIconRefuseThePrimeDirective instance = ModContent.GetInstance<BuffIconRefuseThePrimeDirective>();
			Args val = new Args();
			((ModelArgs<AbilityModel>)(object)val).name = ((ModContent)this).Name;
			val.displayName = ((NamedModContent)this).DisplayName;
			val.description = ((NamedModContent)this).Description;
			val.animation = -1;
			val.icon = ((UpgradePlusPlus)this).IconReference;
			val.Cooldown = 60f;
			Model[] array = new Model[2];
			Args val2 = new Args();
			val2.mutatorId = ((ModContent)this).Name;
			val2.isUnique = true;
			val2.rateModifier = 1f;
			val2.range = 99999f;
			val2.maxNumTowersModified = 99999f;
			val2.lifespan = 20f;
			val2.displayModel = CreateDisplayModelExt.Create(new Args
			{
				display = ModContent.CreatePrefabReference<PrimeDirectiveBuff>(),
				category = (DisplayCategory)64
			});
			val2.buffLocsName = ((ModBuffIcon)instance).BuffLocsName;
			val2.buffIconName = ((ModBuffIcon)instance).BuffIconName;
			val2.filters = (TowerFilterModel[])(object)new TowerFilterModel[1] { (TowerFilterModel)CreateFilterInBaseTowerIdModelExt.Create(new Args
			{
				baseIds = Science.PrimeDirectiveModes.Keys.ToArray()
			}) };
			array[0] = (Model)CreateActivateRateSupportZoneModelExt.Create(val2);
			array[1] = (Model)CreateCreateSoundOnAbilityModelExt.Create(new Args
			{
				sound = CreateSoundModelExt.Create(new Args
				{
					assetId = new AudioClipReference
					{
						guidRef = "8c509ff34947707469192054a463f6b7"
					}
				})
			});
			val.behaviors = (Model[])(object)array;
			val.addedViaUpgrade = ((ModContent)this).Id;
			TowerModelBehaviorExt.AddBehavior<AbilityModel>(towerModel, CreateAbilityModelExt.Create(val));
		}
	}
	public class RepealThePrimeDirective : CareerPathUpgrade<Science>
	{
		public class BuffIconRepealThePrimeDirective : ModBuffIcon
		{
		}

		[HarmonyPatch(typeof(RateMutator), "Mutate")]
		internal static class RateMutator_Mutate
		{
			[HarmonyPostfix]
			private static bool Prefix(RateSupportMutator __instance, Model model, ref bool __result)
			{
				TowerModel val = default(TowerModel);
				if (((BehaviorMutator)__instance).id != "RepealThePrimeDirective" || !Il2CppSystemObjectExt.Is<TowerModel>((Il2CppObjectBase)(object)model, ref val))
				{
					return true;
				}
				__result = Science.PrimeDirectiveTech(val, 5);
				ArrayExt.ForEach<WeaponModel>(ModelExt.FindDescendants<WeaponModel>((Model)(object)val, "Phaser"), (Action<WeaponModel>)delegate(WeaponModel w)
				{
					w.Rate *= 0.75f;
				});
				ArrayExt.ForEach<WeaponModel>(ModelExt.FindDescendants<WeaponModel>((Model)(object)val, "PhotonTorpedo"), (Action<WeaponModel>)delegate(WeaponModel w)
				{
					w.Rate *= 0.75f;
				});
				ArrayExt.ForEach<WeaponModel>(ModelExt.FindDescendants<WeaponModel>((Model)(object)val, "PhaseCannon"), (Action<WeaponModel>)delegate(WeaponModel w)
				{
					w.Rate *= 0.75f;
				});
				return false;
			}
		}

		[HarmonyPatch(typeof(RateSupportMutator), "Mutate")]
		internal static class RateSupportMutator_Mutate
		{
			[HarmonyPostfix]
			private static void Postfix(RateSupportMutator __instance, Model model, ref bool __result)
			{
				TowerModel towerModel = default(TowerModel);
				if (!(((BehaviorMutator)__instance).id != "RepealThePrimeDirective") && Il2CppSystemObjectExt.Is<TowerModel>((Il2CppObjectBase)(object)model, ref towerModel))
				{
					__result = Science.PrimeDirectiveTech(towerModel, 5);
				}
			}
		}

		public override int Cost => 71770;

		public override int Tier => 5;

		public override string Description => base.Description + "Monkeys have permanent access to even more advanced Starfleet technology. Ability now increases its attack speed.";

		public override void ApplyUpgrade(TowerModel towerModel, int tier)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Expected O, but got Unknown
			if (tier < 6)
			{
				AbilityModelBehaviorExt.GetBehavior<ActivateRateSupportZoneModel>(ModelExt.SetName<AbilityModel>(ModelExt.FindDescendant<AbilityModel>((Model)(object)towerModel, "RefuseThePrimeDirective"), ((ModContent)this).Name)).mutatorId = ((ModContent)this).Name;
				BuffIconRepealThePrimeDirective instance = ModContent.GetInstance<BuffIconRepealThePrimeDirective>();
				Args val = new Args();
				((ModelArgs<RateSupportModel>)val).name = ((ModContent)this).Name;
				val.multiplier = 1f;
				val.isUnique = true;
				val.mutatorId = ((ModContent)this).Name;
				val.isGlobal = true;
				val.priority = -1;
				val.buffLocsName = ((ModBuffIcon)instance).BuffLocsName;
				val.buffIconName = ((ModBuffIcon)instance).BuffIconName;
				TowerModelBehaviorExt.AddBehavior<RateSupportModel>(towerModel, CreateRateSupportModelExt.Create(val));
			}
		}
	}
	public class ReverseThePrimeDirective : CareerPathUpgrade<Science>
	{
		public class BuffIconReverseThePrimeDirective : ModBuffIcon
		{
		}

		[HarmonyPatch(typeof(RateMutator), "Mutate")]
		internal static class RateMutator_Mutate
		{
			[HarmonyPostfix]
			private static bool Prefix(RateSupportMutator __instance, Model model, ref bool __result)
			{
				TowerModel val = default(TowerModel);
				if (((BehaviorMutator)__instance).id != "ReverseThePrimeDirective" || !Il2CppSystemObjectExt.Is<TowerModel>((Il2CppObjectBase)(object)model, ref val))
				{
					return true;
				}
				__result = Science.PrimeDirectiveTech(val, 6);
				ArrayExt.ForEach<WeaponModel>(ModelExt.FindDescendants<WeaponModel>((Model)(object)val, "Phaser"), (Action<WeaponModel>)delegate(WeaponModel w)
				{
					w.Rate *= 0.5f;
				});
				ArrayExt.ForEach<WeaponModel>(ModelExt.FindDescendants<WeaponModel>((Model)(object)val, "PhotonTorpedo"), (Action<WeaponModel>)delegate(WeaponModel w)
				{
					w.Rate *= 0.5f;
				});
				ArrayExt.ForEach<WeaponModel>(ModelExt.FindDescendants<WeaponModel>((Model)(object)val, "PhaseCannon"), (Action<WeaponModel>)delegate(WeaponModel w)
				{
					w.Rate *= 0.5f;
				});
				__result = true;
				return false;
			}
		}

		[HarmonyPatch(typeof(RateSupportMutator), "Mutate")]
		internal static class RateSupportMutator_Mutate
		{
			[HarmonyPostfix]
			private static void Postfix(RateSupportMutator __instance, Model model, ref bool __result)
			{
				TowerModel towerModel = default(TowerModel);
				if (!(((BehaviorMutator)__instance).id != "ReverseThePrimeDirective") && Il2CppSystemObjectExt.Is<TowerModel>((Il2CppObjectBase)(object)model, ref towerModel))
				{
					__result = Science.PrimeDirectiveTech(towerModel, 6);
				}
			}
		}

		public override int Cost => 171170;

		public override int Tier => 6;

		public override string Description => base.Description + "Give all Monkeys the most advanced Starfleet technology possible.";

		public override void ApplyUpgrade(TowerModel towerModel)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: 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_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Expected O, but got Unknown
			ActivateRateSupportZoneModel behavior = AbilityModelBehaviorExt.GetBehavior<ActivateRateSupportZoneModel>(ModelExt.SetName<AbilityModel>(ModelExt.FindDescendant<AbilityModel>((Model)(object)towerModel, "RefuseThePrimeDirective"), ((ModContent)this).Name));
			behavior.mutatorId = ((ModContent)this).Name;
			behavior.rateModifier = 0.5f;
			BuffIconReverseThePrimeDirective instance = ModContent.GetInstance<BuffIconReverseThePrimeDirective>();
			Args val = new Args();
			((ModelArgs<RateSupportModel>)val).name = ((ModContent)this).Name;
			val.multiplier = 1f;
			val.isUnique = true;
			val.mutatorId = ((ModContent)this).Name;
			val.isGlobal = true;
			val.priority = -1;
			val.buffLocsName = ((ModBuffIcon)instance).BuffLocsName;
			val.buffIconName = ((ModBuffIcon)instance).BuffIconName;
			TowerModelBehaviorExt.AddBehavior<RateSupportModel>(towerModel, CreateRateSupportModelExt.Create(val));
		}
	}
	public class ScanForLifeForms : CareerPathUpgrade<Science>
	{
		public override int Cost => 1700;

		public override int Tier => 2;

		public override string Description => base.Description + "Allows Enterprise to see and pop Camo Bloons.";

		public override void ApplyUpgrade(TowerModel towerModel)
		{
			Il2CppGenericIEnumerable.ForEach<FilterInvisibleModel>(((Model)towerModel).GetDescendants<FilterInvisibleModel>(), (Action<FilterInvisibleModel>)delegate(FilterInvisibleModel model)
			{
				model.isActive = false;
			});
		}
	}
	public class Science : CareerPath
	{
		public enum PrimeDirectiveMode
		{
			Phaser,
			PhaserDrones,
			PhotonTorpedo,
			PhotonTorpedoOnSelf,
			PhotonTorpedoOnPoint,
			PhotonTorpedoOnTarget,
			PhaseCannon,
			PhaseCannonSpread
		}

		[HarmonyPatch(typeof(Support), "IsInZone")]
		internal static class Support_IsInZone
		{
			[HarmonyPrefix]
			private static bool Prefix(Support __instance)
			{
				return !((RootBehavior)__instance).model.name.Contains("PrimeDirective");
			}
		}

		public static readonly Dictionary<string, PrimeDirectiveMode> PrimeDirectiveModes = new Dictionary<string, PrimeDirectiveMode>
		{
			{
				TowerType.DartMonkey,
				PrimeDirectiveMode.PhaseCannonSpread
			},
			{
				TowerType.BoomerangMonkey,
				PrimeDirectiveMode.Phaser
			},
			{
				TowerType.TackShooter,
				PrimeDirectiveMode.PhaseCannonSpread
			},
			{
				TowerType.BombShooter,
				PrimeDirectiveMode.PhotonTorpedo
			},
			{
				TowerType.GlueGunner,
				PrimeDirectiveMode.PhaseCannon
			},
			{
				TowerType.IceMonkey,
				PrimeDirectiveMode.PhotonTorpedoOnSelf
			},
			{
				TowerType.SniperMonkey,
				PrimeDirectiveMode.Phaser
			},
			{
				TowerType.DartlingGunner,
				PrimeDirectiveMode.PhaseCannonSpread
			},
			{
				TowerType.MonkeySub,
				PrimeDirectiveMode.Phaser
			},
			{
				TowerType.MonkeyBuccaneer,
				PrimeDirectiveMode.PhotonTorpedo
			},
			{
				TowerType.MortarMonkey,
				PrimeDirectiveMode.PhotonTorpedoOnPoint
			},
			{
				TowerType.MonkeyAce,
				PrimeDirectiveMode.Phaser
			},
			{
				TowerType.HeliPilot,
				PrimeDirectiveMode.PhaseCannon
			},
			{
				TowerType.NinjaMonkey,
				PrimeDirectiveMode.PhaseCannonSpread
			},
			{
				TowerType.WizardMonkey,
				PrimeDirectiveMode.Phaser
			},
			{
				TowerType.SuperMonkey,
				PrimeDirectiveMode.PhaseCannonSpread
			},
			{
				TowerType.Druid,
				PrimeDirectiveMode.PhaseCannonSpread
			},
			{
				TowerType.Alchemist,
				PrimeDirectiveMode.PhotonTorpedo
			},
			{
				TowerType.EngineerMonkey,
				PrimeDirectiveMode.Phaser
			},
			{
				TowerType.BeastHandler,
				PrimeDirectiveMode.Phaser
			},
			{
				TowerType.Quincy,
				PrimeDirectiveMode.Phaser
			},
			{
				TowerType.Gwendolin,
				PrimeDirectiveMode.PhaseCannon
			},
			{
				TowerType.StrikerJones,
				PrimeDirectiveMode.PhotonTorpedo
			},
			{
				TowerType.ObynGreenfoot,
				PrimeDirectiveMode.PhotonTorpedo
			},
			{
				TowerType.CaptainChurchill,
				PrimeDirectiveMode.PhaseCannon
			},
			{
				TowerType.Ezili,
				PrimeDirectiveMode.Phaser
			},
			{
				TowerType.PatFusty,
				PrimeDirectiveMode.PhotonTorpedoOnTarget
			},
			{
				TowerType.Adora,
				PrimeDirectiveMode.Phaser
			},
			{
				TowerType.AdmiralBrickell,
				PrimeDirectiveMode.Phaser
			},
			{
				TowerType.Etienne,
				PrimeDirectiveMode.PhaserDrones
			},
			{
				TowerType.Sauda,
				PrimeDirectiveMode.PhotonTorpedoOnTarget
			},
			{
				TowerType.Psi,
				PrimeDirectiveMode.Phaser
			},
			{
				TowerType.Geraldo,
				PrimeDirectiveMode.Phaser
			},
			{
				TowerType.SunAvatarMini,
				PrimeDirectiveMode.PhaseCannonSpread
			},
			{
				TowerType.TrueSunAvatarMini,
				PrimeDirectiveMode.PhaseCannonSpread
			},
			{
				TowerType.Sentry,
				PrimeDirectiveMode.Phaser
			},
			{
				TowerType.SentryBoom,
				PrimeDirectiveMode.PhotonTorpedo
			},
			{
				TowerType.SentryCold,
				PrimeDirectiveMode.Phaser
			},
			{
				TowerType.SentryEnergy,
				PrimeDirectiveMode.PhaseCannon
			},
			{
				TowerType.SentryCrushing,
				PrimeDirectiveMode.PhaseCannon
			},
			{
				TowerType.SentryParagon,
				PrimeDirectiveMode.PhaseCannon
			}
		};

		public override int UpgradeCount => 6;

		protected override int Order => 3;

		public static bool PrimeDirectiveTech(TowerModel towerModel, int tier)
		{
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_038c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0391: Unknown result type (might be due to invalid IL or missing references)
			//IL_0399: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b8: Expected O, but got Unknown
			//IL_03db: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ec: Expected O, but got Unknown
			//IL_03f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_040d: Expected O, but got Unknown
			//IL_0450: Unknown result type (might be due to invalid IL or missing references)
			//IL_0455: Unknown result type (might be due to invalid IL or missing references)
			//IL_0461: Expected O, but got Unknown
			//IL_0327: Unknown result type (might be due to invalid IL or missing references)
			//IL_032c: Unknown result type (might be due to invalid IL or missing references)
			//IL_033f: Expected O, but got Unknown
			//IL_0306: Unknown result type (might be due to invalid IL or missing references)
			//IL_030b: Unknown result type (might be due to invalid IL or missing references)
			//IL_031e: Expected O, but got Unknown
			if (!PrimeDirectiveModes.TryGetValue(((EntityModel)towerModel).baseId, out var value))
			{
				return false;
			}
			TowerModel val = (TowerModel)((value != PrimeDirectiveMode.PhaserDrones) ? ((object)towerModel) : ((object)TowerModelBehaviorExt.GetBehavior<DroneSupportModel>(towerModel).droneModel));
			TowerModel val2 = val;
			AttackModel val3;
			switch (value)
			{
			default:
				val3 = ModelExt.Duplicate<AttackModel>(ModelExt.FindDescendant<AttackModel>((Model)(object)GetEnterprise(tier, 0, 0), "Phaser"));
				if (tier >= 3)
				{
					WeaponModel child2 = ((Model)val3).GetChild<WeaponModel>();
					child2.Rate /= 3f;
				}
				break;
			case PrimeDirectiveMode.PhotonTorpedo:
			case PrimeDirectiveMode.PhotonTorpedoOnSelf:
			case PrimeDirectiveMode.PhotonTorpedoOnPoint:
			case PrimeDirectiveMode.PhotonTorpedoOnTarget:
			{
				val3 = ModelExt.Duplicate<AttackModel>(ModelExt.FindDescendant<AttackModel>((Model)(object)GetEnterprise(0, tier, 0), "PhotonTorpedo"));
				RandomArcEmissionModel descendant2 = ((Model)val3).GetDescendant<RandomArcEmissionModel>();
				EmissionModelBehaviorExt.RemoveBehavior<EmissionRotationOffBloonDirectionModel>((EmissionModel)(object)descendant2);
				if (!ModelExt.HasDescendant<ArcEmissionModel>((Model)(object)val2))
				{
					WeaponModelExt.SetEmission(((Model)val3).GetChild<WeaponModel>(), (EmissionModel)(object)CreateSingleEmissionModelExt.Create());
					if (tier >= 3)
					{
						WeaponModel child = ((Model)val3).GetChild<WeaponModel>();
						child.Rate /= 3f;
					}
				}
				else
				{
					descendant2.randomAngle = 0f;
				}
				break;
			}
			case PrimeDirectiveMode.PhaseCannon:
			case PrimeDirectiveMode.PhaseCannonSpread:
			{
				val3 = ModelExt.Duplicate<AttackModel>(ModelExt.FindDescendant<AttackModel>((Model)(object)GetEnterprise(0, 0, tier), "PhaseCannon"));
				AttackModelExt.RemoveFilter<FilterTargetAngleModel>(val3);
				ParallelEmissionModel descendant = ((Model)val3).GetDescendant<ParallelEmissionModel>();
				if (!TowerModelBehaviorExt.HasBehavior<AirUnitModel>(val2))
				{
					EmissionModelBehaviorExt.RemoveBehavior<EmissionRotationOffBloonDirectionModel>((EmissionModel)(object)descendant);
				}
				if (!TowerModelBehaviorExt.HasBehavior<AirUnitModel>(val2))
				{
					descendant.spreadLength /= 2f;
					MiscModelExt.UpdateOffset(descendant);
				}
				break;
			}
			}
			Il2CppGenericIEnumerable.ForEach<FilterInvisibleModel>(((Model)val3).GetDescendants<FilterInvisibleModel>(), (Action<FilterInvisibleModel>)delegate(FilterInvisibleModel model)
			{
				model.isActive = false;
			});
			Il2CppGenericIEnumerable.ForEach<DamageModel>(((Model)val3).GetDescendants<DamageModel>(), (Action<DamageModel>)delegate(DamageModel model)
			{
				model.immuneBloonProperties = (BloonProperties)0;
			});
			if (Il2CppGenericIEnumerable.Any<TargetSupplierModel>(((Model)val2).GetDescendants<TargetSupplierModel>(), (Func<TargetSupplierModel, bool>)((TargetSupplierModel model) => model.GetName() == "Close" || Il2CppSystemObjectExt.Is<TargetSelectedPointModel>((Il2CppObjectBase)(object)model))))
			{
				AttackModelBehaviorExt.RemoveBehavior<TargetSupplierModel>(val3);
				val3.targetProvider = null;
			}
			WeaponModel child3 = ((Model)val3).GetChild<WeaponModel>();
			if (!val2.isGlobalRange && !TowerModelBehaviorExt.HasBehavior<AirUnitModel>(towerModel))
			{
				val3.range = towerModel.range;
			}
			FilterInvisibleModel descendant3 = ((Model)towerModel).GetDescendant<FilterInvisibleModel>();
			bool camo = descendant3 != null && descendant3.isActive;
			Il2CppGenericIEnumerable.ForEach<FilterInvisibleModel>(((Model)val3).GetDescendants<FilterInvisibleModel>(), (Action<FilterInvisibleModel>)delegate(FilterInvisibleModel camoModel)
			{
				camoModel.isActive = camo;
			});
			Vector3 eject = WeaponModelExt.GetEject(((Model)val2).GetDescendant<WeaponModel>());
			if (((EntityModel)val2).baseId == TowerType.AdmiralBrickell)
			{
				eject = WeaponModelExt.GetEject(ModelExt.FindDescendants<WeaponModel>((Model)(object)val2).Skip(1).First());
			}
			eject.y -= 1f;
			foreach (WeaponModel item in (Il2CppArrayBase<WeaponModel>)(object)val3.weapons)
			{
				if (!TowerModelBehaviorExt.HasBehavior<AirUnitModel>(val2))
				{
					WeaponModelBehaviorExt.RemoveBehavior<FireFromAirUnitModel>(item);
				}
				WeaponModelExt.SetEject(item, eject, false, false, false);
			}
			RotateToTargetModel val4 = default(RotateToTargetModel);
			if (AttackModelBehaviorExt.HasBehavior<RotateToTargetModel>(TowerModelExt.GetAttackModel(val2), ref val4))
			{
				AttackModelBehaviorExt.AddBehavior<RotateToTargetModel>(val3, ModelExt.Duplicate<RotateToTargetModel>(((Model)val2).GetDescendant<RotateToTargetModel>()));
				EmissionModel val5 = default(EmissionModel);
				if (val4.additionalRotation != 0 && ModelExt.HasDescendant<EmissionModel>((Model)(object)val3, ref val5))
				{
					if (Il2CppSystemObjectExt.Is<ArcEmissionModel>((Il2CppObjectBase)(object)val5))
					{
						EmissionModelBehaviorExt.AddBehavior<EmissionArcRotationOffTowerDirectionModel>(val5, CreateEmissionArcRotationOffTowerDirectionModelExt.Create(new Args
						{
							offsetRotation = -val4.additionalRotation
						}));
					}
					else
					{
						EmissionModelBehaviorExt.AddBehavior<EmissionRotationOffTowerDirectionModel>(val5, CreateEmissionRotationOffTowerDirectionModelExt.Create(new Args
						{
							offsetRotation = -val4.additionalRotation
						}));
					}
				}
			}
			switch (value)
			{
			case PrimeDirectiveMode.PhotonTorpedoOnSelf:
			{
				ProjectileModel descendant4 = ((Model)child3.projectile).GetDescendant<ProjectileModel>();
				EffectModel effectModel = ((Model)child3).GetDescendant<CreateEffectOnContactModel>().effectModel;
				WeaponModelExt.SetProjectile(child3, descendant4);
				WeaponModelBehaviorExt.AddBehavior<EjectEffectModel>(child3, CreateEjectEffectModelExt.Create(new Args
				{
					effectModel = effectModel,
					lifespan = effectModel.lifespan,
					fullscreen = effectModel.fullscreen
				}));
				break;
			}
			case PrimeDirectiveMode.PhotonTorpedoOnPoint:
				WeaponModelExt.SetEmission(child3, (EmissionModel)(object)ModelExt.Duplicate<RandomTargetSpreadModel>(((Model)val2).GetDescendant<RandomTargetSpreadModel>()));
				ProjectileModelBehaviorExt.AddBehavior<InstantModel>(child3.projectile, CreateInstantModelExt.Create(new Args
				{
					destroyIfInvalid = true
				}));
				ProjectileModelBehaviorExt.AddBehavior<AgeModel>(child3.projectile, CreateAgeModelExt.Create(new Args
				{
					lifespan = 0.1f
				}));
				ProjectileModelBehaviorExt.RemoveBehavior<TravelStraitModel>(child3.projectile);
				ProjectileModelBehaviorExt.RemoveBehavior<TrackTargetModel>(child3.projectile);
				AttackModelExt.AddWeapon(TowerModelExt.GetAttackModel(val2), child3);
				return true;
			case PrimeDirectiveMode.PhotonTorpedoOnTarget:
				WeaponModelExt.SetEmission(((Model)val3).GetChild<WeaponModel>(), (EmissionModel)(object)CreateInstantDamageEmissionModelExt.Create());
				ProjectileModelBehaviorExt.AddBehavior<InstantModel>(child3.projectile, CreateInstantModelExt.Create(new Args
				{
					destroyIfInvalid = true
				}));
				ProjectileModelBehaviorExt.RemoveBehavior<TravelStraitModel>(child3.projectile);
				break;
			case PrimeDirectiveMode.PhaseCannonSpread:
			{
				int num = ((Model)child3).GetChild<ParallelEmissionModel>().count;
				EmissionWithOffsetsModel val6 = default(EmissionWithOffsetsModel);
				if (ModelExt.HasDescendant<EmissionWithOffsetsModel>((Model)(object)TowerModelExt.GetAttackModel(val2), ref val6))
				{
					EmissionWithOffsetsModel val7 = ModelExt.Duplicate<EmissionWithOffsetsModel>(val6);
					val7.projectileCount = num;
					WeaponModelExt.SetEmission(child3, (EmissionModel)(object)val7);
				}
				ArcEmissionModel val8 = default(ArcEmissionModel);
				if (ModelExt.HasDescendant<ArcEmissionModel>((Model)(object)TowerModelExt.GetAttackModel(val2), ref val8))
				{
					ArcEmissionModel val9 = ModelExt.Duplicate<ArcEmissionModel>(val8);
					num = ((Model)child3).GetChild<ParallelEmissionModel>().count;
					if (val9.angle >= 360f)
					{
						num *= 4;
					}
					val9.count = num;
					WeaponModelExt.SetEmission(child3, (EmissionModel)(object)val9);
					((Model)child3).GetDescendant<TravelStraitModel>().Lifespan = ((Model)val2).GetDescendant<TravelStraitModel>().Lifespan;
				}
				RandomEmissionModel val10 = default(RandomEmissionModel);
				if (ModelExt.HasDescendant<RandomEmissionModel>((Model)(object)TowerModelExt.GetAttackModel(val2), ref val10))
				{
					RandomEmissionModel val11 = ModelExt.Duplicate<RandomEmissionModel>(val10);
					val11.count = num;
					WeaponModelExt.SetEmission(child3, (EmissionModel)(object)val11);
					((Model)child3).GetDescendant<TravelStraitModel>().Lifespan = ((Model)val2).GetDescendant<TravelStraitModel>().Lifespan;
				}
				if (((EntityModel)val2).baseId == TowerType.DartlingGunner)
				{
					val3.fireWithoutTarget = true;
				}
				break;
			}
			}
			TowerModelBehaviorExt.AddBehavior<AttackModel>(val2, val3);
			return true;
		}

		private static TowerModel GetEnterprise(int t1, int t2, int t3)
		{
			TowerModel val = ModContent.GetTowerModel<StarshipEnterprise>(Math.Clamp(t1, 0, 5), Math.Clamp(t2, 0, 5), Math.Clamp(t3, 0, 5));
			if (t1 >= 6 || t2 >= 6 || t3 >= 6)
			{
				val = ModelExt.Duplicate<TowerModel>(val);
			}
			foreach (UpgradePlusPlus item in ((PathPlusPlus)ModContent.GetInstance<PhaserPath>()).Upgrades.Values.Where((UpgradePlusPlus u) => u.Tier <= t1))
			{
				item.ApplyUpgrade(val);
				item.ApplyUpgrade(val, t1);
			}
			foreach (UpgradePlusPlus item2 in ((PathPlusPlus)ModContent.GetInstance<PhotonTorpedoPath>()).Upgrades.Values.Where((UpgradePlusPlus u) => u.Tier <= t2))
			{
				item2.ApplyUpgrade(val);
				item2.ApplyUpgrade(val, t2);
			}
			foreach (UpgradePlusPlus item3 in ((PathPlusPlus)ModContent.GetInstance<PhaseCannonPath>()).Upgrades.Values.Where((UpgradePlusPlus u) => u.Tier <= t3))
			{
				item3.ApplyUpgrade(val);
				item3.ApplyUpgrade(val, t3);
			}
			return val;
		}
	}
	public class SurgicalStrikes : CareerPathUpgrade<Science>
	{
		public override int Cost => 7000;

		public override int Tier => 3;

		public override string Description => base.Description + "Enterprise's attacks remove Regrow, Camo and Fortified properties from Bloons.";

		public override void ApplyUpgrade(TowerModel towerModel)
		{
			Il2CppGenericIEnumerable.ForEach<ProjectileModel>(((Model)towerModel).GetDescendants<ProjectileModel>(), (Action<ProjectileModel>)delegate(ProjectileModel projectile)
			{
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: 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_002d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0037: Expected O, but got Unknown
				//IL_003c: Unknown result type (might be due to invalid IL or missing references)
				//IL_003f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0049: Expected O, but got Unknown
				//IL_0053: Expected O, but got Unknown
				if (ProjectileModelBehaviorExt.HasBehavior<DamageModel>(projectile))
				{
					ProjectileModelBehaviorExt.AddBehavior<RemoveBloonModifiersModel>(projectile, CreateRemoveBloonModifiersModelExt.Create(new Args
					{
						cleanseRegen = true,
						cleanseCamo = true,
						cleanseFortified = true,
						cleanseOnlyIfDamaged = true,
						bloonTagExcludeList = Il2CppArrayBase<string>.op_Implicit((Il2CppArrayBase<string>)new Il2CppStringArray(0L)),
						bloonTagExplicitList = Il2CppArrayBase<string>.op_Implicit((Il2CppArrayBase<string>)new Il2CppStringArray(0L))
					}));
					projectile.UpdateCollisionPassList();
				}
			});
		}
	}
}
namespace StarshipEnterprise.Upgrades.Refit
{
	public class AmbassadorClass : RefitUpgrade<AmbassadorDisplay>
	{
		public override int Tier => 3;

		public override int Cost => 7010;

		public override string Description => "Upgrade to the Enterprise-C, an Ambassador class starship.\n" + base.Description;

		public override float BuffFactor => 0.3f;

		public override float Speed => 40f;
	}
	public class ConstitutionRefit : RefitUpgrade<ConstitutionIIDisplay>
	{
		public override int Tier => 1;

		public override int Cost => 1170;

		public override string Description => "Upgrade to the Enterprise-A, a Constitution-II class starship.\n" + base.Description;

		public override float BuffFactor => 0.1f;
	}
	public class ExcelsiorClass : RefitUpgrade<ExcelsiorDisplay>
	{
		public override int Tier => 2;

		public override int Cost => 2700;

		public override string Description => "Upgrade to the Enterprise-B, an Excelsior class starship.\n" + base.Description;

		public override float BuffFactor => 0.2f;

		public override Vector3 EjectOffset => new Vector3(0f, 30f, 5f);

		public override float Speed => 50f;
	}
	public class GalaxyClass : RefitUpgrade<GalaxyDisplay>
	{
		public override int Tier => 4;

		public override int Cost => 17010;

		public override string Description => "Upgrade to the Enterprise-D, a Galaxy class starship.\n" + base.Description;

		public override float BuffFactor => 0.4f;

		public override float Speed => 30f;
	}
	public class OdysseyClass : RefitUpgrade<OdysseyDisplay>
	{
		public override int Tier => 6;

		public override int Cost => 97000;

		public override string Description => "Upgrade to the Enterprise-F, an Odyssey class starship.\n" + base.Description;

		public override float BuffFactor => 1f;

		public override string Container => UpgradePlusPlus.UpgradeContainerPlatinum;

		public override Vector3 EjectOffset => new Vector3(0f, 40f, 5f);

		public override float Speed => 30f;
	}
	public class RefitPath : PathPlusPlus<StarshipEnterprise>
	{
		public override int UpgradeCount => 6;

		protected override int Order => 4;

		public override int Priority => 100;

		public override bool ValidTiers(int[] tiers)
		{
			return true;
		}
	}
	public abstract class RefitUpgrade : UpgradePlusPlus<RefitPath>
	{
		public override string Description => "Increased pierce and damage for all weapons.";

		public override string Portrait => ((ModContent)this).Name + "-Portrait";

		public abstract float BuffFactor { get; }

		public virtual Vector3 EjectOffset => StarshipEnterprise.EjectOffset;

		public virtual float Speed => StarshipEnterprise.Speed;

		public abstract PrefabReference Display { get; }

		public override void ApplyUpgrade(TowerModel towerModel, int tier)
		{
			if (((UpgradePlusPlus)this).Tier == tier)
			{
				TowerModelBehaviorExt.GetBehavior<AirUnitModel>(towerModel).display = Display;
				((Model)towerModel).GetDescendant<PathMovementModel>().speed = Speed;
				Il2CppGenericIEnumerable.ForEach<WeaponModel>(((Model)towerModel).GetDescendants<WeaponModel>(), (Action<WeaponModel>)delegate(WeaponModel weapon)
				{
					//IL_0002: Unknown result type (might be due to invalid IL or missing references)
					WeaponModelExt.SetEject(weapon, EjectOffset, true, false, false);
				});
				towerModel.portrait = ((UpgradePlusPlus)this).PortraitReference;
			}
			Il2CppGenericIEnumerable.ForEach<ProjectileModel>(((Model)towerModel).GetDescendants<ProjectileModel>(), (Action<ProjectileModel>)delegate(ProjectileModel projectile)
			{
				projectile.pierce += (float)(int)Math.Ceiling(projectile.pierce * BuffFactor);
			});
			Il2CppGenericIEnumerable.ForEach<DamageModel>(((Model)towerModel).GetDescendants<DamageModel>(), (Action<DamageModel>)delegate(DamageModel damage)
			{
				damage.damage += (float)(int)Math.Ceiling(damage.damage * BuffFactor);
			});
			Il2CppGenericIEnumerable.ForEach<CritMultiplierModel>(((Model)towerModel).GetDescendants<CritMultiplierModel>(), (Action<CritMultiplierModel>)delegate(CritMultiplierModel crit)
			{
				crit.damage += (float)(int)Math.Ceiling(crit.damage * BuffFactor);
			});
		}
	}
	public abstract class RefitUpgrade<T> : RefitUpgrade where T : ModDisplay
	{
		public override PrefabReference Display => ModContent.CreatePrefabReference<T>();
	}
	public class SovereignClass : RefitUpgrade<SovereignDisplay>
	{
		public override int Tier => 5;

		public override int Cost => 47000;

		public override string Description => "Upgrade to the Enterprise-E, a Sovereign class starship.\n" + base.Description;

		public override float BuffFactor => 0.5f;

		public override float Speed => 40f;
	}
}
namespace StarshipEnterprise.Upgrades.Phasers
{
	public class AntiprotonBeams : UpgradePlusPlus<PhaserPath>
	{
		public override int Tier => 6;

		public override int Cost => 200000;

		public override string Description => "Phasers become devastating powerful Antiproton beams, with crits strong enough to one-shot many Bloons.";

		public override string Container => UpgradePlusPlus.UpgradeContainerPlatinum;

		public override string Icon => ((ModContent)this).Name;

		public override void ApplyUpgrade(TowerModel towerModel)
		{
			LineProjectileEmissionModel[] array = ModelExt.FindDescendants<LineProjectileEmissionModel>((Model)(object)towerModel);
			foreach (LineProjectileEmissionModel obj in array)
			{
				MiscModelExt.ApplyDisplay<AntiprotonBeam>(obj.displayPath);
				MiscModelExt.ApplyDisplay<AntiProtonParticles>(obj.effectAtEndModel);
				MiscModelExt.ApplyDisplay<AntiprotonBlast>(ProjectileModelBehaviorExt.GetBehavior<CreateEffectOnExhaustFractionModel>(obj.projectileInitialHitModel).effectModel);
			}
			ArrayExt.ForEach<ProjectileModel>(ModelExt.FindDescendants<ProjectileModel>((Model)(object)towerModel, "Phaser"), (Action<ProjectileModel>)delegate(ProjectileModel projectile)
			{
				DamageModel val = default(DamageModel);
				if (ProjectileModelBehaviorExt.HasBehavior<DamageModel>(projectile, ref val))
				{
					DamageModel obj2 = val;
					obj2.damage *= 10f;
				}
				projectile.pierce *= 10f;
			});
			Il2CppGenericIEnumerable.ForEach<CritMultiplierModel>(((Model)towerModel).GetDescendants<CritMultiplierModel>(), (Action<CritMultiplierModel>)delegate(CritMultiplierModel crit)
			{
				crit.damage *= 100f;
			});
		}
	}
	public class BeamOverload : ModUpgrade<StarshipEnterprise>
	{
		public override int Path => 0;

		public override int Tier => 4;

		public override int Cost => 8000;

		public override string Icon => ((ModContent)this).Name;

		public override string Description => "Phaser Beams create a burst of energy on contact with Bloons, also damaging other Bloons nearby.";

		public override void ApplyUpgrade(TowerModel towerModel)
		{
			Il2CppGenericIEnumerable.ForEach<LineProjectileEmissionModel>(((Model)towerModel).GetDescendants<LineProjectileEmissionModel>(), (Action<LineProjectileEmissionModel>)delegate(LineProjectileEmissionModel emission)
			{
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Expected O, but got Unknown
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0021: Expected O, but got Unknown
				//IL_004b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0050: Unknown result type (might be due to invalid IL or missing references)
				//IL_005b: Expected O, but got Unknown
				//IL_005b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0068: Expected O, but got Unknown
				//IL_006b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0070: Unknown result type (might be due to invalid IL or missing references)
				//IL_007b: Expected O, but got Unknown
				//IL_007b: Unknown result type (might be due to invalid IL or missing references)
				//IL_008b: Expected O, but got Unknown
				//IL_008e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0093: Unknown result type (might be due to invalid IL or missing references)
				//IL_009e: Expected O, but got Unknown
				//IL_009e: Unknown result type (might be due to invalid IL or missing references)
				//IL_00aa: 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_00bd: Expected O, but got Unknown
				//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
				//IL_00db: Expected O, but got Unknown
				//IL_00de: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ee: Expected O, but got Unknown
				//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ef: 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_00ff: Unknown result type (might be due to invalid IL or missing references)
				//IL_010f: Expected O, but got Unknown
				//IL_0114: Unknown result type (might be due to invalid IL or missing references)
				//IL_011f: Unknown result type (might be due to invalid IL or missing references)
				//IL_012a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0136: Expected O, but got Unknown
				FilterModel[] filters = (FilterModel[])(object)new FilterModel[1] { (FilterModel)CreateFilterInvisibleModelExt.Create(new Args
				{
					isActive = true
				}) };
				Args val = new Args();
				val.id = "PhaserBlast";
				val.radius = 10f;
				val.pierce = 25f;
				Model[] array = new Model[5];
				Args val2 = new Args();
				((ModelArgs<DisplayModel>)val2).name = "PhaserBlast";
				val2.category = (DisplayCategory)16;
				array[0] = (Model)CreateDisplayModelExt.Create(val2);
				Args val3 = new Args();
				((ModelArgs<AgeModel>)val3).name = "PhaserBlast";
				val3.lifespan = 0.2f;
				array[1] = (Model)CreateAgeModelExt.Create(val3);
				Args val4 = new Args();
				((ModelArgs<ProjectileFilterModel>)val4).name = "PhaserBlast";
				val4.filters = filters;
				array[2] = (Model)CreateProjectileFilterModelExt.Create(val4);
				Args val5 = new Args();
				((ModelArgs<DamageModel>)val5).name = "PhaserBlast";
				val5.damage = 2f;
				val5.immuneBloonProperties = (BloonProperties)8;
				val5.immuneBloonPropertiesOriginal = (BloonProperties)8;
				array[3] = (Model)CreateDamageModelExt.Create(val5);
				Args val6 = new Args();
				((ModelArgs<CreateEffectOnExhaustFractionModel>)val6).name = "PhaserBlast";
				val6.effectModel = CreateEffectModelExt.Create(new Args
				{
					assetId = ModContent.CreatePrefabReference<PhaserBlast>(),
					lifespan = 0.2f
				});
				val6.lifespan = 0.2f;
				val6.durationFraction = 1f;
				val6.randomRotation = true;
				array[4] = (Model)CreateCreateEffectOnExhaustFractionModelExt.Create(val6);
				val.behaviors = (Model[])(object)array;
				val.filters = filters;
				ProjectileModel val7 = (emission.projectileInitialHitModel = CreateProjectileModelExt.Create(val));
				((Model)emission).AddChildDependant<ProjectileModel>(val7);
				emission.endProjectileSharesPierce = true;
				emission.emissionAtEndModel = (EmissionModel)(object)CreateSingleEmissionModelExt.Create();
				((Model)emission).AddChildDependant<EmissionModel>(emission.emissionAtEndModel);
			});
			foreach (DamageModel item in ModelExt.FindDescendants<ProjectileModel>((Model)(object)towerModel, "Phaser").SelectMany((ProjectileModel model) => ModelExt.FindDescendants<DamageModel>((Model)(object)model)))
			{
				float damage = item.damage;
				item.damage = damage + 1f;
			}
		}
	}
	public class FireAtWill : ModUpgrade<StarshipEnterprise>
	{
		public override int Path => 0;

		public override int Tier => 3;

		public override int Cost => 3000;

		public override string Icon => ((ModContent)this).Name;

		public override string Description => "Adds additional Phasers that fire at Strong and Close Bloons.";

		public override void ApplyUpgrade(TowerModel towerModel)
		{
			AttackModel obj = ModelExt.FindDescendant<AttackModel>((Model)(object)towerModel, "Phaser");
			AttackModel val = ModelExt.Duplicate<AttackModel>(obj, "PhaserStrong");
			AttackModelBehaviorExt.RemoveBehaviors<TargetSupplierModel>(val);
			((Model)val).RemoveChildDependant<TargetSupplierModel>(val.targetProvider);
			val.targetProvider = (TargetSupplierModel)(object)CreateTargetStrongAirUnitModelExt.Create();
			AttackModelBehaviorExt.AddBehavior<TargetSupplierModel>(val, val.targetProvider);
			((Model)val).GetChild<WeaponModel>().ejectX = -10f;
			WeaponModel child = ((Model)val).GetChild<WeaponModel>();
			child.Rate *= 1.41f;
			TowerModelBehaviorExt.AddBehavior<AttackModel>(towerModel, val);
			AttackModel val2 = ModelExt.Duplicate<AttackModel>(obj, "PhaserClose");
			AttackModelBehaviorExt.RemoveBehaviors<TargetSupplierModel>(val2);
			((Model)val2).RemoveChildDependant<TargetSupplierModel>(val2.targetProvider);
			val2.targetProvider = (TargetSupplierModel)(object)CreateTargetCloseAirUnitModelExt.Create();
			AttackModelBehaviorExt.AddBehavior<TargetSupplierModel>(val2, val2.targetProvider);
			((Model)val2).GetChild<WeaponModel>().ejectX = 10f;
			((Model)val2).GetChild<WeaponModel>().Rate = 1.73f;
			TowerModelBehaviorExt.AddBehavior<AttackModel>(towerModel, val2);
		}
	}
	public class PhaserPath : PathPlusPlus<StarshipEnterprise>
	{
		public override int UpgradeCount => 6;

		public override int ExtendVanillaPath => 0;

		public override bool ValidTiers(int[] tiers)
		{
			return PathPlusPlus.DefaultValidTiers(tiers.Take(3).ToArray());
		}
	}
	public class PhasersToMaximum : ModUpgrade<StarshipEnterprise>
	{
		public override int Path => 0;

		public override int Tier => 5;

		public override int Cost => 40000;

		public override string Icon => ((ModContent)this).Name;

		public override string Description => "Sets Phasers to their maximum power setting, dealing immense damage and crits.";

		public override void ApplyUpgrade(TowerModel towerModel)
		{
			foreach (DamageModel item in ModelExt.FindDescendants<ProjectileModel>((Model)(object)towerModel, "Phaser").SelectMany((ProjectileModel model) => ModelExt.FindDescendants<DamageModel>((Model)(object)model)))
			{
				item.damage *= 4f;
			}
			Il2CppGenericIEnumerable.ForEach<CritMultiplierModel>(((Model)towerModel).GetDescendants<CritMultiplierModel>(), (Action<CritMultiplierModel>)delegate(CritMultiplierModel model)
			{
				model.damage *= 4f;
			});
		}
	}
	public class PhaseVariance : ModUpgrade<StarshipEnterprise>
	{
		[HarmonyPatch(typeof(ShowTextOnHit), "Collide")]
		internal static class ShowTextOnHit_Collide
		{
			[HarmonyPrefix]
			private static bool Prefix(ShowTextOnHit __instance, Bloon bloon)
			{
				//IL_0034: Unknown result type (might be due to invalid IL or missing references)
				ShowTextOnHitModel showTextOnHitModel = __instance.showTextOnHitModel;
				if (!((Model)showTextOnHitModel).name.Contains("Phaser") || string.IsNullOrEmpty(showTextOnHitModel.text))
				{
					return true;
				}
				((RootObject)__instance).Sim.CreateTextEffect(Vector3Boxed.op_Implicit(((CommonBehaviorProxy<IBloonBehavior>)(object)bloon).Position), showTextOnHitModel.assetId, showTextOnHitModel.lifespan, showTextOnHitModel.text, false, (DisplayCategory)1);
				return false;
			}
		}

		public override int Path => 0;

		public override int Tier => 1;

		public override int Cost => 700;

		public override string Icon => ((ModContent)this).Name;

		public override string Description => "Phaser shots can critically strike Bloons for 10 damage.";

		public override void ApplyUpgrade(TowerModel towerModel)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: 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_0023: 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_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Expected O, but got Unknown
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Expected O, but got Unknown
			WeaponModelBehaviorExt.AddBehavior<CritMultiplierModel>(ModelExt.FindDescendant<WeaponModel>((Model)(object)towerModel, "Phaser"), CreateCritMultiplierModelExt.Create(new Args
			{
				damage = 10f,
				lower = 10,
				upper = 10,
				displayModel = CreateDisplayModelExt.Create(new Args
				{
					category = (DisplayCategory)16
				}),
				distributeToChildren = true
			}));
			ProjectileModel obj = ModelExt.FindDescendant<ProjectileModel>((Model)(object)towerModel, "Phaser");
			Args val = new Args();
			((ModelArgs<ShowTextOnHitModel>)val).name = "Phaser";
			val.assetId = ModContent.CreatePrefabReference("6eaf39977c73cf340b1ce55689e7a4e2");
			val.lifespan = 1f;
			ProjectileModelBehaviorExt.AddBehavior<ShowTextOnHitModel>(obj, CreateShowTextOnHitModelExt.Create(val));
		}
	}
	public class RepulsorBeams : ModUpgrade<StarshipEnterprise>
	{
		public override int Path => 0;

		public override int Tier => 2;

		public override int Cost => 1300;

		public override string Icon => ((ModContent)this).Name;

		public override string Description => "Phaser Beams deal more damage, and will push back Bloons.";

		public override void ApplyUpgrade(TowerModel towerModel)
		{
		}

		public override void LateApplyUpgrade(TowerModel towerModel)
		{
			KnockbackModel knockback = ((Model)Game.instance.model.GetTower(TowerType.SuperMonkey, 0, 0, Math.Clamp(towerModel.tier, 0, 5))).GetDescendant<KnockbackModel>();
			ArrayExt.ForEach<ProjectileModel>(ModelExt.FindDescendants<ProjectileModel>((Model)(object)towerModel, "Phaser"), (Action<ProjectileModel>)delegate(ProjectileModel projectile)
			{
				DamageModel damageModel = ProjectileModelExt.GetDamageModel(projectile);
				float damage = damageModel.damage;
				damageModel.damage = damage + 1f;
				ProjectileModelBehaviorExt.AddBehavior<KnockbackModel>(projectile, ModelExt.Duplicate<KnockbackModel>(knockback));
				projectile.UpdateCollisionPassList();
			});
		}
	}
}
namespace StarshipEnterprise.Upgrades.Engineering
{
	public class AuxiliaryPower : CareerPathUpgrade<Engineering>
	{
		public override int Cost => 1000;

		public override int Tier => 2;

		public override string Description => base.Description + "Boost the power of Enterprise's least upgraded weapon.";

		public override void ApplyUpgrade(TowerModel towerModel)
		{
			int min = ((IEnumerable<int>)towerModel.tiers).Min();
			float factor = 1f / (float)((IEnumerable<int>)towerModel.tiers).Count((int t) => t == min);
			if (((Il2CppArrayBase<int>)(object)towerModel.tiers)[0] == min)
			{
				Apply(towerModel, "Phaser", factor);
			}
			if (((Il2CppArrayBase<int>)(object)towerModel.tiers)[1] == min)
			{
				Apply(towerModel, "Torpedo", factor);
			}
			if (((Il2CppArrayBase<int>)(object)towerModel.tiers)[2] == min)
			{
				Apply(towerModel, "Cannon", factor);
			}
		}

		private static void Apply(TowerModel towerModel, string nameContains, float factor)
		{
			ArrayExt.ForEach<WeaponModel>(ModelExt.FindDescendants<WeaponModel>((Model)(object)towerModel, nameContains), (Action<WeaponModel>)delegate(WeaponModel weapon)
			{
				weapon.Rate /= 1f + factor;
				Il2CppGenericIEnumerable.ForEach<ProjectileModel>(((Model)weapon).GetDescendants<ProjectileModel>(), (Action<ProjectileModel>)delegate(ProjectileModel projectile)
				{
					projectile.pierce += (float)(int)Math.Ceiling(projectile.pierce * factor);
				});
				Il2CppGenericIEnumerable.ForEach<DamageModel>(((Model)weapon).GetDescendants<DamageModel>(), (Action<DamageModel>)delegate(DamageModel damage)
				{
					damage.damage += (float)(int)Math.Ceiling(damage.damage * factor);
				});
			});
		}
	}
	public class DeployRunabouts : CareerPathUpgrade<Engineering>
	{
		public override int Cost => 4000;

		public override int Tier => 3;

		public override string Description => base.Description + "Upgrades deployed Shuttles to stronger Danube-class Runabouts.";

		public override void ApplyUpgrade(TowerModel towerModel, int tier)
		{
			if (tier < 5)
			{
				Engineering.AddShuttles<RunaboutDisplay>(towerModel, 2, 5f);
			}
		}
	}
	public class DeployShuttlecraft : CareerPathUpgrade<Engineering>
	{
		public override int Cost => 800;

		public override int Tier => 1;

		public override string Description => base.Description + "Deploy 2 small Shuttles with slower copies of Enterprise's most upgraded weapon.";

		public override void ApplyUpgrade(TowerModel towerModel, int tier)
		{
			if (tier < 3)
			{
				Engineering.AddShuttles<ShuttleDisplay>(towerModel, 2, 10f);
			}
		}
	}
	public class EjectTheWarpCore : CareerPathUpgrade<Engineering>
	{
		public override int Cost => 30000;

		public override int Tier => 4;

		public override bool Ability => true;

		public override string Description => base.Description + "Ability: Eject the Warp Core, creating an Explosion that deals immense damage to all Bloons on Screen.";

		public override void ApplyUpgrade(TowerModel towerModel)
		{
			AbilityModel val = ModelExt.Duplicate<AbilityModel>(TowerModelExt.GetAbility(Game.instance.model.GetTower(TowerType.MonkeyAce, 0, 5, 0)), ((ModContent)this).Name);
			((Model)val).name = ((ModContent)this).Name;
			val.displayName = ((NamedModContent)this).DisplayName;
			val.description = ((NamedModContent)this).Description;
			val.icon = ((UpgradePlusPlus)this).IconReference;
			val.resetCooldownOnTierUpgrade = false;
			MiscModelExt.ApplyDisplay<WarpCoreExplosion>(((Model)val).GetDescendant<CreateEffectOnAbilityModel>().effectModel);
			AbilityModelBehaviorExt.RemoveBehavior<GroundZeroBombBuffModel>(val);
			ProjectileModel descendant = ((Model)val).GetDescendant<ProjectileModel>();
			descendant.pierce = 9999999f;
			ProjectileModelBehaviorExt.RemoveBehavior<SlowModel>(descendant);
			TowerModelBehaviorExt.AddBehavior<AbilityModel>(towerModel, val);
		}
	}
	public class Engineering : CareerPath
	{
		[HarmonyPatch(typeof(FighterMovement), "Process")]
		internal static class FighterMovement_Process
		{
			[HarmonyPrefix]
			private static void Prefix(FighterMovement __instance)
			{
				if (__instance.currentPathSupplier == null)
				{
					((RootBehavior)__instance).Attatched();
				}
			}
		}

		public override int UpgradeCount => 6;

		protected override int Order => 2;

		public static TowerModel GetBaseShuttle(string name, PrefabReference display, TargetSupplierModel targetProvider)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Expected O, but got Unknown
			TowerModel val = ModelExt.Duplicate<TowerModel>(((Model)Game.instance.model.GetTower(TowerType.MonkeyBuccaneer, 4, 0, 0)).GetDescendant<TowerModel>(), name);
			((EntityModel)val).baseId = name;
			val.towerSet = ModContent.GetTowerSet<Starfleet>();
			val.isGlobalRange = true;
			TowerModelBehaviorExt.RemoveBehaviors<AttackModel>(val);
			TowerModelBehaviorExt.RemoveBehavior<TowerExpireOnParentUpgradedModel>(val);
			TowerModelBehaviorExt.GetBehavior<AirUnitModel>(val).display = display;
			FighterMovementModel descendant = ((Model)val).GetDescendant<FighterMovementModel>();
			descendant.rollChancePerSecondPassed = 1E-08f;
			descendant.rollTimeBeforeNext = 1E+09f;
			descendant.bankAngleMax = 30f;
			Args val2 = new Args();
			val2.range = 2000f;
			val2.attackThroughWalls = true;
			val2.targetProvider = targetProvider;
			val2.behaviors = (Model[])(object)new Model[1] { (Model)targetProvider };
			TowerModelBehaviorExt.AddBehavior<AttackModel>(val, CreateAttackModelExt.Create(val2));
			val.UpdateTargetProviders();
			return val;
		}

		public static void AddShuttles<T>(TowerModel towerModel, int howMany, float factor) where T : ModDisplay
		{
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Expected O, but got Unknown
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Expected O, but got Unknown
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Expected O, but got Unknown
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Expected O, but got Unknown
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Expected O, but got Unknown
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Expected O, but got Unknown
			List<AttackModel> list = TowerModelExt.GetAttackModels(towerModel);
			int num = ((IEnumerable<int>)towerModel.tiers).Max();
			if (((Il2CppArrayBase<int>)(object)towerModel.tiers)[0] == num)
			{
				list = list.Where((AttackModel model) => ((Model)model).name.Contains("Phaser")).ToList();
			}
			else if (((Il2CppArrayBase<int>)(object)towerModel.tiers)[1] == num)
			{
				list = list.Where((AttackModel model) => ((Model)model).name.Contains("PhotonTorpedo")).ToList();
			}
			else if (((Il2CppArrayBase<int>)(object)towerModel.tiers)[2] == num)
			{
				list = list.Where((AttackModel model) => ((Model)model).name.Contains("PhaseCannon")).ToList();
			}
			TargetSupplierModel[] array = (TargetSupplierModel[])(object)new TargetSupplierModel[4]
			{
				(TargetSupplierModel)CreateFighterPilotPatternFirstModelExt.Create(new Args
				{
					offsetDistance = 40f,
					isOnSubTower = true
				}),
				(TargetSupplierModel)CreateFighterPilotPatternStrongModelExt.Create(new Args
				{
					offsetDistance = 40f,
					isOnSubTower = true
				}),
				(TargetSupplierModel)CreateFighterPilotPatternLastModelExt.Create(new Args
				{
					offsetDistance = 40f,
					isOnSubTower = true
				}),
				(TargetSupplierModel)CreateFighterPilotPatternCloseModelExt.Create(new Args
				{
					offsetDistance = 40f,
					isOnSubTower = true
				})
			};
			for (int num2 = 0; num2 < howMany; num2++)
			{
				string name = "Shuttle"