tAPI [Tutorial] Projectile Guide and Implementation

Yeah, you have to make seperate cs files for the Weapon and the Projectile, each in their respective folders of course.

thats what i did and in the weapon cs it has the code i showed you with the projectile.owner, and both of the codes you showed have projectile.owner..
 
thats what i did and in the weapon cs it has the code i showed you with the projectile.owner, and both of the codes you showed have projectile.owner..
I just checked over my code for the weapon cs partial code strip and there is no "projectile.owner" code in it...

Code:
public override bool PreShoot(Player player, Vector2 position, Vector2 velocity, int type, int damage, float knockback)
{
player.statLife -= 2; //Subtract the player's health
CombatText.NewText(new Rectangle((int)player.position.X, (int)player.position.Y, player.width, player.height), new Color(255, 60, 70, 255), string.Concat(2), false, true);
return true; 
}

Where do you see a "projectile.owner" being implemented?

Now let's review the projectile partial code strip. I'm going to use the local scope player variable.

Code:
public override void DealtNPC(NPC n, int hitDir, int dmgDealt, float knockback, bool crit)
{
    Player p = Main.player[projectile.owner];
    if(n.life < 1) //If the npc is dead
    {
        int heal = 5;
        p.statLife += heal; 
        p.HealEffect(heal, true); 
    }
}
 
Hey I dunno it's fine if ask here, how do I make projectile do auto-track enemies? for tModloader, what Codes should i write?
 
Hey I dunno it's fine if ask here, how do I make projectile do auto-track enemies? for tModloader, what Codes should i write?
What do you mean by autotrack? As in it homes into enemies or just targets them and fires a projectile?
 
home, just right click, not need to target, or slow version of chlorophyte bullet.
Well you can just put this in your AI for your projectile. It's very simple but doesn't have the same sort of.... traveling as a chlorophyte bullet. It's just very simple go towards the enemy without doing a curvular motion like the chlorophyte bullet.

Code:
//Note, you can replace NPC with other entities such as Projectiles and Players
public override void AI()
{
    //For all of the NPC slots in Main.npc
    for(int i = 0; i < 200; i++)
    {
       NPC target = Main.npc[i];
       //If the npc is hostile
       if(target.hostile)
       {
           //Get the shoot trajectory from the projectile and target
           float shootToX = target.position.X + (float)target.width * 0.5f - projectile.Center.X;
           float shootToY = target.position.Y - projectile.Center.Y;
           float distance = (float)System.Math.Sqrt((double)(shootToX * shootToX + shootToY * shootToY));

           //If the distance between the live targeted npc and the projectile is less than 480 pixels
           if(distance < 480f && !target.friendly && target.active)
           {
               //Divide the factor, 3f, which is the desired velocity
               distance = 3f / distance;

               //Multiply the distance by a multiplier if you wish the projectile to have go faster
               shootToX *= distance * 5;
               shootToY *= distance * 5;

               //Set the velocities to the shoot values
               projectile.velocity.X = shootToX;
               projectile.velocity.Y = shootToY;
           }
       }
    }
}
 
Last edited:
Well you can just put this in your AI for your projectile. It's very simple but doesn't have the same sort of.... traveling as a chlorophyte bullet. It's just very simple go towards the enemy without doing a curvular motion like the chlorophyte bullet.

Code:
//Note, you can replace NPC with other entities such as Projectiles and Players
public override void AI()
{
    //For all of the NPC slots in Main.npc
    for(int i = 0; i < 200; i++)
    {
       NPC target = Main.npc[i];
       //If the npc is hostile
       if(target.hostile)
       {
           //Get the shoot trajectory from the projectile and target
           float shootToX = target.position.X + (float)target.width * 0.5f - projectile.Center.X;
           float shootToY = target.position.Y - projectile.Center.Y;
           float distance = (float)System.Math.Sqrt((double)(shootToX * shootToX + shootToY * shootToY));

           //If the distance between the live targeted npc and the projectile is less than 480 pixels
           if(distance < 480f && !target.friendly && target.active)
           {
               //Divide the factor, 3f, which is the desired velocity
               distance = 3f / distance;

               //Multiply the distance by a multiplier if you wish the projectile to have go faster
               shootToX *= distance * 5;
               shootToY *= distance * 5;

               //Set the velocities to the shoot values
               projectile.velocity.X = shootToX;
               projectile.velocity.Y = shootToY;
           }
       }
    }
}
thanks, i'll try.
 
