FANDOM


Difficulty: noframe
Clock: N/A


Under Contruction

Under Construction
This page has been marked as under construction, which means information may change rapidly as it updated, or that the page is awaiting updates.


Projectile AI Functionality: Edit

I'm still working with some of the code to figure out how it applies additonal functions to projectiles. Here I will state the things I have not figured out how to modify yet, or effects that still need to rely on stock item values until an alternative is figured out.

Projectile issues still existing for now

Boomerangs: 
- Throw limit is enforced through the CanUse() Item method.
- Chakram style bouncing still requires a pretendType field in the projectile ini

Flails:
- Chain color defaults to blue
- Unless the flail hits a block it always seems to kill itself upon returning to 
  the player instead of being swung around when the mouse button is held down 
  if it does hit a block it will act properly though...

Spears:
- Nothing known as of yet. 
- If anyone finds any issues let me know 
  and show me the source so I can try and figure it out

Making a Bow and ArrowEdit

  1. Go to your "Item" folder
  2. Create a new ini file using the same name as the intended name for the bow
  3. Put inside the ini file:
[Stats]
autoReuse=True
damage=30
height=28
knockBack=8
maxStack=1
noMelee=True
;sets the bow itself to not do damage
ranged=True
rare=4
scale=1
shootSpeed=15
;how fast the projectile must travel.
type=-1
useAnimation=30
;how long 1 animation (in click) is.
useTime=30
;how many times it shoots (in this case), /useAnimation value.
useSound=1
shoot=1
;the arrow projectile type.
;;Projectile='custom projectile name'
useStyle=5
;the style for the bow, for it to 'shoot'
value=200000
width=14
[Recipe]
Items=1 Wood
needWater=False
Amount=1
  1. Create a png file for the bow named the same.

Making a Custom Arrow for Bows/Same for GunsEdit

  1. Go into your Projectile folder in modpack folder.
  2. Create an ini file with the same name as the intended name for the projectile
  3. Put this ini code inside of your .ini file:
[Stats]
aiStyle=1
;the ai style of an arrow and for bullets
aiPretendType=20
;for bullets ONLY, will make the projectile fly straight.
width=6
height=6
scale=1
type=-1
friendly=True
;so it will act as a friendly weapon and not kill your NPC's
;;set as Hostile=True if you actually want it to kill your NPC's
damage=50
hide=false
ranged=True
timeLeft=600
light=1
tileCollide=True
  1. Create a .png file with the same name.
  2. Make sure the item that uses this projectile has its 'projectile' string set to whatever you named this projectile.

Making a GunEdit

1. Go to your "Item" folder
2. Create an ini file that has the same name as the intended name for the gun
3. Put the following code into the .ini file:
It works pretty much the same like bows
[Stats]
width=44
height=14
type=-1 //Still has to be -1
useStyle=5 // the general gun useStyle
useAnimation=43 //how long the full shot cycle takes
useTime=43 //how many shots fired during the cycle useTime/useAnimation=how many
maxStack=1
damage=23
knockBack=4
autoReuse=True
scale=1
useSound=11
rare=1
shoot=10 //change to the projectile you want it to shoot, ONLY FOR NON-CUSTOM PROJECTILES
//projectile=POTATO BULLET //use this if your using a custom projectile, and make sure to remove shoot=#
shootSpeed=8 //the speed the projectile will travel
useAmmo=14 //the non-custom ammo it will use
//useAmmoName=POTATO //the custom ammo the gun will use, remove useAmmo
noMelee=True //so the gun itself wont do damage
value=100000
ranged=True
className=Item

Making the Item for the ProjectileEdit

Place this in the Item's .ini and put it into ~ModPack/[Name of Mod]/Item~ Folder

[Stats]
width=10
height=14
type=-1
maxStack=250
scale=1.0
value=2500
ammoName=Potato
;wich projectile it will shoot, also needed in the gun/bow's .ini
[Recipe]
Items=1 Wood
needWater=False
Amount=25
;set everything to what you want
4. Create a .png file for your gun, name it the same thing.

Adding Dust to a ProjectileEdit

This Example deals with adding a dust to a spear projectile, note that we spawn the dust in the AI() method, although it can be done anywhere else, too.

The primary means of this is to explain how dust spawning a dust work and using it in the projectile we have.

Dust.NewDust(params here), is the a method that will spawn a dust , in a certain box , at a certain variation of velocity , at a certain color , and at a certain size.

Dust.NewDust also returns a number , which is the index of the dust in our array of dusts in the game , so we can tamper with that dust later.

The method itself is:

