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 revisionPrevious revision
Next revision
Previous revision
Next revisionBoth sides next revision
tutorial:tools [2020/08/07 04:07] – [Creating a Tool Material class] boogiemonster1o1tutorial:tools [2020/09/14 01:50] – fix constructor draylar
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 doesn't require you to create an object, like a regular class, and enum constants make adding multiple 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 constantYou can create multiple enum constants if you need multiple tool materials.  +''ToolMaterial''s do //not// have to be registeredA 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]> 
 +public class PotatoToolMaterial implements ToolMaterial {
  
-<code java [enable_line_numbers=true]> +    public static final PotatoToolMaterial INSTANCE new PotatoToolMaterial();
-public enum CustomToolMaterial implements ToolMaterial { +
-    POTATO(1, 167, 4.8F, 1.1F, 11, () -> { +
-        return Ingredient.ofItems(Items.POTATO); +
-    });+
          
     [...]     [...]
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 CustomPickaxeItem(ToolMaterial material, int attackDamage, float attackSpeed, Settings settings) {
         super(material, attackDamage, attackSpeed, settings);         super(material, attackDamage, attackSpeed, settings);
     }     }
 } }
 </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: 2023/09/07 05:32 by drakonkinst