#### Sin Costan

##### Eye of Cthulhu
[Tutorial] Projectile Guide and Implementation
by: Sin Costan

Introduction:
Hello TCF community, by a request, I have imported the original tAPI guide to tModLoader, with a few changes of course.

Projectile Guide and Implementation

Resources:
Dust and Sound Catalogue
Sin Costan's Collection of Fun Projectiles: Once Again

#### Attachments

• MPT.zip
8.1 KB · Views: 3,083
Last edited:

#### Sin Costan

##### Eye of Cthulhu

For those who want to make a homing projectile without the use of an aiStyle try this. This is a modified version of my PDT Bullet in COFP. This should go inside the AI hook.
Code:
``````//For all of the NPC slots in Main.npc
//Note, you can replace NPC with other entities such as Projectiles and Players
public override void AI()
{
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;
}
}
}
}``````

I see this a lot on the forums, asking how to make things shoot at a target so, here you guys go. This is a modified version of my PDT from COFP. This should be inside the AI hook.
Code:
``````//Note, you can use this with an NPC to shoot at a Player also
//For every npc slot in Main.npc
public override void AI()
{
for(int i = 0; i < 200; i++)
{
//Enemy NPC variable being set
NPC target = Main.npc[i];

//Getting the shooting trajectory
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 projectile and the live target is active
if(distance < 480f && !target.friendly && target.active)
{
if(projectile.ai > 4f) //Assuming you are already incrementing this in AI outside of for loop
{
//Dividing the factor of 3f which is the desired velocity by distance
distance = 3f / distance;

//Multiplying the shoot trajectory with distance times a multiplier if you so choose to
shootToX *= distance * 5;
shootToY *= distance * 5;

//Shoot projectile and set ai back to 0
Projectile.NewProjectile(projectile.Center.X, projectile.Center.Y, shootToX, shootToY, 1, 0, 0, Main.myPlayer, 0f, 0f); //Spawning a projectile
Main.PlaySound(2, (int)projectile.position.X, (int)projectile.position.Y, 11); //Bullet noise
projectile.ai = 0f;
}
}
}
projectile.ai += 1f;
}``````

I just figured this out, and I felt really dumb because it was really simple... with the power of Math: Trigonometry Edition, here's how you can make a projectile orbit around something. This example involves orbiting the player.
Code:
``````public override void AI()
{
//Making player variable "p" set as the projectile's owner
Player p = Main.player[projectile.owner];

//Factors for calculations
double deg = (double) projectile.ai; //The degrees, you can multiply projectile.ai to make it orbit faster, may be choppy depending on the value
double rad = deg * (Math.PI / 180); //Convert degrees to radians
double dist = 64; //Distance away from the player

/*Position the player based on where the player is, the Sin/Cos of the angle times the /
/distance for the desired distance away from the player minus the projectile's width   /
/and height divided by two so the center of the projectile is at the right place.     */
projectile.position.X = player.Center.X - (int)(Math.Cos(rad) * dist) - projectile.width/2;
projectile.position.Y = player.Center.Y - (int)(Math.Sin(rad) * dist) - projectile.height/2;

//Increase the counter/angle in degrees by 1 point, you can change the rate here too, but the orbit may look choppy depending on the value
projectile.ai += 1f;
}``````

Last edited:

#### Sin Costan

##### Eye of Cthulhu
Added some useful stuff to post below OP, have fun.

• Noel The Mole

#### Sin Costan

##### Eye of Cthulhu
Once again I have added more stuff to the "Advanced Concepts" section, this time having a projectile orbit around a player. Have fun with this! I have also made a few changes, here are some of the changes.

Code:
``````Advanced Concepts:

- Having a projectile orbit around something with an example with the projectile orbiting the player.
Fixed some mistakes
- 3f is actually the desired velocity for the homing projectile and the projectile shooting something. Fixed comments to reflect this.
- Some of the comments were off, so I fixed some of those too.
- Decided not to be lazy and added the AI hook``````