Dust.NewDust(Vector2 ARG1, int ARG2, int ARG3, int ARG4, float ARG5, float ARG6, int ARG7, Color ARG8, float ARG9);

  • ARG1 is a Vector2 ,which is the top left corner of the box in which your dust spawns
  • ARG2 is an int, which is the width of your box , the width goes towards the right corner of the box, so the right corner's X is at ARG1.X + ARG2, in terms of values.
  • ARG3 is an int, which is the height of your box , the height goes towards the bottom of of the box , so the bottom corner's Y is at ARG1.Y + ARG3, in terms of values.
  • ARG4 is an int, which is the Dust's Type, see the List of Dusts.
  • ARG5 is a float, which is the the dust's X speed, negative values go left, positive values go right.
  • ARG6 is a float, which is the dust's Y speed, negative values go up, positive values go down.
  • ARG7 is an int, which is the dust's alpha, the higher it is the more visible a dust is(or is it less visible.....) , at 0 its transparent, its usually best to set it to 150. (this value ranges from 0 to 255).
  • ARG8 is a color, you will usually want to leave it as 'default(Color)', but if you have the understanding of tampering with it, it can be of great fun.
  • ARG9 is a float, which is the dust's size, for example 5f would mean the dust is 5 times the size of its usual self.

Now the example, the first part regards the spear ai, the second part regards the dusts we make.

Gae Bolg Infernal.cs

public void AI()
{
    projectile.direction = Main.player[projectile.owner].direction;
    Main.player[projectile.owner].heldProj = projectile.whoAmI;
    Main.player[projectile.owner].itemTime = Main.player[projectile.owner].itemAnimation;
    projectile.position.X = Main.player[projectile.owner].position.X + (float)(Main.player[projectile.owner].width / 2) - (float)(projectile.width / 2);
    projectile.position.Y = Main.player[projectile.owner].position.Y + (float)(Main.player[projectile.owner].height / 2) - (float)(projectile.height / 2);

    if (projectile.ai[0] == 0f)
    {
        projectile.ai[0] = 3f;
        projectile.netUpdate = true;
    }
    if (Main.player[projectile.owner].itemAnimation < Main.player[projectile.owner].itemAnimationMax / 3)
    {
        projectile.ai[0] -= 2.4f;
    }
    else
    {
        projectile.ai[0] += 2.1f;
    }
    projectile.position += projectile.velocity * projectile.ai[0];
    if (Main.player[projectile.owner].itemAnimation == 0) // Has the projectile run its animation and returned to the player? If so kill it then...
    {
        projectile.Kill();
    }
    projectile.rotation = (float)Math.Atan2((double)projectile.velocity.Y, (double)projectile.velocity.X) + 2.355f;
    if (projectile.spriteDirection == -1)
    {
        projectile.rotation -= 1.57f;
    }


    //until this point , all we did was writing a spear's ai.


    Vector2 DustPos = projectile.position;
    int DustWidth = projectile.width;
    int DustHeight = projectile.height;
    int DustType = 74; // this controls a dust type
    float DustSpeedX = 0f;
    float DustSpeedY = 0f;
    int DustAlpha = 150;
    float DustSize = 1.4f;
    
    int DustIndex = 0; //we will be using it for our second dust

    //this is where we spawn our first dust , on a random chance
    if (Main.rand.Next(5) == 0) //20% chance to spawn the dust
    {
        Dust.NewDust(DustPos, DustWidth, DustHeight, DustType, DustSpeedX, DustSpeedY, DustAlpha, default(Color), DustSize);
    }

    //our second dust
    DustIndex = Dust.NewDust(DustPos, DustWidth, DustHeight, DustType, DustSpeedX, DustSpeedY, DustAlpha, default(Color), DustSize);
    
    //we're pointing to our dust , and changing it as we see fit.
    Dust DustRef = Main.dust[DustIndex];
    DustRef.noGravity = true;
    DustRef.velocity /= 5f; //divide its velocity by 5
    

    //now for the third dust we change our dust a bit , so it gets a little of its spawner projectile's speed.
    DustSpeedX = projectile.velocity.X * 0.2f + (float)(projectile.direction * 3);
    DustSpeedY = projectile.velocity.Y * 0.2f;
    DustAlpha = 100;
    DustSize = 1.2f;

    DustIndex = Dust.NewDust(DustPos, DustWidth, DustHeight, DustType, DustSpeedX, DustSpeedY, DustAlpha, default(Color), DustSize);

    Dust DustRef = Main.dust[DustIndex];
    DustRef.noGravity = true;
    DustRef.velocity /= 2f; //divide its velocity by a half
}

