Table of Contents

DELETEME 本页已被 Fabric Data Generation API 教程取代,请参见此处

动态配方生成

动态添加的配方是通过代码而非.json文件添加的配方,可以用于,在特定模组与你的模组一同安装的情况下改变配方,或者使用其他模组的标签改变配方,

首先,我们需要有能够为我们的自定义配方创建json对象的函数。

    public static JsonObject createShapedRecipeJson(ArrayList<Character> keys, ArrayList<Identifier> items, ArrayList<String> type, ArrayList<String> pattern, Identifier output) {
        //创建新的json对象,我们在其中保存配方。
        JsonObject json = new JsonObject();
        //我们创建的配方的“类型”,此例子中为有序配方。
        json.addProperty("type", "minecraft:crafting_shaped");
        //这会创建:
        //"type": "minecraft:crafting_shaped"
 
        //创建新的json元素,并在其中添加我们的合成配方。
        JsonArray jsonArray = new JsonArray();
        jsonArray.add(pattern.get(0));
        jsonArray.add(pattern.get(1));
        jsonArray.add(pattern.get(2));
        //为我们的json对象添加图案。
        json.add("pattern", jsonArray);
        //这会创建:
        //"pattern": [
        //  "###",
        //  " | ",
        //  " | "
        //]
 
        //接下来我们需要定义图案中的键。为此我们需要为每一个键的定义提供不同的json对象,以及一个包含所有已定义的键的主要的json对象。
        JsonObject individualKey; //独立的键
        JsonObject keyList = new JsonObject(); //主要的键对象,包含所有的键
 
        for (int i = 0; i < keys.size(); ++i) {
            individualKey = new JsonObject();
            individualKey.addProperty(type.get(i), items.get(i).toString()); //这会以 "type":"input"的形式创建键,其中type是"item"或者"tag",input是输入的物品。
            keyList.add(keys.get(i) + "", individualKey); //然后将这个键添加到主要的键对象。
            //这会添加:
            //"#": { "tag": "c:copper_ingots" }
            //然后添加:
            //"|": { "item": "minecraft:sticks" }
            //等等。
        }
 
        json.add("key", keyList);
        //我们还会得到:
        //"key": {
        //  "#": {
        //    "tag": "c:copper_ingots"
        //  },
        //  "|": {
        //    "item": "minecraft:stick"
        //  }
        //},
 
        //最后,定义我们的结果对象
        JsonObject result = new JsonObject();
        result.addProperty("item", output.toString());
        result.addProperty("count", 1);
        json.add("result", result);
        //This creates:
        //"result": {
        //  "item": "modid:copper_pickaxe",
        //  "count": 1
        //}
 
        return json;
    }

主要的模组文件

首先,我们需要检查特定的模组是否已经加载。为此,我们使用

    FabricLoader.getInstance().isModLoaded("custom_mod");

其中“custom_mod”是我们需要检查的模组。如果模组已加载,则创建我们的配方。

    public class ExampleMod implements ModInitializer {
 
        public static JsonObject COPPER_PICKAXE_RECIPE = null;
 
        @Override
        public void onInitialize() {
            if (FabricLoader.getInstance().isModLoaded("custom_mod")) {
                COPPER_PICKAXE_RECIPE = createShapedRecipeJson(
                    Lists.newArrayList(
                        '#',
                        '|'
                    ), //我们用于输入物品/标签的键。
                    Lists.newArrayList(new Identifier("c", "copper_ingots"), new Identifier("stick")), //我们用于输入的物品/标签。
                    Lists.newArrayList("tag", "item"), //Whether the input we provided is a tag or an item.
                    Lists.newArrayList(
                        "###",
                        " | ",
                        " | "
                    ), //合成图案。
                    new Identifier("examplemod:copper_pickaxe") //合成输出
                );
            }
        }
 
        //The function we previously made.
        public static JsonObject createShapedRecipeJson(...) {
            [...]
        }
 
    }

RecipeManager Mixin

最终,我们需要往 RecipeManager mixin,所以将配方传递到 Minecraft。

    @Mixin(RecipeManager.class)
    public class RecipeManagerMixin {
 
        @Inject(method = "apply", at = @At("HEAD"))
        public void interceptApply(Map<Identifier, JsonElement> map, ResourceManager resourceManager, Profiler profiler, CallbackInfo info) {
            if (ExampleMod.COPPER_PICKAXE_RECIPE != null) {
                map.put(new Identifier("examplemod", "copper_pickaxe"), ExampleMod.COPPER_PICKAXE_RECIPE);
            }
        }
 
    }