Проблемы с контейнером

Версия Minecraft
1.7.10
Итак, начнём с того что я пытаюсь сделать контейнер, который пока-что ничего не делает, а просто имеет слоты игрока и слоты тайла, слоты игрока нормально работают, в отличии от вторых, когда я кладу любой предмет в слот тайла, то он просто выпадает, либо дюпается, но когда я повторно нажимаю по нему, то он просто пропадает..
Код:
public class TileServerCore extends AITile implements IAIMultiBlock, ICellContainer, INetworkToolAgent, IInventoryHost {

    public static final int BLOCKS_IN_STRUCTURE = Patterns.ME_SERVER.length+1;
    // List of blocks in multiblock
    public Vector<IAIMultiBlock> Slaves = new Vector<>();

    public AIGridNodeInventory inv = new AIGridNodeInventory("ME Server",30,1,this){
        @Override
        public boolean isItemValidForSlot(int i, ItemStack itemstack) {
            return AEApi.instance().registries().cell().isCellHandled(itemstack);
        }
    };

    // ME Inventories
    private List<IMEInventoryHandler> items = new LinkedList<>();
    private List<IMEInventoryHandler> fluids = new LinkedList<>();

    // Networks in ports
    public Vector<IGrid> portNetworks = new Vector<>();
    // Network of owner
    public IGrid MainNetwork;

    private boolean tryForm;
    public boolean isFormed;

    public boolean isConflicting;

    private short[] blinkTimers;
    private byte[] cellStatuses = new byte[6];

    // Wait for updating
    public int blocksToPlace = 0;

    @Override
    public void updateEntity() {
        super.updateEntity();
        if (isFormed) {
            for (IAIMultiBlock slave : Slaves) {
                slave.notifyBlock();
            }
            /*if (MainNetwork != null) {
                for (IGrid grid : portNetworks) {
                    if (grid == MainNetwork) {
                        for (IAIMultiBlock slave : Slaves) {
                            if (slave instanceof TileServerRib) {
                                if (!isConflicting) {
                                    TileServerRib rib = (TileServerRib) slave;
                                    rib.notifyConflict();
                                    isConflicting = true;
                                    return;
                                }
                            }
                        }
                    }
                }

            }*/

        /*if(tryForm){
            isFormed = false;
            if(worldObj != null) {
                this.tryConstruct(null);
                tryForm = false;
            }
        }*/
        }
    }
    @Override
    public void validate(){
        tryForm = true;
    }
    @Override
    public void notifyBlock(){
        worldObj.markBlockForUpdate(xCoord,yCoord,zCoord);
    }
    @Override
    public void tryConstruct(EntityPlayer p) {
        if(!isFormed) {
            // For 4d humans =)
            blocksToPlace = BLOCKS_IN_STRUCTURE - 1;
            int count = 0;
            List<IAIMultiBlock> toUpdate = new ArrayList<>();
            for (int i = 0; i < Patterns.ME_SERVER.length; i++) {
                if (!this.worldObj.isRemote) {
                    int x, y, z;
                    Block block;

                    x = this.xCoord + Patterns.ME_SERVER[blocksToPlace - 1].x;
                    y = this.yCoord + Patterns.ME_SERVER[blocksToPlace - 1].y;
                    z = this.zCoord + Patterns.ME_SERVER[blocksToPlace - 1].z;
                    block = Patterns.ME_SERVER[blocksToPlace - 1].b;
                    if (worldObj.getBlock(x, y, z) == block) {
                        count++;
                        toUpdate.add((IAIMultiBlock) worldObj.getTileEntity(x, y, z));
                        blocksToPlace--;
                    }
                }
            }
            int counter = 0;
            for (int i = 0; i < Patterns.ME_SERVER.length; i++)
                if (Patterns.ME_SERVER[i] != null)
                    counter++;
            int BlocksToPlace = Patterns.ME_SERVER_FILL.length - 1;
            if (counter == count) {
                for (int i = 0; i < Patterns.ME_SERVER_FILL.length; i++) {
                    int x, y, z, meta;
                    Block block = Patterns.ME_SERVER_FILL[BlocksToPlace].b;

                    x = this.xCoord + Patterns.ME_SERVER_FILL[BlocksToPlace].x;
                    y = this.yCoord + Patterns.ME_SERVER_FILL[BlocksToPlace].y;
                    z = this.zCoord + Patterns.ME_SERVER_FILL[BlocksToPlace].z;
                    meta = Patterns.ME_SERVER_FILL[BlocksToPlace].meta;

                    worldObj.setBlock(x, y, z, Blocks.air);
                    worldObj.setBlock(x, y, z, block, meta, meta);
                    worldObj.markBlockForUpdate(x, y, z);
                    toUpdate.add((TileServerRib) worldObj.getTileEntity(x, y, z));
                    ((TileServerRib) worldObj.getTileEntity(x, y, z)).changeAlt(true);
                    BlocksToPlace--;
                }
                for (int i = 0; i < toUpdate.size(); i++) {
                    toUpdate.get(i).setMaster(this);
                    if (toUpdate.get(i) instanceof TileServerPort) {
                        TileServerPort port = (TileServerPort) toUpdate.get(i);
                        port.createAELink();
                    } else if (toUpdate.get(i) instanceof TileServerRib) {
                        TileServerRib rib = (TileServerRib) toUpdate.get(i);
                        rib.createAELink();
                    }
                    Slaves.add(toUpdate.get(i));
                }

            }

            isFormed = true;
            if(p!=null)
                p.addChatComponentMessage(new ChatComponentText("ME Server Formed!"));
        }

    }


