Jump to content

[SOLVED] Store data with NBTTag within items


spywhere

Recommended Posts

I have a problem with store data on items...

 

What I want to do is...

  When you sneak & right click, GUI will popup and ask player to enter some data. When click Done (or OK) ,data that player entered will be stored within items. And when they sneak & right click again, they can edit their entered data. Right click will use data stored in the item.

 

Problems is...

  Data is stored but still being reset.

 

This is what I tried to simplify it (So it easier to understand and helps me out)...

  When player right click, the number will be told. And when player sneak & right click, GUI will open and store edited data.

 

Testing...

  Right click several times without sneak & right click.

 

Expectation:

  A random number called X being told when right click and does not change when right click again.

 

Reality:

  As screenshot showing...

 

Source code for item

private void useItem(ItemStack itemStack, World world, EntityPlayer player, boolean addMode) {
   data = new NBTData(itemStack);
   if(world.isRemote){
      //Is client
      if(!data.hasKey("test")){
         data.set("test", new Random().nextInt(100));
         data.save();
      }
      if(player.isSneaking()){
         player.openGui(MyMod.instance, 1, world, (int) player.posX, (int) player.posY, (int) player.posZ);
      }else{
         player.addChatMessage("Number is " + data.get("test", -1));
      }
   }
}

public ItemStack onItemRightClick(ItemStack itemStack, World world, EntityPlayer player) {
   if(!player.capabilities.isCreativeMode){
      itemStack.stackSize = 0;
      return itemStack;
   }
   //On air
   useItem(itemStack, world, player, false);
   return itemStack;
}

public boolean onItemUse(ItemStack itemStack, EntityPlayer player, World world, int blockX, int blockY, int blockZ, int face, float par8, float par9, float par10) {
   if(!player.capabilities.isCreativeMode){
      --itemStack.stackSize;
      return false;
   }
   //On block
   useItem(itemStack, world, player, true);
   return true;
}

 

Screenshot:

width=180 height=102http://s9.postimg.org/cu96dubjv/2013_04_25_02_32_20.jpg[/img]

 

Notes:

  • NBTData is my own wrapper of NBTTagCompound for easier use
  • That "data" will be used with GUI. Store data will do the same (data.save()) on GUI class.
  • data.save() will store all data on NBTTagCompound to ItemStack (using ItemStack.setTagCompound)

Link to comment
Share on other sites

I have a problem with store data on items...

 

What I want to do is...

  When you sneak & right click, GUI will popup and ask player to enter some data. When click Done (or OK) ,data that player entered will be stored within items. And when they sneak & right click again, they can edit their entered data. Right click will use data stored in the item.

 

Problems is...

  Data is stored but still being reset.

 

This is what I tried to simplify it (So it easier to understand and helps me out)...

  When player right click, the number will be told. And when player sneak & right click, GUI will open and store edited data.

 

Testing...

  Right click several times without sneak & right click.

 

Expectation:

  A random number called X being told when right click and does not change when right click again.

 

Reality:

  As screenshot showing...

 

Source code for item

private void useItem(ItemStack itemStack, World world, EntityPlayer player, boolean addMode) {
   data = new NBTData(itemStack);
   if(world.isRemote){
      //Is client
      if(!data.hasKey("test")){
         data.set("test", new Random().nextInt(100));
         data.save();
      }
      if(player.isSneaking()){
         player.openGui(MyMod.instance, 1, world, (int) player.posX, (int) player.posY, (int) player.posZ);
      }else{
         player.addChatMessage("Number is " + data.get("test", -1));
      }
   }
}

public ItemStack onItemRightClick(ItemStack itemStack, World world, EntityPlayer player) {
   if(!player.capabilities.isCreativeMode){
      itemStack.stackSize = 0;
      return itemStack;
   }
   //On air
   useItem(itemStack, world, player, false);
   return itemStack;
}

public boolean onItemUse(ItemStack itemStack, EntityPlayer player, World world, int blockX, int blockY, int blockZ, int face, float par8, float par9, float par10) {
   if(!player.capabilities.isCreativeMode){
      --itemStack.stackSize;
      return false;
   }
   //On block
   useItem(itemStack, world, player, true);
   return true;
}

 

Screenshot:

width=180 height=102http://s9.postimg.org/cu96dubjv/2013_04_25_02_32_20.jpg[/img]

 

Notes:

  • NBTData is my own wrapper of NBTTagCompound for easier use
  • That "data" will be used with GUI. Store data will do the same (data.save()) on GUI class.
  • data.save() will store all data on NBTTagCompound to ItemStack (using ItemStack.setTagCompound)

