Как генерировать разный лут в определённом блоке?

Версия Minecraft
1.12.2
API
Forge
40
4
4
Есть блок с GUI, вопрос как генерировать в нём лут каждые 5 минут, если он пустой.
Я понимаю, что нужно проверять пустой ли он чтобы сгенерировать, но как именно создавать лут из (к примеру) кастомного LootTable и как реализовать таймер в TileEntity?

TileEntityTrashBinSmall.java если нужен:
public class TileEntityTrashBinSmall extends TileEntityLockableLoot implements ITickable {

    private NonNullList<ItemStack> chestContents = NonNullList.<ItemStack>withSize(72, ItemStack.EMPTY);
    public int numPlayersUsing, ticksSinceSync;
    public float lidAngle, prevLidAngle;

    @Override
    public int getSizeInventory() {
        return 72;
    }

    @Override
    public int getInventoryStackLimit() {
        return 64;
    }

    @Override
    public boolean isEmpty() {
        for (ItemStack stack : this.chestContents) {
            if (!stack.isEmpty()) return false;
        }
        return true;
    }

    @Override
    public String getName() {
        return this.hasCustomName() ? this.customName : "container.trash_bin_small";
    }

    @Override
    public void readFromNBT(NBTTagCompound compound) {
        super.readFromNBT(compound);
        this.chestContents = NonNullList.<ItemStack>withSize(this.getSizeInventory(), ItemStack.EMPTY);

        if (!this.checkLootAndRead(compound)) ItemStackHelper.loadAllItems(compound, chestContents);
        if (compound.hasKey("CustomName", 8)) this.customName = compound.getString("CustomName");
    }

    @Override
    public NBTTagCompound writeToNBT(NBTTagCompound compound) {
        super.writeToNBT(compound);

        if (!this.checkLootAndWrite(compound)) ItemStackHelper.saveAllItems(compound, chestContents);
        if (compound.hasKey("CustomName", 8)) compound.setString("CustomName", this.customName);

        return compound;
    }

    @Override
    public Container createContainer(InventoryPlayer playerInventory, EntityPlayer playerIn) {
        return new ContainerTrashBinSmall(playerInventory, this, playerIn);
    }

    @Override
    public String getGuiID() {
        return Reference.MODID + ":trash_bin_small";
    }

    @Override
    public NonNullList<ItemStack> getItems() {
        return this.chestContents;
    }

    @Override
    public void update() {
        if (!this.world.isRemote && this.numPlayersUsing != 0 && (this.ticksSinceSync + pos.getX() + pos.getY() + pos.getZ()) % 200 == 0)
        {
            this.numPlayersUsing = 0;
            float f = 5.0F;

            for (EntityPlayer entityPlayer : this.world.getEntitiesWithinAABB(EntityPlayer.class, new AxisAlignedBB((double)((float)pos.getX() - 5.0F), (double)((float)pos.getY() - 5.0F), (double)((float)pos.getZ() - 5.0F), (double)((float)(pos.getX() + 1) + 5.0F), (double)((float)(pos.getY() + 1) + 5.0F), (double)((float)(pos.getZ() + 1) + 5.0F))))
            {
                if (entityPlayer.openContainer instanceof ContainerTrashBinSmall)
                {
                    if (((ContainerTrashBinSmall)entityPlayer.openContainer).getChestInventory() == this)
                    {
                        ++this.numPlayersUsing;
                    }
                }
            }
        }

        this.prevLidAngle = this.lidAngle;
        float f1 = 0.1F;

        if (this.numPlayersUsing > 0 && this.lidAngle == 0.0F)
        {
            double d1 = (double)pos.getX() + 0.5D;
            double d2 = (double)pos.getZ() + 0.5D;
            this.world.playSound((EntityPlayer)null, d1, (double)pos.getY() + 0.5D, d2, SoundEvents.BLOCK_CLOTH_PLACE, SoundCategory.BLOCKS, 0.5F, this.world.rand.nextFloat() * 0.1F + 0.9F);
        }

        if (this.numPlayersUsing == 0 && this.lidAngle > 0.0F || this.numPlayersUsing > 0 && this.lidAngle < 1.0F)
        {
            float f2 = this.lidAngle;

            if (this.numPlayersUsing > 0)
            {
                this.lidAngle += 0.1F;
            }
            else
            {
                this.lidAngle -= 0.1F;
            }

            if (this.lidAngle > 1.0F)
            {
                this.lidAngle = 1.0F;
            }

            float f3 = 0.5F;

            if (this.lidAngle < 0.5F && f2 >= 0.5F)
            {
                double d3 = (double)pos.getX() + 0.5D;
                double d0 = (double)pos.getZ() + 0.5D;
                this.world.playSound((EntityPlayer)null, d3, (double)pos.getY() + 0.5D, d0, SoundEvents.BLOCK_CLOTH_BREAK, SoundCategory.BLOCKS, 0.5F, this.world.rand.nextFloat() * 0.1F + 0.9F);
            }

            if (this.lidAngle < 0.0F)
            {
                this.lidAngle = 0.0F;
            }
        }
    }

    @Override
    public void openInventory(EntityPlayer player) {
        ++this.numPlayersUsing;
        this.world.addBlockEvent(pos, this.getBlockType(), 1, this.numPlayersUsing);
        this.world.notifyNeighborsOfStateChange(pos, this.getBlockType(), false);
    }

    @Override
    public void closeInventory(EntityPlayer player) {
        --this.numPlayersUsing;
        this.world.addBlockEvent(pos, this.getBlockType(), 1, this.numPlayersUsing);
        this.world.notifyNeighborsOfStateChange(pos, this.getBlockType(), false);
    }

    public String getInventoryName()
    {
        return TrashBinSmall.getUnlocName();
    }
}

также сам блок TrashBinSmall.java:
public class TrashBinSmall extends BlockContainer {
    private static final AxisAlignedBB BOUNDING_BOX = new AxisAlignedBB(0.200D, 0.0D, 0.125D, 0.800D, 0.9465D, 0.875D);
    private static final AxisAlignedBB COLLISION_BOX = new AxisAlignedBB(0.200D, 0.0D, 0.125D, 0.800D, 0.9465D, 0.875D);

    private static String unlocName;

    public TrashBinSmall(String name, Material material)
    {
        super(material);
        this.setRegistryName(name);
        this.setUnlocalizedName(name);
        unlocName = name;
    }

