Basic Modding - Tools and Swords

Goal

I want to show you how to create your own tools and swords.

Difficulty

3/10 - Relatively Easy

Prerequisites

Forge Version

This Tutorial was created with Forge 10.13.0.1180 for Minecraft 1.7.10. If anything doesn't work with other versions, please contact me!


The Tool Material

Every tool (or sword) in Minecraft needs to have a ToolMaterial. This material defines how much hits a tool can take before it breaks, the mining speed of the tool, the damage versus Entities and some other things.

So, if we want to create a tool we first need to create a ToolMaterial. Unfortunately, the ToolMaterial is a class of which we can't create new instances, because its a so called enum. Therefore, the EnumHelper was created by Minecraft Forge. With the help of this class we are able to create a ToolMaterial. So, we go into our ModItems class and add this line of code:

ModItems.class:
public static ToolMaterial TUTORIAL = EnumHelper.addToolMaterial("TUTORIAL", harvestLevel, durability, miningSpeed, damageVsEntities, enchantability);

The method to create a ToolMaterial takes the following arguments:

  • A name for the material. This should be the same as the name of the variable we use to store the material (in this case "TUTORIAL").
  • A harvest level for pickaxes. This is a value between 0 and 3 and defines which blocks can be mined with this tool. Its also possible to create blocks which need a higher harvest level than 3, but then you are not able to mine them with vanilla tools.
    Common values for the harvest level are:
    • Wood/Gold Tool: 0
    • Stone Tool: 1
    • Iron Tool: 2
    • Diamond Tool: 3
  • The durability of the tool or sword. This value defines how often you can use a tool until it breaks. The tools always last one use longer than the entered value.
    Common values for the durability are:
    • Wood Tool: 59
    • Stone Tool: 131
    • Iron Tool: 250
    • Diamond Tool: 1561
    • Gold Tool: 32
  • The mining speed of the tool. This value defines how much faster you are with this tool than with your hand.
    Common values for the mining speed are:
    • Wood Tool: 2.0F
    • Stone Tool: 4.0F
    • Iron Tool: 6.0F
    • Diamond Tool: 8.0F
    • Gold Tool: 12.0F
  • The damage versus Entites. This value is used to calculate the damage an entity takes if you hit it with this tool/sword. This value defines the basic damage to which different values are added, depending on the type of tool. A sword always causes 4 more damage than written in the ToolMaterial. So, if you want to create a sword which adds 10 damage to your normal damage, the value in the ToolMaterial needs to be 6.0F. Of course the values can be below zero.
    Common values for the damage versus Entities are:
    • Wood Tool: 0.0F (Sword adds 4.0 damage)
    • Stone Tool: 1.0F (Sword adds 5.0 damage)
    • Iron Tool: 2.0F (Sword adds 6.0 damage)
    • Diamond Tool: 3.0F (Sword adds 7.0 damage)
    • Gold Tool: 0.0F (Sword adds 4.0 damage)
  • The enchantability of this tool. This value is quite complex to understand and I have to admit that I don't quite know how it is calculated. Basically you can say that a higher enchantability leads to better enchantements with the same amount of XP.
    Common values for the enchantability are:
    • Wood Tool: 15
    • Stone Tool: 5
    • Iron Tool: 14
    • Diamond Tool: 10
    • Gold Tool: 22

 

The values I chose for my tutorial ToolMaterial are:

  • A harvest level of 3 (Like diamond)
  • A durability of 1000 (Between iron and diamond)
  • A mining speed of 15.0F (Better than gold)
  • A damage of 4.0F (Better than diamond, a sword will add 8 damage)
  • A enchantability of 30 (Better than everything else)
ModItems.class:
public static ToolMaterial TUTORIAL = EnumHelper.addToolMaterial("TUTORIAL", 3, 1000, 15.0F, 4.0F, 30);

Now we have the ToolMaterial, so lets head over to the items themselves.

Item Classes

Basically the Items are created just like normal Items, but they need special classes which extend vanilla classes, depending on the type of the tool:

  • Pickaxe: extends ItemPickaxe
  • Axe: extends ItemAxe
  • Spade: extends ItemSpade
  • Hoe: extends ItemHoe
  • Sword: extends ItemSword

All of these classes are structured in a similar way, so I'll only explain one type of tool. (All the other ones can be found in the downloadable code. See link at the bottom.)

 

