pro-mole Posted November 1, 2012 Posted November 1, 2012 Let me try to explain what I am doing. I have an item that, when used, creates a Tile Entity in a Dirt block, for example. This block will have a Tile Entity that will, in summary, build a 5x3x5 room around it. Up to that part I can do fine. Problem arises, though, if I leave and enter the game again. Because when that happens the Tile Entity vanishes from the map, even if it was in the middle of its work. Now, I know there's an easy way to avoid that: creating a custom BlockContainer that will contain the Tile Entity and thus keep track of it. But I'm trying to avoid that just because I've designed my mod that way. I can do that, but I'd like to use that as a last resort. So, to the question. What I'm not understanding is how to make it so the Tile Entity is saved on the map using those read/write NBT functions. Again, I can see how to set one for a container block, but doing that for a Tile Entity that is arbitrarily put on the map like this is not working. The save/load function is simply not being called. I'm missing something and I can't figure out what. Anyone knows how to work with this situation? Quote
Ghostrec35 Posted November 1, 2012 Posted November 1, 2012 Did you do TileEntity.addMapping(tileEntityClass, StringId); Or you can use GameRegistry.registerTileEntity(tileEntityClass, StringID); (GameRegistry just uses this TileEntity method anyway, so it doesn't really matter which you use. This caused my tile entity to disappear until I actually mapped it.) Quote
_bau5 Posted November 1, 2012 Posted November 1, 2012 Containers get most of their information from the TileEntity. Not the other way around. I've heard a lot of people talk about the container as the interface that the server sees, while the client sees the gui which the container populates WITH information from the tileentity. writeToNBT(...) and readFromNBT(...) are functions from TileEntity class, so if your tile entity does extend TileEntity, then you can override those functions. NBTTags are amazing, and can be used to store close to anything, if you work at it. Make sure with the writeToNBT(...) you're actually setting and reading them properly. If you're using NBTTagList make sure you're appending tags to that list with yourTagList.append(yourTag) and then subsequently setting that tagList to the actual tag, with tag.setTag("name" yourTagList. Perhaps this wasn't your question, perhaps this post is worthless. Hope it helps at least a bit, or something. Quote
pro-mole Posted November 1, 2012 Author Posted November 1, 2012 Did you do TileEntity.addMapping(tileEntityClass, StringId); Or you can use GameRegistry.registerTileEntity(tileEntityClass, StringID); (GameRegistry just uses this TileEntity method anyway, so it doesn't really matter which you use. This caused my tile entity to disappear until I actually mapped it.) I actually thought that was the problem, but this has been fixed long ago. Still not quite working. Here's a snippet: GameRegistry.registerTileEntity(TileSeedstoneHouse.class, "House Seedstone"); _bau5, by no means, that was really informative. I'm still confused, though. Here's the code that I've implemented: package Mole.common.seedstone; import Mole.common.Constants; import net.minecraft.src.ItemStack; import net.minecraft.src.NBTTagCompound; import net.minecraft.src.NBTTagList; import net.minecraft.src.TileEntity; import net.minecraft.src.WorldInfo; public class TileSeedstoneHouse extends TileEntity { int index = 0; int width, height; int blockID; int ticks = 0; boolean started = false; //Starts building a House structure from (x,y,z), with block of type blockID public TileSeedstoneHouse(int level, int type) { switch (level) { case 1: width = 7; height = 5; break; case 2: width = 7; height = 6; break; case 3: width = 9; height = 6; break; default: width = 7; height = 5; break; } setType(type); start(); } public void setType(int type) { blockID = type; } public void start() { started = true; System.out.println("Start the Seed!"); } //(...) Here's a lot of code that does the building; not important now, I reckon @Override public void readFromNBT(NBTTagCompound tagCompound) { System.out.println("Loading TE Seedstone at "+xCoord+":"+yCoord+":"+zCoord); super.readFromNBT(tagCompound); index = tagCompound.getInteger("Pointer"); blockID = tagCompound.getInteger("BlockID"); height = tagCompound.getInteger("H"); width = tagCompound.getInteger("W"); } @Override public void writeToNBT(NBTTagCompound tagCompound) { System.out.println("Saving TE Seedstone at "+xCoord+":"+yCoord+":"+zCoord); super.writeToNBT(tagCompound); tagCompound.setInteger("Pointer", index); tagCompound.setInteger("BlockID", blockID); tagCompound.setInteger("H", height); tagCompound.setInteger("W", width); } } I'm not sure if I'm using the readFrom/writeToNBT functions right(BTW: the print functions there don't even appear in the console =/). Or if that tile entity name is valid. Can anyone tutor me here? Quote
pro-mole Posted November 3, 2012 Author Posted November 3, 2012 I did a good load of backtracking while working with another issue(in summary, a fail proof "getBlockTileEntity" call would return null in a block where I did add a tile entity before) I found out the cause for this. Going down the call hierarchy, setBlockTileEntity calls setChunkBlockTileEntity, which will actually save the TE into the chunk data. Here we have this if: if (block != null && block.hasTileEntity(getBlockMetadata(par1, par2, par3))) { ... this.chunkTileEntityMap.put(var5, par4TileEntity); } Which is where my problem lies, as hasTileEntity only returns true for BlockContainer instances. None of the blocks I'm adding a tile entity to are containers. In the end, the tile entity is added and updates, but is not part of the block. For all ends and means, apparently Minecraft won't recognize it as a TileEntity that exists there. So far I couldn't find a way around that, besides creating a new block just to set my Tile Entities into. Anyone has any idea? Quote
pro-mole Posted November 4, 2012 Author Posted November 4, 2012 Ok, so I did some debug and backtracing and came up with this solution when creating the tile entity: _TE = new TileSeedstoneHouse(1, blockId); world.setBlockTileEntity(x, y, z, _TE); chunk.chunkTileEntityMap.put(pos, _TE); It works to some extent. It saves, it loads... once. And the tile entity stops updating. Or existing, for that matter. Apparently the loader doesn't know where to put it. I'm trying to trace deeper to find out how to get around that now, but I think I'm losing hacking momentum... Quote
Ebilkill Posted November 5, 2012 Posted November 5, 2012 In your block file, you COULD just override the hasTileEntity and return true, of course... Quote
pro-mole Posted November 5, 2012 Author Posted November 5, 2012 Considering I intended the block in question to be a Dirt block... no, no I couldn't. Not without making this a coremod, and that's way over my ambitions right now. I'm giving up for now. I'm making a block to contain this damn thing already. =/ Quote
rich1051414 Posted November 5, 2012 Posted November 5, 2012 Considering I intended the block in question to be a Dirt block... no, no I couldn't. Not without making this a coremod, and that's way over my ambitions right now. I'm giving up for now. I'm making a block to contain this damn thing already. =/ Have you thought about making the server keep it's own map for what you want the tile entity to save? Set the key to something like String.valueOf(x) + "-" + String.valueOf(y) + "-" +String.valueOf(z) so you can get the information easily, then set up a simple client to server packet exchange to pass the information? Of course, this would be quite involved for a dirt block Quote
pro-mole Posted November 5, 2012 Author Posted November 5, 2012 I thought about using packets or something like that, but I think this is not the time to dwell into that. I've resigned myself to a solution that just works for now. Quote
Recommended Posts
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.