From 4975b4d7d597ff0b409c51269ad4b7e848f4553f Mon Sep 17 00:00:00 2001 From: Niko Date: Thu, 27 Nov 2025 14:42:12 +0000 Subject: [PATCH] Add BossChecklist support --- Content/NPCs/OriginalNiko/Niko.cs | 45 +++++--- Content/NPCs/OriginalNiko/NikoAvaliScout.cs | 24 +++++ Content/NPCs/OriginalNiko/NikoAvaliScout.png | Bin 0 -> 504 bytes Content/NPCs/TownNPCs/AvalianTrader.cs | 3 +- ForgottenWawiTech.cs | 2 +- .../en-US_Mods.ForgottenWawiTech.hjson | 2 + Systems/BossChecklist.cs | 100 ++++++++++++++++++ 7 files changed, 159 insertions(+), 17 deletions(-) create mode 100644 Content/NPCs/OriginalNiko/NikoAvaliScout.cs create mode 100644 Content/NPCs/OriginalNiko/NikoAvaliScout.png create mode 100644 Systems/BossChecklist.cs diff --git a/Content/NPCs/OriginalNiko/Niko.cs b/Content/NPCs/OriginalNiko/Niko.cs index 3fb6498..614c7b4 100644 --- a/Content/NPCs/OriginalNiko/Niko.cs +++ b/Content/NPCs/OriginalNiko/Niko.cs @@ -21,35 +21,36 @@ namespace ForgottenWawiTech.Content.NPCs.OriginalNiko { NPC.width = 40; NPC.height = 40; - NPC.damage = 2000; - NPC.defense = 300; - NPC.lifeMax = 1000000; + NPC.damage = 20000; + NPC.defense = 500; + NPC.lifeMax = 10000000; NPC.HitSound = SoundID.NPCHit1; NPC.DeathSound = SoundID.NPCDeath1; - NPC.knockBackResist = 0f; + NPC.knockBackResist = 0.5f; NPC.boss = true; NPC.aiStyle = -1; - NPC.value = Item.buyPrice(0, 1, 0, 0); + NPC.value = Item.buyPrice(100, 0, 0, 0); } public override void AI() { /* IDEA: - Phase 1: Somewhat tame, false sense of security. 75% HP + Phase 1: Somewhat tame, false sense of security. Until 75% HP Phase 1.5: Invulnerable, drifts around, monologue for ~1 minute - Phase 2: Heal 50% HP + Phase 2: Heal 50% HP back, more aggressive behaviour until 50% HP Phase 3: Spawn other bosses if undefeated Phase 3.5: After other bosses are defeated (or if they aren't spawned), short pause for dialogue - Phase 4: Final behaviour + Phase 4: More aggressive behaviour until 20% HP + Phase 5: Final behaviour. Practically no restrictions on movement or attacks. Each individual phase I have yet to fully plan out, but the main idea is simple. What if we uncapped a Player's limitations and slapped them as a boss with near end-game gear? - Nintendo don't sue me - I am only copying Inner Agent 3 here. Alongside rough ideas of the Uzi and Cyn fight from Murder Drones. - Music (if legality allows) is planned to be a rock-ier remix of "In The End" by Linkin Park, fitting Niko's emo ass. + Starting music will be a piano remix of "Famous Last Words" by My Chemical Romance, transitioning into a metal-ier remix of "In The End" by Linkin Park for phase 2 onwards, finishing with a + more sombre remix of "My Way" by Frank Sinatra for the ending. */ /* - IDEA: Enraged Behaviour - Attack 1: + IDEA: Attacks + Attack 1 (Phase 2 onwards): Niko will use the Shockwave Hammer (fortnite) and start rapidly bouncing towards the closest player, making large arcs in the air while rapidly spinning. They can not change direction while in the air. They will throw out Nyananades while in this state, designed to either overwhelm or lag the player to death. When nearing a player, they will slam on/next to the player, inflicting extremely high damage. If this doesn't kill the player, Niko will then throw/swing the hammer at the player with predictive aiming, which on hit @@ -67,8 +68,24 @@ namespace ForgottenWawiTech.Content.NPCs.OriginalNiko Niko will grab a cannon and start launching Avali Scouts at the player with high velocity. These Avali Scouts will have 1/10th of Niko's health and deal 1/10th of Niko's damage, but will swarm the player in large numbers. They will prioritise players with the lowest health. + Attack 5: + Niko will throw out a large number of black holes that will slowly drift towards the player. + These black holes will pull players in slowly, dealing high DOT damage to players caught in the pull. + Players can escape the pull with enough movement speed (or rod of discord). + Attack 6: + Niko will summon a large number of holographic clones of themself that will mimic their movements. + These clones will deal 1/20th of Niko's damage and have 1/20th of Niko's health, but will swarm the player in large numbers. + The clones can not use attack 1 (bounce slam) but can use all other attacks. + Attack 7: + Niko will use a modified and uncapped version of the Zenith, allowing them to fire three large arcs of swords that home in on the player. + These swords will deal high damage on hit and fully pierce through players, hitting multiple times. + Attack 8: + Niko will use an uncapped Meowmere/True Nyanageddon, allowing them to bombard the player with a large number of cat projectiles. + These cat projectiles will home in on the player, dealing moderate damage on hit. + The cats will also inflict a stacking debuff that increases damage taken by 2% per stack, up to 25 stacks (50% increased damage taken). Each attack will be used in a semi-random order, with ~0.5 second gaps between each attack to allow the player to reposition. - This will repeat until the player is defeated or Niko is defeated. + All attacks will have their damage and health scaled based on the current phase, with later phases having higher damage and health for all attacks. + Plus, all projectiles will use predictive aiming to make dodging more difficult. */ NPC.TargetClosest(false); @@ -255,8 +272,6 @@ namespace ForgottenWawiTech.Content.NPCs.OriginalNiko // Immediate sync of world flags WorldDefeatedBosses.Sync(ModContent.GetInstance()); } - - } public override void ModifyNPCLoot(NPCLoot npcLoot) diff --git a/Content/NPCs/OriginalNiko/NikoAvaliScout.cs b/Content/NPCs/OriginalNiko/NikoAvaliScout.cs new file mode 100644 index 0000000..866e130 --- /dev/null +++ b/Content/NPCs/OriginalNiko/NikoAvaliScout.cs @@ -0,0 +1,24 @@ +// See Niko.cs for intended behavior and design details. +using Terraria; +using Terraria.ID; +using Terraria.ModLoader; + +namespace ForgottenWawiTech.Content.NPCs.OriginalNiko +{ + public class NikoAvaliScout : ModNPC + { + public override void SetDefaults() + { + NPC.width = 40; + NPC.height = 40; + NPC.damage = 2000; + NPC.defense = 100; + NPC.lifeMax = 100000; + NPC.HitSound = SoundID.NPCHit1; + NPC.DeathSound = SoundID.NPCDeath1; + NPC.knockBackResist = 0.5f; + NPC.aiStyle = 3; // Fighter AI + NPC.value = Item.buyPrice(0, 10, 0, 0); + } + } +} \ No newline at end of file diff --git a/Content/NPCs/OriginalNiko/NikoAvaliScout.png b/Content/NPCs/OriginalNiko/NikoAvaliScout.png new file mode 100644 index 0000000000000000000000000000000000000000..9e0cf81e52f4133dbe85453dd9a37993af17b5be GIT binary patch literal 504 zcmeAS@N?(olHy`uVBq!ia0vp^0U*r53?z4+XPOVBbOU@sT!FNbf{DF-NtsjE_3B;! z|NjSy0D+K@p01v+t9x8zR#D@WS?dlQ`1+YJESG!@x4dC7*`C93=UXkhhvvt!hjSLlJ~RwmnP~Bh_e#*cGOJz5H)U2RZk=*d{>S{o z|7E^K_FWXNcxrjXh&wV*Hfp0Ti%!ljhM&t`NT+&77>M@wN(xASbQfH=B6&8`PK|k& o(pT;d?|57xzrgJ7^Ax@sCjQeEzP*#>W`d&2)78&qol`;+07t#pIRF3v literal 0 HcmV?d00001 diff --git a/Content/NPCs/TownNPCs/AvalianTrader.cs b/Content/NPCs/TownNPCs/AvalianTrader.cs index 9121c1c..98ca693 100644 --- a/Content/NPCs/TownNPCs/AvalianTrader.cs +++ b/Content/NPCs/TownNPCs/AvalianTrader.cs @@ -29,7 +29,8 @@ namespace ForgottenWawiTech.Content.NPCs.TownNPCs private static readonly Condition HasDefeatedCorruptedSwarm = new("Mods.ForgottenWawiTech.Conditions.HasDefeatedCorruptedSwarm", () => Main.hardMode && WorldDefeatedBosses.Niko); // TODO: Replace with Corrupted Swarm flag once implemented. - private static readonly Condition HasDefeatedExoMechs = new("Mods.ForgottenWawiTech.Conditions.HasDefeatedExoMechs", CheckExoMechsDowned); + private static readonly Condition HasDefeatedExoMechs = new("Mods.ForgottenWawiTech.Conditions.HasDefeatedExoMechs", () => + CheckExoMechsDowned()); private static readonly Condition HasDefeatedMoonLord = new("Mods.ForgottenWawiTech.Conditions.HasDefeatedMoonLord", () => NPC.downedMoonlord); diff --git a/ForgottenWawiTech.cs b/ForgottenWawiTech.cs index 9a4c0c6..e374eb9 100644 --- a/ForgottenWawiTech.cs +++ b/ForgottenWawiTech.cs @@ -10,7 +10,7 @@ using Terraria.ModLoader.IO; namespace ForgottenWawiTech { - // Please read https://github.com/tModLoader/tModLoader/wiki/Basic-tModLoader-Modding-Guide#mod-skeleton-contents for more information about the various files in a mod. + // Please read https://github.com/tmodLoader/tmodLoader/wiki/Basic-tmodLoader-modding-Guide#mod-skeleton-contents for more information about the various files in a mod. public class ForgottenWawiTech : Mod { diff --git a/Localization/en-US_Mods.ForgottenWawiTech.hjson b/Localization/en-US_Mods.ForgottenWawiTech.hjson index 3e759f4..ab66023 100644 --- a/Localization/en-US_Mods.ForgottenWawiTech.hjson +++ b/Localization/en-US_Mods.ForgottenWawiTech.hjson @@ -1067,6 +1067,8 @@ NPCs: { LoveNPC: I love {NPCName}. } } + + NikoAvaliScout.DisplayName: Niko Avali Scout } Projectiles: { diff --git a/Systems/BossChecklist.cs b/Systems/BossChecklist.cs new file mode 100644 index 0000000..4c44bfe --- /dev/null +++ b/Systems/BossChecklist.cs @@ -0,0 +1,100 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System; +using System.Collections.Generic; +using Terraria.ModLoader; +using Terraria; +using Terraria.ID; + +namespace ForgottenWawiTech.Systems +{ + public class BossChecklist : ModSystem + { + public override void PostSetupContent() + { + if (ModLoader.TryGetMod("BossChecklist", out Mod bossChecklist)) + { + // For reference, SCal is 23f and Boss Rush is 25.99f. The lower the float, the earlier it appears in the list. + // Lyyka + bossChecklist.Call( + "LogBoss", + Mod, + nameof(Content.NPCs.OriginalLyyka.Lyyka), + 24f, + () => WorldDefeatedBosses.Lyyka, + ModContent.NPCType(), + new Dictionary + { + { "spawnItem", ModContent.ItemType() } + } + ); + // Terra (Miniboss of Lyyka) + bossChecklist.Call( + "LogMiniBoss", + Mod, + nameof(Content.NPCs.OriginalLyyka.Terra), + 24.01f, + () => WorldDefeatedBosses.Terra, + ModContent.NPCType() + ); + // Clara (Miniboss of Lyyka) + bossChecklist.Call( + "LogMiniBoss", + Mod, + nameof(Content.NPCs.OriginalLyyka.Clara), + 24.02f, + () => WorldDefeatedBosses.Clara, + ModContent.NPCType() + ); + // Neptune + bossChecklist.Call( + "LogBoss", + Mod, + nameof(Content.NPCs.OriginalNeptune.Neptune), + 24.1f, + () => WorldDefeatedBosses.Neptune, + ModContent.NPCType(), + new Dictionary + { + { "spawnItem", ModContent.ItemType() } + } + ); + // Raccoon + bossChecklist.Call( + "LogMiniBoss", + Mod, + nameof(Content.NPCs.OriginalNeptune.Raccoon), + 24.11f, + () => WorldDefeatedBosses.Raccoon, + ModContent.NPCType() + ); + // Lexy + bossChecklist.Call( + "LogBoss", + Mod, + nameof(Content.NPCs.OriginalLexy.Lexy), + 24.2f, + () => WorldDefeatedBosses.Lexy, + ModContent.NPCType(), + new Dictionary + { + { "spawnItem", ModContent.ItemType() } + } + ); + // Niko + bossChecklist.Call( + "LogBoss", + Mod, + nameof(Content.NPCs.OriginalNiko.Niko), + 24.7f, + () => WorldDefeatedBosses.Niko, + ModContent.NPCType(), + new Dictionary + { + { "spawnItem", ModContent.ItemType() } + } + ); + } + } + } +} \ No newline at end of file