From f44703376fca8539e0ce21bf4567a404f565aa33 Mon Sep 17 00:00:00 2001 From: Niko Date: Fri, 14 Nov 2025 22:36:20 +0000 Subject: [PATCH] add beam wand (thanks lexy) --- Content/Items/Global/EyeOfCthulhuBagLoot.cs | 20 +++ Content/Items/Weapons/Magic/BeamAttackWand.cs | 95 ++++++++++++++ .../Items/Weapons/Magic/BeamAttackWand.png | Bin 0 -> 4051 bytes .../AvalianInvasion/AvalianEliteCommando.cs | 119 ++++++++++++++++++ .../AvalianInvasion/AvalianRifleman.cs | 85 +++++++++++++ .../Enemies/AvalianInvasion/AvalianScout.cs | 62 +++++++++ .../AvalianInvasion/AvalianTechnician.cs | 97 ++++++++++++++ Content/Players/BeamAttackWandPlayer.cs | 22 ++++ Content/Projectiles/BeamAttackWandBeam.cs | 94 ++++++++++++++ Content/Projectiles/BeamAttackWandBeam.png | Bin 0 -> 9685 bytes Content/Projectiles/ChargedBeamAttackWand.png | Bin 0 -> 43300 bytes .../en-US_Mods.ForgottenWawiTech.hjson | 10 ++ 12 files changed, 604 insertions(+) create mode 100644 Content/Items/Global/EyeOfCthulhuBagLoot.cs create mode 100644 Content/Items/Weapons/Magic/BeamAttackWand.cs create mode 100644 Content/Items/Weapons/Magic/BeamAttackWand.png create mode 100644 Content/NPCs/Enemies/AvalianInvasion/AvalianEliteCommando.cs create mode 100644 Content/NPCs/Enemies/AvalianInvasion/AvalianRifleman.cs create mode 100644 Content/NPCs/Enemies/AvalianInvasion/AvalianScout.cs create mode 100644 Content/NPCs/Enemies/AvalianInvasion/AvalianTechnician.cs create mode 100644 Content/Players/BeamAttackWandPlayer.cs create mode 100644 Content/Projectiles/BeamAttackWandBeam.cs create mode 100644 Content/Projectiles/BeamAttackWandBeam.png create mode 100644 Content/Projectiles/ChargedBeamAttackWand.png diff --git a/Content/Items/Global/EyeOfCthulhuBagLoot.cs b/Content/Items/Global/EyeOfCthulhuBagLoot.cs new file mode 100644 index 0000000..30b2ee1 --- /dev/null +++ b/Content/Items/Global/EyeOfCthulhuBagLoot.cs @@ -0,0 +1,20 @@ +using Terraria; +using Terraria.ID; +using Terraria.ModLoader; +using Terraria.GameContent.ItemDropRules; + +namespace ForgottenWawiTech.Content.Items.Global +{ + // Adds BeamAttackWand to Eye of Cthulhu treasure bag loot table. + public class EyeOfCthulhuBagLoot : GlobalItem + { + public override void ModifyItemLoot(Item item, ItemLoot itemLoot) + { + if (item.type == ItemID.EyeOfCthulhuBossBag) + { + // 1 in 3 chance (adjust if too common) + itemLoot.Add(ItemDropRule.Common(ModContent.ItemType(), 3)); + } + } + } +} diff --git a/Content/Items/Weapons/Magic/BeamAttackWand.cs b/Content/Items/Weapons/Magic/BeamAttackWand.cs new file mode 100644 index 0000000..2d8249b --- /dev/null +++ b/Content/Items/Weapons/Magic/BeamAttackWand.cs @@ -0,0 +1,95 @@ +using ForgottenWawiTech.Content.Projectiles; +using ForgottenWawiTech.Content.Players; +using Microsoft.Xna.Framework; +using Terraria; +using Terraria.ID; +using Terraria.ModLoader; + +namespace ForgottenWawiTech.Content.Items.Weapons.Magic +{ + // A post-Eye of Cthulhu melee/magic hybrid style weapon that swings like a sword and + // emits a flurry of short-lived beam projectiles toward the cursor during the swing. + // Beams have reduced damage (50% of item base) and very short lifetime. + public class BeamAttackWand : ModItem + { + public override void SetStaticDefaults() + { + // DisplayName.SetDefault("Beam Attack Wand"); // tML auto localizes; optional if using hjson. + // Tooltip.SetDefault("Swings and releases a flurry of brief energy beams"); + } + + public override void SetDefaults() + { + Item.width = 32; + Item.height = 32; + Item.useStyle = ItemUseStyleID.Swing; + Item.useAnimation = 28; // frames the swing lasts + Item.useTime = 28; // one use per full animation + Item.autoReuse = true; + Item.UseSound = SoundID.Item1; + Item.damage = 25; + Item.knockBack = 4.5f; + Item.DamageType = DamageClass.Magic; // treat beams as melee for synergy + Item.rare = ItemRarityID.Blue; // around early game progression + Item.value = Item.buyPrice(silver: 50); + Item.shoot = ModContent.ProjectileType(); + Item.shootSpeed = 12f; // base speed of beams + Item.noMelee = false; + Item.mana = 3; + } + + // No recipe: obtained from Eye of Cthulhu treasure bag (see GlobalItem loot class) + + public override void HoldItem(Player player) + { + // Emit beams only while the item is mid-swing + if (player.itemAnimation > 0 && player.HeldItem.type == Item.type && player.whoAmI == Main.myPlayer) + { + var modPlayer = player.GetModPlayer(); + modPlayer.BeamEmissionTimer--; + if (modPlayer.BeamEmissionTimer <= 0) + { + // Kirby-style beam: a sweeping whip that leaves a multi-beam arc. + // We'll spawn several beams at once in a tight angular spread around a smoothed central swing rotation. + float targetRot = player.itemRotation + (player.direction == -1 ? MathHelper.Pi : 0f); + if (modPlayer.LastBeamRot == 0f) + modPlayer.LastBeamRot = targetRot; + // Smooth aggressively so the arc persists briefly (lower factor = larger persistence) + float smoothedRot = modPlayer.LastBeamRot + MathHelper.WrapAngle(targetRot - modPlayer.LastBeamRot) * 0.25f; + modPlayer.LastBeamRot = smoothedRot; + + // Determine swing progress (0..1) to slightly widen arc near middle of swing + float swingProgress = 1f - (player.itemAnimation / (float)player.itemAnimationMax); + // Arc width scales up mid-swing then back down + float baseArc = 0.30f; // radians total small arc + float arcWidth = baseArc * (float)(1.0 - System.Math.Pow(2 * swingProgress - 1, 2)); // bell curve widen + + int beamsThisBurst = 4; // number of simultaneous beams + int beamDamage = (int)(Item.damage * 0.45f); // slight reduction since multiple per tick + for (int i = 0; i < beamsThisBurst; i++) + { + // Evenly distribute within arc centered on smoothedRot + float lerp = beamsThisBurst == 1 ? 0f : i / (float)(beamsThisBurst - 1); + float offset = MathHelper.Lerp(-arcWidth * 0.5f, arcWidth * 0.5f, lerp); + float beamRot = smoothedRot + offset; + Vector2 dir = beamRot.ToRotationVector2(); + if (dir.HasNaNs()) dir = new Vector2(player.direction, 0f); + dir = dir.SafeNormalize(new Vector2(player.direction, 0f)); + + // Stagger spawn distance to create a whip chain illusion (front beams slightly further) + float distance = 14f + 3f * i; + Vector2 spawnPos = player.Center + dir * distance + new Vector2(0f, -4f); + Vector2 velocity = dir * Item.shootSpeed * (1f + i * 0.05f); // slight incremental speed + + Projectile.NewProjectile(player.GetSource_ItemUse(Item), spawnPos, velocity, + Item.shoot, beamDamage, Item.knockBack, player.whoAmI); + } + + // Emit burst every 3 ticks to keep DPS reasonable while visually dense + modPlayer.BeamEmissionTimer = 3; + } + } + } + } +} + diff --git a/Content/Items/Weapons/Magic/BeamAttackWand.png b/Content/Items/Weapons/Magic/BeamAttackWand.png new file mode 100644 index 0000000000000000000000000000000000000000..9dc9497a0c19be38857d19bef8bf280c9ad65997 GIT binary patch literal 4051 zcmeAS@N?(olHy`uVBq!ia0vp^3P3E!!3HFKxnwkf6k~CayA$KhlREW44okYDuOkD) z#(wTUiL5}rLb6AYF9SoB8UsT^3j@P1pisjL28L1t28LG&3=CE?7#PG0=Ijcz0ZMQd zctjR6FmMZlFeAgPITAoY_7YEDSN50Od}7i}rp%Z3Ffj0Idb&7nIXLM-V#{tVnS9t5NxcjBF7;xpEGgsfwl9nKum#!z^6~2zyjzYG4w+~ zY8@ob8KFMsh5B5a9TEa^oDllacLVr_c7DKxK*LMQAP0N8`njxg HN@xNAPC= 180 && distanceToPlayer > 200f) + { + teleportTimer = 0; + + // Teleport dust effect + for (int i = 0; i < 20; i++) + { + Dust.NewDust(NPC.position, NPC.width, NPC.height, DustID.Electric); + } + + // Teleport near player + Vector2 teleportPos = target.Center + new Vector2(Main.rand.Next(-200, 200), -150); + NPC.position = teleportPos; + + for (int i = 0; i < 20; i++) + { + Dust.NewDust(NPC.position, NPC.width, NPC.height, DustID.Electric); + } + } + + // Rapid fire attack every 30 frames (0.5 seconds) + if (attackTimer >= 30) + { + attackTimer = 0; + + if (Main.netMode != NetmodeID.MultiplayerClient) + { + Vector2 shootDirection = Vector2.Normalize(target.Center - NPC.Center); + + // Triple shot spread + for (int i = -1; i <= 1; i++) + { + Vector2 perturbedSpeed = shootDirection.RotatedBy(MathHelper.ToRadians(15 * i)); + Projectile.NewProjectile(NPC.GetSource_FromAI(), NPC.Center, + perturbedSpeed * 14f, ProjectileID.MartianTurretBolt, + NPC.damage / 3, 1f); + } + } + } + + // Aggressive movement + if (distanceToPlayer > 150f) + { + NPC.velocity = toPlayer * 6f; + } + } + } + + public override void HitEffect(NPC.HitInfo hit) + { + if (NPC.life <= 0) + { + // Epic death effects + for (int i = 0; i < 20; i++) + { + Dust.NewDust(NPC.position, NPC.width, NPC.height, DustID.Feather); + } + for (int i = 0; i < 15; i++) + { + Dust.NewDust(NPC.position, NPC.width, NPC.height, DustID.Electric); + } + } + } + + public override float SpawnChance(NPCSpawnInfo spawnInfo) + { + return 0f; // Controlled by invasion system + } + } +} diff --git a/Content/NPCs/Enemies/AvalianInvasion/AvalianRifleman.cs b/Content/NPCs/Enemies/AvalianInvasion/AvalianRifleman.cs new file mode 100644 index 0000000..30d3821 --- /dev/null +++ b/Content/NPCs/Enemies/AvalianInvasion/AvalianRifleman.cs @@ -0,0 +1,85 @@ +using Terraria; +using Terraria.ID; +using Terraria.ModLoader; +using Microsoft.Xna.Framework; + +namespace ForgottenWawiTech.Content.NPCs.Enemies.AvalianInvasion +{ + public class AvalianRifleman : ModNPC + { + private int shootTimer = 0; + + public override void SetStaticDefaults() + { + Main.npcFrameCount[Type] = 6; + NPCID.Sets.NPCBestiaryDrawModifiers value = new NPCID.Sets.NPCBestiaryDrawModifiers(0) + { + Velocity = 1f + }; + NPCID.Sets.NPCBestiaryDrawOffset.Add(Type, value); + } + + public override void SetDefaults() + { + NPC.width = 34; + NPC.height = 42; + NPC.damage = 55; + NPC.defense = 20; + NPC.lifeMax = 400; + NPC.HitSound = SoundID.NPCHit1; + NPC.DeathSound = SoundID.NPCDeath6; + NPC.value = Item.buyPrice(0, 0, 10, 0); + NPC.knockBackResist = 0.3f; + NPC.aiStyle = NPCAIStyleID.Bat; // Flying ranged enemy + } + + public override void AI() + { + // Ranged attack behavior + Player target = Main.player[NPC.target]; + if (target.active && !target.dead) + { + shootTimer++; + + // Keep distance from player + float distanceToPlayer = Vector2.Distance(NPC.Center, target.Center); + if (distanceToPlayer < 300f) + { + // Move away + Vector2 awayDirection = Vector2.Normalize(NPC.Center - target.Center); + NPC.velocity = awayDirection * 3f; + } + + // Shoot every 90 frames (1.5 seconds) + if (shootTimer >= 90) + { + shootTimer = 0; + + if (Main.netMode != NetmodeID.MultiplayerClient) + { + Vector2 shootDirection = Vector2.Normalize(target.Center - NPC.Center); + Projectile.NewProjectile(NPC.GetSource_FromAI(), NPC.Center, + shootDirection * 10f, ProjectileID.BulletHighVelocity, + NPC.damage / 2, 1f); + } + } + } + } + + public override void HitEffect(NPC.HitInfo hit) + { + if (NPC.life <= 0) + { + for (int i = 0; i < 12; i++) + { + Dust.NewDust(NPC.position, NPC.width, NPC.height, DustID.Feather); + } + } + } + + public override float SpawnChance(NPCSpawnInfo spawnInfo) + { + return 0f; // Controlled by invasion system + } + } +} diff --git a/Content/NPCs/Enemies/AvalianInvasion/AvalianScout.cs b/Content/NPCs/Enemies/AvalianInvasion/AvalianScout.cs new file mode 100644 index 0000000..618e609 --- /dev/null +++ b/Content/NPCs/Enemies/AvalianInvasion/AvalianScout.cs @@ -0,0 +1,62 @@ +using Terraria; +using Terraria.ID; +using Terraria.ModLoader; +using Microsoft.Xna.Framework; + +namespace ForgottenWawiTech.Content.NPCs.Enemies.AvalianInvasion +{ + public class AvalianScout : ModNPC + { + public override void SetStaticDefaults() + { + Main.npcFrameCount[Type] = 6; // Animation frames + NPCID.Sets.NPCBestiaryDrawModifiers value = new NPCID.Sets.NPCBestiaryDrawModifiers(0) + { + Velocity = 1f + }; + NPCID.Sets.NPCBestiaryDrawOffset.Add(Type, value); + } + + public override void SetDefaults() + { + NPC.width = 32; + NPC.height = 40; + NPC.damage = 45; + NPC.defense = 15; + NPC.lifeMax = 250; + NPC.HitSound = SoundID.NPCHit1; + NPC.DeathSound = SoundID.NPCDeath6; + NPC.value = Item.buyPrice(0, 0, 5, 0); + NPC.knockBackResist = 0.5f; + NPC.aiStyle = NPCAIStyleID.Fighter; // Basic fighter AI + } + + public override void AI() + { + // Add subtle hover/flight behavior + if (NPC.velocity.Y > -2f && NPC.velocity.Y < 2f) + { + NPC.velocity.Y += Main.rand.NextFloat(-0.1f, 0.1f); + } + } + + public override void HitEffect(NPC.HitInfo hit) + { + // Feather particles on hit + if (NPC.life <= 0) + { + for (int i = 0; i < 10; i++) + { + Dust.NewDust(NPC.position, NPC.width, NPC.height, DustID.Feather, + Main.rand.NextFloat(-2f, 2f), Main.rand.NextFloat(-2f, 2f)); + } + } + } + + public override float SpawnChance(NPCSpawnInfo spawnInfo) + { + // Only spawn during Avalian Invasion event + return 0f; // Controlled by invasion system + } + } +} diff --git a/Content/NPCs/Enemies/AvalianInvasion/AvalianTechnician.cs b/Content/NPCs/Enemies/AvalianInvasion/AvalianTechnician.cs new file mode 100644 index 0000000..ea0f445 --- /dev/null +++ b/Content/NPCs/Enemies/AvalianInvasion/AvalianTechnician.cs @@ -0,0 +1,97 @@ +using Terraria; +using Terraria.ID; +using Terraria.ModLoader; +using Microsoft.Xna.Framework; + +namespace ForgottenWawiTech.Content.NPCs.Enemies.AvalianInvasion +{ + public class AvalianTechnician : ModNPC + { + private int laserTimer = 0; + + public override void SetStaticDefaults() + { + Main.npcFrameCount[Type] = 6; + NPCID.Sets.NPCBestiaryDrawModifiers value = new NPCID.Sets.NPCBestiaryDrawModifiers(0) + { + Velocity = 1f + }; + NPCID.Sets.NPCBestiaryDrawOffset.Add(Type, value); + } + + public override void SetDefaults() + { + NPC.width = 36; + NPC.height = 44; + NPC.damage = 40; + NPC.defense = 12; + NPC.lifeMax = 300; + NPC.HitSound = SoundID.NPCHit1; + NPC.DeathSound = SoundID.NPCDeath6; + NPC.value = Item.buyPrice(0, 0, 15, 0); + NPC.knockBackResist = 0.4f; + NPC.aiStyle = NPCAIStyleID.Bat; + } + + public override void AI() + { + Player target = Main.player[NPC.target]; + if (target.active && !target.dead) + { + laserTimer++; + + // Circle around player + float distanceToPlayer = Vector2.Distance(NPC.Center, target.Center); + if (distanceToPlayer > 400f) + { + // Move closer + Vector2 toPlayer = Vector2.Normalize(target.Center - NPC.Center); + NPC.velocity = toPlayer * 4f; + } + else if (distanceToPlayer < 350f) + { + // Orbit + Vector2 toPlayer = target.Center - NPC.Center; + Vector2 perpendicular = new Vector2(-toPlayer.Y, toPlayer.X); + perpendicular.Normalize(); + NPC.velocity = perpendicular * 3f; + } + + // Fire laser every 60 frames (1 second) + if (laserTimer >= 60) + { + laserTimer = 0; + + if (Main.netMode != NetmodeID.MultiplayerClient) + { + Vector2 shootDirection = Vector2.Normalize(target.Center - NPC.Center); + Projectile.NewProjectile(NPC.GetSource_FromAI(), NPC.Center, + shootDirection * 12f, ProjectileID.DeathLaser, + NPC.damage / 2, 1f); + } + } + } + } + + public override void HitEffect(NPC.HitInfo hit) + { + if (NPC.life <= 0) + { + // Tech parts and feathers + for (int i = 0; i < 8; i++) + { + Dust.NewDust(NPC.position, NPC.width, NPC.height, DustID.Feather); + } + for (int i = 0; i < 5; i++) + { + Dust.NewDust(NPC.position, NPC.width, NPC.height, DustID.Electric); + } + } + } + + public override float SpawnChance(NPCSpawnInfo spawnInfo) + { + return 0f; // Controlled by invasion system + } + } +} diff --git a/Content/Players/BeamAttackWandPlayer.cs b/Content/Players/BeamAttackWandPlayer.cs new file mode 100644 index 0000000..efc0808 --- /dev/null +++ b/Content/Players/BeamAttackWandPlayer.cs @@ -0,0 +1,22 @@ +using Terraria.ModLoader; +using Terraria; + +namespace ForgottenWawiTech.Content.Players +{ + // Tracks per-tick emission cooldown for BeamAttackWand while swinging. + public class BeamAttackWandPlayer : ModPlayer + { + public int BeamEmissionTimer = 0; + public float LastBeamRot; // smoothed rotation used to cluster beams + + public override void ResetEffects() + { + // If not holding the wand, allow immediate beam spawn next time it's used and reset rotation smoothing. + if (Player.HeldItem.type != ModContent.ItemType()) + { + BeamEmissionTimer = 0; + LastBeamRot = 0f; + } + } + } +} diff --git a/Content/Projectiles/BeamAttackWandBeam.cs b/Content/Projectiles/BeamAttackWandBeam.cs new file mode 100644 index 0000000..17d1395 --- /dev/null +++ b/Content/Projectiles/BeamAttackWandBeam.cs @@ -0,0 +1,94 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Terraria; +using Terraria.ID; +using Terraria.ModLoader; +using Terraria.GameContent; + +namespace ForgottenWawiTech.Content.Projectiles +{ + // Short-lived beam projectile emitted rapidly by BeamAttackWand. + // Simple straight projectile with minor dust and fade-out. + public class BeamAttackWandBeam : ModProjectile + { + private const int FrameCount = 3; + public override void SetStaticDefaults() + { + Main.projFrames[Type] = FrameCount; // 3 vertical frames + } + + public override void SetDefaults() + { + Projectile.width = 28; // frame width + Projectile.height = 28; // frame height + Projectile.friendly = true; + Projectile.penetrate = 1; // single hit per beam + Projectile.timeLeft = 15; // very short duration + Projectile.DamageType = DamageClass.Melee; + Projectile.tileCollide = true; + Projectile.light = 0.4f; + Projectile.alpha = 40; + } + + public override void AI() + { + // Frame animation: advance every 4 ticks for subtle flicker + Projectile.frameCounter++; + if (Projectile.frameCounter >= 4) + { + Projectile.frameCounter = 0; + Projectile.frame = (Projectile.frame + 1) % FrameCount; + } + + // Slight acceleration forward for a snappy feel + Projectile.velocity *= 1.02f; + + // Simple fade: become more transparent near end + if (Projectile.timeLeft < 6) + Projectile.alpha += 25; + + // Spawn light dust + if (Main.rand.NextBool(3)) + { + int d = Dust.NewDust(Projectile.position, Projectile.width, Projectile.height, DustID.PurpleTorch, + Projectile.velocity.X * 0.2f, Projectile.velocity.Y * 0.2f, 150, default, 0.9f); + Main.dust[d].noGravity = true; + } + } + + public override bool OnTileCollide(Vector2 oldVelocity) + { + // So beams feel crisp: slight bounce spark then die + Projectile.timeLeft = 5; + Projectile.velocity *= 0.4f; + return false; // don't kill immediately; fade + } + + public override bool PreDraw(ref Color lightColor) + { + Texture2D tex = TextureAssets.Projectile[Type].Value; + int frameHeight = tex.Height / FrameCount; + Rectangle frameRect = new(0, frameHeight * Projectile.frame, tex.Width, frameHeight); + Vector2 origin = new(tex.Width / 2f, frameHeight / 2f); + float baseScale = 1f; + float stretchX = 0.6f + Projectile.velocity.Length() / 30f; // elongate horizontally + Color drawColor = Color.White * (1f - Projectile.alpha / 255f); + + // Slight additive trail effect: draw faint previous frame positions + for (int i = 0; i < 3; i++) + { + Vector2 trailPos = Projectile.Center - Projectile.velocity * i * 0.8f; + float trailAlpha = (0.4f - i * 0.12f) * (1f - Projectile.alpha / 255f); + Main.EntitySpriteDraw(tex, trailPos - Main.screenPosition, frameRect, + drawColor * trailAlpha, Projectile.rotation, origin, + new Vector2(stretchX, baseScale), SpriteEffects.None); + } + + // Main frame (bright) + Main.EntitySpriteDraw(tex, Projectile.Center - Main.screenPosition, frameRect, + drawColor, Projectile.rotation, origin, + new Vector2(stretchX, baseScale), SpriteEffects.None); + return false; + } + } +} diff --git a/Content/Projectiles/BeamAttackWandBeam.png b/Content/Projectiles/BeamAttackWandBeam.png new file mode 100644 index 0000000000000000000000000000000000000000..fb7a26a54247aba2c9de29cc02f6df6238eb212c GIT binary patch literal 9685 zcmds-&uSDw5XNgXn`qW}QB*`w5Ire)76lU$vU^C-5D*VS#Dg9K(L)l=pEW9;#Dfqd z&meg9np2)Y)ECegUqHmQx~IRMp4y(7P7J+^1DooquI{d1e=|KY`0D25_|V|#K_VJz zHb$q|p5fp0p??1RrvLU^Hp$%7_(<}3>(VkieGi5whKWABuK&JQWB=U!#?%DS!bPH$ zHKJb}TKPuw_zKbX4AIqfqLZ^5A8%dbj>EH!J99+!W9paCyNy#E9C*~67#sLrKYF5m zWPN^To2R7a=BZ+K{<{V2*GMHI03fh%YpXs2^}&&$qQ5Og0a#EPEj2F zM4CK4Aqog4#QG615A6ptT^wI?**OJWEj#;qEg5 z2Gd$~kY;3dsIL*7(09_5Kaak$Rjin>%XewvT?rCsC<$a-`WT;CP1+M0W;LZPzos%P z^EFB4rme1>H1;_}1*pu?79m(k;N1Z^9|lL)&=R78606B%<-8LZ;w42VY&D^p&(4Wq z9vhnH8JY_zElc#YxuJR0gm%jPX;f=iOAZDt6_^*D(7r7sMSF?XOl;BE=gKB6dSZNS zLh~>tI$^bjD2+&yGLgKn12XRQqZ3*U9W7*KyCUGhT5CB8w2x2dkd>3Hn)7YhZb}MK z6qksGJU$@`DI^5}605A-0Ylb34Q0W5CaoaDI?*-!{};3m)tW z;(3$=MRAPFtUhDo6QTfz6d~C1GZtBy?XkB-R#?8}5KBTy;O)oRnV*#?x`w;?H;pEf zmGe&ElB9^|Y;?lh>OMzl>FDW8(Xr6H=!Df8uF@Zk&?80{oXlsY)Ph3ao)=G9(!}xw?EE3 z)az)A5Ukb$4qNXI$oY^T{VuhHsG!8=o+sq-PT=yAq7ybcAr>yQO3M;G?YPjq=!ADa V4K8l(Y+Y8BHpeDM-;d0+{sIYnIC=m8 literal 0 HcmV?d00001 diff --git a/Content/Projectiles/ChargedBeamAttackWand.png b/Content/Projectiles/ChargedBeamAttackWand.png new file mode 100644 index 0000000000000000000000000000000000000000..990744f12927eb3c2f3a0145da8ef42a760e9a4c GIT binary patch literal 43300 zcmeI5J&0XJ6oBW+)BLP!BN%_01cDe*kf4pIu&N=sQ5w-G%bMHOl+|3itJ^#6LdrqGJ?$sBHgk2{W zUq9{K+=Ht>1NX)Ghl|J^XO@m0-f?5@frsYyesy7GS5c%}8Z8|EVBnr!`T6XiP?^cU zJD2a==~B?(;9w?oxu;7dwqo9BtEfZ{UI=UFMtRkj3hFuTHFkMFEl2^B1!d+kWHpaKheCB>XCIYPsl??{s=VT;VmlbHh9FBvli^wE=~C`XgDBRN6? zTIK?M=gA2HEGjLB#bvyvFZCp$w!L0*goe^GRv6#8Zuo>&4&*FSyhoDK$|XJ%!V;Q< zfR;|Y)U$|@&yvXz+Awj!-$5qp2hqsyqqI)^5A)&rBE8n3$$@x%cLMjn!Jeu+NlL=vg z8WEL*HK!AEI9?#gh5A^3eMl#xk+9Z9<8{!jD`UO+1FVbkdWa9}nlyVkn@lr_Yn9j3 z1N-YylbCL#`r|`w$=p)zYFqnraz74WCAm0KJtXAE8G5s^&)_2#2`t}MLe3(kjZf(l z^1c&E#yWw3ly(w9dMv5r2o14FSJ{>f?~(czG4fe5T|(Y>EE5E#bHZ(9-H@#kRg#28NmWJLG#uwU>sM@y-ahCyK;s!FmEmo3hoKt-i%FTM{1-bA;u!|(bHLD5&G$mNwm<<9%y<;2?>o<$KoCJrkvz_D0oc55>iSZ zkUj+|@=1N-yUOGU`Cd+1#`{uWZ`XC+*S2?)zC-h+BqU^VKFzCGL>-4J zT6YC>QgJ#um(;|b>zaV#-a1{0E{)rg_sdqX0G6n7Iy)y5anE!p2*&aw>YDlrs< z>`Fuwmv1*pgXHjfTcC3NPdZm!u-^3H7B+ zNLo@_oUqiBVf17#C-p+ZnUJ(tR}0UYRC0uJgXBkUtA&T56=GaqoCwX|*5`OnX!*%~ z#w;zfJ!B5TeCx zNukdUD`88PM9_>oBO-VI2+?wz6q@Xt5w;{m(2F}~C3k-bVF8^K8q6#RTQc7&nQ9?* z9GaS|NUV_}gP#KuVMuY$2W{qNgxkvOLz<;jVp;|fA4^0OlWz!1gRE=#_WkGn>T(xg zFnHoW@kbTcwZ0oucyza?RWH=JX5~!OCwF^T0;v+Q2B;YiNYp12su591Sd%<4sl&vA zT&R!rmyk|IBVjF++1O_w1BtF*gF(F@SNd49Pif;*`aTp&2FoI?V+i!L;|S7Y zNhL>Uh($D6ezm!#F^<>BaJfh3mdENAF_~Wrr%TBDj%a%MrSs$7O(d^dklwTG?V4Xj zz3KImBjm>+S{i!DitlK?(rj1fqz|DdeJQlJOODW{HE5M+C{-v)yE+WV61~! zVRD^{@rdk5jg%x5JO1#VWM>NAhiIXnG0=2HLPkkeqa_(tv1J1FMm;$n@`Pw%tdu^0 zPiaJ?e(ZZ?zT^n`UQV{u`;yVyv2Kz1W5c1dYx$lY62b%qDb$b_IY^+7ELW(_`*G;W z-i`QePw3{07q2?E^QEQH!f_gfRQ(AB?^i@9)JR6M%gXG6Kg&USNrf0>93^sZds;LE zX%a%wCWR()#DgLsA(P|Ih$yAMgs^~43JoMD7lftEC*sl~jp5cl)R?=7tPw-e_l86W xDefkas*N?ITQd8QWg(TAlCdihS!{BIez`dR+w%KA{;=B6rNhTYUmrU0(f`6^OT+*G literal 0 HcmV?d00001 diff --git a/Localization/en-US_Mods.ForgottenWawiTech.hjson b/Localization/en-US_Mods.ForgottenWawiTech.hjson index 646ea88..1cabb02 100644 --- a/Localization/en-US_Mods.ForgottenWawiTech.hjson +++ b/Localization/en-US_Mods.ForgottenWawiTech.hjson @@ -234,6 +234,15 @@ Items: { Tooltip: Surprisingly large for a trophy. Especially from an otter. DisplayName: Neptune Trophy Item } + + BeamAttackWand: { + Tooltip: + ''' + A wand that fires several balls of energy in quick succession. + You'll get em next time! Beam attack! + ''' + DisplayName: Beam Staff + } } NPCs: { @@ -327,6 +336,7 @@ NPCs: { Projectiles: { ShatteredPrismBeam.DisplayName: Shattered Prism Beam ShatteredPrismHoldout.DisplayName: Shattered Prism Holdout + BeamAttackWandBeam.DisplayName: Beam Attack Wand Beam } Prefixes: {