Проблемы с рецептом

Версия Minecraft
1.16.5
API
Forge
84
5
6
Всем привет

проблема в рецептах
JEI их загружает
2022-09-24_19.44.04.png

А если попытаться скрафтить, то нечего не происходит
2022-09-24_19.44.07.png

WoodcuttingContainer
WoodcutterContainer:
public class WoodcutterContainer extends Container {
 private final IWorldPosCallable worldPosCallable;
    private final IntReferenceHolder selectedRecipe = IntReferenceHolder.single();
    private final World world;
    private List<WoodcuttingRecipe> recipes = Lists.newArrayList();
    private ItemStack itemStackInput = ItemStack.EMPTY;
    private long lastOnTake;
    final Slot inputInventorySlot;
    final Slot outputInventorySlot;
    private Runnable inventoryUpdateListener = () -> {};
    public final IInventory inputInventory = new Inventory(1) {

        @Override
        public void markDirty() {
            super.markDirty();
            WoodcutterContainer.this.onCraftMatrixChanged(this);
            WoodcutterContainer.this.inventoryUpdateListener.run();
        }
    };
    private final CraftResultInventory inventory = new CraftResultInventory();

    public WoodcutterContainer(int windowIdIn, PlayerInventory playerInventoryIn) {
        this(windowIdIn, playerInventoryIn, IWorldPosCallable.DUMMY);
    }

    public WoodcutterContainer(int windowIdIn, PlayerInventory playerInventoryIn, final IWorldPosCallable worldPosCallableIn) {
        super(UEContainers.WOODCUTTER, windowIdIn);
        this.worldPosCallable = worldPosCallableIn;
        this.world = playerInventoryIn.player.world;
        this.inputInventorySlot = this.addSlot(new Slot(this.inputInventory, 0, 20, 33));
        this.outputInventorySlot = this.addSlot(new Slot(this.inventory, 1, 143, 33) {

            @Override
            public boolean isItemValid(ItemStack stack) {
                return false;
            }

            public ItemStack onTake(PlayerEntity thePlayer, ItemStack stack) {
                stack.onCrafting(thePlayer.world, thePlayer, stack.getCount());
                WoodcutterContainer.this.inventory.onCrafting(thePlayer);
                ItemStack itemstack = WoodcutterContainer.this.inputInventorySlot.decrStackSize(1);
                if (!itemstack.isEmpty()) {
                    WoodcutterContainer.this.updateRecipeResultSlot();
                }

                worldPosCallableIn.consume((p_216954_1_, p_216954_2_) -> {
                    long l = p_216954_1_.getGameTime();
                    if (WoodcutterContainer.this.lastOnTake != l) {
                        p_216954_1_.playSound((PlayerEntity)null, p_216954_2_, SoundEvents.UI_STONECUTTER_TAKE_RESULT, SoundCategory.BLOCKS, 1.0F, 1.0F);
                        WoodcutterContainer.this.lastOnTake = l;
                    }

                });
                return super.onTake(thePlayer, stack);
            }
        });

        for(int i = 0; i < 3; ++i) {
            for(int j = 0; j < 9; ++j) {
                this.addSlot(new Slot(playerInventoryIn, j + i * 9 + 9, 8 + j * 18, 84 + i * 18));
            }
        }

        for(int k = 0; k < 9; ++k) {
            this.addSlot(new Slot(playerInventoryIn, k, 8 + k * 18, 142));
        }

        this.trackInt(this.selectedRecipe);
    }


    @OnlyIn(Dist.CLIENT)
    public int getSelectedRecipe() {
        return this.selectedRecipe.get();
    }

    @OnlyIn(Dist.CLIENT)
    public List<WoodcuttingRecipe> getRecipeList() {
        return this.recipes;
    }

    @OnlyIn(Dist.CLIENT)
    public int getRecipeListSize() {
        return this.recipes.size();
    }

    @OnlyIn(Dist.CLIENT)
    public boolean hasItemsinInputSlot() {
        return this.inputInventorySlot.getHasStack() && !this.recipes.isEmpty();
    }

    @Override
    public boolean canInteractWith(PlayerEntity playerIn) {
        return isWithinUsableDistance(this.worldPosCallable, playerIn, UEBlocks.LUMBERJACK_TABLE.get());
    }

