User Tools

Site Tools


tutorial:tools

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
Last revision Both sides next revision
tutorial:tools [2020/07/30 11:03]
boogiemonster1o1 Fixed an incorrect method name
tutorial:tools [2020/09/14 01:49]
draylar Reformat away from enum, some formatting/cleanup
Line 1: Line 1:
 ====== Adding Tools ====== ====== Adding Tools ======
  
-==== Introduction ​==== +==== Creating a Tool Material ​====
-Creating a tool is very similar to making armor. It's a bit more complicated than making an item, but it's easy to make multiple of them+
  
-==== Creating ​Tool Material class ====+Tools require ​''​ToolMaterial'',​ which defines the following behavior: 
 +  * durability 
 +  * mining speed 
 +  * attack damage 
 +  * mining level 
 +  * enchantability 
 +  * repair ingredient
  
-The first step to creating a tool is to implement ​the `ToolMaterial` interface in a class +In other words, Tool Materials defines ​the //base// functionality for tools of that type, and tools can choose ​to use the values provided by the materialor roll with their own.
- +
-It's best to make the class as an enumas it doesnt require you to create an object a regular class, and enum constants make adding tool materials easier.+
  
 +Vanilla Tool Materials can be found in ''​ToolMaterials''​. We will create a separate class for our material:
  
 <code java [enable_line_numbers=true]>​ <code java [enable_line_numbers=true]>​
-public ​enum CustomToolMaterial ​implements ToolMaterial {; +public ​class PotatoToolMaterial ​implements ToolMaterial { 
-    ​CustomToolMaterial(int miningLevel,​ int itemDurability,​ float miningSpeedMultiplier,​ float attackDamage,​ int enchantability,​ Supplier<​Ingredient>​ repairIngredient) { +     
-  +    ​[...]
-    ​}+
 } }
 </​code>​ </​code>​
  
-What each argument does:- +''​ToolMaterial''​ has number ​of methods you will need to implement:
-1. `miningLevel` refers to the strength of the tool necessary to mine any material. Wood is 1, Stone is 2, Iron is 3, Diamond is 4. +
-2. `itemDurability` refers to the initial durability of tool. Gold is 32, Iron is 250, Netherite is 2031. +
-3. `miningSpeedMultiplier ` refers to how fast your tools can break blocks. Gold is 12.0f, Diamond is 8.0f, Iron is 6.0f. +
-4. `attackDamage` refers to the melee damage that your tools perform. Wood is 0.0f, Stone is 1.0f, Diamond is 3.0f +
-5. `enchantability` refers to the chance ​of getting high-level enchantments on your tools. Wood is 15, Stone is 5, Gold is 22, Iron is 14. +
-6. `repairIngredient` refers ​to the item that can repair your tools in an anvil. This will not be stored in an `Ingredient`,​ but in a `Lazy<​Ingredient>​`,​ which requires a `Supplier` in the constructor.+
  
-To make these values accessible from outside ​the constructorcreate a final field for each of them and assign their values in the constructor.+=== Durability ===  
 +''​getDurability''​ defines ​the base durability tools will have when they use this material. In vanillaall tools of the same type have the same durability.
 <code java [enable_line_numbers=true]>​ <code java [enable_line_numbers=true]>​
-public ​enum CustomToolMaterial implements ToolMaterial ​{; +@Override 
-    ​private final int miningLevel+public ​int getDurability() ​
-    ​private final int itemDurability;​ +    ​return 500
-    ​private final float miningSpeedMultiplier;​ +} 
-    private final float attackDamage;​ +</code>
-    private final int enchantability;​ +
-    private final Lazy<IngredientrepairIngredient;​+
  
-    CustomToolMaterial(int miningLevel,​ int itemDurability,​ float miningSpeedMultiplier,​ float attackDamage,​ int enchantability,​ Supplier<​Ingredient>​ repairIngredient) { +=== Mining Speed ===  
-        this.miningLevel ​miningLevel;​ +''​getMiningSpeedMultiplier''​ defines how fast tools are when mining blocks. For a general sense of scale, Wooden has a speed of 2.0F, and Diamond has a speed of 8.0F
-        this.itemDurability ​itemDurability;​ +<code java [enable_line_numbers=true]> 
-        this. miningSpeedMultiplier ​miningSpeedMultiplier;​ +@Override 
-        this.attackDamage ​attackDamage;​ +public float getMiningSpeedMultiplier() { 
-        this.enchantability = enchantability;​ +    ​return 5.0F;
-        ​this.repairIngredient ​new Lazy<>(repairIngredient); +
-    ​}+
 } }
 </​code>​ </​code>​
  
