Skip to content

Commit

Permalink
Fixes and balance
Browse files Browse the repository at this point in the history
  • Loading branch information
doombubbles committed Jul 27, 2023
1 parent 7786314 commit a80986e
Show file tree
Hide file tree
Showing 16 changed files with 119 additions and 97 deletions.
7 changes: 2 additions & 5 deletions LATEST.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,2 @@
- Fixed issue with Dartling and Mortar targeting not always applying for all matches
- Internally revamped Dartling and Mortar target changing for improved consistency
- Spike Empowerment now restricts targeted point to within the tower's range by default
- Enable the "OP Spike Empowerment" option in mod settings to restore old behavior
- Fixed the scales of Dreadnought projectiles
- Fixed for BTD6 v38
- Consolidated OP setting toggles into one, and added more balancing for the non-op setting Mega Knowledges
27 changes: 5 additions & 22 deletions MegaKnowledgeMod.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,29 +25,12 @@ namespace MegaKnowledge;
public class MegaKnowledgeMod : BloonsTD6Mod
{
public static MelonPreferences_Category MegaKnowledgeCategory;

public static readonly ModSettingBool OpOvertime = new(false)
{
description =
"Re-enables the old OP behavior of the Engineering Mega Knowledge \"Overtime\" also affecting the Engineer sentries.",
icon = VanillaSprites.SentryGunUpgradeIcon,
displayName = "OP Overtime"
};

public static readonly ModSettingBool OpCrystalBall = new(false)
{
description =
"Wizards with the Guided Magic upgrade can still shoot through walls while using the \"Crystal Ball\" Mega Knowledge.",
icon = VanillaSprites.GuildedMagicUpgradeIcon,
displayName = "OP Crystal Ball"
};

public static readonly ModSettingBool OpSpikeEmpowerment = new(false)
public static readonly ModSettingBool OpKnowledge = new(false)
{
description =
"Re-enables the old behavior of the \"Spike Empowerment\" Mega Knowledge letting Spike Factories target anywhere on the map.",
icon = VanillaSprites.SpikeFactoryIcon,
displayName = "OP Spike Empowerment"
description = "Re-enables the old OP behavior of many MegaKnowledges before they were rebalanced",
icon = VanillaSprites.MaxPowersIcon,
displayName = "OP Knowledge"
};

#if DEBUG
Expand All @@ -69,7 +52,7 @@ public override void OnUpdate()
}
}

public override void OnNewGameModel(GameModel result, Il2CppSystem.Collections.Generic.List<ModModel> mods)
public override void OnNewGameModel(GameModel result, IReadOnlyList<ModModel> mods)
{
var knowledgeDisabled = Game.instance.GetPlayerProfile().knowledgeDisabled ||
mods.ToList().Any(model =>
Expand Down
10 changes: 5 additions & 5 deletions MegaKnowledges/Magic/CrystalBall.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class CrystalBall : MegaKnowledge
public override string TowerId => TowerType.WizardMonkey;

public override string Description =>
MegaKnowledgeMod.OpCrystalBall
MegaKnowledgeMod.OpKnowledge
? "The Guided Magic upgrade gives Wizard Monkeys Advanced Intel style targeting"
: "Instead of letting Wizard Monkeys see through walls, the Guided Magic upgrade gives them Advanced Intel style targeting.";

Expand All @@ -24,7 +24,7 @@ public override void Apply(TowerModel model)
{
if (!model.appliedUpgrades.Contains(UpgradeType.GuidedMagic)) return;

if (!MegaKnowledgeMod.OpCrystalBall)
if (!MegaKnowledgeMod.OpKnowledge)
{
model.ignoreBlockers = false;
}
Expand Down Expand Up @@ -60,7 +60,7 @@ public override void Apply(TowerModel model)
true, true, false, false));
}

