Table of Contents

Динамическая генерация рецептов

Динамически добавляемые рецепты - это рецепты, добавляемые с помощью кода вместо файлов .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": [
        //  "###",
        //  " | ",
        //  " | "
        //]
 
        //Далее нам нужно определить, каковы ключи в шаблоне. Для этого нам нужны разные JsonObjects для каждого определения ключа и один основной JsonObject, который будет содержать все определенные ключи.
        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);
        //Это создаст:
        //"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"), //Независимо от того, является ли предоставленный нами ввод тегом или предметом.
                    Lists.newArrayList(
                        "###",
                        " | ",
                        " | "
                    ), //Шаблон создания.
                    new Identifier("examplemod:copper_pickaxe") //Результат крафта
                );
            }
        }
 
        //Функция, которую мы создали ранее.
        public static JsonObject createShapedRecipeJson(...) {
            [...]
        }
 
    }

Миксин RecipeManager

Наконец, нам нужно сделать миксин в RecipeManager, чтобы мы могли передать рецепт в 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);
            }
        }
 
    }