Jump to content

[1.7.10] Trouble with stackTagCompound


HappyKiller1O1

Recommended Posts

Ok so, my item when crafted sets it's stackTagCompound to a new NBTTagCompound. After that, I set a string. Then, in my event class I get the item in the players hand and, if it's the hammer I am creating; sets an itemstack to it and then gets it's stackTagCompound. What's my problem you may ask? Well, it's always null. I have pondered this for hours and have no clue what I am doing wrong. I have tried setting tags, resetting the stackTagCompound to a another NBTTagCompound, making sure my item is only stackable to 1 etc. I need help because I am about to rip my hair out. Here's the code as it is now.

 

Creation method in my item:

public void onCreated(ItemStack stack, World world, EntityPlayer player) {
	System.out.println("NBT TAG SET");

	stack.stackTagCompound = new NBTTagCompound();

	stack.stackTagCompound.setString("MiningSize", "3x3");
}

 

Event method to get it (this is using the BlockBreak event):

if(event.world != null && player != null) {
		if(player.inventory.getCurrentItem() != null) {
			if(player.inventory.getCurrentItem().getItem().equals(CrewMod.crewHammer)) {
				int direction = MathHelper.floor_double((double)(player.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3;

				ItemStack hammer = player.inventory.getCurrentItem();

				//System.out.println("ITEM IN HAND IS CREW HAMMER");

				Block block = event.block;

				World world = event.world;

				int x = event.x;
				int y = event.y;
				int z = event.z;

				NBTTagCompound cmp = hammer.stackTagCompound;

I am not a cat. I know my profile picture is sexy and amazing beyond anything you could imagine but my cat like features only persist in my fierce eyes. I might be a cat.

Link to comment
Share on other sites

I do craft it and it registers it in the console with my printout. It does seem to call the onCreated method four times (twice for server and twice for client) is that a problem?

I am not a cat. I know my profile picture is sexy and amazing beyond anything you could imagine but my cat like features only persist in my fierce eyes. I might be a cat.

Link to comment
Share on other sites

When you are operating on NBT - always do it on server-only. Do !world.isRemote.

 

And yes, it might be the problem you were looking for. When in creative-mode you (as player) are allowd to edit ItemStack's NBT (the server will accept your client-sided changes on ItemStack and override server's ones with them - your client is treated as "admin" entity).

 

Other than that - I have no idea what can be wrong. You could post more code, where else is your NBT used, maybe you are accidentaly reseting it?

1.7.10 is no longer supported by forge, you are on your own.

Link to comment
Share on other sites

Ok so, it's still returning null. Is it somehow because I can't get the stackTagCompound from the item in the player's hand? I just don't know what's wrong.

I am not a cat. I know my profile picture is sexy and amazing beyond anything you could imagine but my cat like features only persist in my fierce eyes. I might be a cat.

Link to comment
Share on other sites

Ok so, it's still returning null. Is it somehow because I can't get the stackTagCompound from the item in the player's hand? I just don't know what's wrong.

By default stackTagCompound  in itemstack is null. So when you get it, if it is null you set it to new tag...

Link to comment
Share on other sites

Does your code look something like this? If not - try, it's working for me. And also, hint: do fixTags method somewhere, that will do all null checks and fix missing tags. And all it before operating nbt...

NBTTagCompound tag = itemstack.stackTagCompound;
if(tag == null){
itemstack.stackTagCompound = new NBTTagCompound();
tag = itemstack.stackTagCompound;
}
... do your stuff here...
itemstack.stackTagCompound = tag;

 

Link to comment
Share on other sites

I'll try that but, may I ask why you set the stackCompound to a new one and set the tag you made to it but then, after doing everything; set the stackCompound to the tag? O.o

I am not a cat. I know my profile picture is sexy and amazing beyond anything you could imagine but my cat like features only persist in my fierce eyes. I might be a cat.

Link to comment
Share on other sites

I'll try that but, may I ask why you set the stackCompound to a new one and set the tag you made to it but then, after doing everything; set the stackCompound to the tag? O.o

I don't know. Sometimes without last line it is not working? Strange...

Link to comment
Share on other sites

So, I tried that and it still won't get the string. Here's what I did:

ItemStack hammer = new ItemStack(player.inventory.getCurrentItem().getItem());

				//System.out.println("ITEM IN HAND IS CREW HAMMER");

				Block block = event.block;

				World world = event.world;

				int x = event.x;
				int y = event.y;
				int z = event.z;

				NBTTagCompound cmp = hammer.stackTagCompound;

				if(cmp == null) {
					System.out.println("onBlockBreak HAMMER NBT WAS NULL");

					hammer.stackTagCompound = new NBTTagCompound();
					cmp = hammer.stackTagCompound;
				}

				//if(event.isCanceled())
					//return;

				String miningArea = null;

				if(cmp != null) {
					miningArea = cmp.getString("MiningSize");

					System.out.println("CMP WAS NOT NULL");
				}

				hammer.stackTagCompound = cmp;

				System.out.println(miningArea);

				this.breakBlock(world, player, hammer, x, y, z, direction, miningArea);

I am not a cat. I know my profile picture is sexy and amazing beyond anything you could imagine but my cat like features only persist in my fierce eyes. I might be a cat.

Link to comment
Share on other sites

So, I tried that and it still won't get the string. Here's what I did:

ItemStack hammer = new ItemStack(player.inventory.getCurrentItem().getItem());

				//System.out.println("ITEM IN HAND IS CREW HAMMER");

				Block block = event.block;

				World world = event.world;

				int x = event.x;
				int y = event.y;
				int z = event.z;

				NBTTagCompound cmp = hammer.stackTagCompound;

				if(cmp == null) {
					System.out.println("onBlockBreak HAMMER NBT WAS NULL");

					hammer.stackTagCompound = new NBTTagCompound();
					cmp = hammer.stackTagCompound;
				}

				//if(event.isCanceled())
					//return;

				String miningArea = null;

				if(cmp != null) {
					miningArea = cmp.getString("MiningSize");

					System.out.println("CMP WAS NOT NULL");
				}

				hammer.stackTagCompound = cmp;

				System.out.println(miningArea);

				this.breakBlock(world, player, hammer, x, y, z, direction, miningArea);

Do you think that on new stack, your mining area string will magically exist??? Again, null check and new set, this time for string...

 

And also, what the heck is this???

ItemStack hammer = new ItemStack(player.inventory.getCurrentItem().getItem());

Link to comment
Share on other sites

Well see, the string is set from a gui so it would be quite difficult to set it in the event class and item class. And that was me testing if I got the itemstack incorrect so ignore that.

I am not a cat. I know my profile picture is sexy and amazing beyond anything you could imagine but my cat like features only persist in my fierce eyes. I might be a cat.

Link to comment
Share on other sites

Well see, the string is set from a gui so it would be quite difficult to set it in the event class and item class. And that was me testing if I got the itemstack incorrect so ignore that.

Well, then check that you do same nbt check where you set the string. Then check all names of tags.

Link to comment
Share on other sites

Sorry if I am becoming annoying but, could you maybe elaborate on what you just said? NBT sometimes confuses me so, yeah. xD

I am not a cat. I know my profile picture is sexy and amazing beyond anything you could imagine but my cat like features only persist in my fierce eyes. I might be a cat.

Link to comment
Share on other sites

Sorry if I am becoming annoying but, could you maybe elaborate on what you just said? NBT sometimes confuses me so, yeah. xD

Okay, so let's begin optifying nbt manipulations:

First create nbt helper method, that will "fix" missing tags. For you it will look something like:

public static void fixNBT(ItemStack hammer){
NBTTagCompound cmp = hammer.stackTagCompound;				
if(cmp == null) {						
hammer.stackTagCompound = new NBTTagCompound();
cmp = hammer.stackTagCompound;
}
if(!cmp.hasKey("MiningArea")){
cmp.setString("MiningArea", "DEFAULT");
}
hammer.stackTagCompound = cmp;
}

Than before each nbt manipulation (getting/setting included), just call this method...

 

ps: i wrote this code from memory, so it may not have exact method names...

Link to comment
Share on other sites

Thank you for this. Where would I create this though? Considering it is static, would it go in the Item class? And also, you tell the game if it doesn't contain the key "MiningArea" to set the string? I'm guessing that was a typo?

 

EDIT: Nevermind! Forgot hasKey is used for anything set to NBT. Sorry! :P

I am not a cat. I know my profile picture is sexy and amazing beyond anything you could imagine but my cat like features only persist in my fierce eyes. I might be a cat.

Link to comment
Share on other sites

Thank you for this. Where would I create this though? Considering it is static, would it go in the Item class? And also, you tell the game if it doesn't contain the key "MiningArea" to set the string? I'm guessing that was a typo?

 

EDIT: Nevermind! Forgot hasKey is used for anything set to NBT. Sorry! :P

You can put it anywhere, it does not matter...

Is it working now???

Link to comment
Share on other sites

It does seem to work. I added a String variable so I can set the string to something I want. So, in a GUI class I could call the fix NBT to set it correctly? Or am I missing something?

I am not a cat. I know my profile picture is sexy and amazing beyond anything you could imagine but my cat like features only persist in my fierce eyes. I might be a cat.

Link to comment
Share on other sites

It does seem to work. I added a String variable so I can set the string to something I want. So, in a GUI class I could call the fix NBT to set it correctly? Or am I missing something?

Yes. That's made for it...

Link to comment
Share on other sites

Now see, the stackTagCompound will be null in any class besides the Item class (as it is now). By calling this method it would fix the nbt but, I'd have to fix it again in the gui class which wouldn't update it for the event class. This is a problem considering the nbt needs to be set from the gui to be used in the event class for handling.

I am not a cat. I know my profile picture is sexy and amazing beyond anything you could imagine but my cat like features only persist in my fierce eyes. I might be a cat.

Link to comment
Share on other sites

Now see, the stackTagCompound will be null in any class besides the Item class (as it is now). By calling this method it would fix the nbt but, I'd have to fix it again in the gui class which wouldn't update it for the event class. This is a problem considering the nbt needs to be set from the gui to be used in the event class for handling.

The interesting thing about this method is that if nbt is already defined, it will not replace values. That means that you can run it infinite amunt of times, without woriing of defaulting your info...

 

Is that what you mean? Or i misunderstood? Soryy, if yes...

Link to comment
Share on other sites

No that is what I mean but, it seems to always default my info. Like see here where it is called in my Item class and event class (I removed the String variable):

//In Item Class
public void onCreated(ItemStack stack, World world, EntityPlayer player) {
	if(world.isRemote)
		return;

	System.out.println("NBT TAG SET");

	NBTTagCompound cmp = stack.stackTagCompound;

	if(cmp == null) {
		cmp = new NBTTagCompound();
		stack.stackTagCompound = cmp;
	}

	this.fixNBT(stack);

	cmp.setString("MiningSize", "3x3");
}

//Event Class
public void onBlockBreak(BreakEvent event) {
	EntityPlayer player = event.getPlayer();

	if(event.world != null && player != null) {
		if(player.inventory.getCurrentItem() != null) {
			if(player.inventory.getCurrentItem().getItem().equals(CrewMod.crewHammer)) {
				int direction = MathHelper.floor_double((double)(player.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3;

				ItemStack hammer = player.inventory.getCurrentItem();

				//System.out.println("ITEM IN HAND IS CREW HAMMER");

				Block block = event.block;

				World world = event.world;

				int x = event.x;
				int y = event.y;
				int z = event.z;

				CrewHammer.fixNBT(hammer);

				NBTTagCompound cmp = hammer.stackTagCompound;

				//if(event.isCanceled())
					//return;

				String miningArea = null;

				if(cmp != null) {
					miningArea = cmp.getString("MiningSize");

					//System.out.println("CMP WAS NOT NULL");
				}

				System.out.println(miningArea);

				this.breakBlock(world, player, hammer, x, y, z, direction, miningArea);
			}
		}
	}
}

 

When called in the event class, the information is defaulted because the stackTagCompound returns null although I set it in the onCreated (Yes I craft a new hammer every time I go to test it)

I am not a cat. I know my profile picture is sexy and amazing beyond anything you could imagine but my cat like features only persist in my fierce eyes. I might be a cat.

Link to comment
Share on other sites

No that is what I mean but, it seems to always default my info. Like see here where it is called in my Item class and event class (I removed the String variable):

//In Item Class
public void onCreated(ItemStack stack, World world, EntityPlayer player) {
	if(world.isRemote)
		return;

	System.out.println("NBT TAG SET");

	NBTTagCompound cmp = stack.stackTagCompound;

	if(cmp == null) {
		cmp = new NBTTagCompound();
		stack.stackTagCompound = cmp;
	}

	this.fixNBT(stack);

	cmp.setString("MiningSize", "3x3");
}

//Event Class
public void onBlockBreak(BreakEvent event) {
	EntityPlayer player = event.getPlayer();

	if(event.world != null && player != null) {
		if(player.inventory.getCurrentItem() != null) {
			if(player.inventory.getCurrentItem().getItem().equals(CrewMod.crewHammer)) {
				int direction = MathHelper.floor_double((double)(player.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3;

				ItemStack hammer = player.inventory.getCurrentItem();

				//System.out.println("ITEM IN HAND IS CREW HAMMER");

				Block block = event.block;

				World world = event.world;

				int x = event.x;
				int y = event.y;
				int z = event.z;

				CrewHammer.fixNBT(hammer);

				NBTTagCompound cmp = hammer.stackTagCompound;

				//if(event.isCanceled())
					//return;

				String miningArea = null;

				if(cmp != null) {
					miningArea = cmp.getString("MiningSize");

					//System.out.println("CMP WAS NOT NULL");
				}

				System.out.println(miningArea);

				this.breakBlock(world, player, hammer, x, y, z, direction, miningArea);
			}
		}
	}
}

 

When called in the event class, the information is defaulted because the stackTagCompound returns null although I set it in the onCreated (Yes I craft a new hammer every time I go to test it)

Are you sure that on created is succesfully called?

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.