本篇教程的视频

本篇教程的源代码

GitHub地址:TutorialMod-LootTable-1.20.1

本篇教程目标

  • 理解战利品列表文件基本格式
  • 学会为模组方块添加战利品列表掉落物

查看源文件

战利品列表的话,我们就不用去看源代码了,不过得去看看原版的那些数据文件

这里我们就到外部库中去找,外部库我在本系列的第一篇中就讲过

数据文件是在data下面的,它下面有像advancement进度dimension维度recipe配方
loot table战利品列表tag标签等等各种各样的数据文件

本期教程我们就来看看原版的战利品列表文件,不过,在它下面,我们可以发现它又分为了archaeology考古
blocks方块chests箱子entities实体gameplay游戏玩法这几个

考古的话,就是那些可疑的沙子刷出来的战利品列表

箱子则为各种遗迹、各种结构中随机生成的箱子中的物品

游戏玩法上,比如钓鱼猪灵交易等各种玩法生成的战利品

我们还是来看方块的,以oak_planks橡木木板为例,我们找到它

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
"type": "minecraft:block",
"pools": [
{
"bonus_rolls": 0.0,
"conditions": [
{
"condition": "minecraft:survives_explosion"
}
],
"entries": [
{
"type": "minecraft:item",
"name": "minecraft:oak_planks"
}
],
"rolls": 1.0
}
],
"random_sequence": "minecraft:blocks/oak_planks"
}

我们来看一下它的结构

type是这个战利品列表的类型,方块一般就是minecraft:block

pools,里面就是掉落的物品,一般是一个或者多个物品;它里面的entries就是掉落物,
这里掉落的是橡木木板type抽取项类型item是生成单一物品堆栈,
name是物品的名称;rolls抽取次数,一般就抽一次,所以是1.0
bonus_rolls额外抽取次数,一般就是0.0,它是受玩家幸运值
(如时运,钓鱼中的话还有海之眷顾)影响,会增加额外抽取次数;
conditions是掉落物生成的条件,游戏中常规是生存模式下或者是被爆炸破坏,会生成掉落物,
因为我们一般在创造模式下破坏方块,是不会有掉落物的

整个pools,简单一点,其实就是我们抽卡游戏中的那个卡池
只是这里如果只有一个物品,掉落概率为100%

random_sequence是随机序列,一般就是文件名,这里就是oak_planks

基本的战利品列表就这些参数,不过还有更复杂的

我们再来看看copper_ore铜矿石的

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
50
51
52
53
54
55
56
57
58
59
{
"type": "minecraft:block",
"pools": [
{
"bonus_rolls": 0.0,
"entries": [
{
"type": "minecraft:alternatives",
"children": [
{
"type": "minecraft:item",
"conditions": [
{
"condition": "minecraft:match_tool",
"predicate": {
"enchantments": [
{
"enchantment": "minecraft:silk_touch",
"levels": {
"min": 1
}
}
]
}
}
],
"name": "minecraft:copper_ore"
},
{
"type": "minecraft:item",
"functions": [
{
"add": false,
"count": {
"type": "minecraft:uniform",
"max": 5.0,
"min": 2.0
},
"function": "minecraft:set_count"
},
{
"enchantment": "minecraft:fortune",
"formula": "minecraft:ore_drops",
"function": "minecraft:apply_bonus"
},
{
"function": "minecraft:explosion_decay"
}
],
"name": "minecraft:raw_copper"
}
]
}
],
"rolls": 1.0
}
],
"random_sequence": "minecraft:blocks/copper_ore"
}

它中间的pools比橡木木板的长得多了,我们分开来看

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
"type": "minecraft:alternatives",
"children": [
{
"type": "minecraft:item",
"conditions": [
{
"condition": "minecraft:match_tool",
"predicate": {
"enchantments": [
{
"enchantment": "minecraft:silk_touch",
"levels": {
"min": 1
}
}
]
}
}
],
"name": "minecraft:copper_ore"
},
...

这是其中一个,其实我们如果不理解这一堆是啥,但是看到enchantmentsilk_touch应该就知道了

silk_touch就是精准采集附魔,match_tool是匹配工具

conditions中的predicate是谓词,它是用于判定某些对象或参数是否满足某种特性或条件的,这里就是附魔类型及其等级的条件

所以合起来,这个就是当我们用附有精准采集的工具采集铜矿石是,掉落的不是粗铜,而是铜矿石本身

alternatives是一个复合抽取项中的抽取项类型,满足指定条件则会从列表中选择第一个满足条件的子项,

这个列表指的是所有复合抽取项都展开之后的,这里会有铜矿石粗铜,当采集工具不是附有精准采集时,
铜矿石会从列表中剔除,所以掉落的是粗铜;反之,因为抽取的第一个满足条件的,所以掉落的是铜矿石

我们再来看第二个,粗铜

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
"type": "minecraft:item",
"functions": [
{
"add": false,
"count": {
"type": "minecraft:uniform",
"max": 5.0,
"min": 2.0
},
"function": "minecraft:set_count"
},
{
"enchantment": "minecraft:fortune",
"formula": "minecraft:ore_drops",
"function": "minecraft:apply_bonus"
},
{
"function": "minecraft:explosion_decay"
}
],
"name": "minecraft:raw_copper"
}

这里多了functions,这是物品修饰器,用于对抽取的物品进行一些修饰,比如修改物品的堆叠数量

它这里分了3个部分,我们一个个来看

