本篇教程的视频
本篇教程的源代码
本篇教程目标
- 理解原版
Tag
(标签
)的注册,json
文件格式
- 学会Tag的注册和使用,利用数据生成生成
Tag
的json
文件
简述
Tag
,标签
,这是在游戏中用来给物品
、方块
、实体
等东西来进行分类
当然,在我们之前写战利品列表的时候,已经接触过Tag
了,这里的话我们再详细地来讲一下
我们可以使用Tag
来编写配方、战利品列表等数据文件,也可以方便地进行一些方法的判断,
如判断某一些特定的矿石,你要用or
(||
)来写的话,得写一堆,但如果用Tag来写的话,一句话就够了
上面这个例子可参见旧教程
探矿器旧教程:探矿器
Tag旧教程:Tag
本系列教程中移除了探矿器这个案例,因为相对而言,这个例子已经很详细了(1.21
的比1.20
的要更详细)
查看源代码
注意,本期教程只涉及物品
和方块
的标签Tag
,即ItemTag
和BlockTag
,
其他类型的标签我们将会在未来的教程中逐步涉及
常规操作,我们先来看源代码
源代码的话,只要看ItemTags
或者BlockTags
其中一个类就可以了,因为两个类差不多
1 2 3 4 5
| public static final TagKey<Item> WOOL = of("wool"); ... private static TagKey<Item> of(String id) { return TagKey.of(RegistryKeys.ITEM, new Identifier(id)); }
|
这是ItemTags
类中其中一个注册语句和它的注册方法
这里注册的是WOOL
标签,也就是羊毛
,它的类型是TagKey<Item>
注册方法调用的是TagKey.of
方法,传入两个参数,第一个是RegistryKeys.ITEM
,也就是注册表项
,
第二个是Identifier
,当然我们自己写是要加我们模组的ID
的
这里我们顺便来看看它对应的json
文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| { "values": [ "minecraft:white_wool", "minecraft:orange_wool", "minecraft:magenta_wool", "minecraft:light_blue_wool", "minecraft:yellow_wool", "minecraft:lime_wool", "minecraft:pink_wool", "minecraft:gray_wool", "minecraft:light_gray_wool", "minecraft:cyan_wool", "minecraft:purple_wool", "minecraft:blue_wool", "minecraft:brown_wool", "minecraft:green_wool", "minecraft:red_wool", "minecraft:black_wool" ] }
|
这是原版的wool
标签对应的json
文件,可以看到,它里面存放了原版所有颜色的羊毛
那么再找一个用到它的例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| { "type": "minecraft:crafting_shaped", "category": "misc", "key": { "#": { "item": "minecraft:stick" }, "X": { "tag": "minecraft:wool" } }, "pattern": [ "###", "#X#", "###" ], "result": { "item": "minecraft:painting" }, "show_notification": true }
|
这是原版画
对应的配方,可以看到,它里面用到了wool
标签
原版其实有不少配方都用到了Tag
,也有很多类中的方法也用到了Tag
BlockTags
这里就不详细解释了,我们就看一下它的源代码
1 2 3 4 5
| public static final TagKey<Block> WOOL = of("wool"); ... private static TagKey<Block> of(String id) { return TagKey.of(RegistryKeys.BLOCK, new Identifier(id)); }
|
可以看到,BlockTags
和ItemTags
差不多,只是TagKey
使用的泛型
和注册表项
不同
注册Tag
接下来我们就来写自己的Tag
,这里先来写物品的标签
创建ModItemTags
类
1 2 3
| public class ModItemTags { }
|
再写上注册方法,注册方法可以直接拿原版的,然后把命名空间
改写一下
1 2 3
| private static TagKey<Item> of(String id) { return TagKey.of(RegistryKeys.ITEM, new Identifier(TutorialMod.MOD_ID, id)); }
|
最后我们就可以写我们自己的标签
了
1
| public static final TagKey<Item> SUGAR_INGREDIENTS = of("sugar_ingredients");
|
这里注册了一个糖的原料物品
的标签
,我们可以在后面的配方中使用它
相应的,方块的标签
也差不多,也创建一个ModBlockTags
类
1 2 3 4 5 6 7
| public class ModBlockTags { public static final TagKey<Block> ETHER_BLOCK = of("ether_block");
private static TagKey<Block> of(String id) { return TagKey.of(RegistryKeys.BLOCK, new Identifier(TutorialMod.MOD_ID, id)); } }
|
这里注册一个ETHER_BLOCK
的标签
数据生成
接下来我们就来生成我们的Tag
的json
文件,这里我们用数据生成
来生成
前面我们创建过ModItemTagsProvider
类
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class ModItemTagsProvider extends FabricTagProvider.ItemTagProvider { public ModItemTagsProvider(FabricDataOutput output, CompletableFuture<RegistryWrapper.WrapperLookup> completableFuture) { super(output, completableFuture); }
@Override protected void configure(RegistryWrapper.WrapperLookup wrapperLookup) { getOrCreateTagBuilder(ModItemTags.SUGAR_INGREDIENTS) .add(ModItems.CHEESE) .add(ModItems.STRAWBERRY) .add(Items.BEETROOT); } }
|
我们在重写的configure
方法中,使用getOrCreateTagBuilder
方法来将物品放到这个Tag
中
这里就放了模组的CHEESE
、STRAWBERRY
和原版的BEETROOT
方块的标签前面写战利品列表
的时候其实已经写过了,不过我们还是举个例子吧
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
| public class ModBlockTagsProvider extends FabricTagProvider.BlockTagProvider { public ModBlockTagsProvider(FabricDataOutput output, CompletableFuture<RegistryWrapper.WrapperLookup> registriesFuture) { super(output, registriesFuture); }
@Override protected void configure(RegistryWrapper.WrapperLookup wrapperLookup) { getOrCreateTagBuilder(BlockTags.PICKAXE_MINEABLE) .add(ModBlocks.ICE_ETHER_BLOCK) .add(ModBlocks.ICE_ETHER_ORE);
getOrCreateTagBuilder(BlockTags.NEEDS_IRON_TOOL) .add(ModBlocks.ICE_ETHER_ORE);
getOrCreateTagBuilder(ModBlockTags.ETHER_BLOCK) .add(ModBlocks.ICE_ETHER_BLOCK) .add(ModBlocks.RAW_ICE_ETHER_BLOCK) .forceAddTag(BlockTags.COAL_ORES) .forceAddTag(BlockTags.DIAMOND_ORES) .forceAddTag(BlockTags.EMERALD_ORES) .forceAddTag(BlockTags.GOLD_ORES) .forceAddTag(BlockTags.IRON_ORES) .forceAddTag(BlockTags.LAPIS_ORES) .forceAddTag(BlockTags.REDSTONE_ORES); } }
|
我们把原版的矿石
都加入到了ETHER_BLOCK
标签中,这个其实就是旧教程中,应用到探矿器上的例子
forceAddTag
方法可以添加现有的标签
使用Tag
使用配方中使用Tag
的例子吧,我们就用糖的原料那个标签来写吧
1 2 3 4 5
| ShapedRecipeJsonBuilder.create(RecipeCategory.FOOD, Items.SUGAR, 3) .pattern("###") .input('#', ModItemTags.SUGAR_INGREDIENTS) .criterion(hasItem(Items.BEETROOT), conditionsFromTag(ModItemTags.SUGAR_INGREDIENTS)) .offerTo(exporter, new Identifier(TutorialMod.MOD_ID, "sugar_from_beetroot"));
|
这里我们将input
中的输入物品改成了我们自己写的SUGAR_INGREDIENTS
标签,这样我们的模组中的CHEESE
、STRAWBERRY
和原版的BEETROOT
都可以合成糖了
另外,在criterion
中,我们也可以将第二个参数改为conditionsFromTag
方法,这样就可以使用Tag
中的物品作为条件了
第一个参数就不用改它,因为它本身就是一个字符串
,这个在前面的数据生成那期教程就讲过了
然后我们就可以跑数据生成来看看生成的文件
1 2 3 4 5 6 7 8
| { "replace": false, "values": [ "tutorial-mod:cheese", "tutorial-mod:strawberry", "minecraft:beetroot" ] }
|
这个是sugar_ingredients.json
文件的内容,可以看到,我们写的三个物品都成功添加进去了
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| { "replace": false, "values": [ "tutorial-mod:ice_ether_block", "tutorial-mod:raw_ice_ether_block", "#minecraft:coal_ores", "#minecraft:diamond_ores", "#minecraft:emerald_ores", "#minecraft:gold_ores", "#minecraft:iron_ores", "#minecraft:lapis_ores", "#minecraft:redstone_ores" ] }
|
这个是ether_block.json
文件的内容,现有标签会在前面加个#
来与一般物品
、方块
区分开来
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| { "type": "minecraft:crafting_shaped", "category": "misc", "key": { "#": { "tag": "tutorial-mod:sugar_ingredients" } }, "pattern": [ "###" ], "result": { "count": 3, "item": "minecraft:sugar" }, "show_notification": true }
|
这个是我们刚才改的配方文件,可以看到这里的key
已经变成了Tag
测试
那么接下来我们就可以启动我们的游戏去测试了