    @SideOnly(Side.CLIENT)
    public void initModel() {
        ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(this), 0, new ModelResourceLocation(getRegistryName(), "inventory"));
    }

    @Override
    @SideOnly(Side.CLIENT)
    public boolean shouldSideBeRendered(IBlockState blockState, IBlockAccess worldIn, BlockPos pos, EnumFacing side) {
        return false;
    }

    @Override
    public boolean isBlockNormalCube(IBlockState blockState) {
        return false;
    }

    @Override
    public boolean isOpaqueCube(IBlockState blockState) {
        return false;
    }

    @Override
    public boolean isFullCube(IBlockState blockState) {
        return false;
    }

    @Override
    public boolean isFullBlock(IBlockState state) { return false; }

    @Override
    public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos) {
        return BOUNDING_BOX;
    }

    public static AxisAlignedBB getCollisionBox() {
        return COLLISION_BOX;
    }

    public static String getUnlocName() {
        return unlocName;
    };

    private final Random rand = new Random();

    @Override
    public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ)
    {
        // Проверка на сервер
        if(worldIn.isRemote) return true;

        TileEntity te = worldIn.getTileEntity(pos);
        if (te != null && te instanceof TileEntityTrashBinSmall)
        {
            playerIn.openGui(ExileZDecorative.instance, Reference.GUI_TRASH_BIN, worldIn, pos.getX(), pos.getY(), pos.getZ());
            return true;
        }
        return false;
    }

    @Override
    public void breakBlock(World worldIn, BlockPos pos, IBlockState state)
    {
        // Проверка на сервер
        if (worldIn.isRemote) return;

        ArrayList drops = new ArrayList();

        TileEntity teRaw = worldIn.getTileEntity(pos);

        if (teRaw != null && teRaw instanceof TileEntityTrashBinSmall)
        {
            TileEntityTrashBinSmall te = (TileEntityTrashBinSmall) teRaw;
            for (int i = 0; i < te.getSizeInventory(); i++)
            {
                ItemStack stack = te.getStackInSlot(i);
                if (stack != null) drops.add(stack.copy());
            }
        }
        for (int i = 0; i < drops.size(); i++)
        {
            EntityItem item = new EntityItem(worldIn, pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, (ItemStack) drops.get(i));
            item.setVelocity((rand.nextDouble() - 0.5) * 0.25, rand.nextDouble() * 0.5 * 0.25, (rand.nextDouble() - 0.5) * 0.25);
            worldIn.spawnEntity(item);
            // Обновление выхода редстоуна для компараторов
            // (это если кто-нибудь захочет отследить зависимость силы редстоуна от кол-ва предметов в хранилище)
            worldIn.updateComparatorOutputLevel(pos, this);
        }
    }

    @Override
    public void onBlockPlacedBy(World worldIn, BlockPos pos, IBlockState state, EntityLivingBase placer, ItemStack stack) {
        if(stack.hasDisplayName()) {
            TileEntity tileEntity = worldIn.getTileEntity(pos);

            if(tileEntity instanceof TileEntityTrashBinSmall) {
                ((TileEntityTrashBinSmall)tileEntity).setCustomName(stack.getDisplayName());
                ((TileEntityTrashBinSmall)tileEntity).setLootTable(LootTableList.LOOT_TRASH_BIN_SMALL, worldIn.rand.nextLong());
                System.out.println(LootTableList.LOOT_TRASH_BIN_SMALL);
            }
        }
    }

    public TileEntity createNewTileEntity(World world, int par2)
    {
        return new TileEntityTrashBinSmall();
    }

    @Override
    public EnumBlockRenderType getRenderType(IBlockState state) {
        return EnumBlockRenderType.MODEL;
    }
}
 
Последнее редактирование:
116
13
13
Смотри, у setInventorySlotConents есть два параметра: номер слота и ItemStack, т.е. предмет, который ты загружаешь в свой инвентарь тайла (chestContents). Этот метод просто заполняет предметы в нужный слот. Вообще, не совсем понимаю твой подход с использованием LootTable, но тебе стоит самому посмотреть как достать из него лист с предметами и передать в твой setInventorySlotConents
 
40
4
4
Допустим я прописал это в Update, но ничего не меняется, может я не там или не так прописал?

update:
public void update() {
    if (!this.world.isRemote && this.numPlayersUsing != 0 && (this.ticksSinceSync + pos.getX() + pos.getY() + pos.getZ()) % 200 == 0)
    {
        this.numPlayersUsing = 0;
        float f = 5.0F;

        for (EntityPlayer entityPlayer : this.world.getEntitiesWithinAABB(EntityPlayer.class, new AxisAlignedBB((double)((float)pos.getX() - 5.0F), (double)((float)pos.getY() - 5.0F), (double)((float)pos.getZ() - 5.0F), (double)((float)(pos.getX() + 1) + 5.0F), (double)((float)(pos.getY() + 1) + 5.0F), (double)((float)(pos.getZ() + 1) + 5.0F))))
        {
            if (entityPlayer.openContainer instanceof ContainerTrashBinSmall)
            {
                if (((ContainerTrashBinSmall)entityPlayer.openContainer).getChestInventory() == this)
                {
                    ++this.numPlayersUsing;
                }
            }
        }
        setInventorySlotContents(0, new ItemStack(Items.DIAMOND, 1));
    }
}
TileEntityTrashBinSmall.java:
public class TileEntityTrashBinSmall extends TileEntityLockableLoot implements ITickable {

    private NonNullList<ItemStack> chestContents = NonNullList.<ItemStack>withSize(72, ItemStack.EMPTY);
    public int numPlayersUsing, ticksSinceSync;
    public float lidAngle, prevLidAngle;

    private int tickCounter = 0;

    @Override
    public int getSizeInventory() {
        return 72;
    }

    @Override
    public int getInventoryStackLimit() {
        return 64;
    }

    @Override
    public boolean isEmpty() {
        for (ItemStack stack : this.chestContents) {
            if (!stack.isEmpty()) return false;
        }
        return true;
    }

    @Override
    public String getName() {
        return this.hasCustomName() ? this.customName : "container.trash_bin_small";
    }

    @Override
    public void readFromNBT(NBTTagCompound compound) {
        super.readFromNBT(compound);
        this.chestContents = NonNullList.<ItemStack>withSize(this.getSizeInventory(), ItemStack.EMPTY);

        if (!this.checkLootAndRead(compound)) ItemStackHelper.loadAllItems(compound, chestContents);
        if (compound.hasKey("CustomName", 8)) this.customName = compound.getString("CustomName");
    }

    @Override
    public NBTTagCompound writeToNBT(NBTTagCompound compound) {
        super.writeToNBT(compound);

        if (!this.checkLootAndWrite(compound)) ItemStackHelper.saveAllItems(compound, chestContents);
        if (compound.hasKey("CustomName", 8)) compound.setString("CustomName", this.customName);

        return compound;
    }

    @Override
    public Container createContainer(InventoryPlayer playerInventory, EntityPlayer playerIn) {
        return new ContainerTrashBinSmall(playerInventory, this, playerIn);
    }

    @Override
    public String getGuiID() {
        return Reference.MODID + ":trash_bin_small";
    }

    @Override
    public NonNullList<ItemStack> getItems() {
        return this.chestContents;
    }

    @Override
    public void update() {
        if (!this.world.isRemote && this.numPlayersUsing != 0 && (this.ticksSinceSync + pos.getX() + pos.getY() + pos.getZ()) % 200 == 0)
        {
            this.numPlayersUsing = 0;
            float f = 5.0F;

            for (EntityPlayer entityPlayer : this.world.getEntitiesWithinAABB(EntityPlayer.class, new AxisAlignedBB((double)((float)pos.getX() - 5.0F), (double)((float)pos.getY() - 5.0F), (double)((float)pos.getZ() - 5.0F), (double)((float)(pos.getX() + 1) + 5.0F), (double)((float)(pos.getY() + 1) + 5.0F), (double)((float)(pos.getZ() + 1) + 5.0F))))
            {
                if (entityPlayer.openContainer instanceof ContainerTrashBinSmall)
                {
                    if (((ContainerTrashBinSmall)entityPlayer.openContainer).getChestInventory() == this)
                    {
                        ++this.numPlayersUsing;
                    }
                }
            }
            setInventorySlotContents(0, new ItemStack(Items.DIAMOND, 1));
        }

        tickCounter++;
        if (tickCounter >= 200) tickCounter = 0;

        //System.out.println("TickCounter: " + tickCounter);

        this.prevLidAngle = this.lidAngle;
        float f1 = 0.1F;

        if (this.numPlayersUsing > 0 && this.lidAngle == 0.0F)
        {
            double d1 = (double)pos.getX() + 0.5D;
            double d2 = (double)pos.getZ() + 0.5D;
            this.world.playSound((EntityPlayer)null, d1, (double)pos.getY() + 0.5D, d2, SoundEvents.BLOCK_CLOTH_PLACE, SoundCategory.BLOCKS, 0.5F, this.world.rand.nextFloat() * 0.1F + 0.9F);
        }

        if (this.numPlayersUsing == 0 && this.lidAngle > 0.0F || this.numPlayersUsing > 0 && this.lidAngle < 1.0F)
        {
            float f2 = this.lidAngle;

            if (this.numPlayersUsing > 0)
            {
                this.lidAngle += 0.1F;
            }
            else
            {
                this.lidAngle -= 0.1F;
            }

            if (this.lidAngle > 1.0F)
            {
                this.lidAngle = 1.0F;
            }

            float f3 = 0.5F;

            if (this.lidAngle < 0.5F && f2 >= 0.5F)
            {
                double d3 = (double)pos.getX() + 0.5D;
                double d0 = (double)pos.getZ() + 0.5D;
                this.world.playSound((EntityPlayer)null, d3, (double)pos.getY() + 0.5D, d0, SoundEvents.BLOCK_CLOTH_BREAK, SoundCategory.BLOCKS, 0.5F, this.world.rand.nextFloat() * 0.1F + 0.9F);
            }

            if (this.lidAngle < 0.0F)
            {
                this.lidAngle = 0.0F;
            }
        }
    }

