Проблемы с Loot Table

Версия Minecraft
1.12.2
4,045
63
645
Всем привет!
Борюсь тут с проблемой лута и уже не знаю, куда смотреть.
Может кто поможет.

Поведение следующее: при установке гружу в контейнер таблицу лута. Если контейнер сразу же сломать, предметы дропаются. Зато при попытке открыть гуи игра вылетает.
Вот краш-лог:
Код:
[07:34:31] [Server thread/WARN] [minecraft/LootTable]: Tried to over-fill a container
[07:34:31] [main/FATAL] [minecraft/Minecraft]: Error executing task
java.util.concurrent.ExecutionException: java.lang.NullPointerException
    at java.util.concurrent.FutureTask.report(Unknown Source) ~[?:1.8.0_131]
    at java.util.concurrent.FutureTask.get(Unknown Source) ~[?:1.8.0_131]
    at net.minecraft.util.Util.runTask(Util.java:54) [Util.class:?]
    at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1177) [Minecraft.class:?]
    at net.minecraft.client.Minecraft.run(Minecraft.java:441) [Minecraft.class:?]
    at net.minecraft.client.main.Main.main(Main.java:118) [Main.class:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_131]
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_131]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_131]
    at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_131]
    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_131]
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_131]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_131]
    at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_131]
    at net.minecraftforge.gradle.GradleStartCommon.launch(GradleStartCommon.java:97) [start/:?]
    at GradleStart.main(GradleStart.java:25) [start/:?]
Caused by: java.lang.NullPointerException
    at net.minecraft.tileentity.TileEntityLockableLoot.fillWithLoot(TileEntityLockableLoot.java:59) ~[TileEntityLockableLoot.class:?]
    at net.minecraft.tileentity.TileEntityLockableLoot.setInventorySlotContents(TileEntityLockableLoot.java:146) ~[TileEntityLockableLoot.class:?]
    at net.minecraft.inventory.Slot.putStack(Slot.java:97) ~[Slot.class:?]
    at net.minecraft.inventory.Container.setAll(Container.java:565) ~[Container.class:?]
    at net.minecraft.client.network.NetHandlerPlayClient.handleWindowItems(NetHandlerPlayClient.java:1314) ~[NetHandlerPlayClient.class:?]
    at net.minecraft.network.play.server.SPacketWindowItems.processPacket(SPacketWindowItems.java:68) ~[SPacketWindowItems.class:?]
    at net.minecraft.network.play.server.SPacketWindowItems.processPacket(SPacketWindowItems.java:13) ~[SPacketWindowItems.class:?]
    at net.minecraft.network.PacketThreadUtil$1.run(PacketThreadUtil.java:21) ~[PacketThreadUtil$1.class:?]
    at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) ~[?:1.8.0_131]
    at java.util.concurrent.FutureTask.run(Unknown Source) ~[?:1.8.0_131]
    at net.minecraft.util.Util.runTask(Util.java:53) ~[Util.class:?]
    ... 15 more
[07:34:31] [main/FATAL] [minecraft/Minecraft]: Error executing task

И чуть ниже:
Код:
net.minecraft.util.ReportedException: Rendering screen
    at net.minecraft.client.renderer.EntityRenderer.updateCameraAndRender(EntityRenderer.java:1204) ~[EntityRenderer.class:?]
    at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1208) ~[Minecraft.class:?]
    at net.minecraft.client.Minecraft.run(Minecraft.java:441) [Minecraft.class:?]
    at net.minecraft.client.main.Main.main(Main.java:118) [Main.class:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_131]
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_131]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_131]
    at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_131]
    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_131]
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_131]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_131]
    at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_131]
    at net.minecraftforge.gradle.GradleStartCommon.launch(GradleStartCommon.java:97) [start/:?]
    at GradleStart.main(GradleStart.java:25) [start/:?]