For a Screenshot of this particular spear in action from me click here.

Making a BoomerangEdit

For this example, I'll use a boomerang called Hellfire Chakram I created in my modpack. I will show ini and pictures to help with understanding how they should look. I will also show how to have the boomerang inflict poison and fire debuffs to an NPC upon contact.

You'll need an Inventory & Projectile picture. Unless you're doing some sort of special sprite, there is no need for rotation or resizing.

Hellfire Chakram

Example 1

Example 1: This picture will work as an Inventory Item and as the projectile as well

After you're done with the pictures and have them placed in both the Item and Projectile folders, it's time for the ini files.


For the Item Folder in your modpack

Hellfire Chakram.ini

[Stats]
autoReuse=True
damage=30
height=28
knockBack=8
maxStack=1
noMelee=True
;the projectile is what has a hitbox and not the item
noUseGraphic=True
;the inventory item should not show while throwing
melee=True
;boomerangs now do melee damage as of latest update but you can set it to ranged if you prefer that.
rare=4
scale=1
shootSpeed=15
type=-1
useAnimation=15
;the animation for the boomerang
useSound=1
projectile=Hellfire Chakram
useStyle=1
;the style for the boomerang makes a throw animation
useTime=15
value=200000
width=14
[Recipe]
Items=1 Thorn Chakram,1 Flamarang
Tiles=Demon Altar
needWater=False
Amount=1

For the Projectile folder in your modpack:

Hellfire Chakram.ini

[Stats]
aiStyle=3
;A boomerang projectile's AI as found on the projectile AI page
friendly=True
pretendType=33
;makes the boomerang bounce off things like the Thorn Chakram, also gives it the same particle effects and the poison effect too
killPretendType=33
;refer to the aiPretendType Article for more information on this
;(means that it blows up tiles)
height=34
light=1
melee=True
;this should match what is in the Hellfire Chakram's item folder ini
scale=1
tileCollide=True
penetrate=-1
;I believe this stopped the boomerang from disappearing on contact with npcs so now it will bounce off like one does normally
type=-1
width=34


Now comes the C# code for those of you who are a little more advanced. My code is updated to be used with the latest version of tConfig and to be used via a code.dll as Surfpup states with the newest handling of .cs files. Putting this in a .cs file and into your modpack just as is will probably give an error of some sort when you run the modpack builder. I have removed the outdated method as it is obsolete. You will need to make your modpack's c# files into a code.dll following Surf's instructions in the 0.16.9 version of the changelog.

Hellfire Chakram.cs (Visual Studio Code.dll style)

public void DamageNPC(NPC npc, ref int damage, ref float knockback)
{
   if (Main.rand.Next(2) == 1)//33% chance to occur
   {
       npc.AddBuff(24, 360, false); //Light 'em on fire!
       npc.AddBuff(20, 360, false); //Poison 'em too!
       //24 is for onFire buff, 20 is for poisoned buff, look at the list of buffs for more information. to add your own buff, add npc.addBuff("your buff here", 360, false);
   }
}

public void DealtPVP(Player enemyPlayer, ref int damage, ref float knockback) {

  if (Main.rand.Next(2) == 1)
  {
      npc.AddBuff(24, 360, false);
      npc.AddBuff(20, 360, false);
  }

}

//same as for the DealtNPC, only for in a PvP battle.

Method for limiting the number of projectiles you can throw:

public bool CanUse(Player player, int pID) {
	bool use=true;
	//This code is used by boomerangs to limit the amount of boomerang projectiles that can be thrown.
	for (int m = 0; m < 1000; m++)
	{
		if (Main.projectile[m].active && Main.projectile[m].owner == Main.myPlayer && Main.projectile[m].type == item.shoot)
		{
			use = false;
			break;
		}
	}
	return use;
}

Making a FlailEdit

For this example, I'll use a flail I created in my own modpack along with the ini files and pictures of it.

You'll need an Inventory & Projectile picture as usual.

Meteor Masher

Example 1

Example 1: Inventory Icon Version of Meteor Masher
Meteor Masher Ball

Example 2



Example 2: Projectile Version of the Meteor Masher

Note: This will always be what is on the end of your flail, so find or make a picture of ONLY what will be at the end of the chain and not anything else with it.


After you're satisfied with the icon and projectile pictures and put them in their proper places; it's time to make the ini files.

For the Item Folder in your modpack

Meteor Masher.ini

