本篇教程的视频

本篇教程的源代码

Github地址:TutorialMod-ModifyLootTable-1.21

介绍

本期教程我们使用代码来修改原版的战利品列表,这个是从1.20中搬过来的

其实这个教程可有可无,因为你完全可以通过数据包的形式去修改战利品列表

不过,这玩意是FabricAPI的其中一个功能,我们还是来看看吧

创建ModLootTableModifiers类

我们创建一个ModLootTableModifiers类,在这个类里面来实现修改战利品列表的功能

1
2
3
public class ModLootTableModifiers {

}

首先我们需要一个Identifier,这个是用来标识我们要修改的战利品列表的位置(就是原来这个战利品列表的路径)

1
2
private static final Identifier JUNGLE_TEMPLE =
Identifier.ofVanilla("chests/jungle_temple");

这里我们修改的是丛林遗迹中箱子的战利品列表,其路径为chests/jungle_temple

而后我们创建一个modifyLootTable方法

1
2
3
public static void modifyLootTable() {

}

在这个方法里面我们来编写修改战利品列表的代码

1
2
3
4
5
6
7
8
9
10
11
LootTableEvents.MODIFY.register((key, tableBuilder, source) -> {
if (JUNGLE_TEMPLE.equals(key.getValue())) {
LootPool.Builder poolBuilder = LootPool.builder()
.rolls(ConstantLootNumberProvider.create(1))
.conditionally(RandomChanceLootCondition.builder(1.0f))
.with(ItemEntry.builder(ModItems.PROSPECTOR))
.apply(SetCountLootFunction.builder(UniformLootNumberProvider.create(1.0f, 1.0f)));

tableBuilder.pool(poolBuilder);
}
});

这里我们使用LootTableEvents.MODIFY.register来注册一个LootTable修改事件,这个是FabricAPI提供的

其实对应还有一个LootTableEvents.REPLACE,这个是完全替换原版的战利品列表,1.20中我们以可疑的沙子为例用这个事件写的

但是现在在1.21版本中,这个东西其实不太好用,要写还得用Mixin,不如直接写数据包

在这个事件中,我们通过key来判断我们要修改的战利品列表的位置,然后我们创建一个LootPool,在这个LootPool中我们设置了rollsconditionallywithapply等参数

这些参数其实就是战利品列表中的参数,具体的也可以看Wiki上的解释

这里我们将Prospector放入到了丛林遗迹的战利品列表中,设置其数量为1,生成概率为1.0f(当然,也不一定会百分百生成,因为原来的战利品列表中还有东西)

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
public class ModLootTableModifiers {
private static final Identifier JUNGLE_TEMPLE =
Identifier.ofVanilla("chests/jungle_temple");
private static final Identifier CREEPER_ID =
Identifier.ofVanilla("entities/creeper");

public static void modifyLootTable() {
LootTableEvents.MODIFY.register((key, tableBuilder, source) -> {
if (JUNGLE_TEMPLE.equals(key.getValue())) {
LootPool.Builder poolBuilder = LootPool.builder()
.rolls(ConstantLootNumberProvider.create(1))
.conditionally(RandomChanceLootCondition.builder(1.0f))
.with(ItemEntry.builder(ModItems.PROSPECTOR))
.apply(SetCountLootFunction.builder(UniformLootNumberProvider.create(1.0f, 1.0f)));

tableBuilder.pool(poolBuilder);
}

if (CREEPER_ID.equals(key.getValue())) {
LootPool.Builder poolBuilder = LootPool.builder()
.rolls(ConstantLootNumberProvider.create(1))
.conditionally(RandomChanceLootCondition.builder(1.0f))
.with(ItemEntry.builder(ModItems.ANTHRACITE))
.apply(SetCountLootFunction.builder(UniformLootNumberProvider.create(1.0f, 5.0f)));

tableBuilder.pool(poolBuilder);
}
});
}
}

那么同样的,我们也是可以改生物实体的战利品列表的,这里我们修改了Creeper的战利品列表

这里我们将Anthracite放入到了Creeper的战利品列表中,设置其数量为1-5,生成概率为1.0f

这样我们击倒Creeper的时候,就有可能掉落Anthracite

那么到这里为止,我们修改战利品列表的代码就写完了,接下来就得注册

初始化ModLootTableModifiers

我们在TutorialMod类中初始化ModLootTableModifiers

1
ModLootTableModifiers.modifyLootTable();

这里就是把modifyLootTable方法调用一下,然后就可以了

之后我们进入游戏,新建一个存档。在各种结构里的那些箱子,其里面的战利品列表是在其所在区块生成时一起生成,保险起见还是新建一个存档

然后定位到丛林遗迹,打开箱子,就可以看到Prospector了(也可能没有);生成一个Creeper,击倒它,就可以看到除了火药之外,还有Anthracite