    @Override
    public void openInventory(EntityPlayer player) {
        ++this.numPlayersUsing;
        this.world.addBlockEvent(pos, this.getBlockType(), 1, this.numPlayersUsing);
        this.world.notifyNeighborsOfStateChange(pos, this.getBlockType(), false);
    }

    @Override
    public void closeInventory(EntityPlayer player) {
        --this.numPlayersUsing;
        this.world.addBlockEvent(pos, this.getBlockType(), 1, this.numPlayersUsing);
        this.world.notifyNeighborsOfStateChange(pos, this.getBlockType(), false);
    }

    public String getInventoryName()
    {
        return TrashBinSmall.getUnlocName();
    }
}
 
116
13
13
Осталось понять как очищать и заменить или передать LootTables
Очистить инвентарь тайла можно при помощи метода clear(), находящийся в TileEntityLockableLoot, замена (если я правильно понял) как я говорил уже ранее, происходит через setInventorySlotConents.

И я так и не понял твою задумку с LootTable. Однако у TileEntityLockableLoot есть метод fillWithLoot(@Nullable EntityPlayer player), можешь вставить его вместо setInventorySlotConents, однако перед этим замени текущий LootTable на свой через setLootTable(ResourceLocation p_189404_1_, long p_189404_2_). Думаю, с ResourceLocation ты разберешься сам.

Получится что-то типа:
update:
public void update() {
    this.setLootTable(ResourceLocation p_189404_1_, long p_189404_2_);
    this.fillWithLoot(@Nullable EntityPlayer player);
}
 
Последнее редактирование:
40
4
4
если в update поставить fillWithLoot, то он будет постоянно заполнять, разве нет? и я не знаю что ставить на место @Nullable EntityPlayer player, разве что объявлять глобальную переменную, но не уверен что это сработает
 
40
4
4
я более-менее сделал генерацию по LootTable, но при ломании даже пустого блока выпадают вещи которых даже не было в нём. К тому же пока не понятно как к этому приделать таймер.
TrashBinSmall.java:
public class TrashBinSmall extends BlockContainer {
    private static final AxisAlignedBB BOUNDING_BOX = new AxisAlignedBB(0.200D, 0.0D, 0.125D, 0.800D, 0.9465D, 0.875D);
    private static final AxisAlignedBB COLLISION_BOX = new AxisAlignedBB(0.200D, 0.0D, 0.125D, 0.800D, 0.9465D, 0.875D);

    private static String unlocName;

    public TrashBinSmall(String name, Material material)
    {
        super(material);
        this.setRegistryName(name);
        this.setUnlocalizedName(name);
        unlocName = name;
    }

    @SideOnly(Side.CLIENT)
    public void initModel() {
        ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(this), 0, new ModelResourceLocation(getRegistryName(), "inventory"));
    }

    @Override
    @SideOnly(Side.CLIENT)
    public boolean shouldSideBeRendered(IBlockState blockState, IBlockAccess worldIn, BlockPos pos, EnumFacing side) {
        return false;
    }

    @Override
    public boolean isBlockNormalCube(IBlockState blockState) {
        return false;
    }

    @Override
    public boolean isOpaqueCube(IBlockState blockState) {
        return false;
    }

    @Override
    public boolean isFullCube(IBlockState blockState) {
        return false;
    }

    @Override
    public boolean isFullBlock(IBlockState state) { return false; }

    @Override
    public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos) {
        return BOUNDING_BOX;
    }

    public static AxisAlignedBB getCollisionBox() {
        return COLLISION_BOX;
    }

    public static String getUnlocName() {
        return unlocName;
    };

    private final Random rand = new Random();

    @Override
    public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ)
    {
        // Проверка на сервер
        if(worldIn.isRemote) return true;

        TileEntity te = worldIn.getTileEntity(pos);
        if (te != null && te instanceof TileEntityTrashBinSmall)
        {
            playerIn.openGui(ExileZDecorative.instance, Reference.GUI_TRASH_BIN, worldIn, pos.getX(), pos.getY(), pos.getZ());
            return true;
        }
        return false;
    }

    @Override
    public void breakBlock(World worldIn, BlockPos pos, IBlockState state)
    {
        // Проверка на сервер
        if (worldIn.isRemote) return;

        ArrayList drops = new ArrayList();

        TileEntity teRaw = worldIn.getTileEntity(pos);

        if (teRaw != null && teRaw instanceof TileEntityTrashBinSmall)
        {
            TileEntityTrashBinSmall te = (TileEntityTrashBinSmall) teRaw;
            for (int i = 0; i < te.getSizeInventory(); i++)
            {
                ItemStack stack = te.getStackInSlot(i);
                if (stack != null) drops.add(stack.copy());
            }
        }
        for (int i = 0; i < drops.size(); i++)
        {
            EntityItem item = new EntityItem(worldIn, pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, (ItemStack) drops.get(i));
            item.setVelocity((rand.nextDouble() - 0.5) * 0.25, rand.nextDouble() * 0.5 * 0.25, (rand.nextDouble() - 0.5) * 0.25);
            worldIn.spawnEntity(item);
            // Обновление выхода редстоуна для компараторов
            // (это если кто-нибудь захочет отследить зависимость силы редстоуна от кол-ва предметов в хранилище)
            worldIn.updateComparatorOutputLevel(pos, this);
        }
    }

    @Override
    public void onBlockPlacedBy(World worldIn, BlockPos pos, IBlockState state, EntityLivingBase placer, ItemStack stack) {
        TileEntity tileEntity = worldIn.getTileEntity(pos);

        if(tileEntity instanceof TileEntityTrashBinSmall) {
            ((TileEntityTrashBinSmall)tileEntity).setCustomName(stack.getDisplayName());
            ((TileEntityTrashBinSmall)tileEntity).setLootTable(LootTableList.LOOT_TRASH_BIN_SMALL, worldIn.rand.nextLong());
        }
    }

    public TileEntity createNewTileEntity(World world, int par2)
    {
        return new TileEntityTrashBinSmall();
    }

    @Override
    public EnumBlockRenderType getRenderType(IBlockState state) {
        return EnumBlockRenderType.MODEL;
    }
}

TileEntityTrashBinSmall.java:
public class TileEntityTrashBinSmall extends TileEntityLockableLoot implements ITickable {

    private NonNullList<ItemStack> chestContents = NonNullList.<ItemStack>withSize(72, ItemStack.EMPTY);
    public int numPlayersUsing, ticksSinceSync;
    public float lidAngle, prevLidAngle;

    private int tickCounter = 0;
    public boolean isTickFinished = false;
    Random random;
    EntityPlayer player;

    @Override
    public int getSizeInventory() {
        return 72;
    }

    @Override
    public int getInventoryStackLimit() {
        return 64;
    }

    @Override
    public boolean isEmpty() {
        for (ItemStack stack : this.chestContents) {
            if (!stack.isEmpty()) return false;
        }
        return true;
    }

    @Override
    public String getName() {
        return this.hasCustomName() ? this.customName : "container.trash_bin_small";
    }

    @Override
    public void readFromNBT(NBTTagCompound compound) {
        super.readFromNBT(compound);
        this.chestContents = NonNullList.<ItemStack>withSize(this.getSizeInventory(), ItemStack.EMPTY);

        if (!this.checkLootAndRead(compound)) ItemStackHelper.loadAllItems(compound, chestContents);
        if (compound.hasKey("CustomName", 8)) this.customName = compound.getString("CustomName");
    }