if (!MegaKnowledgeMod.OpCrystalBall)
if (!MegaKnowledgeMod.OpKnowledge)
{
attackModel.attackThroughWalls = false;
}
Expand All @@ -77,15 +77,15 @@ public override void Apply(TowerModel model)
var travelStraitModel = projectileModel.GetBehavior<TravelStraitModel>();
if (travelStraitModel != null)
{
var newLifeSpan = travelStraitModel.Lifespan * (150 / travelStraitModel.Speed);
var newLifeSpan = travelStraitModel.Lifespan * (200 / travelStraitModel.Speed);
travelStraitModel.Lifespan = Math.Max(travelStraitModel.Lifespan, newLifeSpan);
if (projectileModel.GetBehavior<TrackTargetModel>() == null)
{
projectileModel.AddBehavior(guidedMagic.Duplicate());
}
}

if (!MegaKnowledgeMod.OpCrystalBall)
if (!MegaKnowledgeMod.OpKnowledge)
{
projectileModel.ignoreBlockers = false;
}
Expand Down
12 changes: 5 additions & 7 deletions MegaKnowledges/Magic/ShadowDouble.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,20 @@ public override void Apply(TowerModel model)
var weapon = attackModel.weapons[0];
var newWeapon = weapon.Duplicate();
newWeapon.projectile.display = CreatePrefabReference<ShadowShuriken>();
weapon.AddBehavior(new FireAlternateWeaponModel("FireAlternateWeaponModel_", 1));
weapon.AddBehavior(new FireAlternateWeaponModel("", 1));

