Table of Contents

战利品表生成

在本教程,你将学习如何使用数据生成器为方块和其他内容生成战利品表。使用数据生成,就不再需要为每个方块写 JSON。在阅读本教程之前,请确认你已经阅读 开始了解数据生成,并且已经有一个实现了 DataGenerationEntrypoint 的类。

首先,创建一个类(或者多个,你需要一个给方块、箱子和实体)来继承(extends) SimpleFabricLootTableProvider,然后像这样注册它:

方块战利品表

要为方块战利品表添加数据生成,只需要创建一个继承了 FabricBlockLootTableProvider 的类。

TutorialBlockLootTableProvider.java
public class TutorialBlockLootTableProvider extends FabricBlockLootTableProvider {
  protected TutorialBlockLootTableProvider(FabricDataOutput dataOutput, CompletableFuture<RegistryWrapper.WrapperLookup> registryLookup) {
    super(dataOutput, registryLookup);
  }
 
  @Override
  public void generate() {
    // ...
  }
}

然后,将数据生成添加到入口点中(这里我们用的例子是 ExampleModDataGenerator):

ExampleModDataGenerator.java
public class ExampleModDataGenerator implements DataGeneratorEntrypoint {
  @Override
  public void onInitializeDataGenerator(FabricDataGenerator generator) {
    FabricDataGenerator.Pack pack = generator.createPack();
 
    pack.addProvider(TutorialBlockLootTableProvider::new);
  }
}
如果使用的是 1.20 之前的版本,请将 pack.addProvider(TutorialBlockLootTableProvider::new); 替换为 fabricDataGenerator.addProvider(TutorialBlockLootTableProvider::new); 并移除 FabricDataGenerator.Pack myPack = fabricDataGenerator.createPack();

在此前的方块教程中,我们创建了一个示例方块。所以使用数据生成器生成战利品表,就像这样简单:

TutorialBlockLootTableProvider.java
  @Override
  public void generate() {
    addDrop(TutorialBlocks.EXAMPLE_BLOCK);
  }

这是方块最简单的战利品表。被挖掘时,掉落一个。在带有损耗的爆炸中被炸掉时(例如苦力怕、下界床),会被完成破坏而不掉落。

也可以弄得复杂一点点,比如(这里的代码仅用作举例,请不要为一个方块多次添加战利品表):

    // 什么也不掉落
    addDrop(TutorialBlocks.EXAMPLE_BLOCK, dropsNothing());
 
    // 掉落泥土方块
    addDrop(TutorialBlocks.EXAMPLE_BLOCK, Blocks.DIRT);
 
    // 只有在使用带有精准采集的工具时掉落自身,否则不掉落
    addDropWithSilkTouch(TutorialBlocks.EXAMPLE_BLOCK);
 
    // 只有在使用带有精准采集的工具时掉落自身,否则掉落泥土方块
    addDropWithSilkTouch(TutorialBlocks.EXAMPLE_BLOCK, Blocks.DIRT);
 
    // 只有在使用剪刀或带有精准采集的工具时掉落自身,否则不掉落
    addDrop(TutorialBlocks.EXAMPLE_BLOCK, dropsWithSilkTouchOrShears(TutorialBlocks.EXAMPLE_BLOCK));
 
    // 掉落五个方块
    addDrop(TutorialBlocks.EXAMPLE_BLOCK, drops(TutorialBlocks.EXAMPLE_BLOCK)
        .apply(SetCountLootFunction.builder(ConstantLootNumberProvider.create(5))));

也可以为我们此前介绍的自定义作物生成战利品表:

    addDrop(TutorialBlocks.CUSTOM_CROP, cropDrops(TutorialBlocks.CUSTOM_CROP, TutorialItems.CUSTOM_ITEM, TutorialItems.CUSTOM_SEEDS, BlockStatePropertyLootCondition.builder(TutorialBlocks.CUSTOM_CROP).properties(StatePredicate.Builder.create().exactMatch(CropBlock.AGE, 7))));

简单战利品表

要添加一个简单的战利品表,我们只需要继承 SimpleFabricLootTableProvider。简单的战利品表也可在多种场合下使用,例如箱子。

TutorialChestLootTableProvider.java
public class TutorialChestLootTableProvider extends SimpleFabricLootTableProvider {
  public TutorialChestLootTableProvider(FabricDataOutput output, CompletableFuture<RegistryWrapper.WrapperLookup> registryLookup) {
    super(output, registryLookup, LootContextTypes.CHEST);
  }
 
  public static final RegistryKey<LootTable> TEST_CHEST = RegistryKey.of(RegistryKeys.LOOT_TABLE, Identifier.of("tutorial", "test_chest"));
 
  @Override
  public void accept(BiConsumer<RegistryKey<LootTable>, LootTable.Builder> lootTableBiConsumer) {
    lootTableBiConsumer.accept(TEST_CHEST, LootTable.builder()
        .pool(LootPool.builder().rolls(ConstantLootNumberProvider.create(1.0F))
            .with(ItemEntry.builder(Items.DIAMOND)
                .apply(SetCountLootFunction.builder(ConstantLootNumberProvider.create(1.0F))))
            .with(ItemEntry.builder(Items.DIAMOND_SWORD)))
    );
  }
}

然后在入口点中:

ExampleModDataGenerator.java
public class ExampleModDataGenerator implements DataGeneratorEntrypoint {
  @Override
  public void onInitializeDataGenerator(FabricDataGenerator generator) {
    // ...
 
    pack.addProvider(TutorialChestLootTableProvider::new);
  }
}
如果使用的是 1.20 之前的版本,请将 pack.addProvider(TutorialChestLootTableProvider::new); 替换为 fabricDataGenerator.addProvider(TutorialChestLootTableProvider::new);,并移除 FabricDataGenerator.Pack myPack = fabricDataGenerator.createPack();

现在运行数据生成器,然后启动 Minecraft,并运行多次命令 /loot give @s loot tutorial:test_chest,看看会发生什么!也可以试试运行命令 /setblock ~ ~ ~ chest{LootTable:“tutorial:test_chest”} 然后打开箱子看看。