Hey I followed your ItemInventory tutorial and it worked but for some reason the slots are all filled with the item that i used to open the gui. Any idea why this might be?
You probably set the contents of all the slots to be that item. Check your inventory's read and write NBT code.
@Override
public void markDirty() {
ItemStack stack = Minecraft.getMinecraft().thePlayer.getHeldItem(); // this line
NEVER NEVER NEVER use Minecraft.getMinecraft() - it is CLIENT side only, and the client does not save things.
The WHOLE point of the entire tutorial was showing how to store the ItemStack reference when the inventory is constructed so that you have it available when you want to save.
Index is very likely out of bounds because you either didn't remove the armor slots from your counting.
Also, using #onContainerClosed is not a bad idea, but the problem comes if the inventory is ever manipulated outside of the Gui/Container system, e.g. calling #setInventorySlotContents directly, which is completely possible, in which case having it save in #markDirty comes to the rescue.
#writeNBT should NOT be getting called when the inventory is opened; only when it is closed. Opening the inventory should be calling #readNBT. Both reading and writing NBT are usually only done on the server.
I recommend you re-read the tutorial, taking special care to read all of the code and code comments. It is pretty clearly explained, but if there is something you don't understand, feel free to ask.
Check your readNBT code - it should be assigning the ItemStacks directly to the inventory array, NOT calling #setInventorySlotContents. The reason is that #setInventorySlotContents is the one method that calls #markDirty, so you can't use it when reading the inventory.
Well you're calling #markDirty from somewhere, then. Right-click on that method in your inventory class and open the call hierarchy for it - that will show you all the places it is called.
I did but its only called in methods where something is changed also i found out (in the minecraft source) that the comment of markDirty says that its used for tile entities could this be the problem? Im using 1.8.9 btw.
Lol, no, that's not a problem. The code comments are submitted by people contributing to MCP, so whomever submitted that one saw that TileEntities used it and nowhere else (at that time, which was many Minecraft versions ago by now) so wrote that comment. Doesn't mean you can't use the method yourself for your own purposes.
Actually, looking at 1.8 code, #markDirty is called for the inventory from Slot#onSlotChanged, so you may not even need to call it yourself from your inventory implementation. Just remove anywhere in your code that calls #markDirty, but keep the implementation of #markDirty as is from the tutorial.
No difference i outcommented every line where i call markDirty myself but the Client Side still calls markDirty.
Well, either you are doing something wrong, or you are coding for 1.8.9 and something I don't know about has changed. I haven't tried porting this code to 1.8.9 yet, so I haven't sussed out any discrepancies.
If you are not using 1.8.9, post links to your code.
Seems your "Creating an Item that stores an Inventory" tutorial is outdated. When I copypaste the code, I get a whole bunch of errors saying the overrided methods don't even exist.
Are there any up-to-date tutorials for achieving this? Thanks.
EDIT: By up-to-date tutorials I mean tutorials for 1.8.9.
Don't copy / paste code from tutorials. That said, it is outdated as they completely overhauled tons of stuff between 1.8 and 1.8.9, including IInventory, IEEP, etc. They (Forge team) want you to use the new Capability system instead.
Don't copy / paste code from tutorials. That said, it is outdated as they completely overhauled tons of stuff between 1.8 and 1.8.9, including IInventory, IEEP, etc. They (Forge team) want you to use the new Capability system instead.
Hm, that is highly annoying. I'd hoped it would be a simple task to create an item that stores an inventory. I'm completely new to working with MC's GUI's and the associated classes and such, so it looks like I have quite the puzzle laid out before me, due to the lack of up-to-date tutorials.
1.7.10, i already have a block made, how would i convert it into a chest?
You need at least a Block, TileEntity, IInventory, Gui, and Container.
However, this tutorial does not cover TileEntity/Block-based inventories - I suggest you search for one that does and also take a look at vanilla chests.
/** Provides NBT Tag Compound to reference */
final ItemStack invItem;
/** Defining your inventory size this way is handy */
public static final int INV_SIZE = 8;
/** Inventory's size must be same as number of slots you add to the Container class */
private ItemStack[] inventory = new ItemStack[INV_SIZE];
public InventoryItem(ItemStack stack)
{
invItem = stack;
// Create a new NBT Tag Compound if one doesn't already exist, or you will crash
if (!invItem.hasTagCompound()) {
invItem.setTagCompound(new NBTTagCompound());
}
// note that it's okay to use stack instead of invItem right there
// both reference the same memory location, so whatever you change using
// either reference will change in the other
// Read the inventory contents from NBT
readFromNBT(invItem.getTagCompound());
}
@Override
public String getName() {
return name;
}
@Override
public boolean hasCustomName() {
return name.length() > 0;
}
@Override
public IChatComponent getDisplayName() {
return new ChatComponentText(name);
}
@Override
public int getSizeInventory() {
return inventory.length;
}
@Override
public ItemStack getStackInSlot(int index) {
return inventory[index];
}
@Override
public ItemStack decrStackSize(int index, int count) {
ItemStack stack = getStackInSlot(index);
if(stack != null)
{
if(stack.stackSize > count)
{
stack = stack.splitStack(count);
// Don't forget this line or your inventory will not be saved!
markDirty();
}
else
{
// this method also calls markDirty, so we don't need to call it again
setInventorySlotContents(index, null);
}
}
return stack;
}
// Don't forget this line or your inventory will not be saved!
markDirty();
}
@Override
public int getInventoryStackLimit() {
return 64;
}
@Override
public void markDirty()
{
for (int i = 0; i < getSizeInventory(); ++i)
{
if (getStackInSlot(i) != null && getStackInSlot(i).stackSize == 0) {
inventory = null;
}
}
// This line here does the work:
writeToNBT(invItem.getTagCompound());
}
@Override
public boolean isUseableByPlayer(EntityPlayer entityplayer)
{
return true;
}
@Override
public void openInventory(EntityPlayer player) {
}
@Override
public void closeInventory(EntityPlayer player) {
}
@Override
public boolean isItemValidForSlot(int index, ItemStack stack) {
// Don't want to be able to store the inventory item within itself
// Bad things will happen, like losing your inventory
// Actually, this needs a custom Slot to work
return !(stack.getItem() instanceof ItemStore);
}
@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 = null;
}
}
public void readFromNBT(NBTTagCompound compound)
{
// Gets the custom taglist we wrote to this compound, if any
// 1.7.2+ change to compound.getTagList("ItemInventory", Constants.NBT.TAG_COMPOUND);
NBTTagList items = compound.getTagList("ItemInventory", Constants.NBT.TAG_COMPOUND);
for (int i = 0; i < items.tagCount(); ++i)
{
// 1.7.2+ change to items.getCompoundTagAt(i)
NBTTagCompound item = items.getCompoundTagAt(i);
int slot = item.getInteger("Slot");
// Just double-checking that the saved slot index is within our inventory array bounds
if (slot >= 0 && slot < getSizeInventory()) {
inventory[slot] = ItemStack.loadItemStackFromNBT(item);
}
}
}
/**
* A custom method to write our inventory to an ItemStack's NBT compound
*/
public void writeToNBT(NBTTagCompound tagcompound)
{
// Create a new NBT Tag List to store itemstacks as NBT Tags
NBTTagList items = new NBTTagList();
for (int i = 0; i < getSizeInventory(); ++i)
{
// Only write stacks that contain items
if (getStackInSlot(i) != null)
{
// Make a new NBT Tag Compound to write the itemstack and slot index to
NBTTagCompound item = new NBTTagCompound();
item.setInteger("Slot", i);
// Writes the itemstack in slot(i) to the Tag Compound we just made
getStackInSlot(i).writeToNBT(item);
// add the tag compound to our tag list
items.appendTag(tagcompound);
}
}
// Add the TagList to the ItemStack's Tag Compound with the name "ItemInventory"
tagcompound.setTag("ItemInventory", items);
}
public SlotItemInv(IInventory inv, int index, int xPos, int yPos)
{
super(inv, index, xPos, yPos);
}
// This is the only method we need to override so that
// we can't place our inventory-storing Item within
// its own inventory (thus making it permanently inaccessible)
// as well as preventing abuse of storing backpacks within backpacks
/**
* Check if the stack is a valid item for this slot.
*/
@Override
public boolean isItemValid(ItemStack itemstack)
{
// Everything returns true except an instance of our Item
return !(itemstack.getItem() instanceof ItemStore);
}
public class GuiItemInventory extends GuiContainer
{
/** x and y size of the inventory window in pixels. Defined as float, passed as int
* These are used for drawing the player model. */
private float xSize_lo;
private float ySize_lo;
/** ResourceLocation takes 2 parameters: ModId, path to texture at the location:
* "src/minecraft/assets/modid/"
*
* I have provided a sample texture file that works with this tutorial. Download it
* from Forge_Tutorials/textures/gui/
*/
private static final ResourceLocation iconLocation = new ResourceLocation("examplemod", "textures/gui/inventoryitem.png");
/** The inventory to render on screen */
private final InventoryItem inventory;
public GuiItemInventory(ContainerItem containerItem)
{
super(containerItem);
this.inventory = containerItem.inventory;
}
/**
* Draws the screen and all the components in it.
*/
public void drawScreen(int par1, int par2, float par3)
{
super.drawScreen(par1, par2, par3);
this.xSize_lo = (float)par1;
this.ySize_lo = (float)par2;
}
/**
* Draw the foreground layer for the GuiContainer (everything in front of the items)
*/
protected void drawGuiContainerForegroundLayer(int par1, int par2)
{
String s = this.inventory.hasCustomName() ? this.inventory.getName() : I18n.format(this.inventory.getName());
this.fontRendererObj.drawString(s, this.xSize / 2 - this.fontRendererObj.getStringWidth(s) / 2, 0, 4210752);
this.fontRendererObj.drawString(I18n.format("container.inventory"), 26, this.ySize - 96 + 4, 4210752);
}
/**
* Draw the background layer for the GuiContainer (everything behind the items)
*/
protected void drawGuiContainerBackgroundLayer(float par1, int par2, int par3)
{
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
this.mc.getTextureManager().bindTexture(iconLocation);
int k = (this.width - this.xSize) / 2;
int l = (this.height - this.ySize) / 2;
this.drawTexturedModalRect(k, l, 0, 0, this.xSize, this.ySize);
GuiInventory.drawEntityOnScreen(k + 51, l + 75, 30, (float)(k + 51) - this.xSize_lo, (float)(l + 75 - 50) - this.ySize_lo, this.mc.thePlayer);
}
public class ItemStore extends Item
{
public ItemStore(String unlocalizedName)
{
super();
this.setUnlocalizedName(unlocalizedName);
// ItemStacks that store an NBT Tag Compound are limited to stack size of 1
setMaxStackSize(1);
// you'll want to set a creative tab as well, so you can get your item
setCreativeTab(Main.tabCustom);
}
// Without this method, your inventory will NOT work!!!
@Override
public int getMaxItemUseDuration(ItemStack stack) {
return 1; // return any value greater than zero
}
@Override
public ItemStack onItemRightClick(ItemStack itemstack, World world, EntityPlayer player)
{
if (!world.isRemote)
{
// If player not sneaking, open the inventory gui
if (!player.isSneaking()) {
player.openGui(Main.instance, ModGuiHandler.GUI_ITEM_INV, world, 0, 0, 0);
}
// Otherwise, stealthily place some diamonds in there for a nice surprise next time you open it up
else {
new InventoryItem(player.getHeldItem()).setInventorySlotContents(0, new ItemStack(Items.diamond,4));
}
}
You probably set the contents of all the slots to be that item. Check your inventory's read and write NBT code.
No, THIS is the problem:
NEVER NEVER NEVER use Minecraft.getMinecraft() - it is CLIENT side only, and the client does not save things.
The WHOLE point of the entire tutorial was showing how to store the ItemStack reference when the inventory is constructed so that you have it available when you want to save.
Index is very likely out of bounds because you either didn't remove the armor slots from your counting.
Also, using #onContainerClosed is not a bad idea, but the problem comes if the inventory is ever manipulated outside of the Gui/Container system, e.g. calling #setInventorySlotContents directly, which is completely possible, in which case having it save in #markDirty comes to the rescue.
#writeNBT should NOT be getting called when the inventory is opened; only when it is closed. Opening the inventory should be calling #readNBT. Both reading and writing NBT are usually only done on the server.
I recommend you re-read the tutorial, taking special care to read all of the code and code comments. It is pretty clearly explained, but if there is something you don't understand, feel free to ask.
Check your readNBT code - it should be assigning the ItemStacks directly to the inventory array, NOT calling #setInventorySlotContents. The reason is that #setInventorySlotContents is the one method that calls #markDirty, so you can't use it when reading the inventory.
Well you're calling #markDirty from somewhere, then. Right-click on that method in your inventory class and open the call hierarchy for it - that will show you all the places it is called.
Lol, no, that's not a problem. The code comments are submitted by people contributing to MCP, so whomever submitted that one saw that TileEntities used it and nowhere else (at that time, which was many Minecraft versions ago by now) so wrote that comment. Doesn't mean you can't use the method yourself for your own purposes.
Actually, looking at 1.8 code, #markDirty is called for the inventory from Slot#onSlotChanged, so you may not even need to call it yourself from your inventory implementation. Just remove anywhere in your code that calls #markDirty, but keep the implementation of #markDirty as is from the tutorial.
Well, either you are doing something wrong, or you are coding for 1.8.9 and something I don't know about has changed. I haven't tried porting this code to 1.8.9 yet, so I haven't sussed out any discrepancies.
If you are not using 1.8.9, post links to your code.
Seems your "Creating an Item that stores an Inventory" tutorial is outdated. When I copypaste the code, I get a whole bunch of errors saying the overrided methods don't even exist.
Are there any up-to-date tutorials for achieving this? Thanks.
EDIT: By up-to-date tutorials I mean tutorials for 1.8.9.
My mods: Archmagus, BetterBoneMeal, BetterVanilla, Brewing-API, NaturalArmors, and PluckableChickens!
Don't copy / paste code from tutorials. That said, it is outdated as they completely overhauled tons of stuff between 1.8 and 1.8.9, including IInventory, IEEP, etc. They (Forge team) want you to use the new Capability system instead.
Hm, that is highly annoying. I'd hoped it would be a simple task to create an item that stores an inventory. I'm completely new to working with MC's GUI's and the associated classes and such, so it looks like I have quite the puzzle laid out before me, due to the lack of up-to-date tutorials.
Thanks anyway for the quick reply.
My mods: Archmagus, BetterBoneMeal, BetterVanilla, Brewing-API, NaturalArmors, and PluckableChickens!
1.7.10, i already have a block made, how would i convert it into a chest?
You need at least a Block, TileEntity, IInventory, Gui, and Container.
However, this tutorial does not cover TileEntity/Block-based inventories - I suggest you search for one that does and also take a look at vanilla chests.
Good luck!
If I am necroposting, then I apologize. However, I had a crash while following the item inventory tutorial.
http://pastebin.com/8KYERDpX
Here is my code.
InventoryItem
package com.example.examplemod.gui.container;
import com.example.examplemod.items.ItemStore;
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.util.ChatComponentText;
import net.minecraft.util.IChatComponent;
import net.minecraftforge.common.util.Constants;
public class InventoryItem implements IInventory{
private String name = "Inventory Item";
/** Provides NBT Tag Compound to reference */
final ItemStack invItem;
/** Defining your inventory size this way is handy */
public static final int INV_SIZE = 8;
/** Inventory's size must be same as number of slots you add to the Container class */
private ItemStack[] inventory = new ItemStack[INV_SIZE];
public InventoryItem(ItemStack stack)
{
invItem = stack;
// Create a new NBT Tag Compound if one doesn't already exist, or you will crash
if (!invItem.hasTagCompound()) {
invItem.setTagCompound(new NBTTagCompound());
}
// note that it's okay to use stack instead of invItem right there
// both reference the same memory location, so whatever you change using
// either reference will change in the other
// Read the inventory contents from NBT
readFromNBT(invItem.getTagCompound());
}
@Override
public String getName() {
return name;
}
@Override
public boolean hasCustomName() {
return name.length() > 0;
}
@Override
public IChatComponent getDisplayName() {
return new ChatComponentText(name);
}
@Override
public int getSizeInventory() {
return inventory.length;
}
@Override
public ItemStack getStackInSlot(int index) {
return inventory[index];
}
@Override
public ItemStack decrStackSize(int index, int count) {
ItemStack stack = getStackInSlot(index);
if(stack != null)
{
if(stack.stackSize > count)
{
stack = stack.splitStack(count);
// Don't forget this line or your inventory will not be saved!
markDirty();
}
else
{
// this method also calls markDirty, so we don't need to call it again
setInventorySlotContents(index, null);
}
}
return stack;
}
@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) {
inventory[index] = stack;
if (stack != null && stack.stackSize > getInventoryStackLimit())
{
stack.stackSize = getInventoryStackLimit();
}
// Don't forget this line or your inventory will not be saved!
markDirty();
}
@Override
public int getInventoryStackLimit() {
return 64;
}
@Override
public void markDirty()
{
for (int i = 0; i < getSizeInventory(); ++i)
{
if (getStackInSlot(i) != null && getStackInSlot(i).stackSize == 0) {
inventory = null;
}
}
// This line here does the work:
writeToNBT(invItem.getTagCompound());
}
@Override
public boolean isUseableByPlayer(EntityPlayer entityplayer)
{
return true;
}
@Override
public void openInventory(EntityPlayer player) {
}
@Override
public void closeInventory(EntityPlayer player) {
}
@Override
public boolean isItemValidForSlot(int index, ItemStack stack) {
// Don't want to be able to store the inventory item within itself
// Bad things will happen, like losing your inventory
// Actually, this needs a custom Slot to work
return !(stack.getItem() instanceof ItemStore);
}
@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 = null;
}
}
public void readFromNBT(NBTTagCompound compound)
{
// Gets the custom taglist we wrote to this compound, if any
// 1.7.2+ change to compound.getTagList("ItemInventory", Constants.NBT.TAG_COMPOUND);
NBTTagList items = compound.getTagList("ItemInventory", Constants.NBT.TAG_COMPOUND);
for (int i = 0; i < items.tagCount(); ++i)
{
// 1.7.2+ change to items.getCompoundTagAt(i)
NBTTagCompound item = items.getCompoundTagAt(i);
int slot = item.getInteger("Slot");
// Just double-checking that the saved slot index is within our inventory array bounds
if (slot >= 0 && slot < getSizeInventory()) {
inventory[slot] = ItemStack.loadItemStackFromNBT(item);
}
}
}
/**
* A custom method to write our inventory to an ItemStack's NBT compound
*/
public void writeToNBT(NBTTagCompound tagcompound)
{
// Create a new NBT Tag List to store itemstacks as NBT Tags
NBTTagList items = new NBTTagList();
for (int i = 0; i < getSizeInventory(); ++i)
{
// Only write stacks that contain items
if (getStackInSlot(i) != null)
{
// Make a new NBT Tag Compound to write the itemstack and slot index to
NBTTagCompound item = new NBTTagCompound();
item.setInteger("Slot", i);
// Writes the itemstack in slot(i) to the Tag Compound we just made
getStackInSlot(i).writeToNBT(item);
// add the tag compound to our tag list
items.appendTag(tagcompound);
}
}
// Add the TagList to the ItemStack's Tag Compound with the name "ItemInventory"
tagcompound.setTag("ItemInventory", items);
}
}
SlotItemInv
package com.example.examplemod.gui.container;
import com.example.examplemod.items.ItemStore;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
public class SlotItemInv extends Slot{
public SlotItemInv(IInventory inv, int index, int xPos, int yPos)
{
super(inv, index, xPos, yPos);
}
// This is the only method we need to override so that
// we can't place our inventory-storing Item within
// its own inventory (thus making it permanently inaccessible)
// as well as preventing abuse of storing backpacks within backpacks
/**
* Check if the stack is a valid item for this slot.
*/
@Override
public boolean isItemValid(ItemStack itemstack)
{
// Everything returns true except an instance of our Item
return !(itemstack.getItem() instanceof ItemStore);
}
}
GUIItemInventory
package com.example.examplemod.gui.container;
import org.lwjgl.opengl.GL11;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.gui.inventory.GuiInventory;
import net.minecraft.client.resources.I18n;
import net.minecraft.util.ResourceLocation;
public class GuiItemInventory extends GuiContainer
{
/** x and y size of the inventory window in pixels. Defined as float, passed as int
* These are used for drawing the player model. */
private float xSize_lo;
private float ySize_lo;
/** ResourceLocation takes 2 parameters: ModId, path to texture at the location:
* "src/minecraft/assets/modid/"
*
* I have provided a sample texture file that works with this tutorial. Download it
* from Forge_Tutorials/textures/gui/
*/
private static final ResourceLocation iconLocation = new ResourceLocation("examplemod", "textures/gui/inventoryitem.png");
/** The inventory to render on screen */
private final InventoryItem inventory;
public GuiItemInventory(ContainerItem containerItem)
{
super(containerItem);
this.inventory = containerItem.inventory;
}
/**
* Draws the screen and all the components in it.
*/
public void drawScreen(int par1, int par2, float par3)
{
super.drawScreen(par1, par2, par3);
this.xSize_lo = (float)par1;
this.ySize_lo = (float)par2;
}
/**
* Draw the foreground layer for the GuiContainer (everything in front of the items)
*/
protected void drawGuiContainerForegroundLayer(int par1, int par2)
{
String s = this.inventory.hasCustomName() ? this.inventory.getName() : I18n.format(this.inventory.getName());
this.fontRendererObj.drawString(s, this.xSize / 2 - this.fontRendererObj.getStringWidth(s) / 2, 0, 4210752);
this.fontRendererObj.drawString(I18n.format("container.inventory"), 26, this.ySize - 96 + 4, 4210752);
}
/**
* Draw the background layer for the GuiContainer (everything behind the items)
*/
protected void drawGuiContainerBackgroundLayer(float par1, int par2, int par3)
{
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
this.mc.getTextureManager().bindTexture(iconLocation);
int k = (this.width - this.xSize) / 2;
int l = (this.height - this.ySize) / 2;
this.drawTexturedModalRect(k, l, 0, 0, this.xSize, this.ySize);
GuiInventory.drawEntityOnScreen(k + 51, l + 75, 30, (float)(k + 51) - this.xSize_lo, (float)(l + 75 - 50) - this.ySize_lo, this.mc.thePlayer);
}
}
ItemStore
package com.example.examplemod.items;
import com.example.examplemod.Main;
import com.example.examplemod.gui.ModGuiHandler;
import com.example.examplemod.gui.container.InventoryItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
public class ItemStore extends Item
{
public ItemStore(String unlocalizedName)
{
super();
this.setUnlocalizedName(unlocalizedName);
// ItemStacks that store an NBT Tag Compound are limited to stack size of 1
setMaxStackSize(1);
// you'll want to set a creative tab as well, so you can get your item
setCreativeTab(Main.tabCustom);
}
// Without this method, your inventory will NOT work!!!
@Override
public int getMaxItemUseDuration(ItemStack stack) {
return 1; // return any value greater than zero
}
@Override
public ItemStack onItemRightClick(ItemStack itemstack, World world, EntityPlayer player)
{
if (!world.isRemote)
{
// If player not sneaking, open the inventory gui
if (!player.isSneaking()) {
player.openGui(Main.instance, ModGuiHandler.GUI_ITEM_INV, world, 0, 0, 0);
}
// Otherwise, stealthily place some diamonds in there for a nice surprise next time you open it up
else {
new InventoryItem(player.getHeldItem()).setInventorySlotContents(0, new ItemStack(Items.diamond,4));
}
}
return itemstack;
}
}
You've got yourself an infinite (looks recursive) loop somewhere.
What version of Minecraft are you coding for? If it's anything later than 1.8, this tutorial may not apply.
Minecraft version 1.8.9