tModLoader Need help to make a custom Arkhalis

Ya Boi Aether

Official Terrarian
So basically I've just got into Terraria modding and for my first item I tried making a sword that works like the Arkhalis. After a bit of research I understood you have to make a melee weapon shoot a projectile (correct me if i'm wrong) but After an hour of trying I just can't get it right. I don't how I'm supposed to make the projectile work and there's nothing on the internet showing how to do it. Can anyone explain how I could do it so I can figure it out more easily?
Thank you in advance. ANY info helps
 
Last edited:
well what i know is that the arkhalis acts like a drill, with not being physically used but with a projectile that always remains in front of the player, i am testing currently so if i find out how i will tell you.
 
ok its not perfect but its a start,

Item: Gǔdàide.png
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;

namespace ExpansionOfRealmsMod.Items.Weapons
{
public class Gǔdàide : ModItem
{
public override void SetStaticDefaults()
{
DisplayName.SetDefault("Gǔdài de");
Tooltip.SetDefault("The life force of the planet");
}

public override void SetDefaults()
{
item.damage = 600;
item.melee = true;
item.width = 66;
item.height = 70;
item.useTime = 7;
item.useAnimation = 25;
item.channel = true;
item.noUseGraphic = true;
item.noMelee = true;
item.useStyle = 5;
item.knockBack = 6;
item.value = Item.buyPrice(0, 22, 50, 0);
item.rare = 9;
item.UseSound = SoundID.Item1;
item.autoReuse = true;
item.shoot = mod.ProjectileType("Swingy");
item.shootSpeed = 40f;
}
}
}

Projectile:Swingy.png
using System.IO;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;

namespace ExpansionOfRealmsMod.Projectiles
{
class Swingy : ModProjectile
{
public override void SetStaticDefaults()
{
Main.projFrames[projectile.type] = 14;
}

public override void SetDefaults()
{
projectile.width = 45;
projectile.height = 45;
projectile.aiStyle = 20;
projectile.friendly = true;
projectile.penetrate = -1;
projectile.tileCollide = false;
projectile.hide = true;
projectile.ownerHitCheck = true; //so you can't hit enemies through walls
projectile.melee = true;
}



public override void OnHitNPC(NPC target, int damage, float knockback, bool crit)
{
//3a: target.immune[projectile.owner] = 20;
//3b: target.immune[projectile.owner] = 5;
}

public override Color? GetAlpha(Color lightColor)
{
//return Color.White;
return new Color(255, 255, 255, 0) * (1f - (float)projectile.alpha / 255f);
}

public override void AI()
{
// Slow down
projectile.velocity *= 0.98f;
// Loop through the 4 animation frames, spending 5 ticks on each.
if (++projectile.frameCounter >= 2)
{
projectile.frameCounter = 0;
if (++projectile.frame >= 14)
{
projectile.frame = 0;
}
}

projectile.direction = (projectile.spriteDirection = ((projectile.velocity.X > 0f) ? 1 : -1));
projectile.rotation = projectile.velocity.ToRotation();
if (projectile.velocity.Y > 16f)
{
projectile.velocity.Y = 16f;
}
// Since our sprite has an orientation, we need to adjust rotation to compensate for the draw flipping.
if (projectile.spriteDirection == -1)
projectile.rotation += MathHelper.Pi;
}

// Some advanced drawing because the texture image isn't centered or symetrical.
public override bool PreDraw(SpriteBatch spriteBatch, Color lightColor)
{
SpriteEffects spriteEffects = SpriteEffects.None;
if (projectile.spriteDirection == -1)
{
spriteEffects = SpriteEffects.FlipHorizontally;
}
Texture2D texture = Main.projectileTexture[projectile.type];
int frameHeight = Main.projectileTexture[projectile.type].Height / Main.projFrames[projectile.type];
int startY = frameHeight * projectile.frame;
Rectangle sourceRectangle = new Rectangle(0, startY, texture.Width, frameHeight);
Vector2 origin = sourceRectangle.Size() / 2f;
origin.X = (float)((projectile.spriteDirection == 1) ? (sourceRectangle.Width - 40) : 40);

Color drawColor = projectile.GetAlpha(lightColor);
Main.spriteBatch.Draw(texture,
projectile.Center - Main.screenPosition + new Vector2(0f, projectile.gfxOffY),
sourceRectangle, drawColor, projectile.rotation, origin, projectile.scale, spriteEffects, 0f);

return false;
}
}
}