    @Override
    public boolean enchantItem(PlayerEntity playerIn, int id) {
        if (this.func_241818_d_(id)) {
            this.selectedRecipe.set(id);
            this.updateRecipeResultSlot();
        }

        return true;
    }

    private boolean func_241818_d_(int p_241818_1_) {
        return p_241818_1_ >= 0 && p_241818_1_ < this.recipes.size();
    }

    @Override
    public void onCraftMatrixChanged(IInventory inventoryIn) {
        ItemStack itemstack = this.inputInventorySlot.getStack();
        if (itemstack.getItem() != this.itemStackInput.getItem()) {
            this.itemStackInput = itemstack.copy();
            this.updateAvailableRecipes(inventoryIn, itemstack);
        }

    }

    private void updateAvailableRecipes(IInventory inventoryIn, ItemStack stack) {
        this.recipes.clear();
        this.selectedRecipe.set(-1);
        this.outputInventorySlot.putStack(ItemStack.EMPTY);
        if (!stack.isEmpty()) {
            this.recipes = this.world.getRecipeManager().getRecipes(UERecipes.WOODCUTTING_RECIPE_TYPE, inventoryIn, this.world);
        }

    }

    private void updateRecipeResultSlot() {
        if (!this.recipes.isEmpty() && this.func_241818_d_(this.selectedRecipe.get())) {
            WoodcuttingRecipe woodcuttingRecipe = this.recipes.get(this.selectedRecipe.get());
            this.inventory.setRecipeUsed(woodcuttingRecipe);
            this.outputInventorySlot.putStack(woodcuttingRecipe.getCraftingResult(this.inputInventory));
        } else {
            this.outputInventorySlot.putStack(ItemStack.EMPTY);
        }

        this.detectAndSendChanges();
    }

    public ContainerType<?> getType() {
        return UEContainers.WOODCUTTER;
    }

    @OnlyIn(Dist.CLIENT)
    public void setInventoryUpdateListener(Runnable listenerIn) {
        this.inventoryUpdateListener = listenerIn;
    }

   @Override
    public boolean canMergeSlot(ItemStack stack, Slot slotIn) {
        return slotIn.inventory != this.inventory && super.canMergeSlot(stack, slotIn);
    }

    @Override
    public ItemStack transferStackInSlot(PlayerEntity playerIn, int index) {
        ItemStack itemstack = ItemStack.EMPTY;
        Slot slot = this.inventorySlots.get(index);
        if (slot != null && slot.getHasStack()) {
            ItemStack itemstack1 = slot.getStack();
            Item item = itemstack1.getItem();
            itemstack = itemstack1.copy();
            if (index == 1) {
                item.onCreated(itemstack1, playerIn.world, playerIn);
                if (!this.mergeItemStack(itemstack1, 2, 38, true)) {
                    return ItemStack.EMPTY;
                }

                slot.onSlotChange(itemstack1, itemstack);
            } else if (index == 0) {
                if (!this.mergeItemStack(itemstack1, 2, 38, false)) {
                    return ItemStack.EMPTY;
                }
            } else if (this.world.getRecipeManager().getRecipe(UERecipes.WOODCUTTING_RECIPE_TYPE, new Inventory(itemstack1), this.world).isPresent()) {
                if (!this.mergeItemStack(itemstack1, 0, 1, false)) {
                    return ItemStack.EMPTY;
                }
            } else if (index < 29) {
                if (!this.mergeItemStack(itemstack1, 29, 38, false)) {
                    return ItemStack.EMPTY;
                }
            } else if (index < 38 && !this.mergeItemStack(itemstack1, 2, 29, false)) {
                return ItemStack.EMPTY;
            }

            if (itemstack1.isEmpty()) {
                slot.putStack(ItemStack.EMPTY);
            }

            slot.onSlotChanged();
            if (itemstack1.getCount() == itemstack.getCount()) {
                return ItemStack.EMPTY;
            }

            slot.onTake(playerIn, itemstack1);
            this.detectAndSendChanges();
        }

        return itemstack;
    }

