Хранение предметов в блоке как в инвентаре

Убедитесь что вы прочли Создание сущности блока(BlockEntity) перед прочтением этого материала.

Обычный способ для хранения вещей в BlockEntity это создать в нём Inventory. Это позволяет воронкам (или другим модам) вставлять и вынимать предметы в BlockEntity без каких либо дополнительных задач.

Реализация интерфейса Inventory

Inventory это интерфейс, который указывает что состояние ItemStack должно быть сохранено в вашем BlockEntity. DefaultedList<ItemStack> может быть использован чтобы легко сохранить ваши ItemStacks, он может быть установлен по умолчанию ItemStack.Empty, и это будет правильным способом указать что в слоте нет элемента. Реализация Inventory довольно проста, однако подвержена ошибкам, поэтому мы будем использовать его реализацию по умолчанию, которая требует только представления DefaultList<ItemStack> (скопируйте это как новый файл):

ImplementedInventory.java
/**
 * Простая реализация {@code Inventory} только со стандартными методами + получателем списка itemов.
 *
 * Originally by Juuz
 */
public interface ImplementedInventory extends Inventory {
 
    /**
     * Получает список предметов этого инвентаря.
     * Должен возвращать один и тот же экземпляр каждый раз, когда он вызывается.
     */
    DefaultedList<ItemStack> getItems();
 
    /**
     * Создаёт инвентарь из этого списка.
     */
    static ImplementedInventory of(DefaultedList<ItemStack> items) {
        return () -> items;
    }
 
    /**
     * Создаёт новый инвентарь с определённым размером
     */
    static ImplementedInventory ofSize(int size) {
        return of(DefaultedList.ofSize(size, ItemStack.EMPTY));
    }
 
    /**
     * Возвращает размер инвентаря
     */
    @Override
    default int size() {
        return getItems().size();
    }
 
    /**
     * Проверяет, пуст ли инвентарь.
     * @возвращает true если этот инвентарь содержит только empty stacks, во всех остальных случаях false.
     */
    @Override
    default boolean isEmpty() {
        for (int i = 0; i < size(); i++) {
            ItemStack stack = getStack(i);
            if (!stack.isEmpty()) {
                return false;
            }
        }
        return true;
    }
 
    /**
     * Получает предмет из слота.
     */
    @Override
    default ItemStack getStack(int slot) {
        return getItems().get(slot);
    }
 
    /**
     * Удаляет предметы из слота
     * @param slot  Из какого слота удалить.
     * @param count Сколько предметов удалить. Если элементов меньше, чем count, то удаляет все.
     */
    @Override
    default ItemStack removeStack(int slot, int count) {
        ItemStack result = Inventories.splitStack(getItems(), slot, count);
        if (!result.isEmpty()) {
            markDirty();
        }
        return result;
    }
 
    /**
     * Удалить все предметы из слота
     * @param slot Из какого слота удалить.
     */
    @Override
    default ItemStack removeStack(int slot) {
        return Inventories.removeStack(getItems(), slot);
    }
 
    /**
     * Заменяет stack в слоте другим.
     * @param slot  Какой слот нужен для замены itemstack.
     * @param stack Новый itemstack. Если stack слишком большой для этого инвентаря
     *              ({@link Inventory#getMaxCountPerStack()}),
     *              Он будет изменён на максимальный для этого инвентаря.
     */
    @Override
    default void setStack(int slot, ItemStack stack) {
        getItems().set(slot, stack);
        if (stack.getCount() > stack.getMaxCount()) {
            stack.setCount(stack.getMaxCount());
        }
    }
 
    /**
     * Очистка инвентаря.
     */
    @Override
    default void clear() {
        getItems().clear();
    }
 
    /**
     * пометить состояние как dirty.
     * Вызовется после изменений в Inventory.
     */
    @Override
    default void markDirty() {
        // Override if you want behavior.
    }
 
    /**
     * @return true if the player can use the inventory, false otherwise.
     */ 
    @Override
    default boolean canPlayerUse(PlayerEntity player) {
        return true;
    }
}

Эта статья не полностью переведена, для оставшейся части контента перейдите сюда Storing items in a block as an Inventory