using Microsoft.Xna.Framework; using Terraria; using Terraria.Audio; using Terraria.ID; using Terraria.ModLoader; using ForgottenWawiTech.Content.Players; using ForgottenWawiTech.Content.GlobalProjectiles; namespace ForgottenWawiTech.Content.Projectiles.Protogen { public class ProtogenSentinelCore : ModProjectile { private const float HoverRadius = 70f; private const float HoverSpeed = 0.035f; private const int FireCooldown = 32; private const float TargetRange = 950f; private const float BeamVelocity = 18f; public override string Texture => "ForgottenWawiTech/Assets/PlaceholderProj"; public override void SetStaticDefaults() { ProjectileID.Sets.MinionSacrificable[Type] = false; ProjectileID.Sets.MinionTargettingFeature[Type] = true; } public override void SetDefaults() { Projectile.width = 36; Projectile.height = 36; Projectile.friendly = false; Projectile.minion = true; Projectile.tileCollide = false; Projectile.ignoreWater = true; Projectile.penetrate = -1; Projectile.netImportant = true; Projectile.timeLeft = 2; Projectile.damage = 0; Projectile.minionSlots = 0f; } public override void AI() { Player owner = Main.player[Projectile.owner]; ProtogenSentinelPlayer modPlayer = owner.GetModPlayer(); if (!owner.active || owner.dead || !modPlayer.SentinelCoreActive) { Projectile.Kill(); return; } Projectile.timeLeft = 2; float rotation = ((float)Main.GameUpdateCount * HoverSpeed) % MathHelper.TwoPi; Vector2 desiredOffset = new Vector2(0f, -HoverRadius).RotatedBy(rotation); Vector2 desiredPosition = owner.Center + desiredOffset; Projectile.Center = Vector2.Lerp(Projectile.Center, desiredPosition, 0.2f); Projectile.velocity = owner.velocity; Lighting.AddLight(Projectile.Center, 0.2f, 0.6f, 0.9f); if (Projectile.owner == Main.myPlayer) { Projectile.localAI[0]++; if (Projectile.localAI[0] >= FireCooldown) { Projectile.localAI[0] = 0f; NPC target = AcquireTarget(owner, Projectile.Center, TargetRange); if (target != null) { FireBeam(owner, target); } } } } private void FireBeam(Player owner, NPC target) { Vector2 velocity = (target.Center - Projectile.Center).SafeNormalize(Vector2.UnitY) * BeamVelocity; int damage = ProtogenSentinelPlayer.GetCoreDamage(owner); var source = Projectile.GetSource_FromThis(); Projectile beam = Projectile.NewProjectileDirect( source, Projectile.Center, velocity, ModContent.ProjectileType(), damage, 3f, owner.whoAmI); beam.GetGlobalProjectile().DisableSentinelSplit = true; SoundEngine.PlaySound(SoundID.Item33 with { Volume = 0.7f, Pitch = 0.15f }, Projectile.Center); } 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; } } }