Terraria_Emilia_s_Expension/Content/Projectiles/SpaceBlasterProjectile.cs

102 lines
3.3 KiB
C#

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 override string Texture => $"Emiliasmod/Assets/Textures/{Name}";
public int JumpsLeft = 10;
private readonly List<int> 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
}
}
}
}