First, we create a class in the package com.<yourname>.<yourmodname>.items and name it ItemModSword. Then we add extends ItemSword behind the class declaration and press Ctrl+Shift+O to import ItemSword.

The class now looks like this:

ItemModSword.class:
package com.bedrockminer.tutorial.item;

import net.minecraft.item.ItemSword;

public class ItemModSword extends ItemSword {
}

Don't worry about the error under ItemModSword, we will fix this now. Hover over the error and you'll see that you have to override a constructor from ItemSword. Click on the quick fix to do this. This will add a constructor which has got an instance of ToolMaterial as an argument.

ItemModSword.class:
public ItemModSword(ToolMaterial material) {
        super(material);
}

If the name of the material is different (p_i45356_1_ or something) you can rename it by selecting it and pressing Alt+Shift+R. Then type the new name and hit Enter.

 

I want to add the unlocalizedName of the item as an argument for the constructor to make coding easier. The unlocalizedName will be used for the item's name and for the texture, so you can pass it directly without calling two methods for the Item.

ItemModSword.class:
public ItemModSword(String unlocalizedName, ToolMaterial material) {
        super(material);
        this.setUnlocalizedName(unlocalizedName);
        this.setTextureName(Main.MODID + ":" + unlocalizedName);
}

You can do exactly the same for the other tool types and then everything is ready for the creation of our Items. By default they are added to the "Tools" creative tab, except of the sword which is added to "Weapons". Of course you can change this by calling setCreativeTab.

You create the items like this:

ModItems.class:
GameRegistry.registerItem(tutorialPickaxe = new ItemModPickaxe("tutorial_pickaxe", TUTORIAL), "tutorial_pickaxe");
GameRegistry.registerItem(tutorialAxe = new ItemModAxe("tutorial_axe", TUTORIAL), "tutorial_axe");
GameRegistry.registerItem(tutorialSpade = new ItemModSpade("tutorial_spade", TUTORIAL), "tutorial_spade");
GameRegistry.registerItem(tutorialHoe = new ItemModHoe("tutorial_hoe", TUTORIAL), "tutorial_hoe");
GameRegistry.registerItem(tutorialSword = new ItemModSword("tutorial_sword", TUTORIAL), "tutorial_sword");

Note that you also can place the ToolMaterial in a seperate class, but then you would have to replace all occurences of TUTORIAL with YourClass.TUTORIAL.

 

Now you can start minecraft and you should find some new tools in the "Tools" CreativeTab and the sword in the "Weapons" tab. If you want to attach textures to them you can use these textures, taken from my mod WeaponCraft:

 

Multiple tool types in a single tool

Sometimes, you want to have a tool that can do the work of two vanilla tools at once, for instance a tool which is a pickaxe and a shovel at the same time. This is also possible.

First, you need to choose the "base" tool. If your tool should have pickaxe behaviour, always choose ItemPickaxe as the base. This is the class you new item will extend:

ModItemMultitool.class:
public class ItemModMultitool extends ItemPickaxe {
}

You now need to create a constructor. You can just take the one from the other tool classes we created. The class now looks like this:

ModItemMultitool.class:
public class ItemModMultitool extends ItemPickaxe {

    protected ItemModMultitool(String unlocalizedName, ToolMaterial material) {
        super(material);
        this.setUnlocalizedName(unlocalizedName);
        this.setTextureName(Main.MODID + ":" + unlocalizedName);
    }
}

Now, we need to tell the game that this tool in not only a pickaxe, but also a shovel (or an axe). Therefore, we override the method getToolClasses.

ModItemMultitool.class:
@Override
public Set<String> getToolClasses(ItemStack stack) {
    return ImmutableSet.of("pickaxe", "spade");
}

This method needs to return a set of Strings, so we return a ImmutableSet from the package com.google.common.collect, which is included in the Minecraft code.


Unfortunately, this method only works if the method setHarvestLevel was called for the Blocks we want to harvest, but this is not done for Vanilla blocks, because the harvest level and the tool class was added by Minecraft Forge. So, we need to add the Vanilla blocks manually (Thats the reason why the base class should be ItemPickaxe, because this is the most complex tool).

First, we need to create a set of all blocks that can be harvested with this tool.

If our tool should have shovel behaviour, the set looks like this:

