zh_cn:tutorial:recipe_type
Table of Contents
创建自定义的合成配方类型
在此界面,我们将创建我们自己的合成配方,包括无序合成的版本! 我们将不使用任何原版的类型,创建一个完全自定义的合成配方类型!
你也可以尝试制作其他的配方类型。 添加烹饪配方类型
添加合成方块
我们先要创建一个能打开合成界面的方块,关于合成的其他类型之后再说。
- TestRecipeBlock.java
public class TestRecipeBlock extends Block { private static final Text TITLE = new TranslatableText("container.test_crafting"); public TestRecipeBlock(Settings settings) { super(settings); } @Override public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) { if(world.isClient) { return ActionResult.SUCCESS; } else { player.openHandledScreen(state.createScreenHandlerFactory(world, pos)); player.incrementStat(Stats.INTERACT_WITH_CRAFTING_TABLE); return ActionResult.CONSUME; } } @Override public NamedScreenHandlerFactory createScreenHandlerFactory(BlockState state, World world, BlockPos pos) { return new SimpleNamedScreenHandlerFactory((i, playerInventory, playerEntity) -> { return new TestCraftingScreenHandler(i, playerInventory, ScreenHandlerContext.create(world, pos)); }, TITLE); } }
现在我们得注册这个方块(Block)和其对应的在物品栏显示的物品(BlockItem)。
- ExampleCustomRecipeMod.java
public class ExampleCustomRecipeMod implements ModInitializer { public static final TestRecipeBlock TEST_RECIPE_BLOCK = new TestRecipeBlock(FabricBlockSettings.of(Material.METAL)); @Override public void onInitialize() { // Resuming later... } }
创建配方类型
现在我们要做的是该文档最有意思的部分,即创建配方类型。
创建有序合成配方类型
有序合成配方是配方类型中的一种,其要求合成原料被放置在特定的物品槽中,常被使用于合成原料需要以一定方式放置的合成配方中。
Recipe 接口需要一个 Inventory 类作为类型参数。任何能放置合成原料的物品栏都是可行的。这里我们将使用 CraftingInventory。
- TestRecipe.java
public class TestRecipe implements Recipe<CraftingInventory> { //你想添加多少个原料(input)都是可以的 //总是使用 Ingredient 类是重要的,因为这样你可以支持具有 nbt 标签的物品。 private final Ingredient inputA; private final Ingredient inputB; private final ItemStack result; private final Identifier id; public TestRecipe(Identifier id, ItemStack result, Ingredient inputA, Ingredient inputB) { this.id = id; this.inputA = inputA; this.inputB = inputB; this.result = result; } public Ingredient getInputA() { return this.inputA; } public Ingredient getInputB() { return this.inputB; } @Override public ItemStack getOutput() { return this.result; } @Override public Identifier getId() { return this.id; } //[...] }
之后,我们需要关注合成时运行的代码,返回正确的合成结果。其中,我们应该使用 this.getOutput().copy()
(来避免浅拷贝的问题),并且 fits
方法应该返回 true。
- TestRecipe.java
public class TestRecipe implements Recipe<CraftingInventory> { //[...] @Override public ItemStack craft(CraftingInventory inv) { return this.getOutput().copy(); } @Override public boolean fits(int width, int height) { return true; } }
在 matches
方法中,当物品栏中的原料和配方中的排列顺序和物品一致时,返回 true。
- TestRecipe.java
public class TestRecipe implements Recipe<CraftingInventory> { //[...] @Override public boolean matches(CraftingInventory inv, World world) { if(inv.size(0) < 2) return false; return inputA.test(inventory.getStack(0)) && inputB.test(inventory.getStack(1)); } }
现在我们需要给予这个配方一个类型
,你所要做的是创建一个继承 RecipeType<TestRecipe> 的实例。
- TestRecipe.java
public class TestRecipe implements Recipe<CraftingInventory> { //[...] public static class Type implements RecipeType<TestRecipe> { private Type() {} public static final Type INSTANCE = new Type(); public static final String ID = "test_recipe"; } @Override pubilc RecipeType<?> getType() { return Type.INSTANCE; } }
之后还需要 RecipeSerializer ,但原作者并没有写完此部分。如果你想继续,请在下面的来源中找到此部分。
zh_cn/tutorial/recipe_type.txt · Last modified: 2023/01/12 04:41 by tao0lu