And also use the images attached, as well as change ExpansionOfRealmsMod to your mod name
It has some problems, the blade isn't perfect in use and it still has the sound of a drill but HEY, it works!
[doublepost=1519532550,1519532330][/doublepost]I will toy with it more in the future to fix it and maybe post a guide, Good luck!
 
Omg dude thank you so much.

In case if you didn't solved the problem of it sounding like a drill, you can get a little creative and add useSound on the projectile. (My sound system from this computer is f**ked and i cannot help you, but you could try.)
 
ok its not perfect but its a start,

Item:View attachment 194750
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;

namespace ExpansionOfRealmsMod.Items.Weapons
{
public class Gǔdàide : ModItem
{
public override void SetStaticDefaults()
{
DisplayName.SetDefault("Gǔdài de");
Tooltip.SetDefault("The life force of the planet");
}

public override void SetDefaults()
{
item.damage = 600;
item.melee = true;
item.width = 66;
item.height = 70;
item.useTime = 7;
item.useAnimation = 25;
item.channel = true;
item.noUseGraphic = true;
item.noMelee = true;
item.useStyle = 5;
item.knockBack = 6;
item.value = Item.buyPrice(0, 22, 50, 0);
item.rare = 9;
item.UseSound = SoundID.Item1;
item.autoReuse = true;
item.shoot = mod.ProjectileType("Swingy");
item.shootSpeed = 40f;
}
}
}

Projectile:View attachment 194751
using System.IO;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;

namespace ExpansionOfRealmsMod.Projectiles
{
class Swingy : ModProjectile
{
public override void SetStaticDefaults()
{
Main.projFrames[projectile.type] = 14;
}

public override void SetDefaults()
{
projectile.width = 45;
projectile.height = 45;
projectile.aiStyle = 20;
projectile.friendly = true;
projectile.penetrate = -1;
projectile.tileCollide = false;
projectile.hide = true;
projectile.ownerHitCheck = true; //so you can't hit enemies through walls
projectile.melee = true;
}



public override void OnHitNPC(NPC target, int damage, float knockback, bool crit)
{
//3a: target.immune[projectile.owner] = 20;
//3b: target.immune[projectile.owner] = 5;
}

public override Color? GetAlpha(Color lightColor)
{
//return Color.White;
return new Color(255, 255, 255, 0) * (1f - (float)projectile.alpha / 255f);
}

public override void AI()
{
// Slow down
projectile.velocity *= 0.98f;
// Loop through the 4 animation frames, spending 5 ticks on each.
if (++projectile.frameCounter >= 2)
{
projectile.frameCounter = 0;
if (++projectile.frame >= 14)
{
projectile.frame = 0;
}
}

projectile.direction = (projectile.spriteDirection = ((projectile.velocity.X > 0f) ? 1 : -1));
projectile.rotation = projectile.velocity.ToRotation();
if (projectile.velocity.Y > 16f)
{
projectile.velocity.Y = 16f;
}
// Since our sprite has an orientation, we need to adjust rotation to compensate for the draw flipping.
if (projectile.spriteDirection == -1)
projectile.rotation += MathHelper.Pi;
}

// Some advanced drawing because the texture image isn't centered or symetrical.
public override bool PreDraw(SpriteBatch spriteBatch, Color lightColor)
{
SpriteEffects spriteEffects = SpriteEffects.None;
if (projectile.spriteDirection == -1)
{
spriteEffects = SpriteEffects.FlipHorizontally;
}
Texture2D texture = Main.projectileTexture[projectile.type];
int frameHeight = Main.projectileTexture[projectile.type].Height / Main.projFrames[projectile.type];
int startY = frameHeight * projectile.frame;
Rectangle sourceRectangle = new Rectangle(0, startY, texture.Width, frameHeight);
Vector2 origin = sourceRectangle.Size() / 2f;
origin.X = (float)((projectile.spriteDirection == 1) ? (sourceRectangle.Width - 40) : 40);

Color drawColor = projectile.GetAlpha(lightColor);
Main.spriteBatch.Draw(texture,
projectile.Center - Main.screenPosition + new Vector2(0f, projectile.gfxOffY),
sourceRectangle, drawColor, projectile.rotation, origin, projectile.scale, spriteEffects, 0f);

return false;
}
}
}

And also use the images attached, as well as change ExpansionOfRealmsMod to your mod name
It has some problems, the blade isn't perfect in use and it still has the sound of a drill but HEY, it works!
[doublepost=1519532550,1519532330][/doublepost]I will toy with it more in the future to fix it and maybe post a guide, Good luck!
Dude, thank you really much.
Really. I thought how it should work, and you solved mu problem!
 