ModItemMultitool.class:
private static Set effectiveAgainst = Sets.newHashSet(new Block[] {
    Blocks.grass, Blocks.dirt, Blocks.sand, Blocks.gravel, 
    Blocks.snow_layer, Blocks.snow, Blocks.clay, Blocks.farmland, 
    Blocks.soul_sand, Blocks.mycelium});

If our tool should have axe behaviour, the set looks like this:

ModItemMultitool.class:
private static Set effectiveAgainst = Sets.newHashSet(new Block[] {
    Blocks.planks, Blocks.bookshelf, Blocks.log, Blocks.log2, 
    Blocks.chest, Blocks.pumpkin, Blocks.lit_pumpkin});

If the tool should have both, you need to combine these sets. Just add the content of one to the other.


To add these blocks to the list of breakable ones, we need to override two methods:

func_150897_b and func_150893_a. If they were deobfuscated, they would be named something like "canHarvestBlock" and "getEfficiencyVersusBlock".

The first one, func_150897_b "canHarvestBlock" only needs to be overridden if we want to add shovel behaviour. Then, we'd need to add this code:

ModItemMultitool.class:
@Override
public boolean func_150897_b(Block block) {
    return effectiveAgainst.contains(block) ? true : super.func_150897_b(block);
}

This method returns true, if a block that cannot be harvested normally, now drops an item if it is destroyed with this tool. For the axe behaviour this is not needed, because everything you can harvest with an axe also drops an item if it is destroyed by hand.


The other method, func_150893_a "getEfficiencyVersusBlock", needs to be overridden anyway, no matter whether we want to add axe or shovel behaviour. This method returns the digging speed of the tool when mining the given block. Here, we need to use this code:

ModItemMultitool.class:
@Override
public float func_150893_a(ItemStack stack, Block block) {
    return effectiveAgainst.contains(block) ? this.efficiencyOnProperMaterial : super.func_150893_a(stack, block);
}

For an axe we need to add two more lines:

ModItemMultitool.class:
@Override
public float func_150893_a(ItemStack stack, Block block) {
    if (block.getMaterial() == Material.wood || block.getMaterial() == Material.vine || block.getMaterial() == Material.plants)
        return this.efficiencyOnProperMaterial;
    return effectiveAgainst.contains(block) ? this.efficiencyOnProperMaterial : super.func_150893_a(stack, block);
}

Once these two methods are added, our tool can harvest all the blocks listed in the set effectiveAgainst. Modded blocks can also be harvested, if their harvestLevel is set to the appropriate value.


If we want to add hoe behaviour to our tool, we also have to add a new method:

ModItemMultitool.class:
public boolean onItemUse(ItemStack stack, EntityPlayer player, World world, int x, int y, int z, int side, float hitX, float hitY, float hitZ) {
    if (!player.canPlayerEdit(x, y, z, side, stack)) {
        return false;
    } else {
        UseHoeEvent event = new UseHoeEvent(player, stack, world, x, y, z);
        if (MinecraftForge.EVENT_BUS.post(event)) {
            return false;
        }

        if (event.getResult() == Result.ALLOW) {
            stack.damageItem(1, player);
            return true;
        }

        Block block = world.getBlock(x, y, z);

        if (side != 0 && world.getBlock(x, y + 1, z).isAir(world, x, y + 1, z) && (block == Blocks.grass || block == Blocks.dirt)) {
            Block block1 = Blocks.farmland;
            world.playSoundEffect((double)((float)x + 0.5F), (double)((float)y + 0.5F), (double)((float)z + 0.5F), block1.stepSound.getStepResourcePath(), (block1.stepSound.getVolume() + 1.0F) / 2.0F, block1.stepSound.getPitch() * 0.8F);

            if (world.isRemote) {
                return true;
            } else {
                world.setBlock(x, y, z, block1);
                stack.damageItem(1, player);
                return true;
            }
        } else {
            return false;
        }
    }
}

This method is copied directly from ItemHoe.

 

With these methods, you can make your tool do the worl of every other tool in Minecraft!


In the downloadable code I created a multitool which has the behaviour of a pickaxe, a shovel and a hoe. Its texture is this one:


You can download the code used in this tutorial as a .zip file from here.


Recommended tutorials to continue with


Comments and Questions:

If you want to report modding problems, please make sure to include the code in a pastebin link or something else! Don't just write "It doesn't work", otherwise your post will be deleted. For more complicated problems, please use the troubleshooter form.