-Now its time to implement ​the methods from the `ToolMaterial` interface +=== Attack Damage ===  
-You should have something like this. Change ​the return ​value of each implemented method to the corresponding field.+''​getAttackDamage''​ returns ​the base damage of the toolNote that //most// tools ask for an integer damage amount in their constructor,​ which means the resulting damage is ''​(float) materialDamage + (int) toolDamage + 1''​. If you want your tool to entirely control its damage amount in its constructor,​ you can make your material ​return ​an attack damage ​of 0F
 <code java [enable_line_numbers=true]>​ <code java [enable_line_numbers=true]>​
-public ​enum CustomToolMaterial implements ToolMaterial ​{; +@Override 
-    ​private final int miningLevel+public ​float getAttackDamage() ​
-    ​private final int itemDurability;​ +    ​return 3.0F
-    ​private final float miningSpeedMultiplier;​ +} 
-    private final float attackDamage;​ +</code>
-    private final int enchantability;​ +
-    private final Lazy<IngredientrepairIngredient;​+
  
-    CustomToolMaterial(int miningLevel,​ int itemDurability,​ float miningSpeedMultiplier,​ float attackDamage,​ int enchantability,​ Supplier<​Ingredient>​ repairIngredient) { +=== Mining Level ===  
-        this.miningLevel ​miningLevel;​ +''​getMiningLevel''​ sets the mining level of a tool. Diamond has a mining level of 3, and a value of 3+ is required to mine Obsidian
-        this.itemDurability ​itemDurability;​ +<code java [enable_line_numbers=true]> 
-        this.miningSpeedMultiplier ​miningSpeedMultiplier;​ +@Override 
-        this.attackDamage ​attackDamage;​ +public int getMiningLevel() 
-        this.enchantability = enchantability;​ +    return 2
-        ​this.repairIngredient ​new Lazy<>(repairIngredient); +} 
-    }+</​code>​
  
-    ​@Override +=== Enchantability ===  
-    public int getDurability() { +''​getEnchantability''​ defines how enchantable a tool is. Gold comes in at 22 Enchatability,​ while Diamond sits at 10. Higher enchantability means better (and higher-level) enchantments. 
-        return ​this.itemDurability+<code java [enable_line_numbers=true]>​ 
-    }+@Override 
 +public int getEnchantability() { 
 +    return ​15
 +} 
 +</​code>​
  
-    @Override +=== Repair Ingredient ===  
-    ​public float getMiningSpeedMultiplier() { +''​getRepairIngredient''​ returns the ''​Ingredient''​ required to repair a tool in an anvil
-        return this.miningSpeedMultiplier;​ +<code java [enable_line_numbers=true]>​ 
-    } +@Override 
- +public ​Ingredient getRepairIngredient() { 
-    ​@Override +    return ​Ingredient.ofItems(Items.POTATO);
-    public ​float getAttackDamage() { +
-        return this.attackDamage;​ +
-    ​+
- +
-    @Override +
-    public int getMiningLevel() { +
-        ​return ​this.miningLevel;​ +
-    } +
- +
-    @Override +
-    public int getEnchantability() { +
-        return this.enchantability;​ +
-    } +
- +
-    @Override +
-    public Ingredient getRepairIngredient() { +
-        return this.repairIngredient.get(); +
-    }+
 } }
 </​code>​ </​code>​
  
-Next, create ​an enum constant. You can create multiple enum constants if you need multiple tool materials +''​ToolMaterial''​s do //not// have to be registered. A good way to pass them out to tools that require them is by keeping ​an instance somewhere (and then referencing it when you need it)In this case, we will put our instance at the top of the Tool Material class:
-This enum constant is for potato tools. +
 <code java [enable_line_numbers=true]>​ <code java [enable_line_numbers=true]>​