    @Override
    public void onContainerClosed(PlayerEntity playerIn) {
        super.onContainerClosed(playerIn);
        this.inventory.removeStackFromSlot(1);
        this.worldPosCallable.consume((p_217079_2_, p_217079_3_) -> {
            this.clearContainer(playerIn, playerIn.world, this.inputInventory);
        });
    }
Screen
WoodcutterScreen:
@ParametersAreNonnullByDefault
@OnlyIn(Dist.CLIENT)
public class WoodcutterScreen extends ContainerScreen<WoodcutterContainer>{

    private static final ResourceLocation BACKGROUND_TEXTURE = new ResourceLocation(ue.MODID, "textures/gui/container/woodcutter.png");

        private float sliderProgress;
        private boolean clickedOnSroll;
        private int recipeIndexOffset;
        private boolean hasItemsInInputSlot;

        public WoodcutterScreen(WoodcutterContainer screenContainer, PlayerInventory playerInventory, ITextComponent title) {
            super(screenContainer, playerInventory, title);
            screenContainer.setInventoryUpdateListener(this::onInventoryUpdate);
            --this.titleY;
        }

        @Override
        public void render(MatrixStack stack, int mouseX, int mouseY, float partialTicks) {
            super.render(stack, mouseX, mouseY, partialTicks);
            this.renderHoveredTooltip(stack, mouseX, mouseY);
        }

        @Deprecated
        protected void drawGuiContainerBackgroundLayer(MatrixStack stack, float p_230450_2_, int p_230450_3_, int p_230450_4_) {
            this.renderBackground(stack);
            RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
            this.minecraft.getTextureManager().bindTexture(BACKGROUND_TEXTURE);
            int i = this.guiLeft;
            int j = this.guiTop;
            this.blit(stack, i, j, 0, 0, this.xSize, this.ySize);
            int k = (int) (41.0F * this.sliderProgress);
            this.blit(stack, i + 119, j + 15 + k, 176 + (this.canScroll() ? 0 : 12), 0, 12, 15);
            int l = this.guiLeft + 52;
            int i1 = this.guiTop + 14;
            int j1 = this.recipeIndexOffset + 12;
            this.renderButtons(stack, p_230450_3_, p_230450_4_, l, i1, j1);
            this.drawRecipesItems(l, i1, j1);
        }

        @Override
        protected void renderHoveredTooltip(MatrixStack stack, int mouseX, int mouseY) {
            super.renderHoveredTooltip(stack, mouseX, mouseY);
            if (this.hasItemsInInputSlot) {
                int i = this.guiLeft + 52;
                int j = this.guiTop + 14;
                int k = this.recipeIndexOffset + 12;
                List<WoodcuttingRecipe> list = this.container.getRecipeList();

                for (int l = this.recipeIndexOffset; l < k && l < this.container.getRecipeListSize(); ++l) {
                    int i1 = l - this.recipeIndexOffset;
                    int j1 = i + i1 % 4 * 16;
                    int k1 = j + i1 / 4 * 18 + 2;
                    if (mouseX >= j1 && mouseX < j1 + 16 && mouseY >= k1 && mouseY < k1 + 18) {
                        this.renderTooltip(stack, list.get(l).getRecipeOutput(), mouseX, mouseY);
                    }
                }
            }

        }

        private void renderButtons(MatrixStack p_238853_1_, int p_238853_2_, int p_238853_3_, int p_238853_4_, int p_238853_5_, int p_238853_6_) {
            for (int i = this.recipeIndexOffset; i < p_238853_6_ && i < this.container.getRecipeListSize(); ++i) {
                int j = i - this.recipeIndexOffset;
                int k = p_238853_4_ + j % 4 * 16;
                int l = j / 4;
                int i1 = p_238853_5_ + l * 18 + 2;
                int j1 = this.ySize;
                if (i == this.container.getSelectedRecipe()) {
                    j1 += 18;
                } else if (p_238853_2_ >= k && p_238853_3_ >= i1 && p_238853_2_ < k + 16 && p_238853_3_ < i1 + 18) {
                    j1 += 36;
                }

                this.blit(p_238853_1_, k, i1 - 1, 0, j1, 16, 18);
            }

        }

