[1.8.9] Краш. Не могу разобраться

1,015
9
102
Сделал GUI с контейнером и tileEntity у блока. И при "активации блока" выскакивает краш: https://gist.github.com/anonymous/1da40630236b6e609eb3

Я задебажил и вроде бы это из за того, что я передаю в GUIHandler TileEntity, который равен null, но я не уверен что это только из за этого.
Вот GUIHandler:
Код:
package com.minebot.statics.gui;

import com.minebot.statics.gui.Magnet.ContainerMagnet;
import com.minebot.statics.gui.Magnet.GUIMagnet;
import com.minebot.statics.gui.Magnet.InventoryMagnet;
import com.minebot.statics.gui.SpoilGenerator.SG_Container;
import com.minebot.statics.gui.SpoilGenerator.SG_GUI;
import com.minebot.statics.gui.SpoilGenerator.SG_TileEntity;

import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.network.IGuiHandler;

public class GuiHandler implements IGuiHandler{

    @Override
    public Object getServerGuiElement(int ID, EntityPlayer player, World world,
            int x, int y, int z) {
        if(ID == 0){ return new ContainerMagnet(player.inventory, player, new InventoryMagnet()); }
        else if(ID == 1){ return new SG_Container(player.inventory,(SG_TileEntity) world.getTileEntity(new BlockPos(x, y, z))); }
        return null;
    }

    @Override
    public Object getClientGuiElement(int ID, EntityPlayer player, World world,
            int x, int y, int z) {
        if(ID == 0){ return new GUIMagnet(player.inventory, player, new InventoryMagnet()); }
        else if(ID == 1){ return new SG_GUI(player.inventory, (SG_TileEntity) world.getTileEntity(new BlockPos(x, y, z))); }
        return null;
    }

}

TileEntity и IInventory:
Код:
package com.minebot.statics.gui.SpoilGenerator;

import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.IChatComponent;

public class SG_TileEntity extends TileEntity implements IInventory{

    private String customName;
    private ItemStack[] inventory = new ItemStack[2];
    
    @Override
    public String getName()
    {
        return this.hasCustomName() ? this.customName : "container.spoilGenerator";
    }

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

    @Override
    public IChatComponent getDisplayName() {
        return null;
    }

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

    @Override
    public ItemStack getStackInSlot(int index)
    {
        if(index >= 0 && index < getSizeInventory())
            return inventory[index];
        return null;
    }

    @Override
    public ItemStack decrStackSize(int index, int count) {
        if (this.inventory[index] != null)
        {
            if (this.inventory[index].stackSize <= count)
            {
                ItemStack itemstack1 = this.inventory[index];
                this.inventory[index] = null;
                this.markDirty();
                return itemstack1;
            }
            else
            {
                ItemStack itemstack = this.inventory[index].splitStack(count);

                if (this.inventory[index].stackSize == 0)
                {
                    this.inventory[index] = null;
                }

                this.markDirty();
                return itemstack;
            }
        }
        else
        {
            return null;
        }
    }

    @Override
    public ItemStack removeStackFromSlot(int index) {
        if (this.inventory[index] != null)
        {
            ItemStack itemstack = this.inventory[index];
            this.inventory[index] = null;
            return itemstack;
        }
        else
        {
            return null;
        }
    }

    @Override
    public void setInventorySlotContents(int index, ItemStack stack) {
        this.inventory[index] = stack;

        if (stack != null && stack.stackSize > this.getInventoryStackLimit())
        {
            stack.stackSize = this.getInventoryStackLimit();
        }

        this.markDirty();
    }

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

    @Override
    public boolean isUseableByPlayer(EntityPlayer player) {
        return true;
    }

    @Override
    public void openInventory(EntityPlayer player) {
        // TODO Auto-generated method stub
        
    }

    @Override
    public void closeInventory(EntityPlayer player) {
        // TODO Auto-generated method stub
        
    }

    @Override
    public boolean isItemValidForSlot(int index, ItemStack stack) {
        return true;
    }
    
