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() { // Возобновление позже... } }
Создание класса рецептов
Теперь мы займемся самой интересной частью этой страницы - созданием класса рецептов.
Создание класса рецептов в форме
Рецепты в форме - это тип рецепта, для которого требуется, чтобы элемент находился в определенном слоте или шаблоне. В основном он используется в рецептах сетки, таких как рецепт крафта.
Интерфейс рецепта ожидает класс инвентаря в качестве параметра типа. Любой инвентарь, содержащий ингредиенты для рецепта, будет работать. Но мы будем использовать CraftingInventory.
- TestRecipe.java
public class TestRecipe implements Recipe<CraftingInventory> { //Вы можете добавить сюда столько входных данных, сколько захотите. //Важно всегда использовать Ingredient, чтобы вы могли поддерживать теги. 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)); } }
Теперь нам нужен Type
Все, что вам нужно сделать, это создать экземпляр класса, который расширяет 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, а пока попробуйте разобраться в этом, используя ссылку на ИСТОЧНИК ниже.
ИСТОЧНИК: Определение Пользовательских Рецептов Крафта (англ.)