第一个是修饰物品掉落时的数量,最大会掉落5个,最小2个,所以掉落数量是2~5

第二个是附魔修饰器,enchantment是附魔类型,这里就是时运formula是附魔公式,
其实这个也是按照玩家是否使用带有时运的工具来采集,修改最终掉落的数量

第三个是爆炸修饰器,用于爆炸时掉落物的数量,爆炸时掉落物数量会衰减,甚至可能没了

其他的参数可以到Wiki上查看,
这里就不再赘述了,可以研究的东西很多很多

编写战利品表

那么现在,我们就可以来编写我们自己的战利品表了

我们要在resources文件夹下创建data/<modid>/loot_tables/blocks文件夹,
文件夹的结构就和原版的一致

ICE ETHER BLOCK

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
"type": "minecraft:block",
"pools": [
{
"bonus_rolls": 0.0,
"conditions": [
{
"condition": "minecraft:survives_explosion"
}
],
"entries": [
{
"type": "minecraft:item",
"name": "tutorial-mod:ice_ether_block"
}
],
"rolls": 1.0
}
],
"random_sequence": "tutorial-mod:blocks/ice_ether_block"
}

ICE ETHER ORE

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
"type": "minecraft:block",
"pools": [
{
"bonus_rolls": 0.0,
"conditions": [
{
"condition": "minecraft:survives_explosion"
}
],
"entries": [
{
"type": "minecraft:item",
"name": "tutorial-mod:raw_ice_ether"
}
],
"rolls": 1.0
}
],
"random_sequence": "tutorial-mod:blocks/ice_ether_ore"
}

原本这个矿石的,应该也是要写成和铜矿石一样的,不过还是忘记了,我们在未来的数据生成中再讲好了

RAW ICE ETHER BLOCK

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
"type": "minecraft:block",
"pools": [
{
"bonus_rolls": 0.0,
"conditions": [
{
"condition": "minecraft:survives_explosion"
}
],
"entries": [
{
"type": "minecraft:item",
"name": "tutorial-mod:raw_ice_ether_block"
}
],
"rolls": 1.0
}
],
"random_sequence": "tutorial-mod:blocks/raw_ice_ether_block"
}

测试

好,现在我们可以进入游戏测试一下了

很快,你就发现问题(如果你是完全按照我的教程来的),当我们挖掘ICE ETHER BLOCK时,发现破坏很,完了还没有掉落物

而另外两个可以正常掉落

现在,我们回过头来看看方块的注册

1
public static final Block ICE_ETHER_BLOCK = register("ice_ether_block", new Block(AbstractBlock.Settings.copy(Blocks.STONE)));

ICE ETHER BLOCK是直接复制了STONE的属性,其中就有一个requireTool属性,它表示方块需要什么工具才能被破坏

而现在,我们并没有指定什么工具可以来破坏ICE ETHER BLOCK,自然它破坏起来就很慢,因为什么东西都不是符合它的工具,同时战利品列表也不符合,就没有掉落物

Tag

这里我们就要看到另外一个东西,Tag

虽然关于Tag教程在后面,不过我们这里还是简单介绍一下

Tag标签,可以用来给方块物品等东西归类,方便一些方法上的判断,未来我们会详细地讲解

现在,我们溜到data/minecraft/tags/blocks文件夹下,我们可以发现,有一个mineable文件夹,
往下翻,还有needs_stone_toolneeds_iron_toolneeds_diamond_tool这三个json文件

mineable里面又分了axepickaxeshovelhoe四个json文件,
我们可以看到STONEpickaxe.json

不过,外面的三个文件中没有它

另外,再看到DIAMOND ORE,它既在pickaxe.json中,又在needs_iron_tool.json

结合起来,不难理解,石头是必须要镐子才能开采,不过任意等级的都可以,而钻石矿,必须用铁质及以上的镐子才能开采

那么,mineable中的,是指定方块可以被哪种工具挖掘,而`needs开头的,是指定方块需要什么等级的工具才能被挖掘

如果needs开头的文件中,没有指定方块,那么就表示任意等级的工具都可以挖掘,最低木质的就可以挖掘

编写Tag

现在,我们就可以来编写我们自己的Tag

值得注意的是,这个tag的命名空间只能是minecraft,如果把它放在我们模组的命名空间下,是不会生效的

我们在data下创建minecraft/tags/blocks文件夹,然后创建mineable文件夹,再创建pickaxe.json文件,
外面再创建一个needs_iron_tool.json文件

接下来我们往pickaxe.json中写入以下内容

1
2
3
4
5
6
7
{
"replace": false,
"values": [
"tutorial-mod:ice_ether_block",
"tutorial-mod:ice_ether_ore"
]
}

ICE ETHER ORE在注册中我也加上了requireTool,所以这里我们也写上

values就是指定这个Tag包含的方块,这里我们指定了ICE ETHER BLOCKICE ETHER ORE

replace表示是否替换原版已有的Tagfalse表示不替换,true表示替换,当然我们不能把原版的换掉,不然原版的都失效了

接下来,我们往needs_iron_tool.json中写入以下内容

1
2
3
4
5
6
{
"replace": false,
"values": [
"tutorial-mod:ice_ether_ore"
]
}

这里我们指定了ICE ETHER ORE,表示ICE ETHER ORE需要铁质及以上的镐子才能被挖掘

好,现在文件再一次进入游戏测试,发现ICE ETHER BLOCKICE ETHER ORE都可以正常破坏了,
而且掉落物也正常了