Хранение предметов в блоке как в инвентаре
Убедитесь что вы прочли Создание сущности блока(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