本篇教程的视频

本篇教程的源代码

GitHub地址:TutorialMod-1.20.1-Forge-Tool

注册工具材料

在注册工具之前,我们需要先注册一些工具材料,后面讲到盔甲的时候,也需要注册对应的盔甲材料

新建类

这里我们先创建一个类,ModToolTiers,注意这是一个枚举类,继承ToolTier

然后我们到原版的ToolTiers类里面拿一些方法和参数过来,并创建构造函数

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
public enum ModToolTiers implements Tier {
;

private final int level;
private final int uses;
private final float speed;
private final float damage;
private final int enchantmentValue;
private final Supplier<Ingredient> repairIngredient;

ModToolTiers(int level, int uses, float speed, float damage, int enchantmentValue, Supplier<Ingredient> repairIngredient) {
this.level = level;
this.uses = uses;
this.speed = speed;
this.damage = damage;
this.enchantmentValue = enchantmentValue;
this.repairIngredient = repairIngredient;
}

public int getUses() {
return this.uses;
}

public float getSpeed() {
return this.speed;
}

public float getAttackDamageBonus() {
return this.damage;
}

public int getLevel() {
return this.level;
}

public int getEnchantmentValue() {
return this.enchantmentValue;
}

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

这里我们来简单介绍一下各个参数

  • level: 工具的采集等级,决定它能够挖掘的方块
  • uses: 工具的耐久度
  • speed: 工具的基础挖掘速度
  • damage: 工具的基础攻击伤害
  • enchantmentValue: 工具的附魔能力,值越大,能获得的附魔品质越好
  • repairIngredient: 工具的修复材料

创建工具材料

然后我们来创建一个工具材料

1
FIRE_ETHER(5, 2031, 12.0f, 5.0f, 30, () -> Ingredient.of(ModItems.FIRE_ETHER.get()));

各参数大家可根据自己的需要来确定

这里的修复材料需要我们新增一个FIRE_ETHER,相应的注册语句如下

1
2
public static final RegistryObject<Item> FIRE_ETHER =
ITEMS.register("fire_ether", () -> new Item(new Item.Properties()));

Forge的工具材料

既然这里是Forge的教程,那么我们再来讲讲Forge这里特有的工具材料的写法

1
2
3
4
public static final Tier ICE_ETHER = TierSortingRegistry.registerTier(
new ForgeTier(5, 1400, 11f, 3f, 26,
ModBlockTags.ORE_TAGS, () -> Ingredient.of(ModItems.ICE_ETHER.get())),
ResourceLocation.fromNamespaceAndPath(TutorialMod.MOD_ID, "ice_ether"), List.of(Tiers.WOOD), List.of());

这里使用TierSortingRegistry.registerTier来注册Tier

ForgeTier和原版的Tier差不多,前5个参数依旧是采集等级、耐久度、挖掘速度、攻击伤害和附魔能力

但在修复材料前面多了一个Tag,这个是指定我们这个工具能挖掘且有掉落物的方块,正好我们之前已经定义过一个Tag,这里就拿来用了

registerTier第二个参数是注册名,第三个是指定这个材料排在哪个材料之后,第四个是指定这个材料排在哪个材料之前

这里的意思呢,就是ICE_ETHER这个工具材料排在WOOD这个工具材料之后,所以其实意思是它只比WOOD这个工具材料采集等级高,木制工具能挖掘的方块它都可以挖

但对于我们ORE_TAGS里面的一些矿石来说,比如里面的钻石矿,实际上它是没法挖的(或者说没有掉落物)

所以其实ForgeTier的第一个参数,它的这个采集一点用也没有(或者说它和原版的没有关联,可作为模组独立出来的采集等级),最终决定这个材料做出来的工具能挖掘的方块是由里面的Tag和后面两个List决定的

教程这里的话就不用它了,只用我们上面写的FIRE_ETHER

注册工具

工具的注册也很简单

1
2
3
4
5
6
7
8
9
10
public static final RegistryObject<Item> FIRE_ETHER_SWORD = ITEMS.register("fire_ether_sword",
() -> new SwordItem(ModToolTiers.FIRE_ETHER, 2, 3, new Item.Properties()));
public static final RegistryObject<Item> FIRE_ETHER_PICKAXE = ITEMS.register("fire_ether_pickaxe",
() -> new PickaxeItem(ModToolTiers.FIRE_ETHER, 1, 2, new Item.Properties()));
public static final RegistryObject<Item> FIRE_ETHER_SHOVEL = ITEMS.register("fire_ether_shovel",
() -> new ShovelItem(ModToolTiers.FIRE_ETHER, 2, 3, new Item.Properties()));
public static final RegistryObject<Item> FIRE_ETHER_AXE = ITEMS.register("fire_ether_axe",
() -> new AxeItem(ModToolTiers.FIRE_ETHER, 2, 3, new Item.Properties()));
public static final RegistryObject<Item> FIRE_ETHER_HOE = ITEMS.register("fire_ether_hoe",
() -> new HoeItem(ModToolTiers.FIRE_ETHER, 2, 3, new Item.Properties()));

我们注册了和原版一样的这5种工具,包括

它们都有对应的物品类,在注册时不要搞错类,不然会出现奇怪的效果,不过在下一期教程中,我们将实现一个组合型的工具

这些工具类的第一个参数都是工具材料,第二个是这个工具附加的工具伤害,第三个是这个工具附加的攻击速度,最后一个是物品的属性

另外,工具类材料会在实际注册时,根据是否有耐久度来设置最大堆叠上限,这个就不用我们设置了

注册完之后也不要忘了将这些工具添加到物品栏

1
2
3
4
5
pOutput.accept(ModItems.FIRE_ETHER_SWORD.get());
pOutput.accept(ModItems.FIRE_ETHER_SHOVEL.get());
pOutput.accept(ModItems.FIRE_ETHER_PICKAXE.get());
pOutput.accept(ModItems.FIRE_ETHER_AXE.get());
pOutput.accept(ModItems.FIRE_ETHER_HOE.get());

数据文件

最后就是这些工具的数据文件了

语言文件

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

物品模型文件

在此之前,我们先创建一个手持类物品的注册方法

1
2
3
4
5
private ItemModelBuilder handheldItem(RegistryObject<Item> item) {
return withExistingParent(item.getId().getPath(),
ResourceLocation.withDefaultNamespace("item/handheld")).texture("layer0",
ResourceLocation.fromNamespaceAndPath(TutorialMod.MOD_ID,"item/" + item.getId().getPath()));
}

因为工具类物品和一般的物品不一样,它的拿取方式不同于一般的物品,所以这里使用的物品父级模型是handheld,而不是generated

创建完这个方法后,我们来注册我们的工具模型

1
2
3
4
5
handheldItem(ModItems.FIRE_ETHER_SWORD);
handheldItem(ModItems.FIRE_ETHER_HOE);
handheldItem(ModItems.FIRE_ETHER_AXE);
handheldItem(ModItems.FIRE_ETHER_PICKAXE);
handheldItem(ModItems.FIRE_ETHER_SHOVEL);

最后,不要忘记将贴图放到对应的位置,然后我们就可以跑数据生成,并进入游戏进行测试了