    @Override
    public NBTTagCompound writeToNBT(NBTTagCompound compound) {
        super.writeToNBT(compound);

        if (!this.checkLootAndWrite(compound)) ItemStackHelper.saveAllItems(compound, chestContents);
        if (compound.hasKey("CustomName", 8)) compound.setString("CustomName", this.customName);

        return compound;
    }

    @Override
    public SPacketUpdateTileEntity getUpdatePacket() {
        return new SPacketUpdateTileEntity(this.pos, this.getBlockMetadata(), this.getUpdateTag());
    }

    @Override
    public void onDataPacket(NetworkManager net, SPacketUpdateTileEntity pkt) {
        handleUpdateTag(pkt.getNbtCompound());
    }

    @Override
    public NBTTagCompound getUpdateTag() {
        return writeToNBT(new NBTTagCompound());
    }

    public void updateStatus() {
        this.updateStatus(this.world.getBlockState(pos));
    }

    public void updateStatus(IBlockState state) {
        this.markDirty();
        this.world.notifyBlockUpdate(pos, this.world.getBlockState(pos), state, 3);
    }

    @Override
    public Container createContainer(InventoryPlayer playerInventory, EntityPlayer playerIn) {
        //return new ContainerTrashBinSmall(playerInventory, this, playerIn);
        this.fillWithLoot(playerIn);
        return new ContainerTrashBinSmall(playerInventory, this, playerIn);
    }

    @Override
    public String getGuiID() {
        return Reference.MODID + ":trash_bin_small";
    }

    @Override
    public NonNullList<ItemStack> getItems() {
        return this.chestContents;
    }

    @Override
    public void update() {
        if (!this.world.isRemote && this.numPlayersUsing != 0 && (this.ticksSinceSync + pos.getX() + pos.getY() + pos.getZ()) % 200 == 0)
        {
            this.numPlayersUsing = 0;
            float f = 5.0F;

            for (EntityPlayer entityPlayer : this.world.getEntitiesWithinAABB(EntityPlayer.class, new AxisAlignedBB((double)((float)pos.getX() - 5.0F), (double)((float)pos.getY() - 5.0F), (double)((float)pos.getZ() - 5.0F), (double)((float)(pos.getX() + 1) + 5.0F), (double)((float)(pos.getY() + 1) + 5.0F), (double)((float)(pos.getZ() + 1) + 5.0F))))
            {
                if (entityPlayer.openContainer instanceof ContainerTrashBinSmall)
                {
                    if (((ContainerTrashBinSmall)entityPlayer.openContainer).getChestInventory() == this)
                    {
                        ++this.numPlayersUsing;
                    }
                }
            }
        }

        //setInventorySlotContents(4, new ItemStack(Items.APPLE, 1));

        if (tickCounter >= 200) {
            tickCounter = 0;
        }

        //System.out.println("TickCounter: " + tickCounter);

        this.prevLidAngle = this.lidAngle;
        float f1 = 0.1F;

        if (this.numPlayersUsing > 0 && this.lidAngle == 0.0F)
        {
            double d1 = (double)pos.getX() + 0.5D;
            double d2 = (double)pos.getZ() + 0.5D;
            this.world.playSound((EntityPlayer)null, d1, (double)pos.getY() + 0.5D, d2, SoundEvents.BLOCK_CLOTH_PLACE, SoundCategory.BLOCKS, 0.5F, this.world.rand.nextFloat() * 0.1F + 0.9F);
        }

        if (this.numPlayersUsing == 0 && this.lidAngle > 0.0F || this.numPlayersUsing > 0 && this.lidAngle < 1.0F)
        {
            float f2 = this.lidAngle;

            if (this.numPlayersUsing > 0)
            {
                this.lidAngle += 0.1F;
            }
            else
            {
                this.lidAngle -= 0.1F;
            }

            if (this.lidAngle > 1.0F)
            {
                this.lidAngle = 1.0F;
            }

            float f3 = 0.5F;

            if (this.lidAngle < 0.5F && f2 >= 0.5F)
            {
                double d3 = (double)pos.getX() + 0.5D;
                double d0 = (double)pos.getZ() + 0.5D;
                this.world.playSound((EntityPlayer)null, d3, (double)pos.getY() + 0.5D, d0, SoundEvents.BLOCK_CLOTH_BREAK, SoundCategory.BLOCKS, 0.5F, this.world.rand.nextFloat() * 0.1F + 0.9F);
            }

            if (this.lidAngle < 0.0F)
            {
                this.lidAngle = 0.0F;
            }
        }
    }

    @Override
    public void openInventory(EntityPlayer player) {
        ++this.numPlayersUsing;
        this.world.addBlockEvent(pos, this.getBlockType(), 1, this.numPlayersUsing);
        this.world.notifyNeighborsOfStateChange(pos, this.getBlockType(), false);
    }

    @Override
    public void closeInventory(EntityPlayer player) {
        --this.numPlayersUsing;
        this.world.addBlockEvent(pos, this.getBlockType(), 1, this.numPlayersUsing);
        this.world.notifyNeighborsOfStateChange(pos, this.getBlockType(), false);
    }

    public String getInventoryName()
    {
        return TrashBinSmall.getUnlocName();
    }

    @Override
    public void fillWithLoot(@Nullable EntityPlayer player) {
        if (this.lootTable != null && this.world instanceof WorldServer) {
            LootTable loottable = this.world.getLootTableManager().getLootTableFromLocation(this.lootTable);
            this.lootTable = null;
            Random random;
            if (this.lootTableSeed == 0L) random = new Random();
            else random = new Random(this.lootTableSeed);
            LootContext.Builder builder = new LootContext.Builder((WorldServer) this.world);
            if (player != null) builder.withLuck(player.getLuck()).withPlayer(player);
            loottable.fillInventory(this, random, builder.build());
        }
    }
}
 
116
13
13
Возможно это связано с тем, что при вызове getStackInSlot() (в твоём методе breakBlock), в нём, помимо получения предмета из списка, происходит повторный вызов fillWithLoot().

Попробуй переопределить у себя getStackInSlot() таким образом:
Your TileEntity:
public ItemStack getStackInSlot(int index) {
    return this.chestContents.get(index);
}

А вообще, советую в цикле перебора вещей (где происходит логика ломания блока) советую сделать проверку на пустой инвентарь и просто выходить из метода, если он пуст
 
40
4
4
С переопределением getStackInSlot он вовсе перестаёт генерировать туда вещи.
Я проверяю на пустой контейнер выводя в консоль - до того как открыл инвентарь он true (пустой), после того как открыл вещи сгенерировались и стал false (не пустой), после того как я забрал все вещи из инвентаря он начинает всё время чередоваться с true и false
 
40
4
4
Я привёл код к такому виду, проблема всё та же

TrashBinSmall:
public class TrashBinSmall extends BlockContainer {
    private static final AxisAlignedBB BOUNDING_BOX = new AxisAlignedBB(0.200D, 0.0D, 0.125D, 0.800D, 0.9465D, 0.875D);
    private static final AxisAlignedBB COLLISION_BOX = new AxisAlignedBB(0.200D, 0.0D, 0.125D, 0.800D, 0.9465D, 0.875D);

    private static String unlocName;

    public TrashBinSmall(String name, Material material)
    {
        super(material);
        this.setRegistryName(name);
        this.setUnlocalizedName(name);
        unlocName = name;
    }