[Stats]
width=30
height=10
type=-1
pretendType=163
;Just to make sure it'll pretend to be a flail for any inventory purposes. May not be needed though.
useStyle=5
;A flail's useStyle
channel=True
;this is used for keeping the flail active while you hold down the mouse button like you would with any flail
useAnimation=45
prefixType=368
useTime=45
maxStack=1
damage=75
knockBack=100
scale=1.5
useSound=1
rare=4
shootSpeed=15
projectile=Meteor Masher Ball
noUseGraphic=True
;Once again we don't want the inventory item's graphic displaying while we swing
noMelee=True
;The inventory item's sprite should not be doing the damage as it's done via a projectile just like a lance or boomerang
value=27000
melee=True
[Recipe]
Items=99 Demonite Bar,99 Meteorite Bar,99 Shadow Scale,50 Diamond,250 Spike
Tiles=Anvil
needWater=False
Amount=1


For the Projectile Folder in your modpack

Meteor Masher Ball.ini

[Stats]
aiStyle=15
;the AI style of a flail
aiPretendType=63
width=42
height=42
scale=1
type=-1
prefixType=368
penetrate=-1
;Once again we want it to bounce around and off things not just disappear upon hitting anything.
timeLeft=3600
;the time left that the flail's projectile will be held till it disappears until fired again
friendly=True
tileCollide=True
melee=True


To make the flail have a custom chain, add this in the Player.cs file inside your mod's Global folder, replacing "Meteor Masher" with whatever your file's names are(and make sure you have a .png file in the Gore folder for both the Blue Moon Chain and the custom flail chain):

Blue Moon ChainThis is the file for the Blue Moon Chain.

Player.cs

public void UpdatePlayer(Player P)
{
   if (P.inventory[P.selectedItem].type == Config.itemDefs.byName["Meteor Masher"].type)
   {
       Main.chain3Texture = Main.goreTexture[Config.goreID["Meteor Masher Chain"]];
   }
   if (P.inventory[P.selectedItem].type != Config.itemDefs.byName["Meteor Masher"].type)
   {
       Main.chain3Texture = Main.goreTexture[Config.goreID["Blue Moon Chain"]];
   }
}

Making a SpearEdit

For this example, I'll use a spear that I created in my own modpack along with the ini files and pictures of it.

As with the boomerang and flail items you'll need an Inventory & Projectile picture.

Sacrificial Spear

Example 1

Example 1: Inventory Icon Version of Sacrificial Spear



Example 2: Projectile Version of the Sacrificial Spear
Sacrifical Spear

Example 2

Note: An easy way to make a spear projectile is by extending the handle on your spear for the inventory picture and then rotating the icon to look like Example 2 or if you prefer, rotate it first and then extend the handle.


Note: Make sure you put an Example 2 style picture in the projectile folder and not an Example 1 style picture.

After you're satisfied with the icon and projectile pictures, it's time to make the ini files.

For the Item Folder in your modpack:

Sacrificial Spear.ini

[Stats]
damage=50
height=40
knockBack=4
maxStack=1
melee=True
noMelee=True
;A spear handles its hitbox from a projectile and not the item itself.
noUseGraphic=True
;Hides the inventory item from being displayed instead of the spear's projectile. If false you'll end up with a weird looking spear attack.
rare=3
scale=1.3
shoot=46
;I still oddly had to add this line to get any projectile custom or not to show up for me it may have been fixed now though so you might be able to omit this line
shootSpeed=7
;How far and fast the spear will extend from the player. Really high values can cause the spear to end up leaving your hands when you attack.
projectile=Sacrificial Spear
;the spear's projectile
type=-1
prefixType=368
toolTip=Demands sacrifices
useAnimation=25
useSound=1
useStyle=5
useTime=15
value=2518000
width=40
[Recipe]
Items=50 Demonite Bar,50 Shadow Scale,50 Bone
Tiles=Anvil
Amount=1
needWater=False

For the Projectile folder in your modpack:

Sacrificial Spear.ini:

[Stats]
aiStyle=19
;Found on the projectile page on the wiki this is the value for a spear style AI
friendly=True
height=22
hide=True
;Was not entirely sure what this was used for but I've made 3+ spears so far, all of which work perfectly so I keep this in there. Figure hide would hide the projectile but maybe it refers to the item which it originates from...
melee=True
;Spears do melee damage, so let's assign this projectile melee type damage here
scale=1.0
;this is where you'd edit the size of the spear for the attack.
timeLeft=3600
type=-1
width=22
pretendType=47
;one of the spear projectile AI's in the stock game
useTime=12
tileCollide=false
;Spears obviously don't stop upon hitting walls so they shouldn't collide with tiles
penetrate=6
;This causes wall penetration for a spear allowing it to hit any mobs through walls (change it to whatever you want though not sure what every value will do however, so mess around a little and see what happens).