        private void drawRecipesItems(int left, int top, int recipeIndexOffsetMax) {
            List<WoodcuttingRecipe> list = this.container.getRecipeList();

            for (int i = this.recipeIndexOffset; i < recipeIndexOffsetMax && i < this.container.getRecipeListSize(); ++i) {
                int j = i - this.recipeIndexOffset;
                int k = left + j % 4 * 16;
                int l = j / 4;
                int i1 = top + l * 18 + 2;
                this.minecraft.getItemRenderer().renderItemAndEffectIntoGUI(list.get(i).getRecipeOutput(), k, i1);
            }

        }

        @Override
        public boolean mouseClicked(double p_231044_1_, double p_231044_3_, int p_231044_5_) {
            this.clickedOnSroll = false;
            if (this.hasItemsInInputSlot) {
                int i = this.guiLeft + 52;
                int j = this.guiTop + 14;
                int k = this.recipeIndexOffset + 12;

                for (int l = this.recipeIndexOffset; l < k; ++l) {
                    int i1 = l - this.recipeIndexOffset;
                    double d0 = p_231044_1_ - (double) (i + i1 % 4 * 16);
                    double d1 = p_231044_3_ - (double) (j + i1 / 4 * 18);
                    if (d0 >= 0.0D && d1 >= 0.0D && d0 < 16.0D && d1 < 18.0D && this.container.enchantItem(this.minecraft.player, l)) {
                        Minecraft.getInstance().getSoundHandler().play(SimpleSound.master(SoundEvents.UI_STONECUTTER_SELECT_RECIPE, 1.0F));
                        this.minecraft.playerController.sendEnchantPacket((this.container).windowId, l);
                        return true;
                    }
                }

                i = this.guiLeft + 119;
                j = this.guiTop + 9;
                if (p_231044_1_ >= (double) i && p_231044_1_ < (double) (i + 12) && p_231044_3_ >= (double) j && p_231044_3_ < (double) (j + 54)) {
                    this.clickedOnSroll = true;
                }
            }

            return super.mouseClicked(p_231044_1_, p_231044_3_, p_231044_5_);
        }

        @Override
        public boolean mouseDragged(double p_231045_1_, double p_231045_3_, int p_231045_5_, double p_231045_6_, double p_231045_8_) {
            if (this.clickedOnSroll && this.canScroll()) {
                int i = this.guiTop + 14;
                int j = i + 54;
                this.sliderProgress = ((float) p_231045_3_ - (float) i - 7.5F) / ((float) (j - i) - 15.0F);
                this.sliderProgress = MathHelper.clamp(this.sliderProgress, 0.0F, 1.0F);
                this.recipeIndexOffset = (int) ((double) (this.sliderProgress * (float) this.getHiddenRows()) + 0.5D) * 4;
                return true;
            } else {
                return super.mouseDragged(p_231045_1_, p_231045_3_, p_231045_5_, p_231045_6_, p_231045_8_);
            }
        }

        @Override
        public boolean mouseScrolled(double p_231043_1_, double p_231043_3_, double p_231043_5_) {
            if (this.canScroll()) {
                int i = this.getHiddenRows();
                this.sliderProgress = (float) ((double) this.sliderProgress - p_231043_5_ / (double) i);
                this.sliderProgress = MathHelper.clamp(this.sliderProgress, 0.0F, 1.0F);
                this.recipeIndexOffset = (int) ((double) (this.sliderProgress * (float) i) + 0.5D) * 4;
            }

            return true;
        }

        private boolean canScroll() {
            return this.hasItemsInInputSlot && this.container.getRecipeListSize() > 12;
        }

        protected int getHiddenRows() {
            return (this.container.getRecipeListSize() + 4 - 1) / 4 - 3;
        }

        private void onInventoryUpdate() {
            this.hasItemsInInputSlot = this.container.hasItemsinInputSlot();
            if (!this.hasItemsInInputSlot) {
                this.sliderProgress = 0.0F;
                this.recipeIndexOffset = 0;
            }

        }
}

UEContainers
UEContainers:
 public static final DeferredRegister<ContainerType<?>> CONTAINER_TYPES = DeferredRegister.create(ForgeRegistries.CONTAINERS, ue.MODID);

