====== Создание пользовательского типа рецепта ====== На этой странице мы создадим наш собственный пользовательский тип рецепта, включая бесформенную версию! Мы не будем использовать какие-либо классы ванильного Майнкрафта, это будет полностью пользовательский тип рецепта. Вы можете найти и узнать, как приготовить другие типы рецептов. [[ru:tutorial:cooking_recipe_type|Создание рецепта приготовления]] ===== Добавление блока ===== Нам нужно будет создать блок, чтобы открыть графический интерфейс рецепта. Некоторые из классов будут созданы позже. 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. public class ExampleCustomRecipeMod implements ModInitializer { public static final TestRecipeBlock TEST_RECIPE_BLOCK = new TestRecipeBlock(FabricBlockSettings.of(Material.METAL)); @Override public void onInitialize() { // Возобновление позже... } } ===== Создание класса рецептов ===== Теперь мы займемся самой интересной частью этой страницы - созданием класса рецептов. ==== Создание класса рецептов в форме ==== Рецепты в форме - это тип рецепта, для которого требуется, чтобы элемент находился в определенном слоте или шаблоне. В основном он используется в рецептах сетки, таких как рецепт крафта. Интерфейс рецепта ожидает класс инвентаря в качестве параметра типа. Любой инвентарь, содержащий ингредиенты для рецепта, будет работать. Но мы будем использовать CraftingInventory. public class TestRecipe implements Recipe { //Вы можете добавить сюда столько входных данных, сколько захотите. //Важно всегда использовать 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. public class TestRecipe implements Recipe { //[...] @Override public ItemStack craft(CraftingInventory inv) { return this.getOutput().copy(); } @Override public boolean fits(int width, int height) { return true; } } В ''matches'' нам нужно указать, удовлетворяет ли данный инвентарь входным данным рецепта. Мы вернем значение true, если первый и второй слоты совпадут с первым и вторым входными данными. public class TestRecipe implements Recipe { //[...] @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. public class TestRecipe implements Recipe { //[...] public static class Type implements RecipeType { private Type() {} public static final Type INSTANCE = new Type(); public static final String ID = "test_recipe"; } @Override pubilc RecipeType getType() { return Type.INSTANCE; } } Чего все ещё не хватает, так это RecipeSerializer, а пока попробуйте разобраться в этом, используя ссылку на ИСТОЧНИК ниже. ИСТОЧНИК: [[https://github.com/natanfudge/fabric-docs/blob/master/newdocs/Modding-Tutorials/Crafting-Recipes/defining-custom-crafting-recipes.md|Определение Пользовательских Рецептов Крафта (англ.)]]