    @SideOnly(Side.CLIENT)
    public void initModel() {
        ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(this), 0, new ModelResourceLocation(getRegistryName(), "inventory"));
    }

    @Override
    @SideOnly(Side.CLIENT)
    public boolean shouldSideBeRendered(IBlockState blockState, IBlockAccess worldIn, BlockPos pos, EnumFacing side) {
        return false;
    }

    @Override
    public boolean isBlockNormalCube(IBlockState blockState) {
        return false;
    }

    @Override
    public boolean isOpaqueCube(IBlockState blockState) {
        return false;
    }

    @Override
    public boolean isFullCube(IBlockState blockState) {
        return false;
    }

    @Override
    public boolean isFullBlock(IBlockState state) { return false; }

    @Override
    public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos) {
        return BOUNDING_BOX;
    }

    public static AxisAlignedBB getCollisionBox() {
        return COLLISION_BOX;
    }

    public static String getUnlocName() {
        return unlocName;
    };

    private final Random rand = new Random();

    @Override
    public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ)
    {
        // Проверка на сервер
        if(worldIn.isRemote) return true;

        TileEntity te = worldIn.getTileEntity(pos);
        if (te != null && te instanceof TileEntityTrashBinSmall)
        {
            playerIn.openGui(ExileZDecorative.instance, Reference.GUI_TRASH_BIN, worldIn, pos.getX(), pos.getY(), pos.getZ());
            return true;
        }
        return false;
    }

    @Override
    public void breakBlock(World worldIn, BlockPos pos, IBlockState state)
    {
        // Проверка на сервер
        if (worldIn.isRemote) return;

        ArrayList drops = new ArrayList();

        TileEntity teRaw = worldIn.getTileEntity(pos);

        if (teRaw != null && teRaw instanceof TileEntityTrashBinSmall)
        {
            TileEntityTrashBinSmall te = (TileEntityTrashBinSmall) teRaw;
            for (int i = 0; i < te.getSizeInventory(); i++)
            {
                ItemStack stack = te.getStackInSlot(i);
                if (stack != null) drops.add(stack.copy());
            }
        }
        for (int i = 0; i < drops.size(); i++)
        {
            EntityItem item = new EntityItem(worldIn, pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, (ItemStack) drops.get(i));
            item.setVelocity((rand.nextDouble() - 0.5) * 0.25, rand.nextDouble() * 0.5 * 0.25, (rand.nextDouble() - 0.5) * 0.25);
            worldIn.spawnEntity(item);
            // Обновление выхода редстоуна для компараторов
            // (это если кто-нибудь захочет отследить зависимость силы редстоуна от кол-ва предметов в хранилище)
            worldIn.updateComparatorOutputLevel(pos, this);
        }
    }

    @Override
    public void onBlockPlacedBy(World worldIn, BlockPos pos, IBlockState state, EntityLivingBase placer, ItemStack stack) {
        TileEntity tileEntity = worldIn.getTileEntity(pos);

        if(tileEntity instanceof TileEntityTrashBinSmall) {
            ((TileEntityTrashBinSmall)tileEntity).setCustomName(stack.getDisplayName());
            ((TileEntityTrashBinSmall)tileEntity).setLootTable(LootTableList.LOOT_TRASH_BIN_SMALL, worldIn.rand.nextLong());
        }
    }

    public TileEntity createNewTileEntity(World world, int par2)
    {
        return new TileEntityTrashBinSmall();
    }

    @Override
    public EnumBlockRenderType getRenderType(IBlockState state) {
        return EnumBlockRenderType.MODEL;
    }

}

TileEntityTrashBinSmall.java:
package ru.qlcreations.exile_z_decorative.objects.blocks.tile;

public class TileEntityTrashBinSmall extends TileEntityLockableLoot implements ITickable {

    private NonNullList<ItemStack> chestContents = NonNullList.<ItemStack>withSize(72, ItemStack.EMPTY);
    public int numPlayersUsing, ticksSinceSync;
    public float lidAngle, prevLidAngle;

    private int tickCounter = 0;
    public boolean isTickFinished = false;
    Random random;
    EntityPlayer player;

    @Override
    public int getSizeInventory() {
        return 72;
    }

    @Override
    public int getInventoryStackLimit() {
        return 64;
    }

    @Override
    public boolean isEmpty() {
        for (ItemStack stack : this.chestContents) {
            if (!stack.isEmpty()) return false;
        }
        return true;
    }

    @Override
    public String getName() {
        return this.hasCustomName() ? this.customName : "container.trash_bin_small";
    }

    @Override
    public void readFromNBT(NBTTagCompound compound) {
        super.readFromNBT(compound);
        this.chestContents = NonNullList.<ItemStack>withSize(this.getSizeInventory(), ItemStack.EMPTY);

        if (!this.checkLootAndRead(compound)) ItemStackHelper.loadAllItems(compound, chestContents);
        if (compound.hasKey("CustomName", 8)) this.customName = compound.getString("CustomName");
    }

    @Override
    public NBTTagCompound writeToNBT(NBTTagCompound compound) {
        super.writeToNBT(compound);

        if (!this.checkLootAndWrite(compound)) ItemStackHelper.saveAllItems(compound, chestContents);
        if (compound.hasKey("CustomName", 8)) compound.setString("CustomName", this.customName);

        return compound;
    }

    @Override
    public SPacketUpdateTileEntity getUpdatePacket() {
        return new SPacketUpdateTileEntity(this.pos, this.getBlockMetadata(), this.getUpdateTag());
    }

    @Override
    public void onDataPacket(NetworkManager net, SPacketUpdateTileEntity pkt) {
        handleUpdateTag(pkt.getNbtCompound());
    }

    @Override
    public NBTTagCompound getUpdateTag() {
        return writeToNBT(new NBTTagCompound());
    }

    public void updateStatus() {
        this.updateStatus(this.world.getBlockState(pos));
    }

    public void updateStatus(IBlockState state) {
        this.markDirty();
        this.world.notifyBlockUpdate(pos, this.world.getBlockState(pos), state, 3);
    }

    @Override
    public Container createContainer(InventoryPlayer playerInventory, EntityPlayer playerIn) {
        return new ContainerTrashBinSmall(playerInventory, this, playerIn);
    }

    @Override
    public String getGuiID() {
        return Reference.MODID + ":trash_bin_small";
    }

    @Override
    public NonNullList<ItemStack> getItems() {
        return this.chestContents;
    }

    @Override
    public void update() {
        if (!this.world.isRemote && this.numPlayersUsing != 0 && (this.ticksSinceSync + pos.getX() + pos.getY() + pos.getZ()) % 200 == 0)
        {
            this.numPlayersUsing = 0;
            float f = 5.0F;

            for (EntityPlayer entityPlayer : this.world.getEntitiesWithinAABB(EntityPlayer.class, new AxisAlignedBB((double)((float)pos.getX() - 5.0F), (double)((float)pos.getY() - 5.0F), (double)((float)pos.getZ() - 5.0F), (double)((float)(pos.getX() + 1) + 5.0F), (double)((float)(pos.getY() + 1) + 5.0F), (double)((float)(pos.getZ() + 1) + 5.0F))))
            {
                if (entityPlayer.openContainer instanceof ContainerTrashBinSmall)
                {
                    if (((ContainerTrashBinSmall)entityPlayer.openContainer).getChestInventory() == this)
                    {
                        ++this.numPlayersUsing;
                    }
                }
            }
        }

        //setInventorySlotContents(4, new ItemStack(Items.APPLE, 1));

        if (tickCounter >= 200) {
            tickCounter = 0;
        }

        //System.out.println("TickCounter: " + tickCounter);

        this.prevLidAngle = this.lidAngle;
        float f1 = 0.1F;

        if (this.numPlayersUsing > 0 && this.lidAngle == 0.0F)
        {
            double d1 = (double)pos.getX() + 0.5D;
            double d2 = (double)pos.getZ() + 0.5D;
            this.world.playSound((EntityPlayer)null, d1, (double)pos.getY() + 0.5D, d2, SoundEvents.BLOCK_CLOTH_PLACE, SoundCategory.BLOCKS, 0.5F, this.world.rand.nextFloat() * 0.1F + 0.9F);
        }

        if (this.numPlayersUsing == 0 && this.lidAngle > 0.0F || this.numPlayersUsing > 0 && this.lidAngle < 1.0F)
        {
            float f2 = this.lidAngle;

            if (this.numPlayersUsing > 0)
            {
                this.lidAngle += 0.1F;
            }
            else
            {
                this.lidAngle -= 0.1F;
            }

            if (this.lidAngle > 1.0F)
            {
                this.lidAngle = 1.0F;
            }

            float f3 = 0.5F;

            if (this.lidAngle < 0.5F && f2 >= 0.5F)
            {
                double d3 = (double)pos.getX() + 0.5D;
                double d0 = (double)pos.getZ() + 0.5D;
                this.world.playSound((EntityPlayer)null, d3, (double)pos.getY() + 0.5D, d0, SoundEvents.BLOCK_CLOTH_BREAK, SoundCategory.BLOCKS, 0.5F, this.world.rand.nextFloat() * 0.1F + 0.9F);
            }

            if (this.lidAngle < 0.0F)
            {
                this.lidAngle = 0.0F;
            }
        }
    }