    public static final RegistryObject<ContainerType<WoodcutterContainer>> WOODCUTTER = CONTAINER_TYPES.register("woodcutter", () -> new ContainerType<>(WoodcutterContainer::new));


    public static void register(IEventBus eventBus) {
        CONTAINER_TYPES.register(eventBus);
    }
WoodcuttingRecipe
WoodcuttingRecipe:
public class WoodcuttingRecipe implements IRecipe<IInventory> {

    public static ResourceLocation ID = new ResourceLocation(ue.MODID, "woodcutting");

    protected final Ingredient ingredient;
    protected final ItemStack result;
    protected final ResourceLocation id;


    public WoodcuttingRecipe( ResourceLocation id,  Ingredient ingredient, ItemStack result) {

        this.id = id;

        this.ingredient = ingredient;
        this.result = result;
    }



    @Override
    public IRecipeType<?> getType() {
        return Registry.RECIPE_TYPE.getOptional(ID).get();
    }

    @Override
    public IRecipeSerializer<?> getSerializer() {
        return UERecipes.WOODCUTTING_SERIALIZER.get();
    }

    @Override
    public ResourceLocation getId() {
        return this.id;
    }


    @Override
    public ItemStack getRecipeOutput() {
        return this.result;
    }

    public NonNullList<Ingredient> getIngredients() {
        return NonNullList.withSize(1, ingredient);
    }

    @Override
    public boolean canFit(int width, int height) {
        return true;
    }

    @Override
    public boolean matches(IInventory inv, World worldIn) {
        return false;
    }

    @Override
    public ItemStack getCraftingResult(IInventory inv) {
        return this.result.copy();
    }

    public static class Serializer<T extends WoodcuttingRecipe> extends net.minecraftforge.registries.ForgeRegistryEntry<IRecipeSerializer<?>> implements IRecipeSerializer<T> {
        final WoodcuttingRecipe.Serializer.IRecipeFactory<T> factory;

        protected Serializer(WoodcuttingRecipe.Serializer.IRecipeFactory<T> factory) {
            this.factory = factory;
        }

        @Deprecated
        public T read(ResourceLocation recipeId, JsonObject json) {

            Ingredient ingredient = Ingredient.deserialize(JSONUtils.getJsonObject(json, "ingredient"));
            String s1 = JSONUtils.getString(json, "result");
            int i = JSONUtils.getInt(json, "count");
            ItemStack itemstack = new ItemStack(Registry.ITEM.getOrDefault(new ResourceLocation(s1)), i);
            return this.factory.create(recipeId,  ingredient, itemstack);
        }
        @Override
        public T read(ResourceLocation recipeId, PacketBuffer buffer) {
            Ingredient ingredient = Ingredient.read(buffer);
            ItemStack itemstack = buffer.readItemStack();
            return this.factory.create(recipeId, ingredient, itemstack);
        }
        @Override
        public void write(PacketBuffer buffer, T recipe) {
            recipe.ingredient.write(buffer);
            buffer.writeItemStack(recipe.result);
        }

        interface IRecipeFactory<T extends WoodcuttingRecipe> {
            T create(ResourceLocation rs,  Ingredient i, ItemStack st);
        }
    }

    protected static class WoodcuttingRecipeType implements IRecipeType<WoodcuttingRecipe> {

        @Override
        public String toString() {
            return ID.toString();
        }

    }

}

UERecipes
UERecipes:
public class UERecipes {

        public static  DeferredRegister<IRecipeSerializer<?>> RECIPE_SERIALIZERS = DeferredRegister.create(ForgeRegistries.RECIPE_SERIALIZERS, ue.MODID);

        public static final RegistryObject<IRecipeSerializer<WoodcuttingRecipe>> WOODCUTTING_SERIALIZER = RECIPE_SERIALIZERS.register("woodcutting", () -> new WoodcuttingRecipe.Serializer(WoodcuttingRecipe::new){

            });




        public static final IRecipeType<WoodcuttingRecipe> WOODCUTTING_RECIPE_TYPE = new WoodcuttingRecipe.WoodcuttingRecipeType();


