====== Динамическая генерация рецептов ======
Динамически добавляемые рецепты - это рецепты, добавляемые с помощью кода вместо файлов .json. Это можно использовать, например, для изменения рецепта, если определенный мод установлен вместе с вашим модом, или для изменения рецепта, чтобы использовать теги из другого мода.
Для начала мы хотим иметь какую-то функцию, которая создаст объект Json для нашего пользовательского рецепта:
public static JsonObject createShapedRecipeJson(ArrayList keys, ArrayList items, ArrayList type, ArrayList 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 map, ResourceManager resourceManager, Profiler profiler, CallbackInfo info) {
if (ExampleMod.COPPER_PICKAXE_RECIPE != null) {
map.put(new Identifier("examplemod", "copper_pickaxe"), ExampleMod.COPPER_PICKAXE_RECIPE);
}
}
}