Caused by: java.lang.NullPointerException
    at net.minecraft.tileentity.TileEntityLockableLoot.fillWithLoot(TileEntityLockableLoot.java:59) ~[TileEntityLockableLoot.class:?]
    at net.minecraft.tileentity.TileEntityLockableLoot.getStackInSlot(TileEntityLockableLoot.java:112) ~[TileEntityLockableLoot.class:?]
    at net.minecraft.inventory.Slot.getStack(Slot.java:81) ~[Slot.class:?]
    at net.minecraft.client.gui.inventory.GuiContainer.drawSlot(GuiContainer.java:234) ~[GuiContainer.class:?]
    at net.minecraft.client.gui.inventory.GuiContainer.drawScreen(GuiContainer.java:116) ~[GuiContainer.class:?]
    at ru.liahim.mist.inventory.gui.GuiUrn.drawScreen(GuiUrn.java:30) ~[GuiUrn.class:?]
    at net.minecraftforge.client.ForgeHooksClient.drawScreen(ForgeHooksClient.java:381) ~[ForgeHooksClient.class:?]
    at net.minecraft.client.renderer.EntityRenderer.updateCameraAndRender(EntityRenderer.java:1177) ~[EntityRenderer.class:?]
    ... 15 more
[07:34:34] [main/INFO] [STDOUT]: [net.minecraft.init.Bootstrap:printToSYSOUT:629]: ---- Minecraft Crash Report ----
// Would you like a cupcake?

Time: 4/29/19 7:34 AM
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:112)
    at net.minecraft.inventory.Slot.getStack(Slot.java:81)
    at net.minecraft.client.gui.inventory.GuiContainer.drawSlot(GuiContainer.java:234)
    at net.minecraft.client.gui.inventory.GuiContainer.drawScreen(GuiContainer.java:116)
    at ru.liahim.mist.inventory.gui.GuiUrn.drawScreen(GuiUrn.java:30)
    at net.minecraftforge.client.ForgeHooksClient.drawScreen(ForgeHooksClient.java:381)
    at net.minecraft.client.renderer.EntityRenderer.updateCameraAndRender(EntityRenderer.java:1177)
    at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1208)
    at net.minecraft.client.Minecraft.run(Minecraft.java:441)
    at net.minecraft.client.main.Main.main(Main.java:118)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    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(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at net.minecraftforge.gradle.GradleStartCommon.launch(GradleStartCommon.java:97)
    at GradleStart.main(GradleStart.java:25)

Таблицу гружу следующим образом:
Java:
@Override
public void onBlockPlacedBy(World world, BlockPos pos, IBlockState state, EntityLivingBase placer, ItemStack stack) {
    TileEntity te = world.getTileEntity(pos);
    if (te instanceof TileEntityUrn) {
        ((TileEntityUrn) te).setLootTable(LootTableList.CHESTS_DESERT_PYRAMID, world.rand.nextLong());
    }
}
Всё остальное - это тупо копия сундука и гуи от раздатчика...

Код:
public class MistUrn extends BlockContainer {

    protected static final AxisAlignedBB URN_AABB = new AxisAlignedBB(0.3125D, 0.0D, 0.3125D, 0.6875D, 0.5625D, 0.6875D);

    public MistUrn() {
        super(Material.ROCK);
        this.setSoundType(SoundType.STONE);
        this.setHardness(0.2F);
        this.setHarvestLevel("pickaxe", 0);
    }

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

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

    @Override
    @SideOnly(Side.CLIENT)
    public boolean hasCustomBreakingProgress(IBlockState state) {
        return true;
    }

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

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

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

    @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 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 (((TileEntityUrn)container).lidAngle == 0) {
                    ((TileEntityUrn)container).openSide = player.getHorizontalFacing();
                }
                player.openGui(Mist.MODID, 5, 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 TileEntityUrn)) return null;
        if (!allowBlocking && this.isBlocked(world, pos)) return null;
        return (TileEntityUrn)tileentity;
    }

    @Override
    public TileEntity createNewTileEntity(World world, int meta) {
        return new TileEntityUrn();
    }

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

    @Override
    public boolean hasComparatorInputOverride(IBlockState state) {
        return true;
    }

    @Override
    public int getComparatorInputOverride(IBlockState blockState, World world, BlockPos pos) {
        return Container.calcRedstoneFromInventory(this.getLockableContainer(world, pos));
    }

    @Override
    public BlockFaceShape getBlockFaceShape(IBlockAccess world, IBlockState state, BlockPos pos, EnumFacing face) {
        return BlockFaceShape.UNDEFINED;
    }
}
Код:
public class TileEntityUrn extends TileEntityLockableLoot implements ITickable {

    private int size = 9;
    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 16;
    }

    @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 ContainerUrn && ((ContainerUrn)player.openContainer).getUrnInventory() == 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 MistUrn) {
            --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 ContainerUrn(this, player);
    }

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

    @Override
    protected NonNullList<ItemStack> getItems() {
        return this.urnContents;
    }
}
Код:
public class GuiHandler implements IGuiHandler {

