• Forge论坛

导航页

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

原料

Ingredient是基于物品的输入的predicate处理器,用于检查某个ItemStack是否满足成为配方中有效输入的条件。所有接受输入的原版配方都使用Ingredient或Ingredient的列表,然后将其合并为单一的Ingredient。

自定义原料

自定义原料可以通过将type设置为原料的序列化器的名称来指定,复合原料除外。当没有指定类型时,type默认为原版原料minecraft:item。自定义原料也可以很容易地用于数据生成。

Forge类型

Forge提供了一些额外的Ingredient类型供程序员实现。

CompoundIngredient

尽管它们在功能上是相同的,但复合原料取代了在配方中实现原料列表的方式。它们作为一个逻辑或(OR)集合工作,其中传入的物品栈必须至少在一个提供的原料中。进行此更改是为了允许自定义原料在列表中正确工作。因此,无需指定类型。

// 对于某个输入
[
  // 这些原料中必须至少有一种必须匹配才能成功
  {
    // 原料
  },
  {
    // 自定义原料
    "type": "examplemod:example_ingredient"
  }
]

StrictNBTIngredient

StrictNBTIngredient比较ItemStack上的物品、耐久和共享标签(由IForgeItem#getShareTag定义),以保证确切的等效性。这可以通过将type指定为forge:nbt来使用。

// 对于某个输入
{
  "type": "forge:nbt",
  "item": "examplemod:example_item",
  "nbt": {
    // 添加nbt数据(必须与物品栈上的数据完全匹配)
  }
}

PartialNBTIngredient

PartialNBTIngredient是StrictNBTIngredient的宽松版本,因为它们与共享标签中指定的单个或一组物品以及仅键(由IForgeItem#getShareTag定义)进行比较。这可以通过将type指定为forge:partial_nbt来使用。

// 对于某个输入
{
  "type": "forge:partial_nbt",

  // 'item'或'items'必须被指定
  // 如果都指定了,那么只有'item'会被读取
  "item": "examplemod:example_item",
  "items": [
    "examplemod:example_item",
    "examplemod:example_item2"
    // ...
  ],

  "nbt": {
    // 仅检查'key1'和'key2'的等效性
    // 不会检查物品栈中的所有其他键
    "key1": "data1",
    "key2": {
      // 数据2
    }
  }
}

IntersectionIngredient

IntersectionIngredient工作为一个逻辑和(AND)集合,其中传入的物品必须与所有提供的原料匹配。必须至少提供两种原料。这可以通过将type指定为forge:intersection来使用。

// 对于某个输入
{
  "type": "forge:intersection",

  // 所有这些原料都必须返回true才能成功
  "children": [
    {
      // 原料1
    },
    {
      // 原料2
    }
    // ...
  ]
}

DifferenceIngredient

DifferenceIngredient工作为一个减法(SUB)集合,其中传入的物品栈必须与第一个原料匹配,但不能与第二个原料匹配。这可以通过将type指定为forge:difference来使用。

// 对于某个输入
{
  "type": "forge:difference",
  "base": {
    // 该物品栈所存在的原料
  },
  "subtracted": {
    // 该物品栈所不存在的原料
  }
}

创建自定义原料

可以通过为创建的Ingredient子类实现IIngredientSerializer来创建自定义原料。

提示

自定义原料应该是AbstractIngredient的子类,因为它提供了一些有用的抽象以便于实现。

原料的子类

对于每个原料子类,有三种重要的方法需要实现:

方法 描述
getSerializer 返回用于读取和写入原料的serializer。
test 如果输入对此原料有效,则返回true。
isSimple 如果原料与物品栈的标签匹配,则返回false。AbstractIngredient的子类需要定义此行为,而Ingredient子类默认返回true。

所有其他定义的方法都留给读者练习,以便根据原料子类的需要使用。

IIngredientSerializer

IIngredientSerializer子类型必须实现三种方法:

方法 描述
parse (JSON) 将JsonObject转换为Ingredient。
parse (Network) 返回用于解码Ingredient的网络缓冲区。
write 将一个Ingredient写入网络缓冲区。

此外,Ingredient子类应实现Ingredient#toJson,以便与数据生成一起使用。AbstractIngredient的子类使#toJson成为一个需要实现该方法的抽象方法。

之后,应声明一个静态实例来保存初始化的序列化器,然后在RecipeSerializer的RegisterEvent期间或在FMLCommonSetupEvent期间使用CraftingHelper#register进行注册。Ingredient子类在Ingredient#getSerializer中返回序列化器的静态实例。

// 在某个序列化器类中
public static final ExampleIngredientSerializer INSTANCE = new ExampleIngredientSerializer();

// 在某个处理器类中
public void registerSerializers(RegisterEvent event) {
  event.register(ForgeRegistries.Keys.RECIPE_SERIALIZERS,
    helper -> CraftingHelper.register(registryName, INSTANCE)
  );
}

// 在某个原料类中
@Override
public IIngredientSerializer<? extends Ingredient> getSerializer() {
  return INSTANCE;
}

提示

如果使用FMLCommonSetupEvent注册原料序列化器,则必须通过FMLCommonSetupEvent#enqueueWork将其排入同步工作队列,因为CraftingHelper#register不是线程安全的。

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