Ahndrek Li'Cyri
Skeletron Prime
Hello there!
I am making a custom beam-type weapon, but there seems to be a bit of a issue.
It activates and fires with no issues, but it doesn't keep using Mana and the sound stops after clicking and holding as well.
Here's the Item code:
And here is the Projectile code:
Any help would be appreciated, thank you!
I am making a custom beam-type weapon, but there seems to be a bit of a issue.
It activates and fires with no issues, but it doesn't keep using Mana and the sound stops after clicking and holding as well.
Here's the Item code:
C#:
class AnnihilationLaserMk1 : ModItem
{
public override void SetStaticDefaults()
{
DisplayName.SetDefault("Annihilation Laser Mk.1");
Tooltip.SetDefault("A basic charge laser weapon. Takes awhile to charge!");
}
public override void SetDefaults()
{
item.magic = true; // Is this item a magic type weapon?
item.damage = 5; // Inital damage with no modifications.
item.crit = 0; // Added to the base critical chance (4%).
item.knockBack = 0; // Knockback of the weapon.
item.channel = true; // Allows item to be held out continually
item.noMelee = true; // Prevents the weapon itself from dealing contact damage.
item.shoot = ProjectileType<AnnihilationLaser1>(); // ID of the shot projectile.
item.shootSpeed = 14f; // Initial velocity of the shot projectile.
item.mana = 5; // Mana per use consumed [Magic Only].
item.width = 18; // X size of the Item.
item.height = 14; // Y size of the Item.
item.scale = 1; // The scale of the Item.
item.useTime = 20;
item.useAnimation = 20; // UseAnimation and useTime SHOULD match to prevent multiple attacks in one animation unless desired.
item.useStyle = ItemUseStyleID.HoldingOut; // Ranged Weapon.
item.UseSound = SoundID.Item13; // Sound made when this item is used.
item.value = Item.sellPrice(0, 1, 0, 0); // The sell price. In (Platnium, Gold, Silver, Copper).
item.rare = ItemRarityID.Green; // Mid Pre-HM
}
}
C#:
class AnnihilationLaser1 : ModProjectile
{
private const float MAX_CRG = 60f * 5;
private const float MOVE_DISTANCE = 60f;
public float Distance
{
get => projectile.ai[0];
set => projectile.ai[0] = value;
}
public float Charge
{
get => projectile.localAI[0];
set => projectile.localAI[0] = value;
}
public bool IsMaxCrg => Charge == MAX_CRG;
public override void SetDefaults()
{
projectile.magic = true; // Is this projectile a magic type?
projectile.friendly = true; // Is this projectile friendly?
projectile.tileCollide = false; // Does this projectile collide with tiles?
projectile.hide = true; // Is this projectile invisible?
projectile.penetrate = -1; // How many times to penitrate. -1 means infinite.
projectile.width = 10; // X size of the projectile.
projectile.height = 10; // Y size of the projectile.
}
public override bool PreDraw(SpriteBatch spriteBatch, Color lightColor)
{
if (IsMaxCrg)
{
DrawLaser(spriteBatch, Main.projectileTexture[projectile.type], Main.player[projectile.owner].Center, projectile.velocity, 10, -1.57f, 1f, Color.White, (int)MOVE_DISTANCE);
}
return false;
}
public void DrawLaser(SpriteBatch spriteBatch, Texture2D texture, Vector2 start, Vector2 unit, float step, float rotation = 0f, float scale = 1, Color color = default, int transDist = 50)
{
float r = unit.ToRotation() + rotation;
// Draws the laser 'body'
for (float i = transDist; i <= Distance; i += step)
{
Color c = color;
var origin = start + i * unit;
spriteBatch.Draw(texture, origin - Main.screenPosition,
new Rectangle(0, 26, 28, 26), i < transDist ? Color.Transparent : c, r,
new Vector2(28 * .5f, 26 * .5f), scale, 0, 0);
}
// Draws the laser 'tail'
spriteBatch.Draw(texture, start + unit * (transDist - step) - Main.screenPosition,
new Rectangle(0, 0, 28, 26), color, r, new Vector2(28 * .5f, 26 * .5f), scale, 0, 0);
// Draws the laser 'head'
spriteBatch.Draw(texture, start + (Distance + step) * unit - Main.screenPosition,
new Rectangle(0, 52, 28, 26), color, r, new Vector2(28 * .5f, 26 * .5f), scale, 0, 0);
}
public override bool? Colliding(Rectangle projHitbox, Rectangle targetHitbox)
{
if (!IsMaxCrg) return false; // Return false so no collision occurs until laser is charged
Player P = Main.player[projectile.owner];
Vector2 Unit = projectile.velocity;
float Point = 0f;
return Collision.CheckAABBvLineCollision(targetHitbox.TopLeft(), targetHitbox.Size(), P.Center, P.Center + Unit * Distance, 22, ref Point);
}
// Set custom immunity time on hitting an NPC
public override void OnHitNPC(NPC target, int damage, float knockback, bool crit)
{
target.immune[projectile.owner] = 5;
}
public override void AI()
{
Player P = Main.player[projectile.owner];
projectile.position = P.Center + projectile.velocity * MOVE_DISTANCE;
projectile.timeLeft = 2;
UpdatePlayer(P);
ChargeLaser(P);
if (Charge < MAX_CRG) return;
SetLaserPos(P);
SpawnDusts(P);
CastLights();
}
private void UpdatePlayer(Player player)
{
if(projectile.owner == Main.myPlayer)
{
Vector2 Diff = Main.MouseWorld - player.Center;
Diff.Normalize();
projectile.velocity = Diff;
projectile.direction = Main.MouseWorld.X > player.position.X ? 1 : -1;
projectile.netUpdate = true;
}
int dir = projectile.direction;
player.ChangeDir(dir);
player.heldProj = projectile.whoAmI;
player.itemTime = 2;
player.itemAnimation = 2;
player.itemRotation = (float)Math.Atan2(projectile.velocity.Y * dir, projectile.velocity.X * dir);
}
private void ChargeLaser(Player player)
{
if (!player.channel) projectile.Kill();
else
{
if (Main.time % 10 < 1 && !player.CheckMana(player.inventory[player.selectedItem].mana, true)) projectile.Kill();
Vector2 Offset = projectile.velocity;
Offset *= MOVE_DISTANCE - 20;
Vector2 Pos = player.Center + Offset - new Vector2(10, 10);
if (Charge < MAX_CRG) Charge++;
int chargeFact = (int)(Charge / 60f);
Vector2 dustVelocity = Vector2.UnitX * 18f;
dustVelocity = dustVelocity.RotatedBy(projectile.rotation - 1.57f);
Vector2 spawnPos = projectile.Center + dustVelocity;
for (int k = 0; k < chargeFact + 1; k++)
{
Vector2 spawn = spawnPos + ((float)Main.rand.NextDouble() * 6.28f).ToRotationVector2() * (12f - chargeFact * 2);
Dust dust = Main.dust[Dust.NewDust(Pos, 20, 20, 61, projectile.velocity.X / 2f, projectile.velocity.Y / 2f, 0, new Color(255, 255, 255), 2.5f)];
dust.velocity = Vector2.Normalize(spawnPos - spawn) * 1.5f * (10f - chargeFact * 2f) / 10f;
dust.noGravity = true;
}
}
}
private void SetLaserPos(Player player)
{
for (Distance = MOVE_DISTANCE; Distance <= 2200f; Distance += 5f)
{
var start = player.Center + projectile.velocity * Distance;
if (!Collision.CanHit(player.Center, 1, 1, start, 1, 1))
{
Distance -= 5f;
break;
}
}
}
private void SpawnDusts(Player player)
{
Vector2 unit;
Vector2 dustPos = player.Center + projectile.velocity * Distance;
for (int i = 0; i < 2; ++i)
{
float num1 = projectile.velocity.ToRotation() + (Main.rand.Next(2) == 1 ? -1.0f : 1.0f) * 1.57f;
float num2 = (float)(Main.rand.NextDouble() * 0.8f + 1.0f);
Vector2 dustVel = new Vector2((float)Math.Cos(num1) * num2, (float)Math.Sin(num1) * num2);
Dust dust = Main.dust[Dust.NewDust(dustPos, 0, 0, 61, dustVel.X, dustVel.Y, 0, new Color(255, 255, 255), 3f)];
dust.noGravity = true;
}
if (Main.rand.NextBool(5))
{
Vector2 offset = projectile.velocity.RotatedBy(1.57f) * ((float)Main.rand.NextDouble() - 0.5f) * projectile.width;
Dust dust = Main.dust[Dust.NewDust(dustPos + offset - Vector2.One * 4f, 8, 8, 31, 0.0f, 0.0f, 100, new Color(), 1.5f)];
dust.velocity *= 0.5f;
dust.velocity.Y = -Math.Abs(dust.velocity.Y);
unit = dustPos - Main.player[projectile.owner].Center;
unit.Normalize();
dust = Main.dust[Dust.NewDust(Main.player[projectile.owner].Center + 55 * unit, 8, 8, 31, 0.0f, 0.0f, 100, new Color(), 1.5f)];
dust.velocity = dust.velocity * 0.5f;
dust.velocity.Y = -Math.Abs(dust.velocity.Y);
}
}
private void CastLights()
{
// Cast a light along the line of the laser
DelegateMethods.v3_1 = Helpers.RGB255To1f(121, 255, 113);
Utils.PlotTileLine(projectile.Center, projectile.Center + projectile.velocity * (Distance - MOVE_DISTANCE), 26, DelegateMethods.CastLight);
}
public override bool ShouldUpdatePosition() => false;
public override void CutTiles()
{
DelegateMethods.tilecut_0 = TileCuttingContext.AttackProjectile;
Vector2 unit = projectile.velocity;
Utils.PlotTileLine(projectile.Center, projectile.Center + unit * Distance, (projectile.width + 16) * projectile.scale, DelegateMethods.CutTiles);
}
}
Any help would be appreciated, thank you!