Skip to content

Instantly share code, notes, and snippets.

@gigaherz
Last active Oct 27, 2021
Embed
What would you like to do?
Explanation of the new tool system

So... You have updated to latest forge and harvestTool, harvestLevel, ToolType, ... are all gone. AAA PANIC!

Here's how to fix it:

Blocks

First, Remove the harvestTool and harvestLevel calls from the block properties.

Then, add the blocks to the relevant tags. You can use datagen, or make the jsons yourself. Datagen is more future-proof.

Harvest tools define which tool(s) can mine this block fast, and if requiresToolForDrops() is set on the properties, also defines which tool(s) can be used to get loot.

  • ToolType.AXE: minecraft:mineable/axe
  • ToolType.PICKAXE: minecraft:mineable/pickaxe
  • ToolType.SHOVEL: minecraft:mineable/shovel
  • ToolType.HOE: minecraft:mineable/hoe
  • Custom tool types: look at the mod's documentation or ask the author

Harvest levels have become their tiers. Each tier has an associated tag. More details below.

If you want your block to drop loot with any tool including an empty hand, you don't need to add the block to any of the tags. If your block should only drop loot with the correct tool and tier, then you'll need to make sure the block has the requiresToolForDrops() property set, and add it to one of the tier tags:

  • Harvest level 0 (wood): forge:needs_wood_tool
  • Harvest level 0* (gold): forge:needs_gold_tool
  • Harvest level 1 (stone): minecraft:needs_stone_tool
  • Harvest level 2 (iron): minecraft:needs_iron_tool
  • Harvest level 3 (diamond): minecraft:needs_diamond_tool
  • Harvest level 4 (netherite): forge:needs_netherite_tool
  • Custom tiers: look at the mod's documentation or ask the author

* Gold tier is equivalent to wood in vanilla, so forge represents that by having gold be better than wood, but have an empty tag. If you add things to the gold tier they will NOT work with wood tools!

Custom tool types

If you have a custom tool type, you just have to define your own tag in the style of yourmod:mineable/tooltype, and use it in the super() call to the DiggerItem superclass.

If you want to share the block list with other mods, make your tag include a forge tag forge:mineable/tooltype. This way modpacks can choose to disassociate the tool types if they want to.

You will probably also want to definea new ToolAction for others to indicate that your tool can perform that action.

Custom tool materials

If you want a new tool material, you have to define a custom Tier, and register it into the TierSortingRegistry. To define the Tier object, you can use ForgeTier as a convenience.

If your tier is supposed to be equivalent to another tier, you will want to put the other tier in the "after" list, and have yours use an optional empty tag reference BlockTags.createOptional. However, if the tier you want to be equivalent to, is a vanilla tier, you will want to also specify the next tier up, in the "before" list!

Example: If you want a Bone tier between wood and stone, you'd have List.of(Tiers.WOOD), List.of(Tiers.STONE).

Code example:

    public static final Tag.Named<Block> MY_TIER_TAG = BlockTags.createOptional(new ResourceLocation("tag_based_tool_types:needs_my_tier_tool"));
    public static final Tier MY_TIER = TierSortingRegistry.registerTier(
            new ForgeTier(5, 5000, 10, 100, 0, MY_TIER_TAG, () -> Ingredient.of(Items.BEDROCK)),
            new ResourceLocation("tag_based_tool_types:my_tier"),
            List.of(Tiers.DIAMOND), List.of());

Multi-tools

If you want to define a multi-tool, you will have to override 3 methods:

  • getDestroySpeed defines which blocks your tool will be able to mine faster than an empty hand (or wrong tool).
  • isCorrectToolForDrops defines which blocks can drop loot with your tool.
  • canPerformAction is used to query if your block can behave like other tools, eg the AXE_DIG action indicates your tool will chop wood, while AXE_STRIP indicates it can turn wood into stripped wood.

For a minimal example see the relevant test mod in the forge repository.

Addendum: Example of a canPerformAction implementation

    private static final Set<ToolAction> TOOL_ACTIONS =  Stream.of(AXE_DIG, PICKAXE_DIG, SHOVEL_DIG).collect(Collectors.toCollection(Sets::newIdentityHashSet));
    @Override
    public boolean canPerformAction(ItemStack stack, ToolAction toolAction)
    {
        return TOOL_ACTIONS.contains(toolAction);
    }

How to figure out if a given tool is of a certain type

The new system doesn't have an explicit tool type. Instead, each tool can advertise its ability to perform certain tool actions.

This means a tool can say it digs like an axe, without also implying it can strip wood, or remove wax from copper.

These actions are queried via canPerformAction.

@LuisAduana

This comment has been minimized.

Copy link

@LuisAduana LuisAduana commented Sep 9, 2021

can you show a basic example of how use loot_table datagen with this new features?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment