• Forge论坛

导航页

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

配方生成

可以通过子类化RecipeProvider并实现#buildRecipes来为模组生成配方。一旦Consumer接受FinishedRecipe视图,就会提供一个用于生成数据的配方。FinishedRecipe既可以手动创建和提供,也可以为方便起见,使用RecipeBuilder创建。

实现后,该提供者必须被添加到DataGenerator。

// 在模组事件总线上
@SubscribeEvent
public void gatherData(GatherDataEvent event) {
    event.getGenerator().addProvider(
        // 告诉生成器仅在生成服务端资源时运行
        event.includeServer(),
        MyRecipeProvider::new
    );
}

RecipeBuilder

RecipeBuilder是一个方便的实现,用于创建要生成的FinishedRecipe。它提供了解锁、分组、保存和获取配方结果的基本定义。这分别通过#unlockedBy、#group、#save和#getResult来完成。

重要

原版配方生成器中不支持配方中的ItemStack输出。对于现有的原版配方序列化器,必须以不同的方式构建FinishedRecipe才能生成此数据。

警告

正在生成的物品结果必须指定有效的RecipeCategory;否则,将引发NullPointerException。

除[SpecialRecipeBuilder]外的所有配方构建器都需要指定一个进度标准。如果玩家以前使用过配方,则所有配方都会生成解锁配方的标准。然而,必须指定一个额外的标准,允许玩家在没有任何先验知识的情况下获得配方。如果指定的任何标准为真,则玩家将获得配方书的配方。

提示

配方标准通常使用InventoryChangeTrigger在用户物品栏中存在某些物品时解锁配方。

ShapedRecipeBuilder

ShapedRecipeBuilder用于生成有序配方。该生成器可以通过#shaped进行初始化。保存前可以指定配方组、输入符号模式、配料的符号定义和配方解锁条件。

// 在RecipeProvider#buildRecipes(writer)中
ShapedRecipeBuilder builder = ShapedRecipeBuilder.shaped(RecipeCategory.MISC, result)
  .pattern("a a") // 创建配方图案
  .define('a', item) // 定义符号代表什么
  .unlockedBy("criteria", criteria) // 该配方如何解锁
  .save(writer); // 将数据加入生成器

附加验证检查

有序配方在构建前进行了一些额外的验证检查:

  • 图案必须被定义且接受多于一个物品。
  • 所有图案行的宽度必须相同。
  • 一个符号不能被定义多次。
  • 空格字符(' ')被保留用于表示格中无物品,因此无法被定义。
  • 图案必须使用用户定义的全部符号。

ShapelessRecipeBuilder

ShapelessRecipeBuilder用于生成无序配方。该生成器可以通过#shapeless进行初始化。保存前可以指定配方组、输入原料和配方解锁条件。

// 在RecipeProvider#buildRecipes(writer)中
ShapelessRecipeBuilder builder = ShapelessRecipeBuilder.shapeless(RecipeCategory.MISC, result)
  .requires(item) // 将物品加入配方
  .unlockedBy("criteria", criteria) // 该配方如何解锁
  .save(writer); // 将数据加入生成器

SimpleCookingRecipeBuilder

SimpleCookingRecipeBuilder用于生成熔炼、高炉熔炼、烟熏和篝火烹饪配方。此外,使用SimpleCookingSerializer的自定义烹饪配方也可以是使用该生成器生成的数据。生成器可以分别通过#smelting、#blasting、#smoking、#campfireCooking或#cooking进行初始化。保存前可以指定配方组和配方解锁条件。

// 在RecipeProvider#buildRecipes(writer)中
SimpleCookingRecipeBuilder builder = SimpleCookingRecipeBuilder.smelting(input, RecipeCategory.MISC, result, experience, cookingTime)
  .unlockedBy("criteria", criteria) // 该配方如何解锁
  .save(writer); // 将数据加入生成器

SingleItemRecipeBuilder

SingleItemRecipeBuilder用于生成切石配方。此外,使用类似SingleItemRecipe$Serializer的序列化器的自定义但物品配方也可以是使用该生成器生成的数据。生成器可以分别通过#stonecutting或通过构造函数进行初始化。保存前可以指定配方组和配方解锁条件。

// 在RecipeProvider#buildRecipes(writer)中
SingleItemRecipeBuilder builder = SingleItemRecipeBuilder.stonecutting(input, RecipeCategory.MISC, result)
  .unlockedBy("criteria", criteria) // 该配方如何解锁
  .save(writer); // 将数据加入生成器

非RecipeBuilder生成器

由于缺少前面提到的所有配方所使用的功能,一些配方生成器没有实现RecipeBuilder。

SmithingTransformRecipeBuilder

SmithingTransformRecipeBuilder用于生成转换物品的锻造配方。此外,使用序列化器(如SmithingTransformRecipe$Serializer)的自定义配方也可以是使用此生成器生成的数据。生成器可以分别通过#smithing或通过构造函数进行初始化。保存前可以指定配方解锁条件。

// 在RecipeProvider#buildRecipes(writer)中
SmithingTransformRecipeBuilder builder = SmithingTransformRecipeBuilder.smithing(template, base, addition, RecipeCategory.MISC, result)
  .unlocks("criteria", criteria) // 该配方如何解锁
  .save(writer, name); // 将数据加入生成器

SmithingTrimRecipeBuilder

SmithingTrimRecipeBuilder用于生成盔甲装饰的锻造配方。此外,使用类似SmithingTrimRecipe$Serializer的序列化器的自定义升级配方也可以是使用该生成器生成的数据。生成器可以分别通过#smithingTrim或通过构造函数进行初始化。保存前可以指定配方解锁条件。

// 在RecipeProvider#buildRecipes(writer)中
SmithingTrimRecipe builder = SmithingTrimRecipe.smithingTrim(template, base, addition, RecipeCategory.MISC)
  .unlocks("criteria", criteria) // 该配方如何解锁
  .save(writer, name); // 将数据加入生成器

SpecialRecipeBuilder

SpecialRecipeBuilder is used to generate empty JSONs for dynamic recipes that cannot easily be constrained to the recipe JSON format (dying armor, firework, etc.). The builder can be initialized via #special.

// 在RecipeProvider#buildRecipes(writer)中
SpecialRecipeBuilder.special(dynamicRecipeSerializer)
  .save(writer, name); // 将数据加入生成器

条件性配方

条件性配方也可以是通过ConditionalRecipe$Builder生成的数据。生成器可以使用#builder获得。

每个配方的条件可以通过首先调用#addCondition,然后在指定所有条件后调用#addRecipe来指定。这个过程可以重复多次,只要程序员愿意。

在指定了所有配方后,可以在最后使用#generateAdvancement为每个配方添加进度。或者,可以使用#setAdvancement设置条件性进度。

// 在RecipeProvider#buildRecipes(writer)中
ConditionalRecipe.builder()
  // 为该配方添加条件
  .addCondition(...)
  // 添加当条件为true时返回的配方
  .addRecipe(...)

  // 为下一个配方添加接下来的条件
  .addCondition(...)
  // 添加当条件为true时返回的下一个配方
  .addRecipe(...)

  // 创建条件性进度,其使用上面配方中的条件和所解锁的进度
  .generateAdvancement()
  .build(writer, name);

IConditionBuilder

为了简化向条件配方添加条件而不必手动构造每个条件实例,扩展的RecipeProvider可以实现IConditionBuilder。该接口添加了可以轻松构造条件实例的方法。

// 在ConditionalRecipe$Builder#addCondition中
(
  // 如果'examplemod:example_item'
  // 或(OR)'examplemod:example_item2'存在
  // 并且(AND)
  // 非FALSE(NOT FALSE)

  // Methods are defined by IConditionBuilder
  and( 
    or(
      itemExists("examplemod", "example_item"),
      itemExists("examplemod", "example_item2")
    ),
    not(
      FALSE()
    )
  )
)

自定义配方序列化器

自定义配方序列化器可以是通过创建可以构造FinishedRecipe的生成器生成的数据。完成的配方将配方数据及其所解锁的进度(如果存在)编码为JSON。此外,还指定了配方的名称和序列化器,以了解在加载时向何处写入以及可以解码对象的内容。构造完FinishedRecipe后,只需将其传递给RecipeProvider#buildRecipes提供的Consumer。

提示

FinishedRecipe足够灵活,任何对象转换都可以是数据生成的,而不仅仅是物品。

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