Making Objects RetrievableEdit

(credit goes to Yoraiz0r for this) (and now actually editted by Yoraiz0r)

To make an arrow or throwing weapon retrievable after use, simply add the following code to the projectile.

Example shown for "Steel Arrow.cs":

public void Kill()
{
    if (!projectile.active)
    {
        return;
    }
    projectile.timeLeft = 0;
    projectile.active = false;

    //those were not important

    Main.PlaySound(0, (int)projectile.position.X, (int)projectile.position.Y, 1); //adding sounds
    for (int i = 0; i < 10; i++) //adding visuals
    {
        Dust.NewDust(projectile.position, projectile.width, projectile.height, 7, 0, 0, 0, default(Color), 1f);
    }
    //up to now we were adding visuals , sound and making sure the projectile is dead


    //here , we check that the projectile is indeed ours (important for multiplayer only) and giving it a random chance , of 1 out of 3 , to drop its item.
    if (projectile.owner == Main.myPlayer && Main.rand.Next(3) == 0)
    {
        Item.NewItem(
        (int)projectile.position.X,
        (int)projectile.position.Y,
        projectile.width,
        projectile.height,
        Config.itemDefs.byName["Steel Arrow"].type, 
        1, 
        false, 
        0);
    }
}

This code , does the following.

1 - make sure the projectile is indeed 'dead' and not just off the screen 'dead'.

2 - add a sound for when it dies , for realism

3 - adding dust , so that the death will look proper.

4 - actually trying to spawn an item , with a chance of 1 in 3.

.

You could replace "Steel Arrow" with whatever you named your item for projectile listed , and feel free to cut out the other parts.

Adding Effects on Projectile DeathEdit

So you want your projectile to explode when it dies? Maybe you want it to spew dust, or make another projectile? Well, here's how.

Simply open your projectile's class file (.cs) and add the following:

public void PreKill() { 
//Stuff you want to happen when your projectile dies.
}

Now I'll go through an example; I wanted to make a bullet that exploded on impact, it proved way harder to figure out than I thought, but here's my method:

public void PreKill() {
Projectile.NewProjectile(projectile.position.X,projectile.position.Y,0,0,112,100,0,projectile.whoAmI); //this creates a new projectile at the position of the dead one. It's also a stupidly fun method in general.
}

Before you can run off and starting making bullets that shit Dynamite, here's what you need to know about Projectile.NewProjectile.

Projectile.NewProjectile(float[X coordinate], //Where on the X axis to spawn
float[Y coordinate], // Where on the Y axis to spawn
float[X velocity], // How fast to move on X axis
float[Y velocity], // How fast to move on Y axis
int[Projectile ID], // The projectile you're spawning (this is the tricky part)
int[Damage], // Damage dealt (Completely ignores any damage defined elsewhere)
float[Knockback], // How far to knockback those hit
int[owner ID]) // This number messes with shit in ways I don't properly understand, so just leave it as projectile.whoAmI

So about the projectile ID, it will spawn the projectile whose number corresponds with this list. You'll notice that the number I used was 112, which isn't on that list. This is because in order for your explosion to work the way you want it to, you need to make a new projectile, here's mine, with the important stuff commented:

[Stats]
width=60 //Width of explosion
height=60 //Height of explosion
damage=1 //Irrelevant unless you're using this projectile elsewhere
type=-1
alpha=0
hide=True //don't draw the sprite on screen
aiStyle=-1
timeLeft=20 //How long the explosion lasts in frames (60 frames = 1 second)
friendly=True
penetrate=999
ignoreWater=True
tileCollide=False
ranged=True

As for making an explosion animation happen:

killPretendType=30 //Add this to your exploding projectile's .ini, it makes it run the grenade's Kill() method.

If you change that ID to the bomb's or dynamite's it will also destroy tiles, I don't know how to change the destruction radius though.

You can make your projectile spawn anything you want, even itself (this messes up the game pretty fast though.), you could also add dust, or make it spawn NPCs, literally anything you want from the game.


Other Methods available Pertaining to Items/ProjectilesEdit

Several methods have already been mentioned in this section for extending the capabilities of what can be done with items and projectiles, such as Kill, UpdatePlayer, and DealtNPC. A full list of these methods is at TConfig Classes, with Item-specific methods at Item Methods.

I wanted to call attention to the PreShoot method which is called before the projectile is shot, and can be used for things such as making multiple shots come out.

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.