• Forge论坛

导航页

  • 主页
  • 向文档做出贡献
  • 入门
    • 概述
    • 模组文件
    • 规划你的模组结构
    • 版本号
  • 核心概念
    • 注册表
    • 端位(Sides)
    • 事件
    • 模组生命周期
    • 资源
    • 国际化与本地化
  • 方块
    • 概述
    • 方块状态
  • 物品
    • 概述
    • BlockEntityWithoutLevelRenderer
  • 网络
    • 概述
    • SimpleImpl
    • 实体的同步
  • 方块实体
    • 概述
    • BlockEntityRenderer
  • 游戏特效
    • 粒子效果
    • 音效
  • 数据储存
    • Capabilities
    • Saved Data
    • 编解码器(Codecs)
  • 图形用户界面
    • 菜单(Menus)
    • 屏幕(Screens)
  • 渲染
    • 模型扩展
      • 概述
      • 根变换
      • 渲染类型
      • 部分可见度
      • 面数据
    • 模型加载器
      • 概述
      • 烘焙模型
      • 变换
      • 物品重载
  • 资源
    • 客户端资源(Assets)
      • 概述
      • 模型
        • 概述
        • 纹理色调
        • 物品属性
    • 服务端数据(Data)
      • 概述
      • 配方
        • 概述
        • 自定义配方
        • 原料
        • 非数据包配方
      • 战利品表
      • 全局战利品修改器
      • 标签
      • 进度
      • 条件性加载数据
  • 数据生成
    • 概述
    • 客户端资源(Assets)
      • 模型提供者
      • 语言提供者
      • 音效提供者
    • 服务端数据(Data)
      • 配方提供者
      • 战利品表提供者
        • LootTableSubProvider
        • 战利品表生成器
      • 标签提供者
      • 进度提供者
      • 全局战利品修改器提供者
      • 数据包注册表对象提供者
  • 杂项功能
    • 配置
    • 键盘布局
    • 游戏测试
    • Forge更新检查器
    • 调试分析器
  • 进阶主题
    • 访问转换器
  • 向Forge做出贡献
    • 概述
    • Pull Request准则
  • 旧版本
    • 概述
    • 移植到当前版本

战利品表生成

可以通过构造新的LootTableProvider并提供LootTableProvider$SubProviderEntry来为模组生成战利品表。该提供者必须被添加到DataGenerator中。

// 在模组事件总线上
@SubscribeEvent
public void gatherData(GatherDataEvent event) {
    event.getGenerator().addProvider(
        // 告诉生成器仅在生成服务端资源时运行
        event.includeServer(),
        output -> new MyLootTableProvider(
          output,
          // 指定需要生成的表的注册表名称,或者可留空
          Collections.emptySet(),
          // 生成战利品的子提供者
          List.of(subProvider1, subProvider2, /*...*/)
        )
    );
}

LootTableSubProvider

每个LootTableProvider$SubProviderEntry接受一个提供的LootTableSubProvider,该LootTableSubProvider为给定的LootContextParamSet生成战利品表。LootTableSubProvider包含一个方法,该方法采用编写器(BiConsumer<ResourceLocation, LootTable.Builder>)来生成表。

public class ExampleSubProvider implements LootTableSubProvider {

  // 用于为包装Supplier创建工厂方法
  public ExampleSubProvider() {}

  // 用于生成战利品表的方法
  @Override
  public void generate(BiConsumer<ResourceLocation, LootTable.Builder> writer) {
    // 在此处通过调用writer#accept生成战利品表
  }
}

The table can then be added to LootTableProvider#getTables for any available LootContextParamSet:

// 在将会传递给LootTableProvider构造函数的列表中
new LootTableProvider.SubProviderEntry(
  ExampleSubProvider::new,
  // 'empty'参数集的战利品表生成器
  LootContextParamSets.EMPTY
)

BlockLootSubProvider和EntityLootSubProvider子类

对于LootContextParamSets#BLOCK和#ENTITY,有一些特殊类型(分别为BlockLootSubProvider和EntityLootSubProvider),它们提供了额外的帮助方法来创建和验证是否存在战利品表。

BlockLootSubProvider的构造函数接受一个物品列表和一个FeatureFlagSet,前者是耐爆炸的,用于确定如果方块爆炸,是否可以生成战利品表,后者用于确定是否启用了该方块,以便为其生成战利品表。