#### BlueWaterMelon

##### Golem
em how do you make a sword shoot a projectile that's already in the game?

#### Sin Costan

##### Eye of Cthulhu
em how do you make a sword shoot a projectile that's already in the game?
Just have the shoot value of the item as the ID number or use TerrariaID like this...

Code:
``````item.shoot = 405; //Literal integer ID of Flairon Bubble
item.shoot = ProjectileID.FlaironBubble; //Must have "using Terraria.ID;" at the top``````

• BlueWaterMelon

#### BlueWaterMelon

##### Golem
k I don't know, it shoots the heads randomly at mobs and it just laggy

Last edited:

#### Sin Costan

##### Eye of Cthulhu
IT WORKS but not the way it shoud you know horesmans balde that the pumpkin things go after an enmies for some reason it gos down
down
[doublepost=1458667021,1458666918][/doublepost]no sorry it gos in one spot and stays there spinning none stop
The reason it does that is because the pumpkin head most likely uses on of it's pojectile.ai[] slots as a way to save the enemy ID to track, which for the FlamingJack projectile, uses projectile.ai to save the npc ID. So you either would need to set a target for the pumpkin depending on a certain factor, for example you can do distance. You would need to use the Shoot() override to do this.

Code:
``````public override bool Shoot(Player player, ref Vector2 position, ref float speedX, ref float speedY, ref int type, ref int damage, ref float knockBack)
{
//Target ID
int target = 0;

//Min distance
float min = 3000;

for(int i = 0; i < 200; i++)
{
//Get npc at slot i
NPC n = Main.npc[i];

//If not friendly and is active
if(n.active && !n.friendly)
{
//Get the distance
float dX = n.Center.X * 0.5f - player.Center.X;
float dY = n.position.Y - player.Center.Y;
float distance = (float)System.Math.Sqrt((double)(dX * dX + dY * dY));

//If the distance is less than the min distance set min to that distance and target to that target ID
if(distance < min)
{
min = distance;
target = n.whoAmI;
}
}
}

//Spawn projectile
Projectile.NewProjectile(position.X, position.Y, speedX, speedY, type, damage, knockBack, player.whoAmI, target, 0f);

//Don't fire original projectile
return false;
}``````

• BlueWaterMelon

#### BlueWaterMelon

##### Golem
where would this go
[doublepost=1458668787,1458668772][/doublepost]the whole code
[doublepost=1458669008][/doublepost]em how could i make it so will attack anything in range expect NPCs

#### Sin Costan

##### Eye of Cthulhu
where would this go
[doublepost=1458668787,1458668772][/doublepost]the whole code
[doublepost=1458669008][/doublepost]em how could i make it so will attack anything in range expect NPCs
1. You would put that in the item cs file, usually I put that under, not in, SetDefaults().
2. Just delete the min within the if statement so that it will only check if the npc is within the min. This only works once after the projectile is fired, the AI handles the rest.

• BlueWaterMelon

#### BlueWaterMelon

##### Golem
it didn't work so my dad helped me with it and here is the working code
Code:
``````        public override bool Shoot(Player player, ref Vector2 position, ref float speedX, ref float speedY, ref int type, ref int damage, ref float knockBack)
{
//Target ID
int target = 0;

//Min distance
float min = 3000;

for(int i = 0; i < 200; i++)
{
//Get npc at slot i
NPC n = Main.npc[i];

//If not friendly and is active
if(n.active && !n.friendly)
{
//Get the distance
//float dX = n.Center.X * 0.5f - player.Center.X;
float dX = n.Center.X - player.Center.X;
//float dY = n.position.Y - player.Center.Y;
float dY = n.Center.Y - player.Center.Y;
float distance = (float)System.Math.Sqrt((double)(dX * dX + dY * dY));

//If the distance is less than the min distance set min to that distance and target to that target ID
if(distance < min)
{
min = distance;
target = n.whoAmI;
}
}
}

//Spawn projectile
if (target > 0)
{
Projectile.NewProjectile(position.X, position.Y, speedX, speedY, type, damage, knockBack, player.whoAmI, target, 0f);
}

//Don't fire original projectile
return false;
}``````