    public void DestroyMultiBlock(){
        for(IAIMultiBlock tile : Slaves){
            if(tile instanceof TileServerRib){
                TileServerRib Rib = (TileServerRib)tile;
                Rib.changeAlt(false);
                Rib.destroyAELink();
            }
            if(tile instanceof TileServerPort){
                TileServerPort port = (TileServerPort)tile;
                port.destroyAELink();
            }
            tile.setMaster(null);

            if(((AIMultiBlockTile)tile).getGridNode(ForgeDirection.UNKNOWN) != null)
                ((AIMultiBlockTile)tile).getGridNode(ForgeDirection.UNKNOWN).updateState();
        }


        isFormed = false;

    }


    @Override
    public boolean hasMaster() {
        return true;
    }

    @Override
    public TileServerCore getMaster() {
        return this;
    }

    @Override
    public void setMaster(TileServerCore tileServerCore) { }

    @Override
    public void readFromNBT(NBTTagCompound nbt) {
        super.readFromNBT(nbt);
    }
    @Override
    public void writeToNBT(NBTTagCompound nbt) {
        super.writeToNBT(nbt);
    }
    @Override
    public Object getServerGuiElement( final EntityPlayer player ) {
        return new ContainerMEServer(player,this);
    }
    @Override
    public Object getClientGuiElement( final EntityPlayer player )
    {
        return new GuiMEServer((ContainerMEServer)this.getServerGuiElement(player));
    }

    @Override
    public void blinkCell(int slot) {
        if (slot > 0 && slot < this.blinkTimers.length)
            this.blinkTimers[slot] = 15;
    }


    @Override
    public void securityBreak() {

    }

    @Override
    public EnumSet<ForgeDirection> getConnectableSides() {
        if(isFormed)
            return EnumSet.allOf(ForgeDirection.class);
        return EnumSet.of(SOUTH,EAST,WEST,NORTH,UP,DOWN);
    }
    @Override
    public EnumSet<GridFlags> getFlags() {
        return EnumSet.of(GridFlags.REQUIRE_CHANNEL);
    }


    // Drive
    @Override
    public int getPriority() {
        return 0;
    }

    @Override
    public void onInventoryChanged() {
        this.items = updateHandlers(StorageChannel.ITEMS);
        this.fluids = updateHandlers(StorageChannel.FLUIDS);
        for (int i = 0; i < this.cellStatuses.length; i++) {
            ItemStack stackInSlot = this.inv.getStackInSlot(i);
            IMEInventoryHandler inventoryHandler = AEApi.instance()
                    .registries().cell()
                    .getCellInventory(stackInSlot, null, StorageChannel.ITEMS);
            if (inventoryHandler == null)
                inventoryHandler = AEApi
                        .instance()
                        .registries()
                        .cell()
                        .getCellInventory(stackInSlot, null,
                                StorageChannel.FLUIDS);

            ICellHandler cellHandler = AEApi.instance().registries().cell()
                    .getHandler(stackInSlot);
            if (cellHandler == null || inventoryHandler == null) {
                this.cellStatuses[i] = 0;
            } else {
                this.cellStatuses[i] = (byte) cellHandler.getStatusForCell(
                        stackInSlot, inventoryHandler);
            }
        }
        IGridNode node = getGridNode(ForgeDirection.UNKNOWN);
        if (node != null) {
            IGrid grid = node.getGrid();
            if (grid != null) {
                grid.postEvent(new MENetworkCellArrayUpdate());
            }
            getWorldObj().markBlockForUpdate(xCoord, yCoord, zCoord);
        }
    }

