Несколько вопросов касательно сундука(блока хранения)

Версия Minecraft
1.12.2
2,932
44
598
Доброго времени суток Земляне и Чужие!
Сегодня столкнулся с таким вопросом:
  1. Как теперь выбрасывать в мир вещи из сломанного сундука? Вроде как, это раньше делали одним методом, просто доставали вещи из тайла, а теперь ему нужен какой-то инвентарь. Этот код просит теперь инвентарь вместо тайла:
    Java:
        @Override    public void breakBlock(World world, BlockPos pos, IBlockState blockstate) {
    InventoryHelper.dropInventoryItems(world, pos, (BoardEightOnEightContainerTileEntity)world.getTileEntity(pos));
    super.breakBlock(world, pos, blockstate);
        }
  2. На фото ниже можно увидеть что слот брони затесался в инвентаре игрока, и что расположение вещей в инвентаре изменилось: 1566976859428.png1566976881328.pngВроде как, код стандартный, не могу понять почему так происходит:
    Java:
     private void addPlayerSlots(IInventory playerInventory) { //Слоты основного инвентаря:
    for (int row = 0; row < 3; ++row) {
    for (int col = 0; col < 9; ++col) {
    int x = 8 + col * 18;
    int y = row * 18 + 174;
    this.addSlotToContainer(new Slot(playerInventory, col + row * 9 + 10, x, y));
    }
    }
    
    //Слоты хотбара:
    for(int row = 0; row < 9; ++row) {
    
    int x = 8 + row * 18;
    int y = 60 + 172;
    this.addSlotToContainer(new Slot(playerInventory, row, x, y));
    }
        }
На этом, вроде бы всё! Благодарю за внимание!
 
3,005
192
592
Сразу видно, что код скопирован из wiki McJty :)
Там у него как-бы ошибка в 1 цифре и из-за этого слоты криво добавляются.

По поводу дропа - у тебя тайл наследует IInventory ?
 
2,932
44
598
Сразу видно, что код скопирован из wiki McJty :)
Да, так и есть :) Недавно даже переводил его: Перевод - Графический интерфейс пользователя с блоком хранения
По поводу дропа - у тебя тайл наследует IInventory ?
Теперь да, спасибо огромное! ;)
 
7,099
324
1,510
Если твой блок сделан по нормальному, через капабилити, то дроп можно сделать так:
взять капабилити IItemHandler из тайла
пройтись по всем слотам, собрать стаки
дропнуть через спавн EntityItem

Т.к. это универсально для любого хранилища с капабилити, то наверное где-то в форже есть этот код, но я не видел
 
3,005
192
592
7,099
324
1,510
Если тайл расширяет IInventory. А он может просто его содержать в себе как поле. Чтобы сделать дроп из тайла с капой, не нужно знать ничего о тайле
 
2,932
44
598
На Forge форуме нашёл такое решение:
Java:
    @Override
    public void breakBlock(World world, BlockPos pos, IBlockState state)
    {
        BoardEightOnEightContainerTileEntity te = (BoardEightOnEightContainerTileEntity) world.getTileEntity(pos);
        IItemHandler cap = te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null);

        for (int i = 0; i < cap.getSlots(); ++i)
        {
            ItemStack itemstack = cap.getStackInSlot(i);

            if (!itemstack.isEmpty())
            {
                InventoryHelper.spawnItemStack(world, pos.getX(), pos.getY(), pos.getZ(), itemstack);
            }
        }

        super.breakBlock(world, pos, state);
    }
Java:
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.ItemStackHandler;

public class BoardEightOnEightContainerTileEntity  extends TileEntity {

    public static final int SIZE = 64;

    private ItemStackHandler itemStackHandler = new ItemStackHandler(SIZE) {
        @Override
        protected void onContentsChanged(int slot) {
            BoardEightOnEightContainerTileEntity.this.markDirty();
        }
    };

    @Override
    public void readFromNBT(NBTTagCompound compound) {
        super.readFromNBT(compound);
        if (compound.hasKey("items")) {
            itemStackHandler.deserializeNBT((NBTTagCompound) compound.getTag("items"));
        }
    }

    @Override
    public NBTTagCompound writeToNBT(NBTTagCompound compound) {
        super.writeToNBT(compound);
        compound.setTag("items", itemStackHandler.serializeNBT());
        return compound;
    }

    @Override
    public boolean hasCapability(Capability<?> capability, EnumFacing facing) {
        if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
            return true;
        }
        return super.hasCapability(capability, facing);
    }

    @Override
    public <T> T getCapability(Capability<T> capability, EnumFacing facing) {
        if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
            return CapabilityItemHandler.ITEM_HANDLER_CAPABILITY.cast(itemStackHandler);
        }
        return super.getCapability(capability, facing);
    }

    public boolean canInteractWith(EntityPlayer playerIn) {
        return !isInvalid() && playerIn.getDistanceSq(pos.add(0.5D, 0.5D, 0.5D)) <= 16D;
    }

}
 
7,099
324
1,510
Ну да, это то ,что я советовал. В тайле кст не обязательно делать эти четыре метода, можно просто приаттачить капу во время события AttachCapabilityEvent
 
Сверху