// 在某个BlockLootSubProvider子类中
public MyBlockLootSubProvider() {
  super(Collections.emptySet(), FeatureFlags.REGISTRY.allFlags());
}

EntityLootSubProvider的构造函数接受一个FeatureFlagSet,它确定是否启用了实体类型,以便为其生成战利品表。

// 在某个EntityLootSubProvider子类中
public MyEntityLootSubProvider() {
  super(FeatureFlags.REGISTRY.allFlags());
}

要使用它们,所有注册的对象必须分别提供给BlockLootSubProvider#getKnownBlocks和EntityLootSubProvider#getKnownEntityTypes。这些方法是为了确保Iterable中的所有对象都有一个战利品表。

提示

如果DeferredRegister用于注册模组的对象,则可以通过DeferredRegister#getEntries向#getKnown*方法提供条目:

// 在针对某个DeferredRegister BLOCK_REGISTRAR的某个BlockLootSubProvider子类中
@Override
protected Iterable<Block> getKnownBlocks() {
  return BLOCK_REGISTRAR.getEntries() // 获取所有已注册的条目
    .stream() // 流播所有已包装的对象
    .flatMap(RegistryObject::stream) // 如果可行,获取该对象
    ::iterator; // 创建该Iterable
}

战利品表本身可以通过实现#generate方法来添加。

// 在某个BlockLootSubProvider子类中
@Override
public void generate() {
  // 在此处添加战利品表
}

战利品表生成器

要生成战利品表,它们被LootTableSubProvider接受为LootTable$Builder。之后,在LootTableProvider$SubProviderEntry中设置指定的LootContextParamSet,然后通过#build生成。在构建之前,生成器可以指定影响战利品表功能的条目、条件和修改器。

注意

战利品表的功能非常广泛,因此本文档不会对其进行全面介绍。取而代之的是,将对每个组件进行简要描述。每个组件的特定子类型可以使用IDE找到。它们的实现将留给读者练习。

LootTable

战利品表是基本对象,可以使用LootTable#lootTable将其转换为所需的LootTable$Builder。战利品表可以通过池列表(通过#withPool)以及修改这些池的结果物品的功能(通过#apply)来构建,池列表按指定的顺序应用。

LootPool

战利品池代表一个执行操作的组,并且可以使用LootPool#lootPool生成LootPool$Builder。每个战利品池都可以指定定义池中操作的条目(通过#add)、定义是否应该执行池中的操作的条件(通过#when)以及修改条目的结果物品的功能(通过#apply)。每个池可以按指定次数执行(通过#setRolls)。此外,还可以指定奖金执行(通过#setBonusRolls),这取决于执行者的运气。

LootPoolEntryContainer

战利品条目定义了选择时要执行的操作,通常是生成物品。每个条目都有一个关联的已注册的LootPoolEntryType。它们也有自己的关联生成器,为LootPoolEntryContainer$Builder的子类型。多个条目可以同时执行(通过#append)或顺序执行,直到一个条目失败为止(通过#then)。此外,条目可以在失败时默认为另一个条目(通过#otherwise)。

LootItemCondition

战利品条件定义了执行某些操作所需满足的要求。每个条件都有一个关联的已注册的LootItemConditionType。它们也有自己的关联生成器,为LootItemCondition$Builder的子类型。默认情况下,所有指定的战利品条件都必须返回true才能执行操作。战利品条件也可以指定为只有一个必须返回true(通过#or)。此外,条件的结果输出可以反转(通过#invert)。

LootItemFunction

战利品函数在将执行结果传递给输出之前会对其进行修改。每个函数都有一个关联的已注册的LootItemFunctionType。它们也有自己的关联生成器,为LootItemFunction$Builder的子类型。

NbtProvider

NBT提供者是由CopyNbtFunction定义的一种特殊类型的函数。它们定义了从何处提取标记信息。每个提供者都有一个关联的已注册的LootNbtProviderType。

NumberProvider

数字提供者决定战利品池执行的次数。每个提供者都有一个关联的已注册的LootNumberProviderType。

ScoreboardNameProvider

记分牌提供者是由ScoreboardValue定义的一种特殊类型的数字提供者。他们定义了记分牌的名称,以获取要执行的掷数。每个提供者都有一个关联的已注册的LootScoreProviderType。

Built with MkDocs using a custom theme. Hosted by Read the Docs.
Enable Dark Theme