To get rid of the drill sound just set projectile.soundDelay to int.MaxValue and the sound will be delayed by ~36 million seconds.
 
ok its not perfect but its a start,

Item:View attachment 194750
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;

namespace ExpansionOfRealmsMod.Items.Weapons
{
public class Gǔdàide : ModItem
{
public override void SetStaticDefaults()
{
DisplayName.SetDefault("Gǔdài de");
Tooltip.SetDefault("The life force of the planet");
}

public override void SetDefaults()
{
item.damage = 600;
item.melee = true;
item.width = 66;
item.height = 70;
item.useTime = 7;
item.useAnimation = 25;
item.channel = true;
item.noUseGraphic = true;
item.noMelee = true;
item.useStyle = 5;
item.knockBack = 6;
item.value = Item.buyPrice(0, 22, 50, 0);
item.rare = 9;
item.UseSound = SoundID.Item1;
item.autoReuse = true;
item.shoot = mod.ProjectileType("Swingy");
item.shootSpeed = 40f;
}
}
}

Projectile:View attachment 194751
using System.IO;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;

namespace ExpansionOfRealmsMod.Projectiles
{
class Swingy : ModProjectile
{
public override void SetStaticDefaults()
{
Main.projFrames[projectile.type] = 14;
}

public override void SetDefaults()
{
projectile.width = 45;
projectile.height = 45;
projectile.aiStyle = 20;
projectile.friendly = true;
projectile.penetrate = -1;
projectile.tileCollide = false;
projectile.hide = true;
projectile.ownerHitCheck = true; //so you can't hit enemies through walls
projectile.melee = true;
}



public override void OnHitNPC(NPC target, int damage, float knockback, bool crit)
{
//3a: target.immune[projectile.owner] = 20;
//3b: target.immune[projectile.owner] = 5;
}

public override Color? GetAlpha(Color lightColor)
{
//return Color.White;
return new Color(255, 255, 255, 0) * (1f - (float)projectile.alpha / 255f);
}

public override void AI()
{
// Slow down
projectile.velocity *= 0.98f;
// Loop through the 4 animation frames, spending 5 ticks on each.
if (++projectile.frameCounter >= 2)
{
projectile.frameCounter = 0;
if (++projectile.frame >= 14)
{
projectile.frame = 0;
}
}

projectile.direction = (projectile.spriteDirection = ((projectile.velocity.X > 0f) ? 1 : -1));
projectile.rotation = projectile.velocity.ToRotation();
if (projectile.velocity.Y > 16f)
{
projectile.velocity.Y = 16f;
}
// Since our sprite has an orientation, we need to adjust rotation to compensate for the draw flipping.
if (projectile.spriteDirection == -1)
projectile.rotation += MathHelper.Pi;
}

// Some advanced drawing because the texture image isn't centered or symetrical.
public override bool PreDraw(SpriteBatch spriteBatch, Color lightColor)
{
SpriteEffects spriteEffects = SpriteEffects.None;
if (projectile.spriteDirection == -1)
{
spriteEffects = SpriteEffects.FlipHorizontally;
}
Texture2D texture = Main.projectileTexture[projectile.type];
int frameHeight = Main.projectileTexture[projectile.type].Height / Main.projFrames[projectile.type];
int startY = frameHeight * projectile.frame;
Rectangle sourceRectangle = new Rectangle(0, startY, texture.Width, frameHeight);
Vector2 origin = sourceRectangle.Size() / 2f;
origin.X = (float)((projectile.spriteDirection == 1) ? (sourceRectangle.Width - 40) : 40);

Color drawColor = projectile.GetAlpha(lightColor);
Main.spriteBatch.Draw(texture,
projectile.Center - Main.screenPosition + new Vector2(0f, projectile.gfxOffY),
sourceRectangle, drawColor, projectile.rotation, origin, projectile.scale, spriteEffects, 0f);

return false;
}
}
}

And also use the images attached, as well as change ExpansionOfRealmsMod to your mod name
It has some problems, the blade isn't perfect in use and it still has the sound of a drill but HEY, it works!
[doublepost=1519532550,1519532330][/doublepost]I will toy with it more in the future to fix it and maybe post a guide, Good luck!
ok, but i have a question, what if i want to make the weapon not autoswing?
 
I ported your Code To 1.4 if ppl want to make an arkhalis sword in 1.4


using System.IO;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;

