Jump to content

[1.6.4]Problem with NBT, TEs and onItemUse


skullywag

Recommended Posts

Apologies for the vague title but couldnt fit it into one short sentence.

 

Simply I need to get at the nbt of a tile entity created when onItemUse does a setBlock:

 

public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, int par5, int par6, int par7, float par8, float par9, float par10)
    {
        if (par7 != 1)
        {
            return false;
        }
        else if (par2EntityPlayer.canPlayerEdit(par4, par5, par6, par7, par1ItemStack) && par2EntityPlayer.canPlayerEdit(par4, par5 + 1, par6, par7, par1ItemStack))
        {
            int i1 = par3World.getBlockId(par4, par5, par6);
            Block soil = Block.blocksList[i1];

            if (soil != null && soil == Block.cobblestoneMossy && soil.canBlockStay(par3World, par4, par5, par6) && par3World.isAirBlock(par4, par5 + 1, par6))
            {
                par3World.setBlock(par4, par5 + 1, par6, this.blockType);                
                --par1ItemStack.stackSize;
                TileEntity te = par3World.getBlockTileEntity(par4, par5+1, par6);
                return true;
            }
            else
            {
                return false;
            }
        }
        else
        {
            return false;
        }
    }

 

You can see where I grab the tile entity in the above code but that "te" doesnt let me "getEntityData" or anything else to get the tag. Is this possible and if not how do i transfer data about the item being used to the block/te it creates?

 

Am i again missing something plainly obvious.....(not having a good day for problem solving)

Link to comment
Share on other sites

The TileEntity is created automatically when the block is placed. There is no 'getEntityData' for TileEntity, but you can get the TE from the world and set class fields accordingly, which will then be saved/loaded if you wrote your TE correctly.

 

You're on the right track:

par3World.setBlock(par4, par5 + 1, par6, this.blockType);                
--par1ItemStack.stackSize;
TileEntity te = par3World.getBlockTileEntity(par4, par5+1, par6);
// you've got the tile entity, now just make sure it's yours and do whatever you want with it:
if (te instanceof YourTileEntityClass) {
YourTileEntityClass myTile = (YourTileEntityClass) te;
// now you can use your tile entity class methods:
myTile.setSomeField(someValue);
// now some field = some value, which will save and load with the tile entity
}
return true;

Link to comment
Share on other sites

Thanks guys, this was just a misunderstanding on my part of how I thought it worked (Java is not my main programming language in my day job), but a question does pop into my head after reading the above, granted I have access to the getter and setter for fields on the TE class so for this instance im good, but if i needed to how do i simply view whats currently in the NBT for the given entity, its something thats always bugged me and something ive not found anyone doing (probably because you wouldnt need it in the final code, debug only)

Link to comment
Share on other sites

No one ever does it because the NBT tag for tile entities is only used to store the data between quitting and restarting the world, unlike that for ItemStacks which is often modified and referenced during the course of the game. Once the tile entity loads, all the data should be stored in local fields, which you can print normally for debugging.

 

If you really want to see what is in the NBT tag, then put your debugging messages in the read / write NBT methods.

Link to comment
Share on other sites

ok its becoming clearer, let me set out what im doing:

 

I have 16 meta items on an item ID, they use the getColorFromItemStack to set a colour to their icon based on a list of colours in the class(16 of them). In the onItemUse method once some checks have been passed it does a setBlock and sets a field on the TileEntity for this block to its metaID, the TileEntityRenderer grabs the metaID from the TE and converts it into a set of RGB colour floats (im probably doing this rather heavily but it works for now) it then uses glColor4f to set the colour to the block/te model when rendered. This all works fine I get coloured renders in world.

 

The issue now is if i log off and back on, all my blocks are grey/white (the orginal texture colour before the gl pass), based on what youve said above should I be saving the colour in NBT as it will then survive past a restart. I that correct? and if so where is the best place to do the write to NBT. I have always set NBT like:

 

NBTTagCompound nbt= tileEntity.getTagCompound();	
nbt.setBoolean("something",(boolean)true);

 

the issue I face is that the above doesnt seem to be posible from anywhere in the classes ive set out above, now this may be (and probably is) down to me screwing something up.

 

Or am i finally going ot have to start working out the madness that is packets...

Link to comment
Share on other sites

If your block isn't using metadata for anything other than your rendering, why not just use the block's metadata value directly as stored in the world? world.setBlockMetatata(x, y, z, meta), then in your rendering class world.getBlockMetadata(x, y, z) done, you've got the index of the item responsible.

 

If that doesn't work for you for whatever reason, store the value as a field in the tile entity (making sure to save it in the tile entity's write / read NBT methods) and override the getDescriptionPacket method.

@Override
public void writeToNBT(NBTTagCompound compound) {
super.writeToNBT(compound);
compound.setInteger("key", value);
}

@Override
public void readFromNBT(NBTTagCompound compound) {
super.readFromNBT(compound);
yourField = compound.getInteger("key");
}

// now this will automatically synchronize your TileEntity from server to client:
@Override
public Packet getDescriptionPacket() {
NBTTagCompound tag = new NBTTagCompound();
this.writeToNBT(tag);
return new Packet132TileEntityData(xCoord, yCoord, zCoord, 1, tag);
}

// combined with this:
@Override
public void onDataPacket(INetworkManager net, Packet132TileEntityData packet) {
readFromNBT(packet.data);
}

From the sounds of it, you are simply missing the synchronization part.

Link to comment
Share on other sites

Thanks guys, this was just a misunderstanding on my part of how I thought it worked (Java is not my main programming language in my day job), but a question does pop into my head after reading the above, granted I have access to the getter and setter for fields on the TE class so for this instance im good, but if i needed to how do i simply view whats currently in the NBT for the given entity, its something thats always bugged me and something ive not found anyone doing (probably because you wouldnt need it in the final code, debug only)

There is a simple way to read the NBT tags from any tileentity, have an example:

 

NBTTagCompound tags = new NBTTagCompound();
tileentity.writeToNBT(tags);
System.out.println(tags);//debug here

 

You can also use readFromNBT to actually change some data within the tileentity, but it isn't recommended.

Link to comment
Share on other sites

You can also use readFromNBT to actually change some data within the tileentity, but it isn't recommended.

 

I use that feature to put custom values into a mob spawner placed during world gen, so that it will spawn a custom mob and at a much lower rate than the default.

http://www.minecraftforge.net/wiki/Mob_Spawners

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

Thanks everyone, not only is it working perfectly now, but due to me now understanding how this all works now i tidied lots of code up and feel a lot happier about this.

 

The block that is set uses 5 metas to render different stages of its model (it "grows" on update) so had to transfer the nbt "colour" to the new TE on update so it didnt lose its colour when it set the next block meta. other than that turns out this was pretty darnd simple.

 

My only issue now is my models....techne seems to not like rotating things the right way, looks fine in techne, looks totally wrong in game. Dont suppose anyone knows why this is, seems to be an issue with the middleslider, I did find a post for help by who i can only assume is the maintainer of it:

 

http://answers.unity3d.com/questions/375526/techne-y-rotation-bug-minecraft-modeling-program.html

 

think this is the issue im having. Wonder if techne will ever get completed.

Link to comment
Share on other sites

My only issue now is my models....techne seems to not like rotating things the right way, looks fine in techne, looks totally wrong in game. Dont suppose anyone knows why this is, seems to be an issue with the middleslider, I did find a post for help by who i can only assume is the maintainer of it

 

Probably has to do with the fact that Euler angles suck and quaternions are better.

 

There is probably not anything you can do.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

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.

Announcements



×
×
  • Create New...

Important Information

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