using System; using System.Collections.Generic; using Microsoft.Xna.Framework; using Terraria; using Terraria.Audio; using Terraria.ID; using Terraria.ModLoader; using Terraria.ModLoader.IO; using Terraria.ObjectData; namespace Emiliasmod.Content.Projectiles { [Autoload(false)] public class SpaceBlasterProjectile : ModProjectile { public int JumpsLeft = 10; private readonly List hitTargets = []; public override void SetDefaults() { Projectile.width = 4; Projectile.height = 4; Projectile.friendly = true; Projectile.DamageType = DamageClass.Generic; Projectile.extraUpdates = 100; Projectile.tileCollide = true; Projectile.timeLeft = 600; Projectile.CritChance = 0; Projectile.penetrate = -1; } public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) { if (JumpsLeft <= 0) { Projectile.Kill(); hitTargets.Clear(); return; } hitTargets.Add(target.whoAmI); target.AddBuff(BuffID.Electrified, 600); target.AddBuff(BuffID.Frozen, 600); target.AddBuff(BuffID.OnFire, 120); //Vector2 launchVelocity = new Vector2(0, -0.5f); //launchVelocity = launchVelocity.RotatedBy(MathHelper.PiOver2); //Vector2 pos = target.Center; //pos.Y += 4f; //Projectile.NewProjectileDirect(Projectile.InheritSource(Projectile), pos, launchVelocity, ProjectileID.ThunderSpearShot, 100, 0, -1, 44); JumpsLeft--; NPC nextTarget = FindNextTarget(target.Center, 400f); // 25 tile radius if (nextTarget != null) { // Visual: Draw a line of dust between targets DrawLightning(target.Center, nextTarget.Center); // Snap projectile to next target Projectile.Center = target.Center; Projectile.velocity = (nextTarget.Center - target.Center).SafeNormalize(Vector2.Zero) * 16f; } else { Projectile.Kill(); hitTargets.Clear(); } } private NPC FindNextTarget(Vector2 origin, float range) { NPC closest = null; float closestDistSq = range * range; // Use squared distance to avoid sqrt in loop for (int i = 0; i < Main.maxNPCs; i++) { NPC npc = Main.npc[i]; if (npc.active && npc.CanBeChasedBy() && !hitTargets.Contains(npc.whoAmI)) { float distSq = Vector2.DistanceSquared(origin, npc.Center); if (distSq < closestDistSq) { // Check collision last (most expensive check) if (Collision.CanHitLine(origin, 1, 1, npc.position, npc.width, npc.height)) { closestDistSq = distSq; closest = npc; } } } } return closest; } private static void DrawLightning(Vector2 start, Vector2 end) { int count = (int)(Vector2.Distance(start, end) / 8f); for (int i = 0; i < count; i++) { Vector2 pos = Vector2.Lerp(start, end, i / (float)count); if (Main.rand.NextBool(10)) { Dust d1 = Dust.NewDustDirect(pos, 0, 0, DustID.Electric, Main.rand.Next(-3, 4), Main.rand.Next(-3, 4), 0, Color.Cyan, 0.8f); d1.noGravity = true; } Dust d2 = Dust.NewDustPerfect(pos, DustID.Electric, Vector2.Zero, 100, Color.Cyan, 0.8f); d2.noGravity = true; Lighting.AddLight(pos, Color.Cyan.ToVector3());//may not be usefull } } } }