    @Override
    public void openInventory(EntityPlayer player) {
        ++this.numPlayersUsing;
        this.world.addBlockEvent(pos, this.getBlockType(), 1, this.numPlayersUsing);
        this.world.notifyNeighborsOfStateChange(pos, this.getBlockType(), false);
    }

    @Override
    public void closeInventory(EntityPlayer player) {
        --this.numPlayersUsing;
        this.world.addBlockEvent(pos, this.getBlockType(), 1, this.numPlayersUsing);
        this.world.notifyNeighborsOfStateChange(pos, this.getBlockType(), false);
    }

    public String getInventoryName()
    {
        return TrashBinSmall.getUnlocName();
    }

    @Override
    public void fillWithLoot(@Nullable EntityPlayer player) {
        if (this.lootTable != null && this.world instanceof WorldServer) {
            LootTable loottable = this.world.getLootTableManager().getLootTableFromLocation(this.lootTable);
            this.lootTable = null;
            Random random;
            if (this.lootTableSeed == 0L) random = new Random();
            else random = new Random(this.lootTableSeed);
            LootContext.Builder builder = new LootContext.Builder((WorldServer) this.world);
            if (player != null) builder.withLuck(player.getLuck()).withPlayer(player);
            loottable.fillInventory(this, random, builder.build());
        }
    }
}

Причём если я убираю переопределение fillWithLoot, то при открытии инвентаря получается краш с ошибками
краш:
[18:12:30] [Client thread/FATAL] [minecraft/Minecraft]: Reported exception thrown!
net.minecraft.util.ReportedException: Rendering screen
    at net.minecraft.client.renderer.EntityRenderer.updateCameraAndRender(EntityRenderer.java:1151) ~[EntityRenderer.class:?]
    at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1119) ~[Minecraft.class:?]
    at net.minecraft.client.Minecraft.run(Minecraft.java:398) [Minecraft.class:?]
    at net.minecraft.client.main.Main.main(Main.java:118) [Main.class:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_382]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_382]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_382]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_382]
    at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) [launchwrapper-1.12.jar:?]
    at net.minecraft.launchwrapper.Launch.main(Launch.java:28) [launchwrapper-1.12.jar:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_382]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_382]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_382]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_382]
    at net.minecraftforge.legacydev.Main.start(Main.java:86) [legacydev-0.2.3.1-fatjar.jar:0.2.3.1+4+372be23]
    at net.minecraftforge.legacydev.MainClient.main(MainClient.java:29) [legacydev-0.2.3.1-fatjar.jar:0.2.3.1+4+372be23]
Caused by: java.lang.NullPointerException
    at net.minecraft.tileentity.TileEntityLockableLoot.fillWithLoot(TileEntityLockableLoot.java:59) ~[TileEntityLockableLoot.class:?]
    at net.minecraft.tileentity.TileEntityLockableLoot.getStackInSlot(TileEntityLockableLoot.java:106) ~[TileEntityLockableLoot.class:?]
    at net.minecraft.inventory.Slot.getStack(Slot.java:60) ~[Slot.class:?]
    at net.minecraft.client.gui.inventory.GuiContainer.drawSlot(GuiContainer.java:202) ~[GuiContainer.class:?]
    at net.minecraft.client.gui.inventory.GuiContainer.drawScreen(GuiContainer.java:98) ~[GuiContainer.class:?]
    at net.minecraftforge.client.ForgeHooksClient.drawScreen(ForgeHooksClient.java:396) ~[ForgeHooksClient.class:?]
    at net.minecraft.client.renderer.EntityRenderer.updateCameraAndRender(EntityRenderer.java:1124) ~[EntityRenderer.class:?]
    ... 15 more
[18:12:30] [Client thread/INFO] [STDOUT]: [net.minecraft.init.Bootstrap:printToSYSOUT:553]: ---- Minecraft Crash Report ----
// You should try our sister game, Minceraft!

Time: 7/26/23 6:12 PM
Description: Rendering screen

java.lang.NullPointerException: Rendering screen
    at net.minecraft.tileentity.TileEntityLockableLoot.fillWithLoot(TileEntityLockableLoot.java:59)
    at net.minecraft.tileentity.TileEntityLockableLoot.getStackInSlot(TileEntityLockableLoot.java:106)
    at net.minecraft.inventory.Slot.getStack(Slot.java:60)
    at net.minecraft.client.gui.inventory.GuiContainer.drawSlot(GuiContainer.java:202)
    at net.minecraft.client.gui.inventory.GuiContainer.drawScreen(GuiContainer.java:98)
    at net.minecraftforge.client.ForgeHooksClient.drawScreen(ForgeHooksClient.java:396)
    at net.minecraft.client.renderer.EntityRenderer.updateCameraAndRender(EntityRenderer.java:1124)
    at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1119)
    at net.minecraft.client.Minecraft.run(Minecraft.java:398)
    at net.minecraft.client.main.Main.main(Main.java:118)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at net.minecraft.launchwrapper.Launch.launch(Launch.java:135)
    at net.minecraft.launchwrapper.Launch.main(Launch.java:28)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at net.minecraftforge.legacydev.Main.start(Main.java:86)
    at net.minecraftforge.legacydev.MainClient.main(MainClient.java:29)


A detailed walkthrough of the error, its code path and all known details is as follows:
---------------------------------------------------------------------------------------

-- Head --
Thread: Client thread
Stacktrace:
    at net.minecraft.tileentity.TileEntityLockableLoot.fillWithLoot(TileEntityLockableLoot.java:59)
    at net.minecraft.tileentity.TileEntityLockableLoot.getStackInSlot(TileEntityLockableLoot.java:106)
    at net.minecraft.inventory.Slot.getStack(Slot.java:60)
    at net.minecraft.client.gui.inventory.GuiContainer.drawSlot(GuiContainer.java:202)
    at net.minecraft.client.gui.inventory.GuiContainer.drawScreen(GuiContainer.java:98)
    at net.minecraftforge.client.ForgeHooksClient.drawScreen(ForgeHooksClient.java:396)

-- Screen render details --
Details:
    Screen name: ru.qlcreations.exile_z_decorative.objects.blocks.gui.GuiTrashBinSmall
    Mouse location: Scaled: (213, 119). Absolute: (427, 240)
    Screen size: Scaled: (427, 240). Absolute: (854, 480). Scale factor of 2

-- Affected level --
Details:
    Level name: MpServer
    All players: 1 total; [EntityPlayerSP['Player937'/19, l='MpServer', x=-416.15, y=4.00, z=850.03]]
    Chunk stats: MultiplayerChunkCache: 121, 121
    Level seed: 0
    Level generator: ID 01 - flat, ver 0. Features enabled: false
    Level generator options:
    Level spawn location: World: (-375,4,814), Chunk: (at 9,0,14 in -24,50; contains blocks -384,0,800 to -369,255,815), Region: (-1,1; contains chunks -32,32 to -1,63, blocks -512,0,512 to -1,255,1023)
    Level time: 59675 game time, 40719 day time
    Level dimension: 0
    Level storage version: 0x00000 - Unknown?
    Level weather: Rain time: 0 (now: false), thunder time: 0 (now: false)
    Level game mode: Game mode: creative (ID 1). Hardcore: false. Cheats: false
    Forced entities: 5 total; [EntityPlayerSP['Player937'/19, l='MpServer', x=-416.15, y=4.00, z=850.03], EntityCow['Cow'/4, l='MpServer', x=-406.33, y=4.00, z=906.57], EntityCow['Cow'/8, l='MpServer', x=-375.84, y=4.00, z=874.05], EntityItem['item.item.egg'/12, l='MpServer', x=-353.91, y=4.00, z=791.32], EntitySheep['Sheep'/13, l='MpServer', x=-354.21, y=4.00, z=787.29]]
    Retry entities: 0 total; []
    Server brand: fml,forge
    Server type: Integrated singleplayer server