    public static void register(IEventBus bus) {
        RECIPE_SERIALIZERS.register(bus);
        Registry.register(Registry.RECIPE_TYPE, WoodcuttingRecipe.ID, WOODCUTTING_RECIPE_TYPE);
    }

}
Конструктор главного класса
ue:
public ue() {
       final IEventBus eventBus = FMLJavaModLoadingContext.get().getModEventBus();

     
        UEBlocks.register(eventBus);
        UEItems.register(eventBus);
     
        UERecipes.register(eventBus);
        UEContainers.register(eventBus);
      


        MinecraftForge.EVENT_BUS.register(this);


    }

Класс Блока(WoodcutterBlock)
WoodcutterBlock:
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
public class WoodcutterBlock extends Block {
    private static final ITextComponent CONTAINER_NAME = new TranslationTextComponent("container.woodcutter");
    public static final DirectionProperty DIRECTION = HorizontalBlock.HORIZONTAL_FACING;
    protected static final VoxelShape SHAPE = Block.makeCuboidShape(0.0D, 0.0D, 0.0D, 16.0D, 8.0D, 16.0D);


    public WoodcutterBlock(AbstractBlock.Properties propertiesIn) {
        super(propertiesIn);
        this.setDefaultState(this.stateContainer.getBaseState().with(DIRECTION, Direction.NORTH));
    }


    @Override
    public BlockState getStateForPlacement(BlockItemUseContext context) {
        return this.getDefaultState().with(DIRECTION, context.getPlacementHorizontalFacing().getOpposite());
    }

    @Override
    public ActionResultType onBlockActivated(BlockState state, World world, BlockPos pos, PlayerEntity playerEntity, Hand hand, BlockRayTraceResult result) {
        if (!world.isRemote) {
            playerEntity.openContainer(state.getContainer(world, pos));
        }
        return ActionResultType.SUCCESS;
    }

    @Nullable
    @Override
    public INamedContainerProvider getContainer(BlockState state, World world, BlockPos pos) {
        return new SimpleNamedContainerProvider((windowId, playerInventory, playerEntity) -> new WoodcutterContainer(windowId, playerInventory, IWorldPosCallable.of(world, pos)), CONTAINER_NAME);
    }

    @Override
    public VoxelShape getShape(BlockState state, IBlockReader reader, BlockPos pos, ISelectionContext context) {
        return SHAPE;
    }

    @Override
    public boolean isTransparent(BlockState state) {
        return true;
    }

    @Override
    public BlockRenderType getRenderType(BlockState state) {
        return BlockRenderType.MODEL;
    }

    @Override
    public BlockState rotate(BlockState state, Rotation rotation) {
        return state.with(DIRECTION, rotation.rotate(state.get(DIRECTION)));
    }

    @Deprecated
    public BlockState mirror(BlockState state, Mirror mirror) {
        return state.rotate(mirror.toRotation(state.get(DIRECTION)));
    }

    @Override
    protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder) {
        builder.add(DIRECTION);
    }

    @Override
    public boolean allowsMovement(BlockState state, IBlockReader reader, BlockPos pos, PathType pathType) {
        return false;
    }
}

помогите пж
 
Последнее редактирование:
1,200
37
237
Мне кажется, у тебя проблема в контейнере. Ты точно правильно скопировал и переделал код камнереза (мне кажется ты именно так сделал этот крафтер)? Ибо я, например, не понимаю зачем нужны пустой Runnable inventoryUpdateListener и функция func_241818_d_ в контейнере.
 
1,369
112
241
приколы на которые я указал
Такое в ванилльном камнерезе. А метод, на который ты так жалуешься, просто проверяет чтобы выбранный рецепт был в пределах доступных рецептов.
Почему чувак не хочет просто переписать это всё дело с толком и расстановкой - вопрос открытый.
 
1,200
37
237
Я к тому и спрашиваю, мол все скопировал и не разобрался, а метод тот может перелпределять надо для этого случая, его же нет тут. Вот из твоих слов я могу сделать вывод, что он все и портит, думая, что ему кормят рецепты древореза, а реализация для камнереза.
 
1,369
112
241
что он все и портит
Он ничего не портит. Смотри сам что делает метод, прежде чем делать такие выводы.
А по поводу копирования соглашусь, слишком уж сильно налегать на такое не стоит.
 
Сверху