I have a question! When I made a Projectile for my Weapon it has (i think) Dirt Particles How would i Change that?
Code:
using System;
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
namespace OpWeaponMod.Items.Weapons
{
    public class AncientSpellBook : ModItem
    {
        public override void SetDefaults()
        {
            item.name = "Magic";         
            item.damage = 34;                       
            item.magic = true;                     //this make the item do magic damage
            item.width = 24;
            item.height = 28;
            item.toolTip = "Casts a fire bolt.";
            item.useTime = 30;
            item.useAnimation = 30;
            item.useStyle = 5;        //this is how the item is holded
            item.noMelee = true;
            item.knockBack = 2;       
            item.value = 1000;
            item.rare = 6;
            item.mana = 5;             //mana use
            item.UseSound = SoundID.Item21;            //this is the sound when you use the item
            item.autoReuse = true;
            item.shoot = mod.ProjectileType ("MagicProjectile");  //this make the item shoot your projectile
            item.shootSpeed = 8f;    //projectile speed when shoot
        }     
    }
}
 
I have a question! When I made a Projectile for my Weapon it has (i think) Dirt Particles How would i Change that?

You need change just this:

Dust.NewDust(new Vector2(projectile.position.X, projectile.position.Y), projectile.width, projectile.height, "HERE", 0f, 0f, 100, default(Color), 1f);

in "HERE" you can change it to whatever you want, you need to visit this page.
 
You need change just this:

Dust.NewDust(new Vector2(projectile.position.X, projectile.position.Y), projectile.width, projectile.height, "HERE", 0f, 0f, 100, default(Color), 1f);

in "HERE" you can change it to whatever you want, you need to visit this page.
Do i need to Just add that line of code to the projectile code?
 
And also how do I make my projectile explode? Becuase for mine, when the projectile is dead it leaves a dark projectile then I need to walk through it in order to make it explode. How do I make my projectile immediately explode on impact?
 
Question please! How can i make my weapon fire two projectiles alternatively?
And also how do I make my projectile explode? Becuase for mine, when the projectile is dead it leaves a dark projectile then I need to walk through it in order to make it explode. How do I make my projectile immediately explode on impact?
So wait is this a tAPI thing or a tModLoader thing? Uhh, the AI stuff should still work anyways, just some of the other stuff will be different like items.

Anyways, what do you mean by firing two projectiles alternatively?

Can you show me what your code looks like for this projectile?
 