Stacktrace:
    at net.minecraft.client.multiplayer.WorldClient.addWorldInfoToCrashReport(WorldClient.java:420)
    at net.minecraft.client.Minecraft.addGraphicsAndWorldToCrashReport(Minecraft.java:2741)
    at net.minecraft.client.Minecraft.run(Minecraft.java:419)
    at net.minecraft.client.main.Main.main(Main.java:118)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at net.minecraft.launchwrapper.Launch.launch(Launch.java:135)
    at net.minecraft.launchwrapper.Launch.main(Launch.java:28)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at net.minecraftforge.legacydev.Main.start(Main.java:86)
    at net.minecraftforge.legacydev.MainClient.main(MainClient.java:29)
 
40
4
4
Исправил переписав все 5 классов

TrashBinSmall:
public class TrashBinSmall extends BlockContainer {
    private static final AxisAlignedBB BOUNDING_BOX = new AxisAlignedBB(0.200D, 0.0D, 0.125D, 0.800D, 0.9465D, 0.875D);
    private static final AxisAlignedBB COLLISION_BOX = new AxisAlignedBB(0.200D, 0.0D, 0.125D, 0.800D, 0.9465D, 0.875D);

    private static String unlocName;

    public TrashBinSmall(String name, Material material)
    {
        super(material);
        this.setRegistryName(name);
        this.setUnlocalizedName(name);
        unlocName = name;
    }

    @SideOnly(Side.CLIENT)
    public void initModel() {
        ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(this), 0, new ModelResourceLocation(getRegistryName(), "inventory"));
    }

    @Override
    @SideOnly(Side.CLIENT)
    public boolean shouldSideBeRendered(IBlockState blockState, IBlockAccess worldIn, BlockPos pos, EnumFacing side) {
        return false;
    }

    @Override
    public boolean isBlockNormalCube(IBlockState blockState) {
        return false;
    }

    @Override
    public boolean isOpaqueCube(IBlockState blockState) {
        return false;
    }

    @Override
    public boolean isFullCube(IBlockState blockState) {
        return false;
    }

    @Override
    public boolean isFullBlock(IBlockState state) { return false; }

    @Override
    public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos) {
        return BOUNDING_BOX;
    }

    public static AxisAlignedBB getCollisionBox() {
        return COLLISION_BOX;
    }

    public static String getUnlocName() {
        return unlocName;
    };

    private final Random rand = new Random();

    @Override
    public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) {
        if (world.isRemote) return true;
        else {
            ILockableContainer container = this.getLockableContainer(world, pos);
            if (container != null) {
                if (((TileEntityTrashBinSmall)container).lidAngle == 0) {
                    ((TileEntityTrashBinSmall)container).openSide = player.getHorizontalFacing();
                }
                player.openGui(Reference.MODID, Reference.GUI_TRASH_BIN, world, pos.getX(), pos.getY(), pos.getZ());
            }
            return true;
        }
    }

    @Nullable
    public ILockableContainer getLockableContainer(World world, BlockPos pos) {
        return this.getContainer(world, pos, false);
    }

    @Nullable
    public ILockableContainer getContainer(World world, BlockPos pos, boolean allowBlocking) {
        TileEntity tileentity = world.getTileEntity(pos);
        if (!(tileentity instanceof TileEntityTrashBinSmall)) return null;
        if (!allowBlocking && this.isBlocked(world, pos)) return null;
        return (TileEntityTrashBinSmall)tileentity;
    }

    @Override
    public BlockFaceShape getBlockFaceShape(IBlockAccess world, IBlockState state, BlockPos pos, EnumFacing face) {
        return BlockFaceShape.UNDEFINED;
    }

    @Override
    public void breakBlock(World world, BlockPos pos, IBlockState state) {
        TileEntity tileentity = world.getTileEntity(pos);
        if (tileentity instanceof IInventory) {
            InventoryHelper.dropInventoryItems(world, pos, (IInventory) tileentity);
            world.updateComparatorOutputLevel(pos, this);
        }
        super.breakBlock(world, pos, state);
    }

    @Override
    public void onBlockPlacedBy(World world, BlockPos pos, IBlockState state, EntityLivingBase placer, ItemStack stack) {
        TileEntity te = world.getTileEntity(pos);
        if (te instanceof TileEntityTrashBinSmall) {
            ((TileEntityTrashBinSmall) te).setLootTable(LootTableList.LOOT_TRASH_BIN_SMALL, world.rand.nextLong());
        }
    }

    private boolean isBlocked(World world, BlockPos pos) {
        return false;
    }

    public TileEntity createNewTileEntity(World world, int par2)
    {
        return new TileEntityTrashBinSmall();
    }

    @Override
    public EnumBlockRenderType getRenderType(IBlockState state) {
        return EnumBlockRenderType.MODEL;
    }

}
TileEntityTrashBinSmall:
public class TileEntityTrashBinSmall extends TileEntityLockableLoot implements ITickable {

    private int size = 27;
    private NonNullList<ItemStack> urnContents = NonNullList.<ItemStack>withSize(size, ItemStack.EMPTY);
    public float lidAngle;
    public float prevLidAngle;
    public int numPlayersUsing;
    /** Server sync counter (once per 20 ticks) */
    private int ticksSinceSync;
    public EnumFacing openSide;

    @Override
    public int getSizeInventory() {
        return size;
    }

    @Override
    public boolean isEmpty() {
        for (ItemStack itemstack : this.urnContents) {
            if (!itemstack.isEmpty()) return false;
        }
        return true;
    }

    @Override
    public int getInventoryStackLimit() {
        return 64;
    }

    @Override
    public String getName() {
        return this.hasCustomName() ? this.customName : "container.mist_urn";
    }

    @Override
    public boolean hasCustomName() {
        return this.customName != null && !this.customName.isEmpty();
    }

    @Override
    public void setCustomName(String name) {
        this.customName = name;
    }

    @Override
    public void readFromNBT(NBTTagCompound compound) {
        super.readFromNBT(compound);
        this.urnContents = NonNullList.<ItemStack>withSize(this.getSizeInventory(), ItemStack.EMPTY);
        if (!this.checkLootAndRead(compound)) {
            ItemStackHelper.loadAllItems(compound, this.urnContents);
        }
        if (compound.hasKey("CustomName", 8)) {
            this.customName = compound.getString("CustomName");
        }
    }

    @Override
    public NBTTagCompound writeToNBT(NBTTagCompound compound) {
        super.writeToNBT(compound);
        if (!this.checkLootAndWrite(compound)) {
            ItemStackHelper.saveAllItems(compound, this.urnContents);
        }
        if (this.hasCustomName()) {
            compound.setString("CustomName", this.customName);
        }
        return compound;
    }

    @Override
    public SPacketUpdateTileEntity getUpdatePacket() {
        return new SPacketUpdateTileEntity(this.pos, this.getBlockMetadata(), this.getUpdateTag());
    }

    @Override
    public void onDataPacket(NetworkManager net, SPacketUpdateTileEntity pkt) {
        handleUpdateTag(pkt.getNbtCompound());
    }

    @Override
    public NBTTagCompound getUpdateTag() {
        return writeToNBT(new NBTTagCompound());
    }

    public void updateStatus() {
        this.updateStatus(this.world.getBlockState(pos));
    }

    public void updateStatus(IBlockState state) {
        this.markDirty();
        this.world.notifyBlockUpdate(pos, this.world.getBlockState(pos), state, 3);
    }

