本篇教程的视频

本篇教程的源代码

Github地址:TutorialMod-Tool-1.21

介绍

在游戏中,有很多的工具,除了常见的有着不同材质的五件套,还有其他的工具,而它们的本质其实是物品,只是能够实现一些特殊的功能

在这篇教程中,我们将会制作五种工具,分别是镐子斧头锄头

这是我所说的五件套,其他的工具如三叉戟弓&箭钓鱼竿等等,以及新加入的重锤,这些工具可以自行研究,当然我后续可能出教程

查看源代码

这里我们先看一下Items类中的DIAMOND_XXX这类工具

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public static final Item DIAMOND_SWORD = register(
"diamond_sword",
new SwordItem(ToolMaterials.DIAMOND, new Item.Settings().attributeModifiers(SwordItem.createAttributeModifiers(ToolMaterials.DIAMOND, 3, -2.4F)))
);
public static final Item DIAMOND_SHOVEL = register(
"diamond_shovel",
new ShovelItem(ToolMaterials.DIAMOND, new Item.Settings().attributeModifiers(ShovelItem.createAttributeModifiers(ToolMaterials.DIAMOND, 1.5F, -3.0F)))
);
public static final Item DIAMOND_PICKAXE = register(
"diamond_pickaxe",
new PickaxeItem(ToolMaterials.DIAMOND, new Item.Settings().attributeModifiers(PickaxeItem.createAttributeModifiers(ToolMaterials.DIAMOND, 1.0F, -2.8F)))
);
public static final Item DIAMOND_AXE = register(
"diamond_axe",
new AxeItem(ToolMaterials.DIAMOND, new Item.Settings().attributeModifiers(AxeItem.createAttributeModifiers(ToolMaterials.DIAMOND, 5.0F, -3.0F)))
);
public static final Item DIAMOND_HOE = register(
"diamond_hoe",
new HoeItem(ToolMaterials.DIAMOND, new Item.Settings().attributeModifiers(HoeItem.createAttributeModifiers(ToolMaterials.DIAMOND, -3.0F, 0.0F)))
);

我们可以看到,它实例化的是各自的工具类

并且传入了ToolMaterials.DIAMOND,这是一个材质

后面定义了它的一些属性,比如攻击力、攻击速度等等

那么这里我们先来看一下ToolMaterials这个类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
...
DIAMOND(BlockTags.INCORRECT_FOR_DIAMOND_TOOL, 1561, 8.0F, 3.0F, 10, () -> Ingredient.ofItems(Items.DIAMOND)),
...
private ToolMaterials(
final TagKey<Block> inverseTag,
final int itemDurability,
final float miningSpeed,
final float attackDamage,
final int enchantability,
final Supplier<Ingredient> repairIngredient
) {
this.inverseTag = inverseTag;
this.itemDurability = itemDurability;
this.miningSpeed = miningSpeed;
this.attackDamage = attackDamage;
this.enchantability = enchantability;
this.repairIngredient = Suppliers.memoize(repairIngredient::get);
}

这是一个枚举类,里面定义了一些材质,比如DIAMOND

根据这个类的构造函数,我们可以确定,这里的参数分别是反向标签(其实就是之前的采集等级,这个是新版本改动的)、最大耐久采集速度攻击伤害附魔能力修复用材料

这里的反向标签通俗来讲是这个工具的采集等级,实际是它无法挖掘的方块,如果你有需求也可以自定义这个标签

耐久度的值也是从0开始的,这里的1561就是钻石的耐久度,共计可使用1562次

倒数第二个参数,也就是附魔的那个,其实我自己并没有研究过,我并不清楚这里的数值会影响什么(按照文档的说法,是指这个物品在附魔台上获得更好、更高级附魔的概率)

根据群友的反映,要想使我们的工具也能附魔还需写tag

这里我们就不讲解了,后续如果有人研究了,可以告诉我,我再更新

那么既然这里是这么一个枚举类,我们就可以自己定义一个了,至于方法什么的就从这里搬即可

注册工具

创建ModToolMaterials类

首先我们创建一个ModToolMaterials枚举类,这个类继承自ToolMaterial

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
public enum ModToolMaterials implements ToolMaterial {
;

private final TagKey<Block> inverseTag;
private final int itemDurability;
private final float miningSpeed;
private final float attackDamage;
private final int enchantability;
private final Supplier<Ingredient> repairIngredient;

ModToolMaterials(TagKey<Block> inverseTag, int itemDurability, float miningSpeed, float attackDamage, int enchantability, Supplier<Ingredient> repairIngredient) {
this.inverseTag = inverseTag;
this.itemDurability = itemDurability;
this.miningSpeed = miningSpeed;
this.attackDamage = attackDamage;
this.enchantability = enchantability;
this.repairIngredient = Suppliers.memoize(repairIngredient::get);
}

@Override
public int getDurability() {
return this.itemDurability;
}

@Override
public float getMiningSpeedMultiplier() {
return this.miningSpeed;
}

@Override
public float getAttackDamage() {
return this.attackDamage;
}

@Override
public TagKey<Block> getInverseTag() {
return this.inverseTag;
}

@Override
public int getEnchantability() {
return this.enchantability;
}

@Override
public Ingredient getRepairIngredient() {
return this.repairIngredient.get();
}
}

这里的构造函数就是从ToolMaterials类中搬过来的,当然我们还得定义我们自己的材料