so this is my code:
Code:
using System;
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
namespace YourModName.Items.Weapons.Magic        //We need this to basically indicate the folder where it is to be read from, so you the texture will load correctly
{
    public class SkysBlessing : ModItem
    {
        public override void SetDefaults()
        {
            item.name = "Sky's Blessing"; //the name displayed when hovering over the Weapon ingame.       
            item.damage = 13;   //The damage stat for the Weapon.                     
            item.magic = true;   //This defines if it does magic damage and if its effected by magic increasing Armor/Accessories.
            item.width = 24;      //The size of the width of the hitbox in pixels.
            item.height = 28;      //The size of the height of the hitbox in pixels.
            item.toolTip = "Rains down a hail of feathers.";  //The description of the Weapon shown when hovering over the Weapon ingame.
            item.useTime = 20;     //How fast the Weapon is used.
            item.useAnimation = 40;
            item.useStyle = 5; //How long the Weapon is used for.
            Item.staff[item.type] = true; //this makes the useStyle animate as a staff instead of as a gu         //The way your Weapon will be used, 5 is the Holding Out Used for: Guns, Spellbooks, Drills, Chainsaws, Flails, Spears for example
            item.noMelee = true;     //Setting to True allows the weapon sprite to stop doing damage, so only the projectile does the damge
            item.knockBack = 8;  //The knockback stat of your Weapon.     
            item.value = Item.buyPrice(0, 10, 0, 0); // How much the item is worth, in copper coins, when you sell it to a merchant. It costs 1/5th of this to buy it back from them. An easy way to remember the value is platinum, gold, silver, copper or PPGGSSCC (so this item price is 10gold)
            item.rare = 6;   //The color the title of your Weapon when hovering over it ingame
            item.mana = 17;//How many mana this weapon use
            item.UseSound = SoundID.Item13; //item.UseSound = SoundID.Item1;   //The sound played when using your Weapon
            item.autoReuse = true; //Weather your Weapon will be used again after use while holding down, if false you will need to click again after use to use it again.
            item.shoot = mod.ProjectileType("SkysBlessing");//This defines what type of projectile this weapon will shoot 
            item.shootSpeed = 15f;    //This defines the projectile speed when shoot

        }
        public override void AddRecipes()
        {
            ModRecipe recipe = new ModRecipe(mod);
            recipe.AddIngredient(ItemID.Feather, 30);
            recipe.AddIngredient(ItemID.RainCloud, 15);//in this example you see how to add your custom item to the crafting recipe
            recipe.AddTile(TileID.SkyMill);     //in this example you see how to add your custom craftingbench
            recipe.SetResult(this);
            recipe.AddRecipe();
        }
        //-----------------------------------------------StarWrath projectile style----------------------------------------------
        public override bool Shoot(Player player, ref Vector2 position, ref float speedX, ref float speedY, ref int type, ref int damage, ref float knockBack)
        {
            int numberProjectiles = 7 + Main.rand.Next(2);  //This defines how many projectiles to shot
            for (int index = 0; index < numberProjectiles; ++index)
            {
                Vector2 vector2_1 = new Vector2((float)((double)player.position.X + (double)player.width * 0.5 + (double)(Main.rand.Next(201) * -player.direction) + ((double)Main.mouseX + (double)Main.screenPosition.X - (double)player.position.X)), (float)((double)player.position.Y + (double)player.height * 0.5 - 600.0));   //this defines the projectile width, direction and position
                vector2_1.X = (float)(((double)vector2_1.X + (double)player.Center.X) / 2.0) + (float)Main.rand.Next(-200, 201);
                vector2_1.Y -= (float)(100 * index);
                float num12 = (float)Main.mouseX + Main.screenPosition.X - vector2_1.X;
                float num13 = (float)Main.mouseY + Main.screenPosition.Y - vector2_1.Y;
                if ((double)num13 < 0.0) num13 *= -1f;
                if ((double)num13 < 20.0) num13 = 20f;
                float num14 = (float)Math.Sqrt((double)num12 * (double)num12 + (double)num13 * (double)num13);
                float num15 = item.shootSpeed / num14;
                float num16 = num12 * num15;
                float num17 = num13 * num15;
                float SpeedX = num16 + (float)Main.rand.Next(-40, 41) * 0.02f;  //this defines the projectile X position speed and randomnes
                float SpeedY = num17 + (float)Main.rand.Next(-40, 41) * 0.02f;  //this defines the projectile Y position speed and randomnes
                Projectile.NewProjectile(vector2_1.X, vector2_1.Y, SpeedX, SpeedY, type, damage, knockBack, Main.myPlayer, 0.0f, (float)Main.rand.Next(5));
            }
            return false;
        } 
    }
}

and what i mean by shooting two projectiles alternatively is that i want to fire blue feathers and golden feathers alternatively but i don't know how to do it so as you can see in my code that i have the starwrath projectile style, i want it to fire blue and golden feathers from the sky but i don't know how.
 