-public ​enum CustomToolMaterial ​implements ToolMaterial { +public ​class PotatoToolMaterial ​implements ToolMaterial { 
-    ​POTATO(1, 167, 4.8F, 1.1F, 11, () -> { + 
-        return Ingredient.ofItems(Items.POTATO);​ +    ​public static final PotatoToolMaterial INSTANCE = new PotatoToolMaterial();
-    });+
     ​     ​
     [...]     [...]
Line 113: Line 88:
 </​code>​ </​code>​
  
 +''​PotatoToolMaterial''​ can now be referenced with ''​PotatoToolMaterial.INSTANCE''​.
  
-==== Creating ​the tool objects ​====+==== Creating ​Tools ====
  
-Swordsshovelspickaxes and axes take in four arguments : The Tool MaterialThe Attack DamageThe Attack Speed and Item Settings+All base tool classes (''​PickaxeItem''​''​ShovelItem''​''​HoeItem'',​ ''​AxeItem'',​ ''​SwordItem''​) require a ''​ToolMaterial'',​ an attack speed (float)an additional attack damage amount (int), and an ''​Item.Settings''​ instance.
  
 <code java [enable_line_numbers=true]>​ <code java [enable_line_numbers=true]>​
-public static ToolItem POTATO_SHOVEL = new ShovelItem(CustomToolMaterial.POTATO, 1.5F, -3.0F, new Item.Settings().group(ItemGroup.TOOLS));​ +public static ToolItem POTATO_SHOVEL = new ShovelItem(PotatoToolMaterial.INSTANCE, 1.5F, -3.0F, new Item.Settings().group(ItemGroup.TOOLS));​ 
-public static ToolItem POTATO_SWORD = new SwordItem(CustomToolMaterial.POTATO, 3, -2.4F, new Item.Settings().group(ItemGroup.COMBAT));​+public static ToolItem POTATO_SWORD = new SwordItem(PotatoToolMaterial.INSTANCE, 3, -2.4F, new Item.Settings().group(ItemGroup.COMBAT));​
 </​code>​ </​code>​
-Unfortunately, ​`PickaxeItem` , `HoeItem` and `AxeItem` ​only have protected constructors, ​so you'll have to make classes that extends each of them. Creating ​subclass makes making multiple pickaxes or axes easier.+ 
 +`PickaxeItem` , `HoeItem` and `AxeItem` have protected constructors, ​which means you will need to create your own sub-class with public constructor: ​
 <code java [enable_line_numbers=true]>​ <code java [enable_line_numbers=true]>​
-public class PickaxeSubclass ​extends PickaxeItem {+public class CustomPickaxeItem ​extends PickaxeItem {
     public PickaxeSubclass(ToolMaterial material, int attackDamage,​ float attackSpeed,​ Settings settings) {     public PickaxeSubclass(ToolMaterial material, int attackDamage,​ float attackSpeed,​ Settings settings) {
         super(material,​ attackDamage,​ attackSpeed,​ settings);         super(material,​ attackDamage,​ attackSpeed,​ settings);
Line 130: Line 107:
 } }
 </​code>​ </​code>​
-To make a pickaxe, hoe and axe, create objects of the subclasses.+ 
 +Using the custom subclass:
 <code java> <code java>
-public static ToolItem POTATO_PICKAXE = new PickaxeSubclass(CustomToolMaterial.POTATO, 1, -2.8F, new Item.Settings().group(ItemGroup.TOOLS));​ +public static ToolItem POTATO_PICKAXE = new CustomPickaxeItem(PotatoToolMaterial.INSTANCE, 1, -2.8F, new Item.Settings().group(ItemGroup.TOOLS));​ 
-public static ToolItem POTATO_AXE = new AxeSubclass(CustomToolMaterial.POTATO, 7.0F, -3.2F, new Item.Settings().group(ItemGroup.TOOLS));​ +public static ToolItem POTATO_AXE = new CustomAxeItem(PotatoToolMaterial.INSTANCE, 7.0F, -3.2F, new Item.Settings().group(ItemGroup.TOOLS));​ 
-public static ToolItem POTATO_HOE = new HoeSubclass(CustomToolMaterial.POTATO, 7, -3.2F, new Item.Settings().group(ItemGroup.TOOLS));​+public static ToolItem POTATO_HOE = new CustomHoeItem(PotatoToolMaterial.INSTANCE, 7, -3.2F, new Item.Settings().group(ItemGroup.TOOLS));​
 </​code>​ </​code>​
  
-If you want to add any special attributes or behavior ​to your tool, create a class that extends one of the tool items, and override any required methods.+If you want to add any special attributes or behaviors ​to your tool, create a subclass ​that extends one of the base tool classes, and override any required methods.
  
 ==== Registering Tools ==== ==== Registering Tools ====
  
-Registering tools is done the same way you would register a normal ​item+For a recap on registering items, read through ​the item tutorial ​[[tutorial:​items|here]].
- +
-<code java [enable_line_numbers=true]>​ +
-    ​[...] +
-     +
-    @Override +
-    public void onInitialize() { +
-        Registry.register(Registry.ITEM,​new Identifier("​tutorial","​potato_pickaxe"​),​ POTATO_PICKAXE);​ +
- Registry.register(Registry.ITEM,​new Identifier("​tutorial","​potato_axe"​),​ POTATO_AXE);​ +
- Registry.register(Registry.ITEM,​new Identifier("​tutorial","​potato_sword"​),​ POTATO_SWORD);​ +
- Registry.register(Registry.ITEM,​new Identifier("​tutorial","​potato_hoe"​),​ POTATO_HOE);​ +
-        Registry.register(Registry.ITEM,​new Identifier("​tutorial","​potato_shovel"​),​ POTATO_SHOVEL);​ +
-    } +
-</​code>​+
  
 ==== Making your tool work with non-vanilla blocks ==== ==== Making your tool work with non-vanilla blocks ====
  
 Visit the last section of https://​fabricmc.net/​wiki/​tutorial:​mining_levels Visit the last section of https://​fabricmc.net/​wiki/​tutorial:​mining_levels
tutorial/tools.txt · Last modified: 2020/09/14 01:50 by draylar