using Microsoft.Xna.Framework; using Terraria; using Terraria.Audio; using Terraria.ID; using Terraria.ModLoader; using ForgottenWawiTech.Content.Players; namespace ForgottenWawiTech.Content.Projectiles.Singularity { public class SingularityOrb : ModProjectile { private const float OrbitRadius = 90f; private const float OrbitSpeed = 0.04f; private const int FireCooldown = 22; private const float TargetRange = 1000f; private const float BeamSpeed = 21f; 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 = 32; Projectile.height = 32; Projectile.friendly = false; Projectile.minion = true; Projectile.DamageType = DamageClass.Generic; Projectile.penetrate = -1; Projectile.tileCollide = false; Projectile.ignoreWater = true; Projectile.netImportant = true; Projectile.timeLeft = 2; Projectile.minionSlots = 0f; } public override void AI() { Player owner = Main.player[Projectile.owner]; SingularityPlayer modPlayer = owner.GetModPlayer(); if (!owner.active || owner.dead || !modPlayer.SingularityOrbActive) { Projectile.Kill(); return; } Projectile.timeLeft = 2; float rotation = ((float)Main.GameUpdateCount * OrbitSpeed) + Projectile.identity * 0.2f; Vector2 offset = new Vector2(0f, -OrbitRadius).RotatedBy(rotation); Vector2 desiredPos = owner.Center + offset; Projectile.Center = Vector2.Lerp(Projectile.Center, desiredPos, 0.28f); Projectile.velocity = owner.velocity; Projectile.rotation += 0.03f * Projectile.direction; Lighting.AddLight(Projectile.Center, 0.55f, 0.2f, 0.65f); 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) * BeamSpeed; int damage = SingularityPlayer.GetOrbDamage(owner); var source = Projectile.GetSource_FromThis(); Projectile.NewProjectile( source, Projectile.Center, velocity, ModContent.ProjectileType(), damage, 2f, owner.whoAmI); SoundEngine.PlaySound(SoundID.Item91 with { Volume = 0.7f, Pitch = 0.35f }, Projectile.Center); } private static NPC AcquireTarget(Player owner, Vector2 center, float range) { if (owner.HasMinionAttackTargetNPC) { NPC forced = Main.npc[owner.MinionAttackTargetNPC]; if (forced.CanBeChasedBy()) { return forced; } } NPC closest = null; float sqrRange = 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 dist = Vector2.DistanceSquared(npc.Center, center); if (dist <= sqrRange && Collision.CanHitLine(center, 0, 0, npc.Center, 0, 0)) { sqrRange = dist; closest = npc; } } return closest; } } }