    @Override
    public void update() {
        int x = this.pos.getX();
        int y = this.pos.getY();
        int z = this.pos.getZ();
        ++this.ticksSinceSync;
        if (!this.world.isRemote && this.numPlayersUsing != 0 && (this.ticksSinceSync + x + y + z) % 200 == 0) {
            this.numPlayersUsing = 0;
            float f = 5.0F;
            for (EntityPlayer player : this.world.getEntitiesWithinAABB(EntityPlayer.class, new AxisAlignedBB(x - f, y - f, z - f, x + 1 + f, y + 1 + f, z + 1 + f))) {
                if (player.openContainer instanceof ContainerTrashBinSmall && ((ContainerTrashBinSmall)player.openContainer).getTrashBinSmallInventory() == this) {
                    ++this.numPlayersUsing;
                }
            }
        }
        this.prevLidAngle = this.lidAngle;
        if (this.numPlayersUsing > 0 && this.lidAngle == 0.0F) {
            this.world.playSound((EntityPlayer)null, x + 0.5D, y + 0.5D, z + 0.5D, SoundEvents.BLOCK_CHEST_OPEN, SoundCategory.BLOCKS, 0.5F, this.world.rand.nextFloat() * 0.1F + 0.9F);
        }
        if (this.numPlayersUsing == 0 && this.lidAngle > 0.0F || this.numPlayersUsing > 0 && this.lidAngle < 1.0F) {
            float speed = 0.1F;

            if (this.numPlayersUsing > 0) this.lidAngle += speed;
            else this.lidAngle -= speed;

            if (this.lidAngle > 1.0F) this.lidAngle = 1.0F;

            if (this.lidAngle < 0.5F && this.prevLidAngle >= 0.5F) {
                this.world.playSound((EntityPlayer)null, x + 0.5D, y + 0.5D, z + 0.5D, SoundEvents.BLOCK_CHEST_CLOSE, SoundCategory.BLOCKS, 0.5F, this.world.rand.nextFloat() * 0.1F + 0.9F);
            }
            if (this.lidAngle < 0.0F) this.lidAngle = 0.0F;
        }
    }

    @Override
    public boolean receiveClientEvent(int id, int type) {
        if (id == 1) {
            this.numPlayersUsing = type;
            return true;
        } else if (id == 2) {
            this.openSide = EnumFacing.getFront(type);
            return true;
        } else return super.receiveClientEvent(id, type);
    }

    @Override
    public void openInventory(EntityPlayer player) {
        if (!player.isSpectator()) {
            if (this.numPlayersUsing < 0) this.numPlayersUsing = 0;
            ++this.numPlayersUsing;
            this.world.addBlockEvent(this.pos, this.getBlockType(), 1, this.numPlayersUsing);
            if (!this.world.isRemote)
                this.world.addBlockEvent(this.pos, this.getBlockType(), 2, this.openSide.getIndex());
        }
    }

    @Override
    public void closeInventory(EntityPlayer player) {
        if (!player.isSpectator() && this.getBlockType() instanceof TrashBinSmall) {
            --this.numPlayersUsing;
            this.world.addBlockEvent(this.pos, this.getBlockType(), 1, this.numPlayersUsing);
        }
    }

    @Override
    public Container createContainer(InventoryPlayer playerInventory, EntityPlayer player) {
        this.fillWithLoot(player);
        return new ContainerTrashBinSmall(this, player);
    }

    @Override
    public String getGuiID() {
        return "mist:urn";
    }

    @Override
    protected NonNullList<ItemStack> getItems() {
        return this.urnContents;
    }

    @Override
    public void fillWithLoot(@Nullable EntityPlayer player) {
        if (this.lootTable != null && this.world instanceof WorldServer) {
            LootTable loottable = this.world.getLootTableManager().getLootTableFromLocation(this.lootTable);
            this.lootTable = null;
            Random random;
            if (this.lootTableSeed == 0L) random = new Random();
            else random = new Random(this.lootTableSeed);
            LootContext.Builder builder = new LootContext.Builder((WorldServer) this.world);
            if (player != null) builder.withLuck(player.getLuck()).withPlayer(player);
            loottable.fillInventory(this, random, builder.build());
        }
    }
}
ContainerTrashBinSmall:
public class ContainerTrashBinSmall extends Container {

    private final IInventory inventory;
    private int slotID = 0;

    public ContainerTrashBinSmall(IInventory inventory, EntityPlayer player) {
        this.inventory = inventory;
        inventory.openInventory(player);
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 9; j++) {
                this.addSlotToContainer(new Slot(this.inventory, slotID++, 8 + j * 18, 18 + i * 18));
            }
        }
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 9; j++) {
                this.addSlotToContainer(new Slot(player.inventory, j + i * 9 + 9, 8 + j * 18, 84 + i * 18));
            }
        }
        for (int i = 0; i < 9; i++) {
            this.addSlotToContainer(new Slot(player.inventory, i, 8 + i * 18, 142));
        }
    }

    @Override
    public ItemStack transferStackInSlot(EntityPlayer player, int slotRaw)
    {
        ItemStack stack = ItemStack.EMPTY;
        Slot slot = inventorySlots.get(slotRaw);

        if (slot != null && slot.getHasStack())
        {
            ItemStack stackInSlot = slot.getStack();
            stack = stackInSlot.copy();

            // С помощью кода ниже мы предотвращаем краш при перетаскивании предметов нажатием Shift
            if (slotRaw < 3)
            {
                if (!mergeItemStack(stackInSlot, 3, inventorySlots.size(), true))
                {
                    return ItemStack.EMPTY;
                }
            }
            else if (!mergeItemStack(stackInSlot, 0, 3, false))
            {
                return ItemStack.EMPTY;
            }

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

            else
            {
                slot.onSlotChanged();
            }
        }
        return stack;
    }

    @Override
    public boolean canInteractWith(EntityPlayer player) {
        return this.inventory.isUsableByPlayer(player);
    }

    @Override
    public void onContainerClosed(EntityPlayer player) {
        super.onContainerClosed(player);
        this.inventory.closeInventory(player);
    }

    public IInventory getTrashBinSmallInventory() {
        return this.inventory;
    }
}
GuiTrashBinSmall:
public class GuiTrashBinSmall extends GuiContainer
{
    private static final ResourceLocation TEXTURES = new ResourceLocation(Reference.MODID, "textures/gui/container/chest.png");
    private final InventoryPlayer playerInventory;
    public IInventory urnInventory;

    public GuiTrashBinSmall(IInventory trashBinSmallInv, EntityPlayer player) {
        super(new ContainerTrashBinSmall(trashBinSmallInv, player));
        this.playerInventory = player.inventory;
        this.urnInventory = trashBinSmallInv;
    }

    public void drawScreen(int mouseX, int mouseY, float partialTicks) {
        this.drawDefaultBackground();
        super.drawScreen(mouseX, mouseY, partialTicks);
        this.renderHoveredToolTip(mouseX, mouseY);
    }

    protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) {
        String s = this.urnInventory.getDisplayName().getUnformattedText();
        this.fontRenderer.drawString(s, this.xSize / 2 - this.fontRenderer.getStringWidth(s) / 2, 6, 4210752);
        this.fontRenderer.drawString(this.playerInventory.getDisplayName().getUnformattedText(), 8, this.ySize - 96 + 2, 4210752);
    }

    protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) {
        GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
        this.mc.getTextureManager().bindTexture(TEXTURES);
        int i = (this.width - this.xSize) / 2;
        int j = (this.height - this.ySize) / 2;
        this.drawTexturedModalRect(i, j, 0, 0, this.xSize, this.ySize);
    }
}
GuiHandler:
public class GuiHandler implements IGuiHandler
{
    @Override
    public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z)
    {
        if(ID == Reference.GUI_TRASH_BIN) return new ContainerTrashBinSmall((TileEntityTrashBinSmall) world.getTileEntity(new BlockPos(x, y, z)), player);
        return null;
    }

    @Override
    @SideOnly(Side.CLIENT)
    public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z)
    {
        if(ID == Reference.GUI_TRASH_BIN) return new GuiTrashBinSmall((TileEntityTrashBinSmall) world.getTileEntity(new BlockPos(x, y, z)), player);
        return null;
    }
}
Осталось только таймер
 
Сверху