参考视频:
工具物品注册时的新写法
我的《在MC1.21.4中创建Item时候遇到的问题》这篇博客中提到了Mojang在
1.21.4版本中要求一个新的Register方法的写法,而工具的注册在原版代码的写法及其register
方法如下:
1
2
3
4
5
6
7
8
9
|
public class Items {
···
public static final Item WOODEN_SWORD = register("wooden_sword", settings -> new SwordItem(ToolMaterial.WOOD, 3.0F, -2.4F, settings));
···
public static Item register(String id, Function<Item.Settings, Item> factory) {
return register(keyOf(id), factory, new Item.Settings());
}
···
}
|
而一般物品的注册写法和register
方法如下:
1
2
3
4
5
6
7
8
9
|
public class Items {
···
public static final Item APPLE = register("apple", new Item.Settings().food(FoodComponents.APPLE));
···
public static Item register(String id, Item.Settings settings) {
return register(keyOf(id), Item::new, settings);
}
···
}
|
可以看到两个register
方法的形参列表不一样,所以我们需要在ModItems
中仿制一个register
方法。
我写的如下:
1
2
3
4
5
6
7
8
|
public class ModItems {
···
public static Item register(String name, Function<Item.Settings, Item> factory) {
final RegistryKey<Item> registryKey = RegistryKey.of(RegistryKeys.ITEM, Identifier.of(<YOURMODID>, name));
return Items.register(registryKey, factory, new Item.Settings());
}
···
}
|
于是我们注册工具的写法如下:
1
2
3
4
5
6
7
8
9
10
11
|
public class ModItems {
···
//这里的SWORD展示了防火(下界合金)写法
public static final Item GA_SWORD = register("ga_sword", settings -> new SwordItem(ModToolMaterial.GALLIUM, 3.0F, -2.0F, new Item.Settings()
.fireproof()
.registryKey(RegistryKey.of(RegistryKeys.ITEM, Identifier.of(<YOURMODID>, "ga_sword")))));
//需要多传递一个.registryKey参数
//PICKAXE是普通写法
public static final Item GA_PICKAXE = register("ga_pickaxe", settings -> new PickaxeItem(ModToolMaterial.GALLIUM, 1.5F, -2.8F, settings));
···
}
|
但对于GA_SWORD
这种有特殊属性的工具,这样写显得代码很难看。但我又发现,不管是普通Item还是工具Item,都定义了一个RegistryKey.of
的量,于是我把两个register
方法和这里的RegistryKey.of
量提出来改写为函数。全部重写后如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
public class ModItems {
//普通item注册
public static final Item INGOT_GA = register("ingot_ga", Item::new, new Item.Settings());
//工具item注册
public static final Item GA_SWORD = register("ga_sword", settings -> new SwordItem(ModToolMaterial.GALLIUM, 3.0F, -2.0F, new Item.Settings()
.fireproof()
.registryKey(ModregistryKey("ga_sword"))));
public static final Item GA_PICKAXE = register("ga_pickaxe", settings -> new PickaxeItem(ModToolMaterial.GALLIUM, 1.5F, -2.8F, settings));
//工具item注册方法,registryKey被提出
public static Item register(String name, Function<Item.Settings, Item> factory) {
return Items.register(ModregistryKey(name), factory, new Item.Settings());
}
//普通item注册方法,registryKey被提出
public static Item register(String name, Function<Item.Settings, Item> factory, Item.Settings settings) {
return Items.register(ModregistryKey(name), factory, settings);
}
//RegistryKey.of量的返回方法
private static RegistryKey<Item> ModregistryKey(String name) {
return RegistryKey.of(RegistryKeys.ITEM, Identifier.of(<YOURMODID>, name));
}
}
|
视频中提到我们需要新建一个自己的ToolMaterials
变量来决定工具物品的等级、耐久等,但在1.21.4中,ToolMaterials
内被Mojang移除了,但好在ToolMaterials
继承自ToolMaterial
类,且ToolMaterial
是一个record
类,具体描述如下:
“Java 14 引入了 record 这一概念,提供了一种简洁的方式来定义包含数据的类。Record 是一种特殊的类,主要用于携带数据,其成员变量是默认 final 的。虽然 record 提高了代码的可读性和简洁性,但有一个重要的特性是,record 不能被继承。这一限制使得 record 在对象模型设计中的角色与传统类有所不同。” ——摘自“java record不能被继承”
所以用子类继承的想法被淘汰了,而ToolMaterial实际上成为了一个可以被定义和初始化的量。
综上所述,我们只需要新建一个ModToolMaterial的类,然后把这些量定义到这即可。写法如下:
1
2
3
4
5
6
7
8
9
10
|
public class ModToolMaterial {
public static final ToolMaterial GALLIUM = new ToolMaterial(
BlockTags.INCORRECT_FOR_IRON_TOOL,//TagKey<Block> incorrectBlocksForDrops,
1000,//int durability,
7.0F,//float speed,
2.0F,//float attackDamageBonus,
14,//int enchantmentValue,
ModItemTags.GALLIUM_TAG//TagKey<Item> repairItems
);
}
|
这里因为反编译的代码和文档提供的不一致,为了方便阅读,每个量给了注释。另外,修复用的物品要求一个ItemTag,所以自己去定义一个Tag(实际上大部分时候你会觉得建一个Tag是Mojang找事的写法)。