    private List<IMEInventoryHandler> updateHandlers(StorageChannel channel) {
        ICellRegistry cellRegistry = AEApi.instance().registries().cell();
        List<IMEInventoryHandler> handlers = new ArrayList<IMEInventoryHandler>();
        for (int i = 0; i < this.inv.getSizeInventory(); i++) {
            ItemStack cell = this.inv.getStackInSlot(i);
            if (cellRegistry.isCellHandled(cell)) {
                IMEInventoryHandler cellInventory = cellRegistry
                        .getCellInventory(cell, null, channel);
                if (cellInventory != null)
                    handlers.add(cellInventory);
            }
        }
        return handlers;
    }
    @Override
    public List<IMEInventoryHandler> getCellArray(StorageChannel channel) {
        if (!theGridNode.isActive())
            return new ArrayList<IMEInventoryHandler>();
        return channel == StorageChannel.ITEMS ? this.items : this.fluids;
    }

    @Override
    public void saveChanges(IMEInventory cellInventory) {

    }
    @Override
    public void invalidate() {
        super.invalidate();
        if (worldObj != null && !worldObj.isRemote) {
            destroyAELink();
        }
        if(isFormed)
            this.DestroyMultiBlock();

    }

    @Override
    public boolean showNetworkInfo(MovingObjectPosition where) {
        return true;
    }

    public void addSlave(AIMultiBlockTile slave) {
        Slaves.add(slave);
    }
}
Код:
public abstract class AITile extends TileEntity implements IActionHost,IGridHost,IGridBlock {

    public IGridNode theGridNode = null;
    public IGridConnection theConnection;
    private IGridBlock gridBlock;
    private IGridNode node = null;

    protected boolean loaded = false;
    private boolean cached = false;

    public Object getServerGuiElement( final EntityPlayer player )
    {
        return null;
    }
    public Object getClientGuiElement( final EntityPlayer player )
    {
        return null;
    }

    /**
     * Prepare a Packet to send the state of the {@link TileEntity} to the Client
     */
    @Override
    public Packet getDescriptionPacket() {
        NBTTagCompound nbt = new NBTTagCompound();
        writeToNBT(nbt);
        return new S35PacketUpdateTileEntity(xCoord, yCoord, zCoord, 1, nbt);
    }

    /**
     * Process a Packet to update the state of the {@link TileEntity} on the Client
     */
    @Override
    public void onDataPacket(NetworkManager pNet, S35PacketUpdateTileEntity pPacket) {
        super.onDataPacket(pNet, pPacket);
        NBTTagCompound nbt = pPacket.func_148857_g();
        readFromNBT(nbt);
    }
    @Override
    public double getIdlePowerUsage() {
        // TODO Auto-generated method stub
        return 1;
    }

    @Override
    public EnumSet<GridFlags> getFlags() {
        // TODO Auto-generated method stub
        return EnumSet.of(GridFlags.REQUIRE_CHANNEL);
    }

    @Override
    public boolean isWorldAccessible() {
        // TODO Auto-generated method stub
        return true;
    }

    @Override
    public DimensionalCoord getLocation() {
        // TODO Auto-generated method stub
        return new DimensionalCoord(this);
    }

    @Override
    public AEColor getGridColor() {
        // TODO Auto-generated method stub
        return AEColor.Transparent;
    }

    @Override
    public void onGridNotification(GridNotification notification) {

    }
    @Override
    public void setNetworkStatus(IGrid grid, int channelsInUse) {

    }
    @Override
    public EnumSet<ForgeDirection> getConnectableSides() {
        return EnumSet.of(ForgeDirection.SOUTH,ForgeDirection.DOWN,ForgeDirection.EAST,ForgeDirection.UP,ForgeDirection.NORTH,ForgeDirection.WEST);
    }
    public void createAELink() {
        if(worldObj != null) {
            if (isServer()) {
                try{
                    node = AEApi.instance().createGridNode(gridBlock);
                    node.updateState();
                }catch (Exception e){

                }
            }
        }
    }
    public void destroyAELink() {
        if (theGridNode != null) theGridNode.destroy();
    }
    @Override
    public IGridHost getMachine() {
        return this;
    }

