Jump to content
Search In
  • More options...
Find results that contain...
Find results in...

Working with Tile Entities (Not Saving When Quitting)


pro-mole
 Share

Recommended Posts

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?

Link to comment
Share on other sites

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.)

Link to comment
Share on other sites

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.

 

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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... :/

Link to comment
Share on other sites

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 :P

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
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.

 Share



×
×
  • Create New...

Important Information

By using this site, you agree to our Privacy Policy.