配方
配方是在 Minecraft 世界中将一定数量的对象转化为其他对象的方式。原版系统只处理物品转换,但整个系统可以扩展为使用程序员创建的任何对象。
原创说明图,依据 Forge 1.21.x 官方文档 绘制。
数据驱动配方
原版大多数配方实现由 JSON 数据驱动,因此创建新配方不需要 Mod,只需要数据包。如何创建配方并放入 Mod 的 resources 文件夹,参见 Minecraft Wiki。
完成进度后,配方可作为奖励在配方书中获得。配方进度总是以 minecraft:recipes/root 为父级,因此不会出现在进度界面。默认条件检查用户是否使用过配方一次,或通过 /recipe 等命令获得配方:
带注释和省略号的示例用于说明结构;实际 JSON 文件需移除注释并补全内容。
// 在某个配方进度 JSON 中
"has_the_recipe": { // 条件标签
// 使用 examplemod:example_recipe 时成功
"trigger": "minecraft:recipe_unlocked",
"conditions": { "recipe": "examplemod:example_recipe" }
},
// ...
"requirements": [
["has_the_recipe" /* ...其他以 OR 组合来解锁配方的条件标签 */]
]
数据驱动配方及解锁它的进度可通过 RecipeProvider 生成。
配方管理器
配方由 RecipeManager 加载和保存,获取可用配方的操作由其处理。两个重要方法:
| 方法 | 说明 |
|---|---|
getRecipeFor |
获取匹配当前输入的第一个配方。 |
getRecipesFor |
获取匹配当前输入的所有配方。 |
每个方法接收表示使用配方方式(合成、烧炼等)的 RecipeType、保存输入配置的 Container,以及当前世界;世界与容器一起传给 Recipe#matches。
重要:Forge 提供
RecipeWrapper工具类,它扩展Container,用于包装IItemHandler并将其传给需要Container参数的方法。
// 在具有 IItemHandlerModifiable handler 的方法中
recipeManger.getRecipeFor(RecipeType.CRAFTING, new RecipeWrapper(handler), level);
附加功能
Forge 对配方格式及实现提供额外行为,以便更好地控制系统。
配方 ItemStack 结果
除 minecraft:stonecutting 配方外,所有原版配方序列化器都扩展了 result 标签,使其可接收表示完整 ItemStack 的 JsonObject,而非某些情况下仅有的物品名称和数量。
// 在某个配方 JSON 中
"result": {
"item": "examplemod:example_item", // 作为结果给出的注册物品名称
"count": 4, // 返回的物品数量
"nbt": { // 堆的标签数据,也可以是字符串
// 在此添加标签数据
}
}
nbt 也可为包含字符串化 NBT(SNBT)的字符串,用于无法正确表示为 JSON 对象的数据,例如 IntArrayTag。
条件配方
配方及其解锁进度可以根据现有信息(Mod 是否加载、物品是否存在等)条件加载并使用默认值。
更大的合成网格
原版默认将合成网格的最大宽高设为 3×3。可在 FMLCommonSetupEvent 中调用 ShapedRecipe#setCraftingSize 并传入新宽高来扩展。
警告:
ShapedRecipe#setCraftingSize不是线程安全的,必须通过FMLCommonSetupEvent#enqueueWork加入同步工作队列。
较大的配方网格可以数据生成。
配料类型
Forge 添加了额外的配料类型,使配方输入能够检查标签数据,或将多个配料组合为一个输入检查器。
原文:Recipes。