    @Override
    public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) {
        switch(ID) {
            ...
            case 5: return new ContainerUrn((TileEntityUrn) world.getTileEntity(new BlockPos(x, y, z)), player);
            default: return null;
        }
    }

    @Override
    public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) {
        switch(ID) {
            ...
            case 5: return new GuiUrn((TileEntityUrn) world.getTileEntity(new BlockPos(x, y, z)), player);
            default: return null;
        }
    }
}
Код:
public class ContainerUrn extends Container {

    private final IInventory inventory;

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

    @Override
    public ItemStack transferStackInSlot(EntityPlayer player, int index) {
        ItemStack stack = ItemStack.EMPTY;
        Slot slot = this.inventorySlots.get(index);
        if (slot != null && slot.getHasStack()) {
            ItemStack stack1 = slot.getStack();
            stack = stack1.copy();
            if (index < 9) {
                if (!this.mergeItemStack(stack1, 9, 45, true)) return ItemStack.EMPTY;
            } else if (!this.mergeItemStack(stack1, 0, 9, false)) return ItemStack.EMPTY;
            if (stack1.isEmpty()) slot.putStack(ItemStack.EMPTY);
            else slot.onSlotChanged();
            if (stack1.getCount() == stack.getCount()) return ItemStack.EMPTY;
            slot.onTake(player, stack1);
        }
        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 getUrnInventory() {
        return this.inventory;
    }
}
Код:
@SideOnly(Side.CLIENT)
public class GuiUrn extends GuiContainer {

    private static final ResourceLocation TEXTURES = new ResourceLocation(Mist.MODID, "textures/gui/container/urn.png");
    private final InventoryPlayer playerInventory;
    public IInventory urnInventory;

    public GuiUrn(IInventory urnInv, EntityPlayer player) {
        super(new ContainerUrn(urnInv, player));
        this.playerInventory = player.inventory;
        this.urnInventory = urnInv;
    }

    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);
    }
}
 
Последнее редактирование:
1,159
38
544
Прошу извинить меня за возможное капитанство, но ты пробовал зайти отладчиком в TileEntityLockableLoot#fillWithLoot()?
 
4,045
63
645
Прощаю, а можно кодом?
Что значит "зайти отладчиком"?
Пробовал переопределать данный метод следующим образом:
Java:
public void fillWithLoot(@Nullable EntityPlayer player) {
    System.out.println(this.world.getLootTableManager().getLootTableFromLocation(this.lootTable).toString());
    super.fillWithLoot(player);
}

И при уничтожении блока вылетало следующее:
Код:
Caused by: java.lang.NullPointerException
    at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:770) ~[guava-21.0.jar:?]
    at com.google.common.cache.LocalCache.get(LocalCache.java:4153) ~[guava-21.0.jar:?]
    at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:4158) ~[guava-21.0.jar:?]
    at com.google.common.cache.LocalCache$LocalLoadingCache.get(LocalCache.java:5147) ~[guava-21.0.jar:?]
    at com.google.common.cache.LocalCache$LocalLoadingCache.getUnchecked(LocalCache.java:5153) ~[guava-21.0.jar:?]
    at net.minecraft.world.storage.loot.LootTableManager.getLootTableFromLocation(LootTableManager.java:40) ~[LootTableManager.class:?]
    at ru.liahim.mist.tileentity.TileEntityUrn.fillWithLoot(TileEntityUrn.java:214) ~[TileEntityUrn.class:?]
    at net.minecraft.tileentity.TileEntityLockableLoot.getStackInSlot(TileEntityLockableLoot.java:112) ~[TileEntityLockableLoot.class:?]
    at net.minecraft.inventory.InventoryHelper.dropInventoryItems(InventoryHelper.java:28) ~[InventoryHelper.class:?]
    at net.minecraft.inventory.InventoryHelper.dropInventoryItems(InventoryHelper.java:16) ~[InventoryHelper.class:?]
    at ru.liahim.mist.block.gizmos.MistUrn.breakBlock(MistUrn.java:86) ~[MistUrn.class:?]

ПыСы: хотя это было ещё тогда, когда подпихивал свою таблицу... С ванильной не пробовал, но судя по тому, что краш вылетает в обоих случаях, скорее всего, ситуация будет аналогичная.
 