    @Override
    public void readFromNBT(NBTTagCompound compound) 
    {
            NBTTagList list = compound.getTagList("Items", 10);
            for(int i = 0; i < list.tagCount(); i++)
            {
                NBTTagCompound tag = list.getCompoundTagAt(i);
                int j = tag.getByte("Slot") & 255;
                if (j >= 0 && j < this.inventory.length)
                {
                    this.inventory[j] = ItemStack.loadItemStackFromNBT(tag);
                }
        }
    }
    
    @Override
    public void writeToNBT(NBTTagCompound compound) 
    {
        NBTTagList list = new NBTTagList();
        for(int i = 0; i < inventory.length; i++)
        {
            if(getStackInSlot(i) != null)
            {
                NBTTagCompound tag = new NBTTagCompound();
                tag.setByte("Slot",(byte) i);
                getStackInSlot(i).writeToNBT(tag);
                list.appendTag(tag);
            }
        }
        compound.setTag("Items", list);
    }

    @Override
    public int getField(int id) {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public void setField(int id, int value) {
        // TODO Auto-generated method stub
        
    }

    @Override
    public int getFieldCount() {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public void clear() {
        for (int i = 0; i < this.inventory.length; ++i)
        {
            this.inventory[i] = null;
        }
    }

}


Контейнер:
Код:
package com.minebot.statics.gui.SpoilGenerator;

import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;

public class SG_Container extends Container{
    private SG_TileEntity te;
    
    public SG_Container(IInventory playerInv, SG_TileEntity te) {
        this.te = te;

        // Tile Entity, Slot 0-2, Slot IDs 0-1
        addSlotToContainer(new SG_LeftSlot(te, 0, 40, 9));
        addSlotToContainer(new SG_RightSlot(te, 1, 97, 30));

        // Player Inventory, Slot 9-35, Slot IDs 9-35
        for (int y = 0; y < 3; ++y) {
            for (int x = 0; x < 9; ++x) {
                this.addSlotToContainer(new Slot(playerInv, x + y * 9 + 9, 8 + x * 18, 84 + y * 18));
            }
        }

        // Player Inventory, Slot 0-8, Slot IDs 36-44
        for (int x = 0; x < 9; ++x) {
            this.addSlotToContainer(new Slot(playerInv, x, 8 + x * 18, 142));
        }
    }

    @Override
    public boolean canInteractWith(EntityPlayer playerIn) {
        return te.isUseableByPlayer(playerIn);
    }
    
    @Override
    public ItemStack transferStackInSlot(EntityPlayer playerIn, int fromSlot) {
        ItemStack previous = null;
        Slot slot = (Slot) this.inventorySlots.get(fromSlot);

        if (slot != null && slot.getHasStack()) {
            ItemStack current = slot.getStack();
            previous = current.copy();

            if (fromSlot < 2) {
                // From TE Inventory to Player Inventory
                if (!this.mergeItemStack(current, 2, 41, true))
                    return null;
            } else {
                // From Player Inventory to TE Inventory
                if (!this.mergeItemStack(current, 0, 2, false))
                    return null;
            }

            if (current.stackSize == 0)
                slot.putStack((ItemStack) null);
            else
                slot.onSlotChanged();

            if (current.stackSize == previous.stackSize)
                return null;
            slot.onPickupFromSlot(playerIn, current);
        }
        return previous;
    }
}


GUI:
Код:
package com.minebot.statics.gui.SpoilGenerator;

import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.inventory.IInventory;
import net.minecraft.util.ResourceLocation;

import org.lwjgl.opengl.GL11;

public class SG_GUI extends GuiContainer{
    public SG_GUI(IInventory playerInv, SG_TileEntity te) {
        super(new SG_Container(playerInv, te));

        this.xSize = 176;
        this.ySize = 166;
    }

    @Override
    protected void drawGuiContainerBackgroundLayer(float par1, int par2,
                    int par3) {
            ResourceLocation texture = new ResourceLocation("st", "textures/gui/spoilGenerator_GUI.png");
            GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
            this.mc.renderEngine.bindTexture(texture);
            int x = (width - xSize) / 2;
            int y = (height - ySize) / 2;
            this.drawTexturedModalRect(x, y, 0, 0, xSize, ySize);
    }
}


Один слот:
Код:
package com.minebot.statics.gui.SpoilGenerator;

import net.minecraft.init.Items;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Slot;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;

import com.minebot.statics.ModInfo;

public class SG_RightSlot extends Slot{

    public SG_RightSlot(IInventory inventoryIn, int index, int xPosition,
            int yPosition) {
        super(inventoryIn, index, xPosition, yPosition);
    }
    
    @Override
    public boolean isItemValid(ItemStack stack) {
        Item[] itemsIsValid = new Item[]{ Items.iron_ingot, Items.gold_ingot, Items.diamond, Items.coal, ModInfo.Staryse }; 
        boolean Return = false;
        for (Item item : itemsIsValid) {
            if(stack.getItem().getUnlocalizedName() == item.getUnlocalizedName()) Return = true;
        }
        return Return;
    }
}


И другой слот:
Код:
package com.minebot.statics.gui.SpoilGenerator;

import com.minebot.statics.ModInfo;

import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;

public class SG_LeftSlot extends Slot{

    public SG_LeftSlot(IInventory inventoryIn, int index, int xPosition,
            int yPosition) {
        super(inventoryIn, index, xPosition, yPosition);
    }
    
    @Override
    public boolean isItemValid(ItemStack stack) {
        if(stack.getItem().getUnlocalizedName() == ModInfo.Staryse.getUnlocalizedName())
        return true;
        else return false;
    }
    
}
 
Нужно ItemStack проверять на не равен нулевому значению ("!= null").
Класс слота SG_RightSlot, метод isItemValid - думаю нужно сделать перед циклом условие "stack != null".
Класс слота SG_LeftSlot, метод isItemValid - думаю нужно добавить в условие "stack != null".
 
Сделал вот так:
Код:
    @Override
    public boolean isItemValid(ItemStack stack) {
        if(stack == null){ return false; }
        if(stack.getItem().getUnlocalizedName() == ModInfo.Staryse.getUnlocalizedName())
        return true;
        else return false;
    }
И так:
Код:
    @Override
    public boolean isItemValid(ItemStack stack) {
        Item[] itemsIsValid = new Item[]{ Items.iron_ingot, Items.gold_ingot, Items.diamond, Items.coal, ModInfo.Staryse }; 
        if(stack == null){ return false; }
        boolean Return = false;
        for (Item item : itemsIsValid) {
            if(stack.getItem().getUnlocalizedName() == item.getUnlocalizedName()) Return = true;
        }
        return Return;
    }
Но краш тот же остался. Проблема в другом
 
Да, я был прав. Краш происходит из за того, что передаваемое в GUIHundler'e TileEntity равно null. Вот та строчка, почему TileEntity из блока равно null?
Код:
else if(ID == 1){ return new SG_Container(player.inventory,(SG_TileEntity) world.getTileEntity(new BlockPos(x, y, z))); }
 
Кода твоего блока нет.
 
Вот:
Код:
package com.minebot.statics.blocks;

import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.BlockPos;
import net.minecraft.util.EnumFacing;
import net.minecraft.world.World;

import com.minebot.statics.Main;
import com.minebot.statics.ModInfo;

public class SplitGenerator extends Block {

    public static final SplitGenerator splitGenerator = new SplitGenerator() ;
    
    public SplitGenerator() {
        super(Material.iron);
        this.setUnlocalizedName(ModInfo.MODID + ":splitGenerator");
        this.setCreativeTab(ModInfo.stCreativeTab);
        this.setHardness(5f);
        this.setHarvestLevel("pickaxe", 2);
        this.setStepSound(soundTypeMetal);
    }
    
    @Override
    public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn, EnumFacing side, float hitX, float hitY, float hitZ)
    {
        playerIn.openGui(Main.instance, 1, worldIn, pos.getX(), pos.getY(), pos.getZ());
        return true;
    }

}
 
Сам блок не ставить твоего TileEntity, по этому он нулл, так как этой позиции нет твоего TileEntity.
 
Точно! Я его не зарегал
[merge_posts_bbcode]Добавлено: 16.03.2016 21:39:31[/merge_posts_bbcode]

А как его блоку дать?
 
На 1.8.9 не знаю, что именно надо. Но вроде нужно к наследству подставить "implements ITileEntityProvider". Пример можно взять BlockContainer.
 
Назад
Сверху