namespace Rejeffed.Items.Mellee.ForgorBlade
{
class ForgorProj : ModProjectile
{
public override void SetStaticDefaults()
{
Main.projFrames[Projectile.type] = 14;
}

public override void SetDefaults()
{
Projectile.width = 45;
Projectile.height = 45;
Projectile.aiStyle = 20;
Projectile.friendly = true;
Projectile.penetrate = -1;
Projectile.tileCollide = false;
Projectile.hide = true;
Projectile.ownerHitCheck = true; //so you can't hit enemies through walls
Projectile.soundDelay = int.MaxValue;


}



public override void OnHitNPC(NPC target, int damage, float knockback, bool crit)
{
//3a: target.immune[projectile.owner] = 20;
//3b: target.immune[projectile.owner] = 5;
}

public override Color? GetAlpha(Color lightColor)
{
//return Color.White;
return new Color(255, 255, 255, 0) * (1f - (float)Projectile.alpha / 255f);
}

public override void AI()
{
// Slow down
Projectile.velocity *= 0.98f;
// Loop through the 4 animation frames, spending 5 ticks on each.
if (++Projectile.frameCounter >= 2)
{
Projectile.frameCounter = 0;
if (++Projectile.frame >= 14)
{
Projectile.frame = 0;
}
}

Projectile.direction = (Projectile.spriteDirection = ((Projectile.velocity.X > 0f) ? 1 : -1));
Projectile.rotation = Projectile.velocity.ToRotation();
if (Projectile.velocity.Y > 16f)
{
Projectile.velocity.Y = 16f;
}
// Since our sprite has an orientation, we need to adjust rotation to compensate for the draw flipping.
if (Projectile.spriteDirection == -1)
Projectile.rotation += MathHelper.Pi;
}

// Some advanced drawing because the texture image isn't centered or symetrical.
public override bool PreDraw(ref Color lightColor)
{
SpriteEffects spriteEffects = SpriteEffects.None;
if (Projectile.spriteDirection == -1)
{
spriteEffects = SpriteEffects.FlipHorizontally;
}
Texture2D texture = (Texture2D)ModContent.Request<Texture2D>(Texture);
int frameHeight = texture.Height / Main.projFrames[Projectile.type];
int startY = frameHeight * Projectile.frame;
Rectangle sourceRectangle = new Rectangle(0, startY, texture.Width, frameHeight);
Vector2 origin = sourceRectangle.Size() / 2f;
origin.X = (float)((Projectile.spriteDirection == 1) ? (sourceRectangle.Width - 40) : 40);

Color drawColor = Projectile.GetAlpha(lightColor);
Main.spriteBatch.Draw(texture,
Projectile.Center - Main.screenPosition + new Vector2(0f, Projectile.gfxOffY),
sourceRectangle, drawColor, Projectile.rotation, origin, Projectile.scale, spriteEffects, 0f);

return false;
}
}
}
 
I ported your Code To 1.4 if ppl want to make an arkhalis sword in 1.4


using System.IO;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;

namespace Rejeffed.Items.Mellee.ForgorBlade
{
class ForgorProj : ModProjectile
{
public override void SetStaticDefaults()
{
Main.projFrames[Projectile.type] = 14;
}

public override void SetDefaults()
{
Projectile.width = 45;
Projectile.height = 45;
Projectile.aiStyle = 20;
Projectile.friendly = true;
Projectile.penetrate = -1;
Projectile.tileCollide = false;
Projectile.hide = true;
Projectile.ownerHitCheck = true; //so you can't hit enemies through walls
Projectile.soundDelay = int.MaxValue;


}



public override void OnHitNPC(NPC target, int damage, float knockback, bool crit)
{
//3a: target.immune[projectile.owner] = 20;
//3b: target.immune[projectile.owner] = 5;
}

public override Color? GetAlpha(Color lightColor)
{
//return Color.White;
return new Color(255, 255, 255, 0) * (1f - (float)Projectile.alpha / 255f);
}

public override void AI()
{
// Slow down
Projectile.velocity *= 0.98f;
// Loop through the 4 animation frames, spending 5 ticks on each.
if (++Projectile.frameCounter >= 2)
{
Projectile.frameCounter = 0;
if (++Projectile.frame >= 14)
{
Projectile.frame = 0;
}
}

Projectile.direction = (Projectile.spriteDirection = ((Projectile.velocity.X > 0f) ? 1 : -1));
Projectile.rotation = Projectile.velocity.ToRotation();
if (Projectile.velocity.Y > 16f)
{
Projectile.velocity.Y = 16f;
}
// Since our sprite has an orientation, we need to adjust rotation to compensate for the draw flipping.
if (Projectile.spriteDirection == -1)
Projectile.rotation += MathHelper.Pi;
}

// Some advanced drawing because the texture image isn't centered or symetrical.
public override bool PreDraw(ref Color lightColor)
{
SpriteEffects spriteEffects = SpriteEffects.None;
if (Projectile.spriteDirection == -1)
{
spriteEffects = SpriteEffects.FlipHorizontally;
}
Texture2D texture = (Texture2D)ModContent.Request<Texture2D>(Texture);
int frameHeight = texture.Height / Main.projFrames[Projectile.type];
int startY = frameHeight * Projectile.frame;
Rectangle sourceRectangle = new Rectangle(0, startY, texture.Width, frameHeight);
Vector2 origin = sourceRectangle.Size() / 2f;
origin.X = (float)((Projectile.spriteDirection == 1) ? (sourceRectangle.Width - 40) : 40);

Color drawColor = Projectile.GetAlpha(lightColor);
Main.spriteBatch.Draw(texture,
Projectile.Center - Main.screenPosition + new Vector2(0f, Projectile.gfxOffY),
sourceRectangle, drawColor, Projectile.rotation, origin, Projectile.scale, spriteEffects, 0f);

return false;
}
}
}
1659821163896.png
 