• Eli10293

#### Sin Costan

##### Eye of Cthulhu
it didn't work so my dad helped me with it and here is the working code
Code:
``````        public override bool Shoot(Player player, ref Vector2 position, ref float speedX, ref float speedY, ref int type, ref int damage, ref float knockBack)
{
//Target ID
int target = 0;

//Min distance
float min = 3000;

for(int i = 0; i < 200; i++)
{
//Get npc at slot i
NPC n = Main.npc[i];

//If not friendly and is active
if(n.active && !n.friendly)
{
//Get the distance
//float dX = n.Center.X * 0.5f - player.Center.X;
float dX = n.Center.X - player.Center.X;
//float dY = n.position.Y - player.Center.Y;
float dY = n.Center.Y - player.Center.Y;
float distance = (float)System.Math.Sqrt((double)(dX * dX + dY * dY));

//If the distance is less than the min distance set min to that distance and target to that target ID
if(distance < min)
{
min = distance;
target = n.whoAmI;
}
}
}

//Spawn projectile
if (target > 0)
{
Projectile.NewProjectile(position.X, position.Y, speedX, speedY, type, damage, knockBack, player.whoAmI, target, 0f);
}

//Don't fire original projectile
return false;
}``````
Oh wow, I did dX and dY the stupid way... Forgot I changed my style to instead use centers... Thanks for your feedback!

#### BlueWaterMelon

##### Golem #### BlueWaterMelon

##### Golem
I need help with ore coding

#### Sin Costan

##### Eye of Cthulhu
I need help with ore coding
Ore coding isn't my sort of thing and this place isn't really the place to ask about ore coding, as this place is only for projectiles and their implements, which ore is not an implement of projectiles. You should post these sorts of questions in the Official tModLoader Help Thread or the tModLoader page. Anyways, here's a code snippet from the ExampleMod that should help you with ore generation.

Here I have the code from the ExampleMod's ExampleWorld. I'm just going to use jopojelly's explanations to explain this code. In the ExampleMod, this was called in the "ModifyWorldGenTasks(List<GenPass> tasks, ref float totalWeigh)" hook.
Code:
``````//The 6E-05 is the number of patchess
for (int k = 0; k < (int)((double)(Main.maxTilesX * Main.maxTilesY) * 6E-05); k++)
{
//The below comment are the arguments for TileRunner
//TileRunner(int i, int j, double strength, int steps, int type, bool addTile = false, float speedX = 0f, float speedY = 0f, bool noYChange = false, bool overRide = true)
WorldGen.TileRunner(WorldGen.genRand.Next(0, Main.maxTilesX), WorldGen.genRand.Next((int)WorldGen.worldSurfaceLow, Main.maxTilesY), (double)WorldGen.genRand.Next(3, 6), WorldGen.genRand.Next(2, 6), mod.TileType("ExampleBlock"), false, 0f, 0f, false, true);
}``````

• BlueWaterMelon

#### BlueWaterMelon

##### Golem
how do you make a unfriendly projectile to friendly for example some projectile are used from enemies wich damages the player so if i use a weapons with that projectile and some how hit me (not to hard) it damages me and not the mobs

#### Kazzymodus

##### Moderator
Staff member
Moderator
how do you make a unfriendly projectile to friendly for example some projectile are used from enemies wich damages the player so if i use a weapons with that projectile and some how hit me (not to hard) it damages me and not the mobs

You can just set projectile.friendly to true in the SetDefaults function of your projectile.

• BlueWaterMelon

#### BlueWaterMelon

##### Golem
but the projectile is from the game