Link to comment
Share on other sites

 if(world.isRemote){

so you don't want your data stored...? if it's not done serverside, the item will have its data reset... unless you have [/code]@Override

public boolean shareTag(ItemStack i){

//something like this, double check the method name

return false;

}[/code] to prevent the server from sending an overwriting nbt packet, but whatever data you store WILL be lost when the itemstack is offloaded in any way...

I think its my java of the variables.

Link to comment
Share on other sites

 if(world.isRemote){

so you don't want your data stored...? if it's not done serverside, the item will have its data reset... unless you have [/code]@Override

public boolean shareTag(ItemStack i){

//something like this, double check the method name

return false;

}[/code] to prevent the server from sending an overwriting nbt packet, but whatever data you store WILL be lost when the itemstack is offloaded in any way...

I think its my java of the variables.

Link to comment
Share on other sites

 if(world.isRemote){

so you don't want your data stored...? if it's not done serverside, the item will have its data reset... unless you have [/code]@Override

public boolean shareTag(ItemStack i){

//something like this, double check the method name

return false;

}[/code] to prevent the server from sending an overwriting nbt packet, but whatever data you store WILL be lost when the itemstack is offloaded in any way...

 

 

That's what I just thinking about how it's work... Before posting this, I try to make it store data on server side and open GUI on client side but there's a problem which is when you first open GUI, the random value generated but didn't stored and when you try open it again, that's the time it's stored the value...

 

 

Or simple is... it's start to store data on second time I open the GUI. Like this...

Number is 53

Number is 14

Number is 14

Number is 14

Number is 14

 

 

I just don't know how to fix that so it's generate number only once... I'll try fix that again...

 

 

And thanks for reply.

Link to comment
Share on other sites

 if(world.isRemote){

so you don't want your data stored...? if it's not done serverside, the item will have its data reset... unless you have [/code]@Override

public boolean shareTag(ItemStack i){

//something like this, double check the method name

return false;

}[/code] to prevent the server from sending an overwriting nbt packet, but whatever data you store WILL be lost when the itemstack is offloaded in any way...

 

 

That's what I just thinking about how it's work... Before posting this, I try to make it store data on server side and open GUI on client side but there's a problem which is when you first open GUI, the random value generated but didn't stored and when you try open it again, that's the time it's stored the value...

 

 

Or simple is... it's start to store data on second time I open the GUI. Like this...

Number is 53

Number is 14

Number is 14

Number is 14

Number is 14

 

 

I just don't know how to fix that so it's generate number only once... I'll try fix that again...

 

 

And thanks for reply.

Link to comment
Share on other sites

If you need to set the value, look at GuiScreenBook, if the value is set by opening the Gui its done by sending the changed value.

 

Alternatively, if you are setting the value server side, you could simply do so in your IGuiHandler like so:

Random rand = new Random();
@Override
public Object getServerGuiElement(int ID, EntityPlayer p, World w,
		int x, int y, int z) {
if(ID == yourGuiID && p.getCurrentEquippedItem == yourItem){
ItemStack i = p.getCurrentEquippedItem();
if(!i.hasTagCompound());
i.setTagCompound(new NBTTagCompound);
i.getTagCompound().setInteger("randVal", rand.nextInt(intYourRange);
//or use your wrapper here
}
	return null;
}

I think its my java of the variables.

Link to comment
Share on other sites

If you need to set the value, look at GuiScreenBook, if the value is set by opening the Gui its done by sending the changed value.

 

Alternatively, if you are setting the value server side, you could simply do so in your IGuiHandler like so:

Random rand = new Random();
@Override
public Object getServerGuiElement(int ID, EntityPlayer p, World w,
		int x, int y, int z) {
if(ID == yourGuiID && p.getCurrentEquippedItem == yourItem){
ItemStack i = p.getCurrentEquippedItem();
if(!i.hasTagCompound());
i.setTagCompound(new NBTTagCompound);
i.getTagCompound().setInteger("randVal", rand.nextInt(intYourRange);
//or use your wrapper here
}
	return null;
}

I think its my java of the variables.

Link to comment
Share on other sites

If you need to set the value, look at GuiScreenBook, if the value is set by opening the Gui its done by sending the changed value.

 

Alternatively, if you are setting the value server side, you could simply do so in your IGuiHandler like so:

Random rand = new Random();
   @Override
   public Object getServerGuiElement(int ID, EntityPlayer p, World w,
         int x, int y, int z) {
   if(ID == yourGuiID && p.getCurrentEquippedItem == yourItem){
ItemStack i = p.getCurrentEquippedItem();
if(!i.hasTagCompound());
i.setTagCompound(new NBTTagCompound);
i.getTagCompound().setInteger("randVal", rand.nextInt(intYourRange);
//or use your wrapper here
}
      return null;
   }

 

 

Thank you. Problem now solved.

 

 

In fact, I saw that "GuiScreenBook" have a method called "sendBookToServer" which required to send a packet to server.

Instead of sending a packet to server. I set a global variable inside GUI class and use that data to save on server call which is works great. :D

Link to comment
Share on other sites

If you need to set the value, look at GuiScreenBook, if the value is set by opening the Gui its done by sending the changed value.

 

Alternatively, if you are setting the value server side, you could simply do so in your IGuiHandler like so:

Random rand = new Random();
   @Override
   public Object getServerGuiElement(int ID, EntityPlayer p, World w,
         int x, int y, int z) {
   if(ID == yourGuiID && p.getCurrentEquippedItem == yourItem){
ItemStack i = p.getCurrentEquippedItem();
if(!i.hasTagCompound());
i.setTagCompound(new NBTTagCompound);
i.getTagCompound().setInteger("randVal", rand.nextInt(intYourRange);
//or use your wrapper here
}
      return null;
   }

 

 

Thank you. Problem now solved.

 

 

In fact, I saw that "GuiScreenBook" have a method called "sendBookToServer" which required to send a packet to server.

Instead of sending a packet to server. I set a global variable inside GUI class and use that data to save on server call which is works great. :D

Link to comment
Share on other sites

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.



×
×
  • Create New...

Important Information

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