newWeapon.AddBehavior(new FireWhenAlternateWeaponIsReadyModel("FireWhenAlternateWeaponIsReadyModel_", 1));
newWeapon.AddBehavior(new FilterTargetAngleFilterModel("FilterTargetAngleFilterModel_", 45.0f, 180f, true,
newWeapon.AddBehavior(new FireWhenAlternateWeaponIsReadyModel("", 1));
newWeapon.AddBehavior(new FilterTargetAngleFilterModel("", 45.0f, 180f, true,
56));

var arcEmissionModel = newWeapon.emission.TryCast<ArcEmissionModel>();
if (arcEmissionModel != null)
{
newWeapon.emission.AddBehavior(
new EmissionArcRotationOffTowerDirectionModel("EmissionArcRotationOffTowerDirectionModel_", 180));
newWeapon.emission.AddBehavior(new EmissionArcRotationOffTowerDirectionModel("", 180));
}
else
{
newWeapon.emission.AddBehavior(
new EmissionRotationOffTowerDirectionModel("EmissionRotationOffTowerDirectionModel_", 180));
newWeapon.emission.AddBehavior(new EmissionRotationOffTowerDirectionModel("", 180));
}

newWeapon.name += " Secondary";
Expand Down
14 changes: 9 additions & 5 deletions MegaKnowledges/Magic/TheBigThree.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,17 @@ public class TheBigThree : MegaKnowledge

public override void Apply(TowerModel model)
{
if (model.tier < 3) return;
var supeFilter = new FilterInBaseTowerIdModel("Filter_Supes", new[] {TowerType.SuperMonkey});
if (model.tier < 3) return;

var supeFilter = new FilterInBaseTowerIdModel("Filter_Supes", new[] { TowerType.SuperMonkey });

var tier = MegaKnowledgeMod.OpKnowledge ? model.tier : model.tier - 2;

var buffs = new[]
{
new RateSupportModel("", 1f - model.tier * .05f, true, "TheBigThree1", false, 0, null, null, null)
new RateSupportModel("", 1f - tier * .05f, true, "TheBigThree1", false, 0, null, null, null)
.ApplyBuffIcon<SunAvatarIcon>(),
new RangeSupportModel("", true, model.tier * .05f, 0f, "TheBigThree2", null, false, null, null)
new RangeSupportModel("", true, tier * .05f, 0f, "TheBigThree2", null, false, null, null)
.ApplyBuffIcon<RoboMonkeyIcon>(),
new PierceSupportModel("", true, model.tier, "TheBigThree3", null, false, null, null)
.ApplyBuffIcon<DarkKnightIcon>()
Expand All @@ -45,7 +49,7 @@ public override void Apply(TowerModel model)
buffForPath.filters = new TowerFilterModel[]
{
supeFilter.Duplicate(),
new FilterInTowerTiersModel("FilterInTowerTiersModel_",
new FilterInTowerTiersModel("",
otherPath == 0 ? 3 : 0, 5,
otherPath == 1 ? 3 : 0, 5,
otherPath == 2 ? 3 : 0, 5)
Expand Down
2 changes: 1 addition & 1 deletion MegaKnowledges/Military/AttackAndSupport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public override void Apply(TowerModel model)
if (submerge.heroXpScale > 1.0)
{
model.AddBehavior(new HeroXpScaleSupportModel("HeroXpScaleSupportModel_", true, submerge.heroXpScale,
null));
null, submerge.buffLocsName, submerge.buffIconName));
}

if (submerge.abilityCooldownSpeedScale > 1.0)
Expand Down
28 changes: 20 additions & 8 deletions MegaKnowledges/Military/Dreadnought.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Linq;
using BTD_Mod_Helper.Api.Enums;
using Il2CppAssets.Scripts.Models.Bloons.Behaviors;
using Il2CppAssets.Scripts.Models.Towers;
using Il2CppAssets.Scripts.Models.Towers.Projectiles;
Expand All @@ -18,26 +19,37 @@ public class Dreadnought : MegaKnowledge
public override void Apply(TowerModel model)
{
var attackModel = model.GetAttackModel();
var flameGrape = Game.instance.model.GetTower(TowerType.MonkeyBuccaneer, 0, 2, 0).GetWeapons()[3]
.projectile;
var flameGrape = Game.instance.model.GetTower(TowerType.MonkeyBuccaneer, 0, 2, 0)
.GetDescendant<AddBehaviorToBloonModel>();

foreach (var projectileModel in attackModel.GetDescendants<ProjectileModel>().ToList()
.Where(projectileModel => !projectileModel.name.Contains("Explosion") &&
projectileModel.GetDamageModel() != null))
{
projectileModel.collisionPasses = flameGrape.collisionPasses;
if (!projectileModel.HasBehavior<AddBehaviorToBloonModel>())
{
projectileModel.AddBehavior(flameGrape.GetBehavior<AddBehaviorToBloonModel>().Duplicate());
projectileModel.AddBehavior(flameGrape.Duplicate());
}

var dot = projectileModel.GetDescendant<DamageOverTimeModel>();
var hotShots = model.appliedUpgrades.Contains(UpgradeType.HotShot);

if (MegaKnowledgeMod.OpKnowledge)
{
dot.triggerImmediate = hotShots;
}
if (model.appliedUpgrades.Contains("Buccaneer-Hot Shot"))
else if (!hotShots)
{
projectileModel.GetBehavior<AddBehaviorToBloonModel>().GetBehavior<DamageOverTimeModel>()
.triggerImmediate = true;
dot.damage = 1;
}

projectileModel.scale = projectileModel.radius > 3 ? .7f : .5f;
projectileModel.display = CreatePrefabReference("c840e245a0b1deb4284cfc3f953e16cf");
projectileModel.GetDamageModel().immuneBloonProperties = BloonProperties.None;

var damage = projectileModel.GetDamageModel();
damage.immuneBloonProperties = damage.immuneBloonPropertiesOriginal = BloonProperties.None;

projectileModel.UpdateCollisionPassList();
}
}
}
6 changes: 3 additions & 3 deletions MegaKnowledges/Military/RifleRange.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ public class RifleRange : MegaKnowledge
public override void Apply(TowerModel model)
{
var damage = model.GetWeapon().projectile.GetDamageModel().damage;
model.GetWeapon().AddBehavior(new CritMultiplierModel("CritMultiplierModel_", damage * 2, 1, 6,
new DisplayModel("DisplayModel_Crit", CreatePrefabReference("252e82e70578330429a758339e10fd25"), 0, DisplayCategory.Effect),
model.GetWeapon().AddBehavior(new CritMultiplierModel("", damage * 2, 1, 6,
new DisplayModel("Crit", CreatePrefabReference("252e82e70578330429a758339e10fd25"), 0, DisplayCategory.Effect),
true));

model.GetWeapon().projectile.AddBehavior(new ShowTextOnHitModel("ShowTextOnHitModel_",
model.GetWeapon().projectile.AddBehavior(new ShowTextOnHitModel("",
CreatePrefabReference("3dcdbc19136c60846ab944ada06695c0"), 0.5f, false, ""));
}
}
41 changes: 29 additions & 12 deletions MegaKnowledges/Primary/BombVoyage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,49 @@
using Il2CppAssets.Scripts.Models.Towers.Projectiles;
using Il2CppAssets.Scripts.Models.Towers.Projectiles.Behaviors;
using BTD_Mod_Helper.Extensions;
using HarmonyLib;
using Il2Cpp;
using Il2CppAssets.Scripts.Data;
using Il2CppAssets.Scripts.Models.Store;
using Il2CppAssets.Scripts.Models.Towers.Filters;
using Il2CppAssets.Scripts.Unity.CollectionEvent;
using Il2CppAssets.Scripts.Unity.UI_New.InGame;

namespace MegaKnowledge.MegaKnowledges.Primary;

public class BombVoyage : MegaKnowledge
{
public override string TowerId => TowerType.BombShooter;
public override string Description => "Bomb Shooters' projectiles travel much faster and can damage any Bloon type.";

public override string Description =>
MegaKnowledgeMod.OpKnowledge
? "Bomb Shooters' projectiles travel much faster and can damage any Bloon type."
: "Bomb Shooters' projectiles travel much faster, and explosions can splash damage onto Camo bloons.";

public override int Offset => -400;

public override void Apply(TowerModel model)
{
foreach (var projectileModel in model.GetDescendants<ProjectileModel>().ToList())
var projectile = model.GetAttackModel().weapons[0].projectile;
var travelStraitModel = projectile.GetBehavior<TravelStraitModel>();
var createProjectileOnContactModel = projectile.GetBehavior<CreateProjectileOnContactModel>();
if (travelStraitModel != null && createProjectileOnContactModel != null)
{
var damageModel = projectileModel.GetBehavior<DamageModel>();
if (damageModel != null)
{
damageModel.immuneBloonProperties = BloonProperties.None;
}
travelStraitModel.Speed *= MegaKnowledgeMod.OpKnowledge ? 2 : 1.5f;
}

var travelStraitModel = projectileModel.GetBehavior<TravelStraitModel>();
var createProjectileOnContactModel = projectileModel.GetBehavior<CreateProjectileOnContactModel>();
if (travelStraitModel != null && createProjectileOnContactModel != null)
if (MegaKnowledgeMod.OpKnowledge)
{
model.GetDescendants<DamageModel>().ForEach(damageModel =>
{
travelStraitModel.Speed *= 2;
}
damageModel.immuneBloonProperties = BloonProperties.None;
});
}
else
{
model.GetDescendants<ProjectileModel>().ForEach(p =>
p.GetDescendants<FilterInvisibleModel>().ForEach(invisibleModel => invisibleModel.isActive = false)
);
}
}
}
8 changes: 7 additions & 1 deletion MegaKnowledges/Primary/DoubleRanga.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,17 @@ namespace MegaKnowledge.MegaKnowledges.Primary;
public class DoubleRanga : MegaKnowledge
{
public override string TowerId => TowerType.BoomerangMonkey;
public override string Description => "Boomerang Monkeys throw 2 Boomerangs at a time!";

public override string Description => MegaKnowledgeMod.OpKnowledge
? "Boomerang Monkeys throw 2 Boomerangs at a time!"
: "Boomerang Monkeys tier 3 and below throw 2 Boomerangs at a time!";

public override int Offset => -800;

public override void Apply(TowerModel model)
{
if (model.tier > 3 && !MegaKnowledgeMod.OpKnowledge) return;

var weaponModel = model.GetAttackModel().weapons[0];
var random = new RandomArcEmissionModel("RandomArcEmissionModel_", 2, 0, 0, 30, 1, null);
var eM = new ArcEmissionModel("ArcEmissionModel_", 2, 0, 30, null, false, false);
Expand Down
3 changes: 2 additions & 1 deletion MegaKnowledges/Primary/IceSeeYou.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Il2CppAssets.Scripts.Models.Towers.Projectiles;
using Il2CppAssets.Scripts.Models.Towers.Projectiles.Behaviors;
using BTD_Mod_Helper.Extensions;
using Il2CppAssets.Scripts.Models.Towers.Filters;
using Il2CppSystem.Collections.Generic;

namespace MegaKnowledge.MegaKnowledges.Primary;
Expand All @@ -22,6 +23,6 @@ public override void Apply(TowerModel model)
projectileModel.AddBehavior(behavior.Duplicate());
}

model.AddBehavior(new OverrideCamoDetectionModel("OverrideCamoDetectionModel_", true));
model.GetDescendants<FilterInvisibleModel>().ForEach(invisibleModel => invisibleModel.isActive = false);
}
}
35 changes: 18 additions & 17 deletions MegaKnowledges/Primary/SplodeyDarts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,46 +13,47 @@ namespace MegaKnowledge.MegaKnowledges.Primary;
public class SplodeyDarts : MegaKnowledge
{
public override string TowerId => TowerType.DartMonkey;
public override string Description => "Dart Monkey projectiles explode on expiration.";

public override string Description => MegaKnowledgeMod.OpKnowledge
? "Dart Monkey projectiles explode on expiration."
: "Dart Monkey projectiles for Tier 3 and below explode on expiration.";

public override int Offset => -1200;

public override void Apply(TowerModel model)
{
if (model.tier > 3 && !MegaKnowledgeMod.OpKnowledge) return;

var baseBomb = Game.instance.model.GetTowerFromId(TowerType.BombShooter).GetWeapon().projectile;
foreach (var projectileModel in model.GetDescendants<ProjectileModel>().ToList())
{
var bomb = Game.instance.model.GetTowerFromId(TowerType.BombShooter).GetWeapon()
.projectile.Duplicate();
var bomb = baseBomb.Duplicate();
var pb = bomb.GetBehavior<CreateProjectileOnContactModel>();
var sound = bomb.GetBehavior<CreateSoundOnProjectileCollisionModel>();
var effect = bomb.GetBehavior<CreateEffectOnContactModel>();


if (model.appliedUpgrades.Contains(UpgradeType.EnhancedEyesight))
{
pb.projectile.GetBehavior<ProjectileFilterModel>().filters
.GetItemOfType<FilterModel, FilterInvisibleModel>().isActive = false;
pb.projectile.GetDescendant<FilterInvisibleModel>().isActive = false;
}

/*pb.name = "CreateProjectileOnContactModel_SplodeyDarts";
sound.name = "CreateSoundOnProjectileCollisionModel_SplodeyDarts";
effect.name = "CreateEffectOnContactModel_SplodeyDarts";
projectileModel.AddBehavior(pb);
projectileModel.AddBehavior(sound);
projectileModel.AddBehavior(effect);*/

var behavior = new CreateProjectileOnExhaustFractionModel(
"CreateProjectileOnExhaustFractionModel_SplodeyDarts",
var behavior = new CreateProjectileOnExhaustFractionModel("SplodeyDarts",
pb.projectile, pb.emission, 1f, 1f, true, false, false);
projectileModel.AddBehavior(behavior);

var soundBehavior = new CreateSoundOnProjectileExhaustModel(
"CreateSoundOnProjectileExhaustModel_SplodeyDarts",
var soundBehavior = new CreateSoundOnProjectileExhaustModel("SplodeyDarts",
sound.sound1, sound.sound2, sound.sound3, sound.sound4, sound.sound5);
projectileModel.AddBehavior(soundBehavior);

var eB = new CreateEffectOnExhaustedModel("CreateEffectOnExhaustedModel_SplodeyDarts",
var eB = new CreateEffectOnExhaustedModel("SplodeyDarts",
CreatePrefabReference(""), 0f, Fullscreen.No, false, effect.effectModel);
projectileModel.AddBehavior(eB);

if (!MegaKnowledgeMod.OpKnowledge)
{
pb.projectile.pierce = 5;
}
}
}
}
Loading

0 comments on commit a80986e

Please sign in to comment.