    @Override
    public void gridChanged() {

    }
    public boolean isServer() {
        return !isClient();
    }

    public boolean isClient() {
        return getWorldObj().isRemote;
    }
    @Override
    public ItemStack getMachineRepresentation() {
        return null;

    }

    @Override
    public IGridNode getGridNode(ForgeDirection dir) {
        if(theGridNode==null) createAELink();
            return theGridNode;
    }

    @Override
    public AECableType getCableConnectionType(ForgeDirection dir) {
        return AECableType.DENSE;
    }

    @Override
    public void securityBreak() {

    }
    @Override
    public IGridNode getActionableNode() {
        if (FMLCommonHandler.instance().getEffectiveSide().isClient())
            return null;
        if (this.node == null) {
            this.node = AEApi.instance().createGridNode(this.gridBlock);
        }
        return this.node;

    }
    @Override
    public void updateEntity() {
        //create grid node on add to world
        if (!loaded && hasWorldObj() && !worldObj.isRemote) {
            loaded = true;
            createAELink();
        }
    }
    public void notifyBlock(){
        worldObj.markBlockForUpdate(xCoord,yCoord,zCoord);
    }
}
Код:
public class ContainerMEServer extends Container
{
    private TileServerCore master;

    public ContainerMEServer(EntityPlayer player, TileServerCore master) {


        this.master = master;

        this.bindPlayerInventory(player.inventory);
        this.addDriveSlots(master.inv);
        master.inv.openInventory();

    }

    private void addDriveSlots(IInventory master) {
        int i=0;
        for (int y = 0; y<5; y++){
            for(int x = 0; x<6; x++){
                if(master != null) {
                    this.addSlotToContainer( new SlotMEServer(master, i, 35 + x * 18, y * 18 - 1 ) );
                    i++;
                }
            }
        }
        i=0;
    }


    protected void bindPlayerInventory(IInventory inventoryPlayer) {
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 9; j++) {
                addSlotToContainer(new Slot(inventoryPlayer, j + i * 9 + 9,
                        8 + j * 18, (i * 18 + 149)-47));
            }
        }

        for (int i = 0; i < 9; i++) {
            addSlotToContainer(new Slot(inventoryPlayer, i, 8 + i * 18, (207)-47));
        }
    }


    @Override
    public boolean canInteractWith(EntityPlayer p) {
        return true;
    }

    @Override
    public ItemStack transferStackInSlot(EntityPlayer p, int i)
    {
        ItemStack itemstack = null;
        Slot slot = (Slot)inventorySlots.get(i);
        if (slot != null && slot.getHasStack())
        {
            ItemStack itemstack1 = slot.getStack();
            itemstack = itemstack1.copy();
            if (AEApi.instance().registries().cell().isCellHandled(itemstack))
            {
                if (i < 3)
                {
                    if (!mergeItemStack(itemstack1, 3, 38, false))
                    {
                        return null;
                    }
                } else if (!mergeItemStack(itemstack1, 0, 3, false))
                {
                    return null;
                }
                if (itemstack1.stackSize == 0)
                {
                    slot.putStack(null);
                } else
                {
                    slot.onSlotChanged();
                }
            }
        }
        return itemstack;
    }
}
Код:
public class GuiMEServer extends AIBaseGui {
    private static final ResourceLocation texture = new ResourceLocation(AppliedIntegrations.modid, "textures/gui/Server/ServerStorage.png");

    public GuiMEServer(ContainerMEServer container) {
        super(container);
    }

    @Override
    public AIContainer getNodeContainer() {
        return null;
    }

    @Override
    protected void drawGuiContainerBackgroundLayer(float p_146976_1_, int p_146976_2_, int p_146976_3_) {
        drawDefaultBackground();
        GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
        Minecraft.getMinecraft().renderEngine.bindTexture(this.texture);
        this.drawTexturedModalRect(this.guiLeft, this.guiTop-15, 0, 0, 200, 200);
    }
    @Override
    protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) {
        super.drawGuiContainerForegroundLayer(mouseX, mouseY);
        this.fontRendererObj.drawString("ME Server Drive", 9, -12, 4210752);
    }
}
Код:
public class AIGridNodeInventory implements IInventory {

