Jump to content

Recommended Posts

Posted

I have a block with an associated tile entity with an inventory and right-clicking on the block opens a GUI showing the inventory. When you put items in most of the slots, they stay there - including between sessions. However, if you put them in the first slot (slot zero), then the item disappears almost immediately. The slot becomes empty right away visually, but you can still click on it and take the item you put in back out. If you restart the game, then the item is gone permanently. However, if all the other slots are filled, then for some reason, the item in the first slot doesn't disappear, persisting even after a reload.

 

I don't understand how this is happening. I followed video tutorials I found and everything worked fine for them. I made some changes but I see nothing that explains this. I'm not doing any special logic on slot 0 -- it should behave exactly the same as all the other slots as far as I can tell. What am I missing?

 

ContainerVisReader.java

 

 

package tuhljin.automagy.container;

import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import tuhljin.automagy.entities.TileEntityVisReader;

public class ContainerVisReader extends Container {

private TileEntityVisReader teVR;

public ContainerVisReader(InventoryPlayer inventoryPlayer, TileEntityVisReader te) {
	teVR = te;

	for (int i = 0; i < 4; i++) {
		this.addSlotToContainer(new Slot(teVR, i, 6, 10 + i*19));
	}

	// Add player's hotbar:
	for (int i = 0; i < 9; i++) {
		this.addSlotToContainer(new Slot(inventoryPlayer, i, 8 + i*18, 154));
	}
	// Add the rest of the player's inventory:
	for (int i = 0; i < 3; i++) {
		for (int j = 0; j < 9; j++) {
			this.addSlotToContainer(new Slot(inventoryPlayer, 9 + j + i*9, 8 + j*18, 96 + i*18));
		}
	}

}

@Override
public boolean canInteractWith(EntityPlayer player) {
	return player.getDistanceSq(teVR.xCoord + 0.5D, teVR.yCoord + 0.5D, teVR.zCoord + 0.5D) <= 64;
}

@Override
public ItemStack transferStackInSlot(EntityPlayer player, int i) {
	return null;
}

}

 

 

 

TileEntityVisReader.java

 

 

package tuhljin.automagy.entities;

import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import tuhljin.automagy.lib.References;

public class TileEntityVisReader extends ModTileEntityWithInventory { 

public TileEntityVisReader() {
	super(References.BLOCK_VISREADER, 4);
}

@Override
public int[] getAccessibleSlotsFromSide(int var1) {
	return new int[] { 0, 1, 2, 3 };
}

}

 

 

ModTileEntityWithInventory.java

 

 

package tuhljin.automagy.entities;

import java.util.ArrayList;
import java.util.List;

import tuhljin.automagy.lib.TjUtil;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.Packet;
import net.minecraft.network.play.server.S35PacketUpdateTileEntity;
import net.minecraftforge.common.util.Constants;

public abstract class ModTileEntityWithInventory extends ModTileEntity implements ISidedInventory {

protected ItemStack[] inventorySlots;
private String inventoryName;
private final int numSlots;

public ModTileEntityWithInventory(String inventoryName, int numSlots) {
	this.inventoryName = inventoryName;
	this.numSlots = numSlots;
	inventorySlots = new ItemStack[numSlots];
}

public ItemStack[] getAllItems() {
	List<ItemStack> list = new ArrayList<ItemStack>();
	for (int i=0; i < numSlots; i++) {
		if (inventorySlots[i] != null)  list.add(inventorySlots[i]);
	}
	return list.toArray(new ItemStack[list.size()]);
}

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

@Override
public ItemStack getStackInSlot(int slot) {
	return inventorySlots[slot];
}

@Override
public ItemStack decrStackSize(int slot, int num) {
	if (inventorySlots[slot] != null) {
		ItemStack stack;
		if (inventorySlots[slot].stackSize <= num) {
			stack = inventorySlots[slot];
			inventorySlots[slot] = null;
			this.markDirty();
			return stack;
		} else {
			stack = inventorySlots[slot].splitStack(num);
			if (inventorySlots[slot].stackSize == 0)  inventorySlots[slot] = null;
			this.markDirty();
			return stack;
		}
	}
	return null;
}

@Override
public ItemStack getStackInSlotOnClosing(int slot) {
	return getStackInSlot(slot);
}

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

	this.markDirty();
}

@Override
public String getInventoryName() {
	return inventoryName;
}

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

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

@Override
public boolean isUseableByPlayer(EntityPlayer player) {
	return worldObj.getTileEntity(xCoord, yCoord, zCoord) == this && player.getDistanceSq(xCoord + 0.5D, yCoord + 0.5D, zCoord + 0.5D) <= 64;
}

@Override
public void openInventory() {

}

@Override
public void closeInventory() {
}

@Override
public boolean isItemValidForSlot(int slot, ItemStack stack) {
	return true;
}

@Override
public int[] getAccessibleSlotsFromSide(int var1) {
	return new int[] { 0 };
}

@Override
public boolean canInsertItem(int slot, ItemStack stack, int var3) {
	return isItemValidForSlot(slot, stack);
}

@Override
public boolean canExtractItem(int var1, ItemStack var2, int var3) {
	return true;
}



@Override
public void readCustomNBT(NBTTagCompound nbttagcompound) {
	NBTTagList nbttaglist = nbttagcompound.getTagList("Items", Constants.NBT.TAG_COMPOUND);
	inventorySlots = new ItemStack[numSlots];
	if (nbttaglist.tagCount() > 0) {
		for (int i = 0; i < numSlots; i++) {
			NBTTagCompound tagList = nbttaglist.getCompoundTagAt(i);
			byte slot = tagList.getByte("Slot");
			if (slot >= 0 && slot < numSlots) {
				inventorySlots[slot] = ItemStack.loadItemStackFromNBT(tagList);
			}
		}
	}
}

@Override
public void writeCustomNBT(NBTTagCompound nbttagcompound) {
	NBTTagList nbttaglist = new NBTTagList();
	for (int i = 0; i < numSlots; i++) {
		if (inventorySlots[i] != null) {
			NBTTagCompound tagList = new NBTTagCompound();
			tagList.setByte("Slot", (byte) i);
			inventorySlots[i].writeToNBT(tagList);
			nbttaglist.appendTag(tagList);
		}
	}
	nbttagcompound.setTag("Items", nbttaglist);
}

}

 

 

Posted

So, I fixed it with a sanity check in my readCustomNBT method:

 

...
			byte slot = tagList.getByte("Slot");
			if (slot >= 0 && slot < numSlots) {
				if (inventorySlots[slot] == null)  // Prevent inexplicable overwrite of slot 0
					inventorySlots[slot] = ItemStack.loadItemStackFromNBT(tagList);
			}
...

 

But I still don't see why this was necessary. The tutorials and other code from open source projects doesn't have to take these precautions. Now, of course the most important thing is it's working, but I'd still like to get any insight on why that change was necessary in my case and not in others, or more to the point, what I did/didn't do that caused the problem in the first place.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.