diff --git a/LATEST.md b/LATEST.md index e21cd35..c884d30 100644 --- a/LATEST.md +++ b/LATEST.md @@ -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 \ No newline at end of file +- Fixed for BTD6 v38 +- Consolidated OP setting toggles into one, and added more balancing for the non-op setting Mega Knowledges \ No newline at end of file diff --git a/MegaKnowledgeMod.cs b/MegaKnowledgeMod.cs index c18fc65..dd3e7cf 100644 --- a/MegaKnowledgeMod.cs +++ b/MegaKnowledgeMod.cs @@ -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 @@ -69,7 +52,7 @@ public override void OnUpdate() } } - public override void OnNewGameModel(GameModel result, Il2CppSystem.Collections.Generic.List mods) + public override void OnNewGameModel(GameModel result, IReadOnlyList mods) { var knowledgeDisabled = Game.instance.GetPlayerProfile().knowledgeDisabled || mods.ToList().Any(model => diff --git a/MegaKnowledges/Magic/CrystalBall.cs b/MegaKnowledges/Magic/CrystalBall.cs index 83284c8..cb3c6f3 100644 --- a/MegaKnowledges/Magic/CrystalBall.cs +++ b/MegaKnowledges/Magic/CrystalBall.cs @@ -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."; @@ -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; } @@ -60,7 +60,7 @@ public override void Apply(TowerModel model) true, true, false, false)); } - if (!MegaKnowledgeMod.OpCrystalBall) + if (!MegaKnowledgeMod.OpKnowledge) { attackModel.attackThroughWalls = false; } @@ -77,7 +77,7 @@ public override void Apply(TowerModel model) var travelStraitModel = projectileModel.GetBehavior(); 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() == null) { @@ -85,7 +85,7 @@ public override void Apply(TowerModel model) } } - if (!MegaKnowledgeMod.OpCrystalBall) + if (!MegaKnowledgeMod.OpKnowledge) { projectileModel.ignoreBlockers = false; } diff --git a/MegaKnowledges/Magic/ShadowDouble.cs b/MegaKnowledges/Magic/ShadowDouble.cs index 10359da..1fbfc73 100644 --- a/MegaKnowledges/Magic/ShadowDouble.cs +++ b/MegaKnowledges/Magic/ShadowDouble.cs @@ -23,22 +23,20 @@ public override void Apply(TowerModel model) var weapon = attackModel.weapons[0]; var newWeapon = weapon.Duplicate(); newWeapon.projectile.display = CreatePrefabReference(); - 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(); 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"; diff --git a/MegaKnowledges/Magic/TheBigThree.cs b/MegaKnowledges/Magic/TheBigThree.cs index cdc055e..090f332 100644 --- a/MegaKnowledges/Magic/TheBigThree.cs +++ b/MegaKnowledges/Magic/TheBigThree.cs @@ -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(), - new RangeSupportModel("", true, model.tier * .05f, 0f, "TheBigThree2", null, false, null, null) + new RangeSupportModel("", true, tier * .05f, 0f, "TheBigThree2", null, false, null, null) .ApplyBuffIcon(), new PierceSupportModel("", true, model.tier, "TheBigThree3", null, false, null, null) .ApplyBuffIcon() @@ -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) diff --git a/MegaKnowledges/Military/AttackAndSupport.cs b/MegaKnowledges/Military/AttackAndSupport.cs index 1bd49c8..ca05415 100644 --- a/MegaKnowledges/Military/AttackAndSupport.cs +++ b/MegaKnowledges/Military/AttackAndSupport.cs @@ -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) diff --git a/MegaKnowledges/Military/Dreadnought.cs b/MegaKnowledges/Military/Dreadnought.cs index a857d81..4adbb9f 100644 --- a/MegaKnowledges/Military/Dreadnought.cs +++ b/MegaKnowledges/Military/Dreadnought.cs @@ -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; @@ -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(); + foreach (var projectileModel in attackModel.GetDescendants().ToList() .Where(projectileModel => !projectileModel.name.Contains("Explosion") && projectileModel.GetDamageModel() != null)) { - projectileModel.collisionPasses = flameGrape.collisionPasses; if (!projectileModel.HasBehavior()) { - projectileModel.AddBehavior(flameGrape.GetBehavior().Duplicate()); + projectileModel.AddBehavior(flameGrape.Duplicate()); + } + + var dot = projectileModel.GetDescendant(); + 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().GetBehavior() - .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(); } } } \ No newline at end of file diff --git a/MegaKnowledges/Military/RifleRange.cs b/MegaKnowledges/Military/RifleRange.cs index f907ebd..bf76354 100644 --- a/MegaKnowledges/Military/RifleRange.cs +++ b/MegaKnowledges/Military/RifleRange.cs @@ -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, "")); } } \ No newline at end of file diff --git a/MegaKnowledges/Primary/BombVoyage.cs b/MegaKnowledges/Primary/BombVoyage.cs index 43df765..8ed8cd9 100644 --- a/MegaKnowledges/Primary/BombVoyage.cs +++ b/MegaKnowledges/Primary/BombVoyage.cs @@ -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().ToList()) + var projectile = model.GetAttackModel().weapons[0].projectile; + var travelStraitModel = projectile.GetBehavior(); + var createProjectileOnContactModel = projectile.GetBehavior(); + if (travelStraitModel != null && createProjectileOnContactModel != null) { - var damageModel = projectileModel.GetBehavior(); - if (damageModel != null) - { - damageModel.immuneBloonProperties = BloonProperties.None; - } + travelStraitModel.Speed *= MegaKnowledgeMod.OpKnowledge ? 2 : 1.5f; + } - var travelStraitModel = projectileModel.GetBehavior(); - var createProjectileOnContactModel = projectileModel.GetBehavior(); - if (travelStraitModel != null && createProjectileOnContactModel != null) + if (MegaKnowledgeMod.OpKnowledge) + { + model.GetDescendants().ForEach(damageModel => { - travelStraitModel.Speed *= 2; - } + damageModel.immuneBloonProperties = BloonProperties.None; + }); + } + else + { + model.GetDescendants().ForEach(p => + p.GetDescendants().ForEach(invisibleModel => invisibleModel.isActive = false) + ); } } } \ No newline at end of file diff --git a/MegaKnowledges/Primary/DoubleRanga.cs b/MegaKnowledges/Primary/DoubleRanga.cs index 7133f74..61b78a6 100644 --- a/MegaKnowledges/Primary/DoubleRanga.cs +++ b/MegaKnowledges/Primary/DoubleRanga.cs @@ -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); diff --git a/MegaKnowledges/Primary/IceSeeYou.cs b/MegaKnowledges/Primary/IceSeeYou.cs index 3af2e43..36109c5 100644 --- a/MegaKnowledges/Primary/IceSeeYou.cs +++ b/MegaKnowledges/Primary/IceSeeYou.cs @@ -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; @@ -22,6 +23,6 @@ public override void Apply(TowerModel model) projectileModel.AddBehavior(behavior.Duplicate()); } - model.AddBehavior(new OverrideCamoDetectionModel("OverrideCamoDetectionModel_", true)); + model.GetDescendants().ForEach(invisibleModel => invisibleModel.isActive = false); } } \ No newline at end of file diff --git a/MegaKnowledges/Primary/SplodeyDarts.cs b/MegaKnowledges/Primary/SplodeyDarts.cs index 9466ff7..b0b458f 100644 --- a/MegaKnowledges/Primary/SplodeyDarts.cs +++ b/MegaKnowledges/Primary/SplodeyDarts.cs @@ -13,15 +13,21 @@ 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().ToList()) { - var bomb = Game.instance.model.GetTowerFromId(TowerType.BombShooter).GetWeapon() - .projectile.Duplicate(); + var bomb = baseBomb.Duplicate(); var pb = bomb.GetBehavior(); var sound = bomb.GetBehavior(); var effect = bomb.GetBehavior(); @@ -29,30 +35,25 @@ public override void Apply(TowerModel model) if (model.appliedUpgrades.Contains(UpgradeType.EnhancedEyesight)) { - pb.projectile.GetBehavior().filters - .GetItemOfType().isActive = false; + pb.projectile.GetDescendant().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; + } } } } \ No newline at end of file diff --git a/MegaKnowledges/Support/DigitalAmplification.cs b/MegaKnowledges/Support/DigitalAmplification.cs index 7ccd567..a0f7d1a 100644 --- a/MegaKnowledges/Support/DigitalAmplification.cs +++ b/MegaKnowledges/Support/DigitalAmplification.cs @@ -11,11 +11,13 @@ public class DigitalAmplification : MegaKnowledge public override void Apply(TowerModel model) { - model.range *= 2; + var amount = MegaKnowledgeMod.OpKnowledge ? 2 : 1.5f; + + model.range *= amount; foreach (var attackModel in model.GetAttackModels()) { - attackModel.range *= 2; + attackModel.range *= amount; } } } \ No newline at end of file diff --git a/MegaKnowledges/Support/Overtime.cs b/MegaKnowledges/Support/Overtime.cs index 1806e5d..568be11 100644 --- a/MegaKnowledges/Support/Overtime.cs +++ b/MegaKnowledges/Support/Overtime.cs @@ -3,6 +3,7 @@ using Il2CppAssets.Scripts.Unity; using Il2CppAssets.Scripts.Unity.UI_New.InGame; using BTD_Mod_Helper.Extensions; +using Il2CppSystem.Linq; namespace MegaKnowledge.MegaKnowledges.Support; @@ -10,13 +11,12 @@ public class Overtime : MegaKnowledge { public override string TowerId => TowerType.EngineerMonkey; - public override string Description => MegaKnowledgeMod.OpOvertime + public override string Description => MegaKnowledgeMod.OpKnowledge ? "Engineers and their sentries are permanently overclocked." : "Engineers permanently Overclock themselves."; public override int Offset => 1200; - public override void Apply(TowerModel model) { } @@ -27,11 +27,12 @@ public override void OnUpdate() .GetTower(TowerType.EngineerMonkey, 0, 4) .GetAbility() .GetBehavior(); - foreach (var tts in InGame.instance.bridge.GetAllTowers()) + + foreach (var tts in InGame.instance.bridge.GetAllTowers().ToArray()) { var baseId = tts.tower.towerModel.baseId; - if ((baseId == TowerType.EngineerMonkey || - baseId.Contains(TowerType.Sentry) && MegaKnowledgeMod.OpOvertime) && + if ((baseId == TowerType.EngineerMonkey && (!tts.Def.isParagon || MegaKnowledgeMod.OpKnowledge) || + baseId.Contains(TowerType.Sentry) && MegaKnowledgeMod.OpKnowledge) && tts.tower.GetMutatorById("Overclock") == null) { tts.tower.AddMutator(overclock.Mutator, -1, false); diff --git a/MegaKnowledges/Support/SpikeEmpowerment.cs b/MegaKnowledges/Support/SpikeEmpowerment.cs index 9032690..d850dd5 100644 --- a/MegaKnowledges/Support/SpikeEmpowerment.cs +++ b/MegaKnowledges/Support/SpikeEmpowerment.cs @@ -31,7 +31,7 @@ public override void Apply(TowerModel model) { var tspm = new TargetSelectedPointModel("TargetSelectedPointModel_", true, false, CreatePrefabReference("f786dd2ad0e3e8649a8ff0ac9f8cc6fb"), 1, "", - !MegaKnowledgeMod.OpSpikeEmpowerment, false, CreatePrefabReference("d053160180f53da43be4f9972ee1497a"), + !MegaKnowledgeMod.OpKnowledge, !MegaKnowledgeMod.OpKnowledge, CreatePrefabReference("d053160180f53da43be4f9972ee1497a"), true, null, true); model.GetAttackModel().AddBehavior(tspm); } diff --git a/ModHelperData.cs b/ModHelperData.cs index d17e850..1b348e4 100644 --- a/ModHelperData.cs +++ b/ModHelperData.cs @@ -2,8 +2,8 @@ public static class ModHelperData { - public const string WorksOnVersion = "37.0"; - public const string Version = "1.2.2"; + public const string WorksOnVersion = "38.0"; + public const string Version = "1.2.3"; public const string Name = "Mega Knowledge"; public const string Description =