Jump to content

[1.8] [SOLVED] Item added to inventory disappearing on world load


Recommended Posts

Posted

I'm building a mod that, among other things, contains teleporters. The location of target teleporters is stored in punch cards. On right-click on a teleporter with a blank punch card, the blank card is replaced with a written card. Then, the location of the target teleporter is written to the written card's NBT.

 

All of that works just fine. The problem comes when reloading the world; for whatever reason, written punch cards don't persist in inventories through a world reload. I suspect the problem lies in my implementation of NBT. I don't totally understand NBT; it makes a convenient scapegoat.

 

The code that replaces punch cards:

 

	public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn, EnumFacing side, float hitX, float hitY, float hitZ) {
	//Get the tile entity of this teleporter
	TeleporterTileEntity t = (TeleporterTileEntity) worldIn.getTileEntity(pos);
	//Check if they're holding a blank punch card
	ItemStack item = playerIn.getCurrentEquippedItem();
	if(item != null && item.getItem() == EnderScience.blankPunch) {
		//Replace with written card
		ItemStack card = new ItemStack(EnderScience.writtenPunch, 1);
		int slot = playerIn.inventory.currentItem;
		playerIn.replaceItemInInventory(slot, card);
		//Store this teleporter's coordinates in the new punch card
		NBTTagCompound tag = new NBTTagCompound();
		tag.setString("teleporter", pos.getX() + " " + pos.getY() + " " + pos.getZ());
		card.setTagCompound(tag);
		if(playerIn.getCurrentEquippedItem().getTagCompound() == null)
			System.out.println("[Ender Science]: Failed to write card's NBT.");
		System.out.println("[Ender Science]: Teleporter coordinates: " + tag.getString("teleporter"));
		return true;
	}
	else if (item != null && item.getItem() == EnderScience.writtenPunch){
		//TODO: Fix teleport call
		t.teleport(playerIn, worldIn, item.getTagCompound().getString("teleporter"));
		return true;
	}
	return true;
}

 

And the base class for the written punch card:

 

public class WrittenPunchCard extends Item {
public WrittenPunchCard()
{
	setMaxStackSize(1);
	setUnlocalizedName("writtenpunch");
	setCreativeTab(EnderScience.tab);
}

@Override
public void addInformation(ItemStack stack, EntityPlayer playerIn, List tooltip, boolean advanced) 
{
	tooltip.add("Coordinates: " + stack.getTagCompound().getString("teleporter"));
}
}

 

The problem persists when I comment out the code that writes the teleporter coordinates to the punch card.

Posted

public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn, EnumFacing side, float hitX, float hitY, float hitZ)
{
	if (!worldIn.isRemote) // run on server
	{
		TeleporterTileEntity t = (TeleporterTileEntity) worldIn.getTileEntity(pos);
		if (t != null)
		{
			ItemStack stack = playerIn.getCurrentEquippedItem();
			if (stack != null && stack.getItem() == EnderScience.card) // you don't need separate items, but if you do... well, you can replace ItemStack like you did before, just do it on server.
			{
				NBTTagCompound nbt = stack.getTagCompound();
				if (nbt == null)
				{
					nbt = new NBTTagCompound();
					stack.setTagCompound(nbt);
				}

				if (!nbt.getBoolean("punch")) // has NBT, but not punched, so punch
				{
					nbt.setBoolean("punched", true);
					nbt.setInteger("x", pos.getX());
					nbt.setInteger("y", pos.getY());
					nbt.setInteger("z", pos.getZ());
					System.out.println("[Ender Science]: Teleporter coordinates: " + pos.getX() + " / " + pos.getY() + " / " + pos.getZ());
				}
				else // punched, teleport
				{
					t.teleport(playerIn, worldIn, nbt.getInteger("x"), nbt.getInteger("y"), nbt.getInteger("z")); // change it to 3-arg coords.
				}
			}
		}
	}
	return true;
}

 

Ahh... this can be done nicer....

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

Posted

Ahh... this can be done nicer....

Lol, yeah, I'd probably try to reduce the indentation a few levels, for one :P

public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumFacing side, float hitX, float hitY, float hitZ)
{
TileEntity te = world.getTileEntity(pos);
ItemStack stack = player.getHeldItem();
if (!worldIn.isRemote && te instanceof TeleporterTileEntity && stack != null && stack.getItem() == EnderScience.card)
{
	// now we're cookin' with a whole lot less mess 
	// do all your other stuff here
}
}

 

But that's not really related to your problem... your problem sounds to me like you are managing the inventory from a client-side GUI and expecting it to persist, but the client is like a dream or a ghost - it is completely ephemeral.

 

You need to make sure that any setting you do, be it adding items to inventories or changing NBT data, is done on the server.

Posted

Ahh... this can be done nicer....

Lol, yeah, I'd probably try to reduce the indentation a few levels, for one :P

 

This is what happens when you get back to "micro-optimization-is-bullshit-java" after finishing algorithmics project in savage C (notice how hard I tried to declare fields in smallest scopes and other mad shit and I didn't even do that well thing well - #sleepy)... :D

Worthless code. And yeah - main point was to use world.isRemote (which he OP didn't in main post).

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

Posted

Thank you both! I modified the system so that written punch cards have different metadata than unwritten (I want them to have different names and have distinct icons). The call for server-only fixed the persistence issue; however, I have to call my teleport code client-side for it to work.

 

The teleport code just calls player.setPosition(). Is there some other way I should be doing this so that it works from server-side?

Posted

There should be similar method "setPositionAndUpdate" . Look into vanilla, you should find it.

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

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.