Minecraft 1.12.2 Mod开发笔记——新的合成表、烧炼规则和燃料

总目录:Minecraft 1.12.2 开发笔记

新的合成表

在这之前,合成表使用 GameRegistry.addShapedRecipe() 创建,但从 1.12 开始,Minecraft 使用 json 文件创建合成表。Forge 会自动加载在 resources/assets/mymod/recipes/ 下的 json 合成表文件。现在我们来给之前的 Cross Block 创建合成表。

有序合成表

新建目录 resources/assets/mymod/recipes/,新建文件 cross_block.json,文件名无所谓,使用对应产物的名字比较方便。里面写入:

{
    "type": "minecraft:crafting_shaped",
    "group": "mymod:cross",
    "pattern": [
        "A B",
        " C ",
        "B A"
    ],
    "key": {
        "A": {"item": "minecraft:redstone"},
        "B": {"item": "minecraft:sugar"},
        "C": {"item": "minecraft:dirt","data": 0}
    },
    "result": {"item": "mymod:cross_block","count": 1}
}
  • type 分为有序合成 minecraft:crafting_shaped 和无序合成 minecraft:crafting_shapeless

  • group 合成分组,比如各种颜色的床属于同一组,它们的合成表会合并在一起,可省略

  • pattern 有序合成时的材料顺序,排成两行或三行,用空格表示空,随便一种字母/符号表示一种材料

  • key 规定 pattern 中自定义字母代表的材料,如果限定 meta 信息,需要使用 data 键。例如,原版的各种台阶是一个方块的不同 meta 信息的结果,设置了 data 键后,只有特定的台阶才能参与这个合成,否则任何台阶均可参与合成。

  • 如果有替代材料,使用列表形式,如:

    "key": {
        "A": [{"item": "minecraft:redstone"},
              {"item": "minecraft:sugar"}]
    }
    
  • result 产物,但有 meta 信息的产物 data 键是必须的

  • count 产物数量,默认为1,可省略

无序合成表

我们再给铁板添加无序合成表:

新建文件 iron_plate.json,写入:

{
    "type": "minecraft:crafting_shapeless",
    "result": { "item": "mymod:iron_plate", "count": 18 },
    "ingredients": [
        { "item": "minecraft:iron_block" },
        { "item": "minecraft:iron_block" }
    ]
}
  • ingredients 用于无序合成的原料设置
  • 其他比如 result/type/group/count 同上

新的烧炼规则

Forge 并没有统一的把各种 recipe 整合到一起,烧炼规则仍然使用 GameRegistry 来添加。在 common 包中新建 Recipes.java,统一管理烧炼和燃料:

public class Recipes {
    public Recipes(){
        GameRegistry.addSmelting(BlockLoader.cross, new ItemStack(Items.IRON_AXE), 0.5F);
    }
}

这里我们设置了一个奇怪的规则:Cross Block 燃烧生成铁斧。

CommonPorxy.java 的 init() 中添加:

new Recipes();

GameRegistry.addSmelting(input, output, exp)

新的燃料

之前,燃料需要使用 FurnaceRecipes 类管理,不过现在,Forge 将燃料问题整合成了一个事件,修改 Recipes.java 为:

@Mod.EventBusSubscriber
public class Recipes {
    public Recipes(){
        GameRegistry.addSmelting(BlockLoader.cross, new ItemStack(Items.IRON_AXE), 0.5F);
    }
    @SubscribeEvent
    public static void getVanillaFurnaceFuelValue(FurnaceFuelBurnTimeEvent event) {
        if(event.getItemStack().getItem() == Item.getItemFromBlock(BlockLoader.cross)){
            event.setBurnTime(200);
        }
    }
}
  • 当有物品尝试放进燃料槽时触发这个事件
  • event.getItemStack().getItem() 放进去的物品,物品可以直接使用 instanceof 判断物品种类,方块可以用 Item.getItemFromBlock() 来判断
  • event.setBurnTime() 用于设置燃烧时间,设置0表示不是燃料,设置为-1表示根据原版内容判断(默认)
  • 经查看源码发现,Minecraft 设定的值中,原版的煤是16000,烧8个物品,也就是说烧1个物品为200,这样就可以根据需要进行设置了。
  • 当然也提供了 event.getBurnTime() 获取当前设置的燃烧时间
  • 原版的燃料燃烧时间参照 net/minecraft/tileentity/TileEntityFurnace.java 的 getItemBurnTime() (353行)
posted @ 2020-02-17 10:41  0.0~~  阅读(6036)  评论(0编辑  收藏  举报