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 BuffsInShop;
using HarmonyLib;
using HonoraryParagons;
using Il2Cpp;
using Il2CppAssets.Scripts.Models;
using Il2CppAssets.Scripts.Models.Effects;
using Il2CppAssets.Scripts.Models.Entities;
using Il2CppAssets.Scripts.Models.GenericBehaviors;
using Il2CppAssets.Scripts.Models.Profile;
using Il2CppAssets.Scripts.Models.Towers;
using Il2CppAssets.Scripts.Models.Towers.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.Upgrades;
using Il2CppAssets.Scripts.Models.Towers.Weapons.Behaviors;
using Il2CppAssets.Scripts.Simulation.Input;
using Il2CppAssets.Scripts.Simulation.Objects;
using Il2CppAssets.Scripts.Simulation.SMath;
using Il2CppAssets.Scripts.Simulation.SimulationBehaviors;
using Il2CppAssets.Scripts.Simulation.Towers;
using Il2CppAssets.Scripts.Simulation.Towers.Behaviors;
using Il2CppAssets.Scripts.Unity;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppNinjaKiwi.Common;
using Il2CppNinjaKiwi.Common.ResourceUtils;
using MelonLoader;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(HonoraryParagonsMod), "Honorary Paragons", "1.0.3", "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("HonoraryParagons")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+2bcf10ad5231017dc34c96950c98360a3c9b93bf")]
[assembly: AssemblyProduct("HonoraryParagons")]
[assembly: AssemblyTitle("HonoraryParagons")]
[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 HonoraryParagons
{
public class HonoraryParagon : ModBuffInShop
{
public override string OriginTower => null;
public override string BaseDescription => "Converts a Tier 3 or higher tower into an Honorary Paragon. You can no longer upgrade or buff it, only invest into its Paragon Degree. Honorary Paragons can see Camo and pop all Bloon types, but don't do as much bonus damage to Elite Bosses.";
public override float BaseCost => 5000f;
public override KeyCode KeyCode => (KeyCode)92;
public override EffectModel? PlacementEffect => null;
public override AudioClipReference? PlacementSound => null;
public override bool IsBlocked(TowerInventory ti)
{
return false;
}
public override bool CanApplyTo(Tower tower, ref string helperMessage)
{
if (tower.towerModel.IsHero() && tower.towerModel.tier < 20)
{
helperMessage = "Hero must be max level";
return false;
}
if (tower.towerModel.tier < 3)
{
helperMessage = "Tower must be at least tier 3";
return false;
}
if (tower.towerModel.isParagon)
{
helperMessage = "Already a paragon";
return false;
}
return ((ModBuffInShop)this).CanApplyTo(tower, ref helperMessage);
}
public override BehaviorMutator GetMutator(Tower? tower)
{
return ((ModMutator)ModContent.GetInstance<HonoraryParagonMutator>()).Create((JToken)null);
}
public override void Apply(Tower tower, float purchaseCost = -1f, bool sideEffects = false)
{
((ModBuffInShop)this).Apply(tower, purchaseCost, sideEffects);
BloonsMod val = default(BloonsMod);
if (ModHelper.HasMod("TacticalTweaks", ref val) && val.ModSettings.TryGetValue("BuffableParagons", out var value))
{
ModSettingBool val2 = (ModSettingBool)(object)((value is ModSettingBool) ? value : null);
if (val2 != null && ModSettingBool.op_Implicit(val2))
{
goto IL_0157;
}
}
List<string> list = new List<string>();
BloonsMod val3 = default(BloonsMod);
if (ModHelper.HasMod("PathsPlusPlus", ref val3))
{
list.AddRange((IEnumerable<string>)val3.Call("GetPathIds", Array.Empty<object>()));
}
foreach (TimedMutator item in ((IEnumerable<TimedMutator>)((ListLite<TimedMutator>)(object)((Mutable)tower).mutators).ToArray()).Reverse())
{
if (item.mutator.id.Contains(((ModContent)this).Name) || list.Contains(item.mutator.id))
{
item.isParagonMutator = true;
}
if (!item.isParagonMutator && !item.mutator.isArtifactMutator)
{
tower.RemoveMutatorIncludeSubTowers(item.mutator);
}
}
goto IL_0157;
IL_0157:
Il2CppGenericIEnumerable.ForEach<ParagonOfPower>(((RootObject)tower).Sim.factory.GetUncast<ParagonOfPower>(), (Action<ParagonOfPower>)delegate(ParagonOfPower power)
{
power.CheckBuffs(tower, ((EntityModel)tower.towerModel).baseId, tower.owner, false);
});
}
public override void OnPlace(Vector2 at, TowerModel towerModelFake, Tower? tower, float towerCost)
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
if (tower != null)
{
((ModBuffInShop)this).OnPlace(at, towerModelFake, tower, towerCost);
ParagonTower towerBehavior = TowerBehaviorExt.GetTowerBehavior<ParagonTower>(tower);
EffectModel val = default(EffectModel);
if (Il2CppSystemObjectExt.Is<EffectModel>(towerBehavior.paragonTowerModel.effectDuringModel, ref val))
{
towerBehavior.effectDuring = SimulationExt.SpawnEffect(((RootObject)towerBehavior).Sim, val, (Vector3?)Vector3Boxed.op_Implicit(((CommonBehaviorProxy<ITowerBehavior>)(object)tower).Position), (RootBehavior)(object)((CommonBehaviorProxy<ITowerBehavior>)(object)tower).Transform);
}
towerBehavior.SetActive(false, true);
towerBehavior.activeAt = ((RootObject)towerBehavior).Sim.time.elapsed + towerBehavior.paragonTowerModel.inactiveDurationFrames;
towerBehavior.PlayParagonUpgradeSound();
}
}
public static UpgradeModel GetParagonUpgrade(GameModel gameModel, string id)
{
//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
//IL_00d4: Expected O, but got Unknown
string text = id.Split("_").Skip(1).First();
TowerModel towerWithName = gameModel.GetTowerWithName(text);
string[] source = id.Split("_").Last().Split(",");
UpgradeModel[] source2 = ((IEnumerable<string>)source).Select((Func<string, UpgradeModel>)gameModel.GetUpgrade).ToArray();
float cost = gameModel.GetTowerWithName(ModContent.TowerID<HonoraryParagon>(0, 0, 0)).cost;
if (towerWithName.IsHero())
{
return new UpgradeModel(((EntityModel)towerWithName).baseId, (int)(cost + ModSettingDouble.op_Implicit((ModSettingDouble)(object)HonoraryParagonsMod.InternalCostFactor) * (float)source2.Sum((UpgradeModel model) => model.xpCost) / 2f), 0, towerWithName.icon, 0, 0, 0, "", "");
}
UpgradeModel val = ModelExt.Duplicate<UpgradeModel>(source2.MaxBy((UpgradeModel upgrade) => upgrade.tier));
val.cost = (int)(ModSettingDouble.op_Implicit((ModSettingDouble)(object)HonoraryParagonsMod.InternalCostFactor) * source2.Aggregate(towerWithName.cost + cost, (float num, UpgradeModel model) => num + (float)model.cost));
return val;
}
public static string GetParagonUpgradeId(TowerModel towerModel)
{
return "HonoraryParagon_" + ((Model)towerModel).name + "_" + GeneralExtensions.Join<string>((IEnumerable<string>)towerModel.appliedUpgrades, (Func<string, string>)null, ",");
}
public static void Paragonify(TowerModel towerModel)
{
towerModel.isParagon = true;
ParagonTowerModel val = ModelExt.Duplicate<ParagonTowerModel>(TowerModelBehaviorExt.GetBehavior<ParagonTowerModel>(Game.instance.model.GetParagonTower(TowerType.DartMonkey)));
foreach (AssetPathModel item in (Il2CppArrayBase<AssetPathModel>)(object)val.displayDegreePaths)
{
ModelExt.SetName<AssetPathModel>(item, ((Model)towerModel).name);
item.assetPath = ((EntityModel)towerModel).display;
}
TowerModelBehaviorExt.AddBehavior<ParagonTowerModel>(towerModel, val);
List<string> list = ((IEnumerable<string>)towerModel.appliedUpgrades).ToList();
string paragonUpgradeId = GetParagonUpgradeId(towerModel);
while (list.Count < 6)
{
list.Add(paragonUpgradeId);
}
list[5] = paragonUpgradeId;
towerModel.appliedUpgrades = Il2CppStringArray.op_Implicit(list.ToArray());
Il2CppGenericIEnumerable.ForEach<DamageModel>(((Model)towerModel).GetDescendants<DamageModel>(), (Action<DamageModel>)delegate(DamageModel model)
{
model.immuneBloonProperties = (BloonProperties)0;
});
Il2CppGenericIEnumerable.ForEach<ProjectileModel>(((Model)towerModel).GetDescendants<ProjectileModel>(), (Action<ProjectileModel>)delegate(ProjectileModel projectile)
{
DamageModifierForTagModel val2 = default(DamageModifierForTagModel);
DamageModifierForTagModel val3 = default(DamageModifierForTagModel);
if (ProjectileModelBehaviorExt.HasBehavior<DamageModifierForTagModel>(projectile, "BonusBossDamage", ref val2) && ProjectileModelBehaviorExt.HasBehavior<DamageModifierForTagModel>(projectile, "FinalEliteBossDamageBonus", ref val3))
{
DamageModifierForTagModel obj = val3;
obj.damageMultiplier -= 1f / val2.damageMultiplier;
}
});
Il2CppGenericIEnumerable.ForEach<FilterInvisibleModel>(((Model)towerModel).GetDescendants<FilterInvisibleModel>(), (Action<FilterInvisibleModel>)delegate(FilterInvisibleModel invis)
{
invis.isActive = false;
});
}
}
public class HonoraryParagonMutator : ModMutator
{
public override BuffIndicatorModel BuffIcon => ModBuffIcon.op_Implicit((ModBuffIcon)(object)ModContent.GetInstance<HonoraryParagonIcon>());
public override int Priority => 50;
public override string MutatorId => "HonoraryParagon";
public override bool Mutate(Model baseModel, Model model, JToken data)
{
HonoraryParagon.Paragonify(((Il2CppObjectBase)model).Cast<TowerModel>());
return true;
}
}
public class HonoraryParagonIcon : ModBuffIcon
{
public override string Icon => "Ui[ParagonPip]";
}
public class HonoraryParagonsMod : BloonsTD6Mod
{
public static readonly ModSettingFloat InternalCostFactor = new ModSettingFloat(1f)
{
description = "The internal multiplier that Honorary Paragons use for determining what their pretend paragon upgrade cost is for the purposes of calculating power investments. Higher numbers mean it takes more money to add additional power."
};
public override void OnTowerSaved(Tower tower, TowerSaveDataModel saveData)
{
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
if (((Mutable)tower).IsMutatedBy("HonoraryParagon"))
{
InvestmentInfo investmentInfo = TowerBehaviorExt.GetTowerBehavior<ParagonTower>(tower).investmentInfo;
saveData.metaData["HonoraryParagonDegree"] = JsonConvert.SerializeObject((object)investmentInfo);
}
}
public override void OnTowerLoaded(Tower tower, TowerSaveDataModel saveData)
{
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
string text = default(string);
if (!saveData.metaData.TryGetValue("HonoraryParagonDegree", ref text))
{
return;
}
ParagonTower val = default(ParagonTower);
if (Il2CppSystemObjectExt.Is<ParagonTower>(TowerBehaviorExt.GetTowerBehavior<ParagonTower>(tower), ref val))
{
InvestmentInfo investmentInfo = JsonConvert.DeserializeObject<InvestmentInfo>(text);
val.investmentInfo = investmentInfo;
val.UpdateDegree();
return;
}
TaskScheduler.ScheduleTask((Action)delegate
{
((BloonsTD6Mod)this).OnTowerLoaded(tower, saveData);
}, (Func<bool>)(() => TowerBehaviorExt.GetTowerBehavior<ParagonTower>(tower) != null), (Func<bool>)(() => ((RootObject)tower).IsDestroyed));
}
public override object Call(string operation, params object[] parameters)
{
if (1 == 0)
{
}
object result;
if (!(operation == "GetParagonUpgradeId"))
{
if (!(operation == "GetParagonUpgrade"))
{
goto IL_0073;
}
GameModel gameModel = default(GameModel);
string id = default(string);
if (ArrayExt.CheckTypes<GameModel, string>(parameters, ref gameModel, ref id))
{
result = HonoraryParagon.GetParagonUpgrade(gameModel, id);
}
else
{
GameModel gameModel2 = default(GameModel);
TowerModel towerModel = default(TowerModel);
if (!ArrayExt.CheckTypes<GameModel, TowerModel>(parameters, ref gameModel2, ref towerModel))
{
goto IL_0073;
}
result = HonoraryParagon.GetParagonUpgrade(gameModel2, HonoraryParagon.GetParagonUpgradeId(towerModel));
}
}
else
{
TowerModel towerModel2 = default(TowerModel);
if (!ArrayExt.CheckTypes<TowerModel>(parameters, ref towerModel2))
{
goto IL_0073;
}
result = HonoraryParagon.GetParagonUpgradeId(towerModel2);
}
goto IL_007f;
IL_007f:
if (1 == 0)
{
}
return result;
IL_0073:
result = ((BloonsMod)this).Call(operation, parameters);
goto IL_007f;
}
}
public static class ModHelperData
{
public const string WorksOnVersion = "54.3";
public const string Version = "1.0.3";
public const string Name = "Honorary Paragons";
public const string Description = "Adds a custom buff to the shop that turns a regular tier 3+ tower into an Honorary Paragon.\nYou can no longer upgrade or buff an Honorary Paragon, but can invest into its Paragon Degree to increase its power.\nHonorary Paragons can see Camo and pop all Bloon types, but don't do as much bonus damage to Elite Bosses.\n\nRequires Paragonomics and Buffs in Shop";
public const string RepoOwner = "doombubbles";
public const string PrevRepoName = "honorary-paragons";
public const string RepoName = "HonoraryParagons";
public const string Dependencies = "doombubbles/paragonomics,doombubbles/buffs-in-shop";
public const string Icon = "HonoraryParagon.png";
}
[HarmonyPatch(typeof(GameModel), "GetUpgrade")]
internal static class GameModel_GetUpgrade
{
[HarmonyPrefix]
internal static bool Prefix(GameModel __instance, string id, ref UpgradeModel __result)
{
if (!id.StartsWith("HonoraryParagon"))
{
return true;
}
__result = HonoraryParagon.GetParagonUpgrade(__instance, id);
return false;
}
}
[HarmonyPatch(typeof(PowerDegreeMutator), "MutateTower")]
internal static class PowerDegreeMutator_MutateTower
{
[HarmonyPostfix]
internal static void Postfix(PowerDegreeMutator __instance, TowerModel tower)
{
Il2CppGenericIEnumerable.ForEach<CashModel>(((Model)tower).GetDescendants<CashModel>(), (Action<CashModel>)delegate(CashModel cash)
{
cash.bonusMultiplier += __instance.percentDamageUp / 100f;
});
Il2CppGenericIEnumerable.ForEach<EmissionsPerRoundFilterModel>(((Model)tower).GetDescendants<EmissionsPerRoundFilterModel>(), (Action<EmissionsPerRoundFilterModel>)delegate(EmissionsPerRoundFilterModel filter)
{
filter.count += Math.CeilToInt((float)filter.count * __instance.attackCooldownReductionPercent / 100f);
});
Il2CppGenericIEnumerable.ForEach<PerRoundCashBonusTowerModel>(((Model)tower).GetDescendants<PerRoundCashBonusTowerModel>(), (Action<PerRoundCashBonusTowerModel>)delegate(PerRoundCashBonusTowerModel bonus)
{
bonus.cashRoundBonusMultiplier += __instance.percentDamageUp / 100f;
});
Il2CppGenericIEnumerable.ForEach<BankModel>(((Model)tower).GetDescendants<BankModel>(), (Action<BankModel>)delegate(BankModel bank)
{
bank.interest *= 1f + __instance.attackCooldownReductionPercent / 100f;
bank.capacity += (float)Math.RoundToNearestInt(bank.capacity * __instance.percentPierceUp / 100f, 500);
});
}
}
}