I ported your Code To 1.4 if ppl want to make an arkhalis sword in 1.4


using System.IO;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;

namespace Rejeffed.Items.Mellee.ForgorBlade
{
class ForgorProj : ModProjectile
{
public override void SetStaticDefaults()
{
Main.projFrames[Projectile.type] = 14;
}

public override void SetDefaults()
{
Projectile.width = 45;
Projectile.height = 45;
Projectile.aiStyle = 20;
Projectile.friendly = true;
Projectile.penetrate = -1;
Projectile.tileCollide = false;
Projectile.hide = true;
Projectile.ownerHitCheck = true; //so you can't hit enemies through walls
Projectile.soundDelay = int.MaxValue;


}



public override void OnHitNPC(NPC target, int damage, float knockback, bool crit)
{
//3a: target.immune[projectile.owner] = 20;
//3b: target.immune[projectile.owner] = 5;
}

public override Color? GetAlpha(Color lightColor)
{
//return Color.White;
return new Color(255, 255, 255, 0) * (1f - (float)Projectile.alpha / 255f);
}

public override void AI()
{
// Slow down
Projectile.velocity *= 0.98f;
// Loop through the 4 animation frames, spending 5 ticks on each.
if (++Projectile.frameCounter >= 2)
{
Projectile.frameCounter = 0;
if (++Projectile.frame >= 14)
{
Projectile.frame = 0;
}
}

Projectile.direction = (Projectile.spriteDirection = ((Projectile.velocity.X > 0f) ? 1 : -1));
Projectile.rotation = Projectile.velocity.ToRotation();
if (Projectile.velocity.Y > 16f)
{
Projectile.velocity.Y = 16f;
}
// Since our sprite has an orientation, we need to adjust rotation to compensate for the draw flipping.
if (Projectile.spriteDirection == -1)
Projectile.rotation += MathHelper.Pi;
}

// Some advanced drawing because the texture image isn't centered or symetrical.
public override bool PreDraw(ref Color lightColor)
{
SpriteEffects spriteEffects = SpriteEffects.None;
if (Projectile.spriteDirection == -1)
{
spriteEffects = SpriteEffects.FlipHorizontally;
}
Texture2D texture = (Texture2D)ModContent.Request<Texture2D>(Texture);
int frameHeight = texture.Height / Main.projFrames[Projectile.type];
int startY = frameHeight * Projectile.frame;
Rectangle sourceRectangle = new Rectangle(0, startY, texture.Width, frameHeight);
Vector2 origin = sourceRectangle.Size() / 2f;
origin.X = (float)((Projectile.spriteDirection == 1) ? (sourceRectangle.Width - 40) : 40);

Color drawColor = Projectile.GetAlpha(lightColor);
Main.spriteBatch.Draw(texture,
Projectile.Center - Main.screenPosition + new Vector2(0f, Projectile.gfxOffY),
sourceRectangle, drawColor, Projectile.rotation, origin, Projectile.scale, spriteEffects, 0f);

return false;
}
}
}
just makes the first frame loop incredibly fast and deal 0 damage
 
Back
Top Bottom