using Microsoft.Xna.Framework; using Terraria; using Terraria.ID; using Terraria.ModLoader; namespace ForgottenWawiTech.Content.Projectiles.Protogen { public class ProtogenOperativeNanite : ModProjectile { private const float DetectionRange = 640f; private const float HomingStrength = 0.14f; private const float DesiredSpeed = 14f; public override void SetStaticDefaults() { ProjectileID.Sets.MinionShot[Type] = true; ProjectileID.Sets.MinionSacrificable[Type] = false; } public override void SetDefaults() { Projectile.width = 14; Projectile.height = 14; Projectile.friendly = true; Projectile.penetrate = 1; Projectile.timeLeft = 360; Projectile.tileCollide = false; Projectile.ignoreWater = true; Projectile.DamageType = DamageClass.Generic; Projectile.usesLocalNPCImmunity = true; Projectile.localNPCHitCooldown = 20; Projectile.extraUpdates = 1; } public override void AI() { Player owner = Main.player[Projectile.owner]; if (!owner.active || owner.dead) { Projectile.Kill(); return; } Projectile.rotation += 0.2f * Projectile.direction; Lighting.AddLight(Projectile.Center, 0.25f, 0.55f, 0.75f); NPC target = AcquireTarget(owner, Projectile.Center, DetectionRange); if (target != null) { Vector2 desiredVelocity = (target.Center - Projectile.Center).SafeNormalize(Vector2.Zero) * DesiredSpeed; Projectile.velocity = Vector2.Lerp(Projectile.velocity, desiredVelocity, HomingStrength); } else { Projectile.velocity *= 0.98f; } if (Main.rand.NextBool(4)) { Dust dust = Dust.NewDustDirect(Projectile.position, Projectile.width, Projectile.height, DustID.Electric, 0f, 0f, 100, default, 1.1f); dust.noGravity = true; } } public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) { if (Main.myPlayer != Projectile.owner) { return; } Player owner = Main.player[Projectile.owner]; int healAmount = (int)(damageDone * 0.5f); if (healAmount <= 0) { return; } owner.statLife = Utils.Clamp(owner.statLife + healAmount, 0, owner.statLifeMax2); owner.HealEffect(healAmount); } private static NPC AcquireTarget(Player owner, Vector2 center, float range) { if (owner.HasMinionAttackTargetNPC) { NPC target = Main.npc[owner.MinionAttackTargetNPC]; if (target.CanBeChasedBy()) { return target; } } NPC closest = null; float squaredRange = range * range; for (int i = 0; i < Main.maxNPCs; i++) { NPC npc = Main.npc[i]; if (!npc.active || npc.friendly || npc.dontTakeDamage || npc.life <= 0) { continue; } float distance = Vector2.DistanceSquared(npc.Center, center); if (distance <= squaredRange && Collision.CanHitLine(center, 0, 0, npc.Center, 0, 0)) { squaredRange = distance; closest = npc; } } return closest; } } }