不过在此之前,我们先注册另外一个物品

注册FireEther

1
public static final Item FIRE_ETHER = registerItems("fire_ether", new Item(new Item.Settings()));

这个是我们的火之以太,将作为我们工具的材料

注册工具材质

1
2
FIRE_ETHER(BlockTags.INCORRECT_FOR_IRON_TOOL, 2031, 12.0f, 4.0f, 50,
() -> Ingredient.ofItems(ModItems.FIRE_ETHER));

接下来我们就在这个枚举类里面定义我们的材质即可,里面的参数顺序参照构造函数的

这里面的参数就随便写吧,这里是下界合金的耐久度,金质的采集速度……就一缝合怪

注册工具

完成材质的编写之后,我们就可以注册我们的工具了

1
2
3
4
5
6
7
8
9
10
public static final Item FIRE_ETHER_SWORD = registerItems("fire_ether_sword", new SwordItem(ModToolMaterials.FIRE_ETHER,
new Item.Settings().fireproof().attributeModifiers(SwordItem.createAttributeModifiers(ModToolMaterials.FIRE_ETHER, 3, -2.0f))));
public static final Item FIRE_ETHER_SHOVEL = registerItems("fire_ether_shovel", new ShovelItem(ModToolMaterials.FIRE_ETHER,
new Item.Settings().fireproof().attributeModifiers(ShovelItem.createAttributeModifiers(ModToolMaterials.FIRE_ETHER, 1.5f, -3.0f))));
public static final Item FIRE_ETHER_PICKAXE = registerItems("fire_ether_pickaxe", new PickaxeItem(ModToolMaterials.FIRE_ETHER,
new Item.Settings().fireproof().attributeModifiers(PickaxeItem.createAttributeModifiers(ModToolMaterials.FIRE_ETHER, 1.5f, -2.8f))));
public static final Item FIRE_ETHER_AXE = registerItems("fire_ether_axe", new AxeItem(ModToolMaterials.FIRE_ETHER,
new Item.Settings().fireproof().attributeModifiers(AxeItem.createAttributeModifiers(ModToolMaterials.FIRE_ETHER, 6.0f, -3.2f))));
public static final Item FIRE_ETHER_HOE = registerItems("fire_ether_hoe", new HoeItem(ModToolMaterials.FIRE_ETHER,
new Item.Settings().fireproof().attributeModifiers(HoeItem.createAttributeModifiers(ModToolMaterials.FIRE_ETHER, -4.0f, 0.0f))));

记得各自实例化对应的工具类,传入我们的材质,后面的属性可以根据实际来调整,不过建议还是和原版一致

其后面的两个参数是额外的攻击伤害攻击速度,不过工具类自己也带一个基础的值。所以最后显示在你的物品上的提示信息(在主手时:…),是基础值+材料值+这里附加的值

另外在原版中,所有斧头的额外攻击伤害是同材质里面最高的。自然,锄头是最低的

这里我们还加了一个fireproof()方法,这个是设置物品不会被火焰烧毁,原版中的下界合金类的工具就有这个属性,你把它丢岩浆里也不会烧毁(反而会飘起来,嘿,岩浆密度够大哈(bushi))

写入物品栏

1
2
3
4
5
6
7
entries.add(ModItems.FIRE_ETHER);

entries.add(ModItems.FIRE_ETHER_SWORD);
entries.add(ModItems.FIRE_ETHER_SHOVEL);
entries.add(ModItems.FIRE_ETHER_PICKAXE);
entries.add(ModItems.FIRE_ETHER_AXE);
entries.add(ModItems.FIRE_ETHER_HOE);

这里我们将我们的工具加入到物品栏中,也别忘了我们新加的材料

数据文件

语言文件

1
2
3
4
5
6
7
translationBuilder.add(ModItems.FIRE_ETHER_SWORD, "Fire Ether Sword");
translationBuilder.add(ModItems.FIRE_ETHER_SHOVEL, "Fire Ether Shovel");
translationBuilder.add(ModItems.FIRE_ETHER_PICKAXE, "Fire Ether Pickaxe");
translationBuilder.add(ModItems.FIRE_ETHER_AXE, "Fire Ether Axe");
translationBuilder.add(ModItems.FIRE_ETHER_HOE, "Fire Ether Hoe");

translationBuilder.add(ModItems.FIRE_ETHER, "Fire Ether");

模型文件

1
2
3
4
5
6
7
itemModelGenerator.register(ModItems.FIRE_ETHER, Models.GENERATED);

itemModelGenerator.register(ModItems.FIRE_ETHER_SWORD, Models.HANDHELD);
itemModelGenerator.register(ModItems.FIRE_ETHER_SHOVEL, Models.HANDHELD);
itemModelGenerator.register(ModItems.FIRE_ETHER_PICKAXE, Models.HANDHELD);
itemModelGenerator.register(ModItems.FIRE_ETHER_AXE, Models.HANDHELD);
itemModelGenerator.register(ModItems.FIRE_ETHER_HOE, Models.HANDHELD);

在这里,除了材料还是用之前的模型,工具我们使用HANDHELD这个模型,这个也就是手持工具的模型

如果你还用之前的模型的话,看起来可能就怪怪的

那么最后,我们跑完数据生成,然后将材质文件放到对应的位置,之后我们就可以进入游戏了