1,159
38
544
Тов. @Liahim, в эклипсе/нетбинсе/идее есть кнопка, запускающая вашу программу в режиме отладчика. В этом режиме вы можете устанавливать точки остановки, при достижении которой программа зависнет, а вы сможете посмотреть/изменить значения любой переменной, доступной на этом участке
2019-04-29_17-45-24.png
2019-04-29_17-49-22.png

Попробуйте исследовать отладчиком метод TileEntityLockableLoot#fillWithLoot(). Думаю, проблема в нем.
 
1,159
38
544
3,005
192
592
Идет первый TileEntityLockableLoot#fillWithLoot.
Далее - lootTable становится нулл.
Но, почему-то вызывается еще раз TileEntityLockableLoot#fillWithLoot, где lootTable не является нуллом (буквально в проверке < тика назад), а в момент выполнения следующий строки (world.getLootTableManager().getLootTableFromLocation(this.lootTable)) lootTable уже является нуллом.
 
1,159
38
544
Как такое может быть?
Уж не знаю, извини. Не работал с 1.12.2. Думаю, тебе придется поиграть в детектива и хорошенько поиследовать пробленый код. Попробуй посмотреть что происходит в коде, который вызывает TileEntityLockableLoot#fillWithLoot().

wMI5laTnsno.jpg
 
4,045
63
645
В общем, прошёлся по последовательности. Беда, естественно в клиенте...
На серваке всё норм, заполняется, а потом всё это отправляется в гуи и на этом моменте он опять открывает слоты и пытается всё это заполнить...
Но там-то таблица не нулевая. Однако найти он её не может.
Попробовал то же самое проделать с ванильным сундуком, так он на клиенте вообще к данному месту не обращается.
Вывод: нужно как-то иначе вызывать ГуиХендлер.

Кстати, сундук открывается так:

Java:
public void displayGUIChest(IInventory chestInventory)
{
    if (chestInventory instanceof ILootContainer && ((ILootContainer)chestInventory).getLootTable() != null && this.isSpectator())
    {
        this.sendStatusMessage((new TextComponentTranslation("container.spectatorCantOpen", new Object[0])).setStyle((new Style()).setColor(TextFormatting.RED)), true);
    }
    else
    {
        if (this.openContainer != this.inventoryContainer)
        {
            this.closeScreen();
        }

        if (chestInventory instanceof ILockableContainer)
        {
            ILockableContainer ilockablecontainer = (ILockableContainer)chestInventory;

            if (ilockablecontainer.isLocked() && !this.canOpen(ilockablecontainer.getLockCode()) && !this.isSpectator())
            {
                this.connection.sendPacket(new SPacketChat(new TextComponentTranslation("container.isLocked", new Object[] {chestInventory.getDisplayName()}), ChatType.GAME_INFO));
                this.connection.sendPacket(new SPacketSoundEffect(SoundEvents.BLOCK_CHEST_LOCKED, SoundCategory.BLOCKS, this.posX, this.posY, this.posZ, 1.0F, 1.0F));
                return;
            }
        }

        this.getNextWindowId();

        if (chestInventory instanceof IInteractionObject)
        {
            this.connection.sendPacket(new SPacketOpenWindow(this.currentWindowId, ((IInteractionObject)chestInventory).getGuiID(), chestInventory.getDisplayName(), chestInventory.getSizeInventory()));
            this.openContainer = ((IInteractionObject)chestInventory).createContainer(this.inventory, this);
        }
        else
        {
            this.connection.sendPacket(new SPacketOpenWindow(this.currentWindowId, "minecraft:container", chestInventory.getDisplayName(), chestInventory.getSizeInventory()));
            this.openContainer = new ContainerChest(this.inventory, chestInventory, this);
        }

        this.openContainer.windowId = this.currentWindowId;
        this.openContainer.addListener(this);
        net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.player.PlayerContainerEvent.Open(this, this.openContainer));
    }
}

Но как тут вызвать моё гуи?

ПыСы: Кстати, если открываю его подобным образом, всё работает, но гуи открывается от сундука.
 
Последнее редактирование:
4,045
63
645
Итак!
Для всех тех, кто столкнётся с данной проблемой, тупо переопределяем метод и добавляем проверку на мир... Усё!
Код:
@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());
    }
}

Что-то форджевцы опять намутили.
 
Сверху