so this is my code:
Code:
using System;
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
namespace YourModName.Items.Weapons.Magic        //We need this to basically indicate the folder where it is to be read from, so you the texture will load correctly
{
    public class SkysBlessing : ModItem
    {
        public override void SetDefaults()
        {
            item.name = "Sky's Blessing"; //the name displayed when hovering over the Weapon ingame.      
            item.damage = 13;   //The damage stat for the Weapon.                    
            item.magic = true;   //This defines if it does magic damage and if its effected by magic increasing Armor/Accessories.
            item.width = 24;      //The size of the width of the hitbox in pixels.
            item.height = 28;      //The size of the height of the hitbox in pixels.
            item.toolTip = "Rains down a hail of feathers.";  //The description of the Weapon shown when hovering over the Weapon ingame.
            item.useTime = 20;     //How fast the Weapon is used.
            item.useAnimation = 40;
            item.useStyle = 5; //How long the Weapon is used for.
            Item.staff[item.type] = true; //this makes the useStyle animate as a staff instead of as a gu         //The way your Weapon will be used, 5 is the Holding Out Used for: Guns, Spellbooks, Drills, Chainsaws, Flails, Spears for example
            item.noMelee = true;     //Setting to True allows the weapon sprite to stop doing damage, so only the projectile does the damge
            item.knockBack = 8;  //The knockback stat of your Weapon.    
            item.value = Item.buyPrice(0, 10, 0, 0); // How much the item is worth, in copper coins, when you sell it to a merchant. It costs 1/5th of this to buy it back from them. An easy way to remember the value is platinum, gold, silver, copper or PPGGSSCC (so this item price is 10gold)
            item.rare = 6;   //The color the title of your Weapon when hovering over it ingame
            item.mana = 17;//How many mana this weapon use
            item.UseSound = SoundID.Item13; //item.UseSound = SoundID.Item1;   //The sound played when using your Weapon
            item.autoReuse = true; //Weather your Weapon will be used again after use while holding down, if false you will need to click again after use to use it again.
            item.shoot = mod.ProjectileType("SkysBlessing");//This defines what type of projectile this weapon will shoot
            item.shootSpeed = 15f;    //This defines the projectile speed when shoot

        }
        public override void AddRecipes()
        {
            ModRecipe recipe = new ModRecipe(mod);
            recipe.AddIngredient(ItemID.Feather, 30);
            recipe.AddIngredient(ItemID.RainCloud, 15);//in this example you see how to add your custom item to the crafting recipe
            recipe.AddTile(TileID.SkyMill);     //in this example you see how to add your custom craftingbench
            recipe.SetResult(this);
            recipe.AddRecipe();
        }
        //-----------------------------------------------StarWrath projectile style----------------------------------------------
        public override bool Shoot(Player player, ref Vector2 position, ref float speedX, ref float speedY, ref int type, ref int damage, ref float knockBack)
        {
            int numberProjectiles = 7 + Main.rand.Next(2);  //This defines how many projectiles to shot
            for (int index = 0; index < numberProjectiles; ++index)
            {
                Vector2 vector2_1 = new Vector2((float)((double)player.position.X + (double)player.width * 0.5 + (double)(Main.rand.Next(201) * -player.direction) + ((double)Main.mouseX + (double)Main.screenPosition.X - (double)player.position.X)), (float)((double)player.position.Y + (double)player.height * 0.5 - 600.0));   //this defines the projectile width, direction and position
                vector2_1.X = (float)(((double)vector2_1.X + (double)player.Center.X) / 2.0) + (float)Main.rand.Next(-200, 201);
                vector2_1.Y -= (float)(100 * index);
                float num12 = (float)Main.mouseX + Main.screenPosition.X - vector2_1.X;
                float num13 = (float)Main.mouseY + Main.screenPosition.Y - vector2_1.Y;
                if ((double)num13 < 0.0) num13 *= -1f;
                if ((double)num13 < 20.0) num13 = 20f;
                float num14 = (float)Math.Sqrt((double)num12 * (double)num12 + (double)num13 * (double)num13);
                float num15 = item.shootSpeed / num14;
                float num16 = num12 * num15;
                float num17 = num13 * num15;
                float SpeedX = num16 + (float)Main.rand.Next(-40, 41) * 0.02f;  //this defines the projectile X position speed and randomnes
                float SpeedY = num17 + (float)Main.rand.Next(-40, 41) * 0.02f;  //this defines the projectile Y position speed and randomnes
                Projectile.NewProjectile(vector2_1.X, vector2_1.Y, SpeedX, SpeedY, type, damage, knockBack, Main.myPlayer, 0.0f, (float)Main.rand.Next(5));
            }
            return false;
        }
    }
}

and what i mean by shooting two projectiles alternatively is that i want to fire blue feathers and golden feathers alternatively but i don't know how to do it so as you can see in my code that i have the starwrath projectile style, i want it to fire blue and golden feathers from the sky but i don't know how.
if you're talking about it changing projectiles every time it is fired, then inside the for loop, add an if statement that changes the "type" variable before firing. You probably want that if statement to do something like an 80% chance for blues and 20% chance for gold, so it might look something like this.

Code:
if(Main.rand.next(5) == 0)
{
   type = mod.ProjectileType("What_You_Named_Your_Gold_Feathers");
}
else
{
   type = mod.ProjectileType("What_You_Named_Your_Blue_Feathers");
}

Just stuff that in the for loop replacing the random name I gave it with the proper names under the for loop and you should be good for that.

As for the explosion thing, did you already figure that out?
 
Back
Top Bottom