    public ItemStack[] slots;
    public String customName;
    private int stackLimit;
    private IInventoryHost receiver;

    public AIGridNodeInventory(String _customName, int _size, int _stackLimit) {
        this(_customName, _size, _stackLimit, null);
    }

    public AIGridNodeInventory(String _customName, int _size, int _stackLimit,
                               IInventoryHost _receiver) {
        this.slots = new ItemStack[_size];
        this.customName = _customName;
        this.stackLimit = _stackLimit;
        this.receiver = _receiver;
    }

    @Override
    public void closeInventory() {
        // NOBODY needs this!
    }

    @Override
    public ItemStack decrStackSize(int slotId, int amount) {
        if (this.slots[slotId] == null)
            return null;
        ItemStack itemstack;
        if (this.slots[slotId].stackSize <= amount) {
            itemstack = this.slots[slotId];
            this.slots[slotId] = null;
            markDirty();
            return itemstack;
        } else {
            ItemStack temp = this.slots[slotId];
            itemstack = temp.splitStack(amount);
            this.slots[slotId] = temp;
            if (temp.stackSize == 0) {
                this.slots[slotId] = null;
            } else {
                this.slots[slotId] = temp;
            }
            markDirty();
            return itemstack;
        }
    }

    @Override
    public String getInventoryName() {
        return this.customName;
    }

    @Override
    public int getInventoryStackLimit() {
        return this.stackLimit;
    }

    @Override
    public int getSizeInventory() {
        return this.slots.length;
    }

    @Override
    public ItemStack getStackInSlot(int i) {
        return this.slots[i];
    }

    @Override
    public ItemStack getStackInSlotOnClosing(int slotId) {
        return this.slots[slotId];
    }

    @Override
    public boolean hasCustomInventoryName() {
        return false;
    }


    public ItemStack incrStackSize(int slotId, int amount) {
        ItemStack slot = this.slots[slotId];
        if (slot == null)
            return null;
        int stackLimit = getInventoryStackLimit();
        if (stackLimit > slot.getMaxStackSize())
            stackLimit = slot.getMaxStackSize();
        ItemStack added = slot.copy();
        added.stackSize = slot.stackSize + amount > stackLimit ? stackLimit
                : amount;
        slot.stackSize += added.stackSize;
        return added;
    }

    @Override
    public boolean isItemValidForSlot(int i, ItemStack itemstack) {
        return true;
    }

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

    @Override
    public void markDirty() {
        if (this.receiver != null)
            this.receiver.onInventoryChanged();
    }

    @Override
    public void openInventory() {
        // NOBODY needs this!
    }

    public void readFromNBT(NBTTagList nbtList) {
        if(nbtList == null){
            for(int i = 0; i < slots.length; i++){
                slots[i] = null;
            }
            return;
        }
        for (int i = 0; i < nbtList.tagCount(); ++i) {
            NBTTagCompound nbttagcompound = nbtList.getCompoundTagAt(i);
            int j = nbttagcompound.getByte("Slot") & 255;

            if (j >= 0 && j < this.slots.length) {
                this.slots[j] = ItemStack.loadItemStackFromNBT(nbttagcompound);
            }
        }
    }

    @Override
    public void setInventorySlotContents(int slotId, ItemStack itemstack) {
        if (itemstack != null && itemstack.stackSize > getInventoryStackLimit()) {
            itemstack.stackSize = getInventoryStackLimit();
        }
        this.slots[slotId] = itemstack;

        markDirty();
    }

    public NBTTagList writeToNBT() {
        NBTTagList nbtList = new NBTTagList();

        for (int i = 0; i < this.slots.length; ++i) {
            if (this.slots[i] != null) {
                NBTTagCompound nbttagcompound = new NBTTagCompound();
                nbttagcompound.setByte("Slot", (byte) i);
                this.slots[i].writeToNBT(nbttagcompound);
                nbtList.appendTag(nbttagcompound);
            }
        }
        return nbtList;
    }
}

P.S. Это аддон для AE2, так что тут много странных методов, по типу "getGridNode", на них можно не обращать внимание, как я убедился они никак не влияют на проблему
 
Последнее редактирование:
Назад
Сверху