DELETEME // 本页已被 Fabric Data Generation API 教程取代,[[datagen_recipe|请参见此处]]。// ====== 动态配方生成 ====== 动态添加的配方是通过代码而非.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": [ // "###", // " | ", // " | " //] //接下来我们需要定义图案中的键。为此我们需要为每一个键的定义提供不同的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 map, ResourceManager resourceManager, Profiler profiler, CallbackInfo info) { if (ExampleMod.COPPER_PICKAXE_RECIPE != null) { map.put(new Identifier("examplemod", "copper_pickaxe"), ExampleMod.COPPER_PICKAXE_RECIPE); } } }