2026-02-22 20:09:01 +01:00

93 lines
3.9 KiB
C#

using Microsoft.Xna.Framework;
using Terraria;
using Terraria.Audio;
using Terraria.ID;
using Terraria.ModLoader;
namespace Emiliasmod.Content.Projectiles
{
public class EmiliasWandProjectile : ModProjectile
{
public override void SetStaticDefaults() {
// Prevents jitter when stepping up and down blocks and half blocks
ProjectileID.Sets.HeldProjDoesNotUsePlayerGfxOffY[Type] = true;
}
public override void SetDefaults() {
Projectile.width = 14;
Projectile.height = 16;
Projectile.friendly = true;
Projectile.tileCollide = false;
Projectile.penetrate = -1;
Projectile.DamageType = DamageClass.Melee;
Projectile.ownerHitCheck = true;
Projectile.aiStyle = -1; // Replace with 20 if you do not want custom code
Projectile.hide = true; // Hides the projectile, so it will draw in the player's hand when we set the player's heldProj to this one.
}
// This code is adapted and simplified from aiStyle 20 to use a different dust and more noises. If you want to use aiStyle 20, you do not need to do any of this.
// It should be noted that this projectile has no effect on mining and is mostly visual.
public override void AI() {
Player player = Main.player[Projectile.owner];
Projectile.timeLeft = 60;
// Animation code could go here if the projectile was animated.
// Plays a sound every 20 ticks. In aiStyle 20, soundDelay is set to 30 ticks.
//if (Projectile.soundDelay <= 0) {
//SoundEngine.PlaySound(SoundID.Item22, Projectile.Center);
//Projectile.soundDelay = 20;
//}
Vector2 playerCenter = player.RotatedRelativePoint(player.MountedCenter);
if (Main.myPlayer == Projectile.owner) {
// This code must only be ran on the client of the projectile owner
if (player.channel) {
float holdoutDistance = player.HeldItem.shootSpeed * Projectile.scale;
// Calculate a normalized vector from player to mouse and multiply by holdoutDistance to determine resulting holdoutOffset
Vector2 holdoutOffset = holdoutDistance * Vector2.Normalize(Main.MouseWorld - playerCenter);
if (holdoutOffset.X != Projectile.velocity.X || holdoutOffset.Y != Projectile.velocity.Y) {
// This will sync the projectile, most importantly, the velocity.
Projectile.netUpdate = true;
}
// Projectile.velocity acts as a holdoutOffset for held projectiles.
Projectile.velocity = holdoutOffset;
}
else {
Projectile.Kill();
}
}
if (Projectile.velocity.X > 0f) {
player.ChangeDir(1);
}
else if (Projectile.velocity.X < 0f) {
player.ChangeDir(-1);
}
Projectile.spriteDirection = Projectile.direction;
player.ChangeDir(Projectile.direction); // Change the player's direction based on the projectile's own
player.heldProj = Projectile.whoAmI; // We tell the player that the drill is the held projectile, so it will draw in their hand
player.SetDummyItemTime(2); // Make sure the player's item time does not change while the projectile is out
Projectile.Center = playerCenter; // Centers the projectile on the player. Projectile.velocity will be added to this in later Terraria code causing the projectile to be held away from the player at a set distance.
Projectile.rotation = Projectile.velocity.ToRotation() + MathHelper.PiOver2;
player.itemRotation = (Projectile.velocity * Projectile.direction).ToRotation();
// Gives the drill a slight jiggle
Projectile.velocity.X *= 1f + Main.rand.Next(-3, 4) * 0.01f;
Projectile.velocity.Y *= 1f + Main.rand.Next(-3, 4) * 0.01f;
// Spawning dust
if (Main.rand.NextBool(10)) {
Dust dust = Dust.NewDustDirect(Projectile.position + Projectile.velocity * Main.rand.Next(6, 10) * 0.15f, Projectile.width, Projectile.height, DustID.Honey, 0f, 0f, 80, Color.White, 1f);
dust.position.X -= 4f;
dust.noGravity = true;
dust.velocity.X *= 0.5f;
dust.velocity.Y = -Main.rand.Next(3, 8) * 0.1f;
}
}
}
}