Items
Last update: 9th of June, 2016
Table of contents:
1. Prerequisites
2. Introduction
3. The first item
4. How to create any vanilla weapon type you want
5. Doing something on hit
6. Other things
Prerequisites
Make sure you have....
Introduction
In this tutorial we're going to look at items in general. After recipes, items are generally the easiest to proceed with. Although, you can create very complicated items.In this tutorial, I will try to cover every item type for a custom item. (swords,spears,boomerang etc.) Complicated AI is for a later tutorial.
Before we begin, the SkeletonGenerator should already have created MyFirstItem.cs along with a sprite in your 'Items' folder.
The first item
Let's take a look at MyFirstItem.cs It currently contains SetDefaults() and AddRecipes(), let's take a look.
SetDefaults()
This method (or hook) serves to set any properties of an item.
Most of these, should speak for themselves.
There are 5 damage types: item.melee, item.magic, item.ranged, item.summon and item.thrown
Each of these are booleans, you must set which damage type you want to use to true.
The item.width and item.height should generally be the size of the used sprite. These are the dimensions used in game. (hitbox etc.)
item.useTime determines how fast the item can actually be used. item.useAnimation actually determines how long it takes to perform the item's animation (in this case a swing)
You can not use the item again until the animation finishes, so you can have a long animation even though the item itself is very fast.
item.useStyle detemines which type of 'useStyle' is used, in this case 1 is an overhead swing. Here's a list of useStyles with examples:
item.useSound determines which sound is used when using this item. In this case, 1 is general using sound. Here's a list of item useSounds:
AddRecipes()
Hey, this is familiar! As said in the previous tutorial, there are various places to add recipes.
Let's take a look!
As you can see, we are no longer passing "this" to our new ModRecipe as "this" would now refer to our ModItem, not our mod. That's why a mod variable has been opened up for you to use.
Instead, we can use "this" when setting our result, as we want our result to be our ModItem! The same recipe principles apply here, so there's nothing fancy to find.
How to create any vanilla weapon type you want
There is a neat function we can make use of, called CloneDefaults()
The following new ModItem class could be pasted below your previous ModItem class, in the same file.
This item will function exactly the same as a regular Terra Blade, but with 500 damage and a different name & texture.
I don't think I need to explain SetDefaults()
Overriding Autoload()
You don't have to override Autoload, the reason I'm doing it here is because I don't want to add a new sprite for this item: I want to use the vanilla Terra Blade sprite. We're manually setting the texure location. Remember if you want to access a mod's source, it starts from 'Mod Sources' so you need to begin with the mod's folder name. Autoload would normally look for a sprite named BetterTerraBlade.png which isn't there so we would get errors. You can access vanilla sprites by using "Terraria/" followed by the sprite name. Item sprites are named "Item_ID" where the ID is the ID of the item. For Terra Blade, the ID is 757. You can use Terraria.ID to get any ID as well as follows:
An empty recipe?
To those of you who didn't know: it's possible to not require anything in a recipe. This allows us to craft this item without needing any ingredients. The only thing you have to do is simply not add any ingredient!
Custom drawing?
The above principles can be applied for any vanilla weapon. In the next example, I'm creating a Better Flairon ModItem. What's important to note here is that flails use custom drawing. No matter what you set the texture to, you'll see a Flairon texture when you use this item. This is due to manual drawing, which we will look at in a later tutorial. It will still display the texture we set in the inventory and any other place really.
The trick with flails, same for certain other weapon types, is that they are throwing a projectile and the drawing happens in their AI. Again, this is something we should look at later.
A custom health potion
We can again use this to create a health potion that instantly heals us to full life! It's actually every easy!
The item is consumed upon use, but we are healed the following every time it's used:
statLifeMax2 is the player's health INCLUDING buffs. statLifeMax is excluding buffs.
Doing something onhit
I'm sure you know of those items that can set enemies ablaze. We can do exactly the same! Let's go back to our Better Terra Blade item, we can use the following hook to add a debuff when it hits something:
It's very important to note here that only the actual sword swung will apply this debuff, as we've not added this hook to the projectile. This is demonstrated in the following picture
The first dummy was hit by our actual sword, the second one was only hit by the projectile. As projectiles do not cover this tutorial, unfortunately I will not go into this now.
Something more unique
Adding debuffs on hit isn't just the only thing you can do. You could for example deal some damage to the player when hitting an npc that is a town npc!
The above code would damage the player by 5 with a knockback to the opposite direction. If you die, it uses the custom text "Player is an evil ..."
Other things
I will fill the following list as time progresses. If you want me to cover something here, let me now in a comment.
Custom CanUseItem rules
We can start using the CanUseItem() hook to decide whether or not an item can be used.
Let's go back to our Better Flairon item add the following: the item can only be used if the player is in hardmode.
If you return true in this hook, the item can be used. Vice versa for false. Try it out! Use the next example if you want to test this more easily.
UseItem rules
No hardmode? Let's make it so that our potion toggles the hardMode variable for testing purposes.
Add the following in InstantHealPotion:
We are now using the UseItem() hook to do stuff when the item is used. The above code will reverse Main.hardMode.
If your world isn't hardMode, consume this potion and you will be able to use Better Flairon! Consume another potion and you will no longer be able to!
It's magic!
WIP, MORE TO COME
Full code
Go to next tutorial: Tutorial [3] Projectiles
Last update: 9th of June, 2016
Table of contents:
1. Prerequisites
2. Introduction
3. The first item
4. How to create any vanilla weapon type you want
5. Doing something on hit
6. Other things
Prerequisites
Make sure you have....
- ...the latest tModLoader installed (offical thread)
- ...the latest Microsoft .NET Framework installed (offical .net site)
- ...the Microsoft XNA Framework installed (you have this if you are able to play Terraria)
- ...Microsoft Visual Studio (community = free) installed with the C# workspace (official MVS site)
- .. actually, MVS isn't required but it's a very nice IDE to work with. You can also use notepad or notepadd++ or alike, but MVS will be super useful for noobs that makes simple mistakes because the IDE will help you program
- ...C# knowledge, all tML mods currently are programmed with the C# language
- ...followed the tutorial prior to this one http://forums.terraria.org/index.php?threads/tutorial-2-recipes.44822/
Introduction
In this tutorial we're going to look at items in general. After recipes, items are generally the easiest to proceed with. Although, you can create very complicated items.In this tutorial, I will try to cover every item type for a custom item. (swords,spears,boomerang etc.) Complicated AI is for a later tutorial.
Before we begin, the SkeletonGenerator should already have created MyFirstItem.cs along with a sprite in your 'Items' folder.
The first item
Let's take a look at MyFirstItem.cs It currently contains SetDefaults() and AddRecipes(), let's take a look.
SetDefaults()
Code:
public override void SetDefaults()
{
item.name = "MyFirstItem";
item.damage = 50;
item.melee = true;
item.width = 40;
item.height = 40;
item.toolTip = "This is a modded sword.";
item.useTime = 20;
item.useAnimation = 20;
item.useStyle = 1;
item.knockBack = 6;
item.value = 10000;
item.rare = 2;
item.useSound = 1;
item.autoReuse = true;
}
Most of these, should speak for themselves.
There are 5 damage types: item.melee, item.magic, item.ranged, item.summon and item.thrown
Each of these are booleans, you must set which damage type you want to use to true.
The item.width and item.height should generally be the size of the used sprite. These are the dimensions used in game. (hitbox etc.)
item.useTime determines how fast the item can actually be used. item.useAnimation actually determines how long it takes to perform the item's animation (in this case a swing)
You can not use the item again until the animation finishes, so you can have a long animation even though the item itself is very fast.
item.useStyle detemines which type of 'useStyle' is used, in this case 1 is an overhead swing. Here's a list of useStyles with examples:
- Swinging / Throwing (swords)
- Eating / Using (potions)
- Stabbing (shortswords)
- Holding up (summon items)
- Holdout out (spellbooks)
item.useSound determines which sound is used when using this item. In this case, 1 is general using sound. Here's a list of item useSounds:
- General Using Sound (for melee and most thrown stuff)
- Mushroom
- Potion Use
- Fallen Star, Life Crystal
- Arrow, Blowpipe Shooting Sound
- Magic Mirror
- Lower version of general using sound (deep swish)
- Demon Scythe, Dirt Rod, Orb of Light, Vilethorn
- Crystal Storm, Magic Missile, Star Cannon, Starfury
- Harpoon
- Guns
- Laser Rifle, Space Gun
- Water Spray
- Bomb Explosion
- Phaseblades
- Whoopie Cushion Fart
- Stinger Dart?
- Duplicate of #1
- Throwing sound (higher-pitched general use sound)
- Cursed Flames, Flamelash, Flower of Fire
- Water Bolt
- Motorized Tools (Drill, Chainsaw, Hamdrax loop this sound while being used)
- Motorized Tools Activation (plays with #22 at the start, but does not loop with it)
- Spectre Boots sound
- Fairy Bell
- Harp
- Coin Clink (Crystal Shard sound when broken)
- Ice Rod, Rainbow Rod
- Mana Crystal
- Ice Rod's Ice Block appearance sound
- Clockwork Assault Rifle
- Angel Wings / Demon Wings flapping sound
- Death Laser firing sound (Red lasers from the Destroyer and second-form Retinazer)
- Flamethrower
- Bell
- Shotgun
- Anvil clink
AddRecipes()
Hey, this is familiar! As said in the previous tutorial, there are various places to add recipes.
Let's take a look!
Code:
public override void AddRecipes()
{
ModRecipe recipe = new ModRecipe(mod);
recipe.AddIngredient(ItemID.DirtBlock, 10);
recipe.AddTile(TileID.WorkBenches);
recipe.SetResult(this);
recipe.AddRecipe();
}
Instead, we can use "this" when setting our result, as we want our result to be our ModItem! The same recipe principles apply here, so there's nothing fancy to find.
How to create any vanilla weapon type you want
There is a neat function we can make use of, called CloneDefaults()
The following new ModItem class could be pasted below your previous ModItem class, in the same file.
Code:
public class BetterTerraBlade : ModItem
{
public override void SetDefaults()
{
item.CloneDefaults(ItemID.TerraBlade);
item.name = "Better Terra Blade";
item.damage = 500;
}
public override bool Autoload(ref string name, ref string texture, IList<EquipType> equips)
{
texture = "Terraria/Item_757";
return true;
}
public override void AddRecipes()
{
ModRecipe recipe = new ModRecipe(mod);
recipe.SetResult(this);
recipe.AddRecipe();
}
}
I don't think I need to explain SetDefaults()
Overriding Autoload()
You don't have to override Autoload, the reason I'm doing it here is because I don't want to add a new sprite for this item: I want to use the vanilla Terra Blade sprite. We're manually setting the texure location. Remember if you want to access a mod's source, it starts from 'Mod Sources' so you need to begin with the mod's folder name. Autoload would normally look for a sprite named BetterTerraBlade.png which isn't there so we would get errors. You can access vanilla sprites by using "Terraria/" followed by the sprite name. Item sprites are named "Item_ID" where the ID is the ID of the item. For Terra Blade, the ID is 757. You can use Terraria.ID to get any ID as well as follows:
Code:
texture = "Terraria/Item_" + ItemID.TerraBlade;
An empty recipe?
To those of you who didn't know: it's possible to not require anything in a recipe. This allows us to craft this item without needing any ingredients. The only thing you have to do is simply not add any ingredient!
Custom drawing?
The above principles can be applied for any vanilla weapon. In the next example, I'm creating a Better Flairon ModItem. What's important to note here is that flails use custom drawing. No matter what you set the texture to, you'll see a Flairon texture when you use this item. This is due to manual drawing, which we will look at in a later tutorial. It will still display the texture we set in the inventory and any other place really.
Code:
public class BetterFlairon : ModItem
{
public override void SetDefaults()
{
item.CloneDefaults(ItemID.Flairon);
item.name = "Better Flairon";
item.damage = 500;
}
public override bool Autoload(ref string name, ref string texture, IList<EquipType> equips)
{
texture = "Terraria/Item_" + ItemID.Flairon;
return true;
}
public override void AddRecipes()
{
ModRecipe recipe = new ModRecipe(mod);
recipe.SetResult(this);
recipe.AddRecipe();
}
}
A custom health potion
We can again use this to create a health potion that instantly heals us to full life! It's actually every easy!
Code:
public class InstantHealPotion : ModItem
{
public override void SetDefaults()
{
item.CloneDefaults(ItemID.SuperHealingPotion);
item.name = "Instant health potion";
item.healLife = Main.player[item.owner].statLifeMax2;
}
public override bool Autoload(ref string name, ref string texture, IList<EquipType> equips)
{
texture = "Terraria/Item_" + ItemID.SuperHealingPotion;
return true;
}
public override void AddRecipes()
{
ModRecipe recipe = new ModRecipe(mod);
recipe.SetResult(this);
recipe.AddRecipe();
}
}
Code:
item.healLife = Main.player[item.owner].statLifeMax2;
Doing something onhit
I'm sure you know of those items that can set enemies ablaze. We can do exactly the same! Let's go back to our Better Terra Blade item, we can use the following hook to add a debuff when it hits something:
Code:
public override void OnHitNPC(Player player, NPC target, int damage, float knockBack, bool crit)
{
target.AddBuff(BuffID.OnFire, 5 * 60);
}
The first dummy was hit by our actual sword, the second one was only hit by the projectile. As projectiles do not cover this tutorial, unfortunately I will not go into this now.
Something more unique
Adding debuffs on hit isn't just the only thing you can do. You could for example deal some damage to the player when hitting an npc that is a town npc!
Code:
public override void OnHitNPC(Player player, NPC target, int damage, float knockBack, bool crit)
{
target.AddBuff(BuffID.OnFire, 5 * 60);
if (target.townNPC)
{
player.Hurt(5, -player.direction, false, false, " is an evil :red:...");
}
}
Other things
I will fill the following list as time progresses. If you want me to cover something here, let me now in a comment.
Custom CanUseItem rules
We can start using the CanUseItem() hook to decide whether or not an item can be used.
Let's go back to our Better Flairon item add the following: the item can only be used if the player is in hardmode.
Code:
public override bool CanUseItem(Player player)
{
return Main.hardMode;
}
If you return true in this hook, the item can be used. Vice versa for false. Try it out! Use the next example if you want to test this more easily.
UseItem rules
No hardmode? Let's make it so that our potion toggles the hardMode variable for testing purposes.
Add the following in InstantHealPotion:
Code:
public override bool UseItem(Player player)
{
Main.hardMode = !Main.hardMode;
return base.UseItem(player);
}
If your world isn't hardMode, consume this potion and you will be able to use Better Flairon! Consume another potion and you will no longer be able to!
It's magic!
WIP, MORE TO COME
Full code
Code:
using System.Collections.Generic;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
namespace MyFirstMod.Items
{
public class MyFirstItem : ModItem
{
public override void SetDefaults()
{
item.name = "MyFirstItem";
item.damage = 50;
item.width = 40;
item.height = 40;
item.toolTip = "This is a modded sword.";
item.useTime = 20;
item.useAnimation = 20;
item.useStyle = 1;
item.knockBack = 6;
item.value = 10000;
item.rare = 2;
item.useSound = 1;
item.autoReuse = true;
}
public override void AddRecipes()
{
ModRecipe recipe = new ModRecipe(mod);
recipe.AddIngredient(ItemID.DirtBlock, 10);
recipe.AddTile(TileID.WorkBenches);
recipe.SetResult(this);
recipe.AddRecipe();
}
}
public class BetterTerraBlade : ModItem
{
public override void SetDefaults()
{
item.CloneDefaults(ItemID.TerraBlade);
item.name = "Better Terra Blade";
item.damage = 500;
}
public override void OnHitNPC(Player player, NPC target, int damage, float knockBack, bool crit)
{
target.AddBuff(BuffID.OnFire, 5 * 60);
if (target.townNPC)
{
player.Hurt(5, -player.direction, false, false, " is an evil :red:...");
}
}
public override bool Autoload(ref string name, ref string texture, IList<EquipType> equips)
{
texture = "Terraria/Item_" + ItemID.TerraBlade;
return true;
}
public override void AddRecipes()
{
ModRecipe recipe = new ModRecipe(mod);
recipe.SetResult(this);
recipe.AddRecipe();
}
}
public class BetterFlairon : ModItem
{
public override void SetDefaults()
{
item.CloneDefaults(ItemID.Flairon);
item.name = "Better Flairon";
item.damage = 500;
}
public override bool Autoload(ref string name, ref string texture, IList<EquipType> equips)
{
texture = "Terraria/Item_" + ItemID.Flairon;
return true;
}
public override bool CanUseItem(Player player)
{
return Main.hardMode;
}
public override void AddRecipes()
{
ModRecipe recipe = new ModRecipe(mod);
recipe.SetResult(this);
recipe.AddRecipe();
}
}
public class InstantHealPotion : ModItem
{
public override void SetDefaults()
{
item.CloneDefaults(ItemID.SuperHealingPotion);
item.name = "Instant health potion";
item.healLife = Main.player[item.owner].statLifeMax2;
}
public override bool UseItem(Player player)
{
Main.hardMode = !Main.hardMode;
return base.UseItem(player);
}
public override bool Autoload(ref string name, ref string texture, IList<EquipType> equips)
{
texture = "Terraria/Item_" + ItemID.SuperHealingPotion;
return true;
}
public override void AddRecipes()
{
ModRecipe recipe = new ModRecipe(mod);
recipe.SetResult(this);
recipe.AddRecipe();
}
}
}
Go to next tutorial: Tutorial [3] Projectiles
Last edited: