Jump to content

Trying to save data per world


Roxane

Recommended Posts

Hi,

I'm helping some other guys to write their mod in which you can place teleporter blocks. When rightclicking with the staff it should teleport you to the nearest teleporter block.

I'm trying to save the teleporter block's position in the world data using WorldSavedData but neither readFromNBT nor writeToNBT gets called...

 

Can you help me?

 

Teleporter Block:

 

 

package seval.healmod;

import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;

public class BlockTeleporter extends Block
{

public BlockTeleporter()
{
	super(Material.tnt);
	this.setCreativeTab(CreativeTabs.tabRedstone);
	this.setUnlocalizedName("teleporter");
	this.setRegistryName("teleporter");
}


public IBlockState onBlockPlaced(World worldIn,BlockPos pos,EnumFacing facing,float hitX,float hitY,float hitZ,int meta,EntityLivingBase placer)
{
	HealMod.positionen.addBlockPos(pos,worldIn);
	return super.onBlockPlaced(worldIn, pos, facing, hitX, hitY, hitZ, meta, placer);
}

public void onBlockHarvested(World worldIn,BlockPos pos,IBlockState state,EntityPlayer player)
{
	HealMod.positionen.removeBlockPos(pos,worldIn);
	super.onBlockHarvested(worldIn, pos, state, player);
}
}

 

 

 

Teleporter Staff:

 

package seval.healmod;

import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ActionResult;
import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;

public class ItemTeleporterStab extends Item
{
public ItemTeleporterStab()
{

	this.setUnlocalizedName("teleporterStab");
	this.setRegistryName("teleporterStab");
	this.setCreativeTab(CreativeTabs.tabCombat);
	this.maxStackSize = 1;
	this.setMaxDamage(9);
}

public ActionResult<ItemStack> onItemRightClick(ItemStack itemStackIn,World worldIn,EntityPlayer playerIn,EnumHand hand)
{
	//Get the data from the world save file
	SavedDataTeleporter saver = SavedDataTeleporter.forWorld(worldIn);
	HealMod.positionen.readNBTList(saver.getData());

	BlockPosList naechster = HealMod.positionen.findNearest(playerIn.getPosition());
	System.out.println(naechster);
	if(playerIn.getPosition().getDistance(naechster.pos.getX(), naechster.pos.getY(), naechster.pos.getZ())<100000)
	{
		//playerIn.attemptTeleport(naechster.pos.getX(), naechster.pos.getY()+1, naechster.pos.getZ());
		playerIn.teleportTo_(naechster.pos.getX(), naechster.pos.getY()+1, naechster.pos.getZ());
	}
	return new ActionResult(EnumActionResult.SUCCESS,itemStackIn);
}
}

 

 

My WorldSavedData class:

 

package seval.healmod;

import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;
import net.minecraft.world.WorldSavedData;
import net.minecraft.world.storage.MapStorage;

public class SavedDataTeleporter extends WorldSavedData
{
private NBTTagCompound data = new NBTTagCompound();

public SavedDataTeleporter()
{
	super(HealMod.MODID);
}

public SavedDataTeleporter(String name)
{
	super(name);
}

@Override
public void readFromNBT(NBTTagCompound nbt)
{
	data = nbt.getCompoundTag("Teleporter");
	System.out.println("Reating from NBT: " + nbt);
}

@Override
public void writeToNBT(NBTTagCompound nbt)
{
	nbt.setTag("Teleporter", data);
	System.out.println("Writing to NBT: " + nbt);
	//return nbt;
}

@Override
public void markDirty()
{
	System.out.println("Marked dirty: " + data);
	super.markDirty();
}

public NBTTagCompound getData() {
        return data;
    }

public void setData(NBTTagCompound nbt) {
        data = nbt;
    }

public static SavedDataTeleporter forWorld(World world)
{
	// Retrieves the SavedDataTeleporter instance for the given world, creating it if necessary
	MapStorage storage = world.getMapStorage();
	SavedDataTeleporter saver = (SavedDataTeleporter) storage.loadData(SavedDataTeleporter.class, HealMod.MODID);
	if (saver == null)
	{
		saver = new SavedDataTeleporter();
		storage.setData(HealMod.MODID, saver);
	}
	return saver;
}
}

 

 

BlockPosList:

 

package seval.healmod;

import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagInt;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.FMLCommonHandler;

public class BlockPosList
{
public BlockPos pos;
private BlockPosList nextElement;
private double distance = -1;

BlockPosList()
{
	pos = new BlockPos(60000000,256,60000000);
	nextElement = null;
}

BlockPosList(BlockPos posIn, BlockPosList next)
{
	pos = posIn;
	nextElement = next;
}

public boolean isEndElement()
{
	return this.nextElement == null;
}

public void setToEndElement()
{
	this.nextElement = null;
}

public void addBlockPos(BlockPos newPos,World world)
{
	if (newPos.equals(this.pos))
	{
		//do nothing as this pos already exists
	}
	else if (!isEndElement())
	{
		nextElement.addBlockPos(newPos,world);
	}
	else
	{
		nextElement = new BlockPosList(newPos, null);
		//System.out.println("Adding new Element: " + newPos.getX() + " " + newPos.getY() + " " + newPos.getZ());

		//Save the previously created NBTTagCompound to the world save
		SavedDataTeleporter saver = SavedDataTeleporter.forWorld(world);
		saver.setData(writeNBTList());
		world.getPerWorldStorage().setData("Teleporter", saver);
		saver.markDirty();


	}


}

public BlockPosList removeBlockPos(BlockPos deletePos, World world)
{
	if (deletePos.equals(this.pos)) 
	{
		//Save the NBTTagCompound to the world save
		SavedDataTeleporter saver = SavedDataTeleporter.forWorld(world);
		saver.setData(writeNBTList());
		saver.markDirty();

		//System.out.println("Removing Element: " + deletePos.getX() + " " + deletePos.getY() + " " + deletePos.getZ());
		return this.nextElement;
	}
	else 
	{
		if (!isEndElement()) this.nextElement = nextElement.removeBlockPos(deletePos, world);
		return this;
	}
}

public void readNBTList(NBTTagCompound nbt)
{
	this.readNBTList(nbt, 0);
}

public void readNBTList(NBTTagCompound nbt, int index)
{
	if (nbt.hasKey(Integer.toString(index)))
	{
		NBTTagList pos = nbt.getTagList(Integer.toString(index), 3);
		if (!pos.hasNoTags())
		{
			NBTTagInt x = (NBTTagInt) pos.get(0);
			NBTTagInt y = (NBTTagInt) pos.get(1);
			NBTTagInt z = (NBTTagInt) pos.get(2);

			if (x != null && y != null && z != null) this.pos = new BlockPos(x.getInt(), y.getInt(), z.getInt());
		}
	}

	if (nbt.hasKey(Integer.toString(index + 1)))
	{
		nextElement = new BlockPosList();
		nextElement.readNBTList(nbt, index + 1);
	}
}

public NBTTagCompound writeNBTList()
{
	return this.writeNBTList(new NBTTagCompound(), 0);
}

public NBTTagCompound writeNBTList(NBTTagCompound nbt, int index)
{
	NBTTagList pos = new NBTTagList();

	NBTTagInt x = new NBTTagInt(this.pos.getX());
	NBTTagInt y = new NBTTagInt(this.pos.getY());
	NBTTagInt z = new NBTTagInt(this.pos.getZ());
	pos.appendTag(x);
	pos.appendTag(y);
	pos.appendTag(z);

	nbt.setTag(Integer.toString(index), pos);

	if (!isEndElement())
	{
		nbt = nextElement.writeNBTList(nbt, index + 1);
	}
	return nbt;
}

@Override
public String toString()
{
	return this.pos.toString();//this.writeNBTList().toString();
}

public BlockPosList findNearest(BlockPos pos)
{		
	//BlockPos neuePos=pos;
	this.distance = pos.getDistance(this.pos.getX(), this.pos.getY(), this.pos.getZ());
	if(!isEndElement())
	{
		BlockPosList otherPos = this.nextElement.findNearest(pos);
		double otherDistance = otherPos.distance;

		if (this.distance < otherDistance)
		{
			return this;
		}
		else
		{
			return otherPos;
		}
	}
	else return this;
}
}

 

Link to comment
Share on other sites

When accessing your data you must always grab the

WorldSavedData

from the

World

instance.

Am I not accessing the data with the

World

instance by calling

public ActionResult<ItemStack> onItemRightClick(ItemStack itemStackIn,World worldIn,EntityPlayer playerIn,EnumHand hand)
{
	//Get the data from the world save file
	SavedDataTeleporter saver = SavedDataTeleporter.forWorld(worldIn);
	HealMod.positionen.readNBTList(saver.getData());

and

public static SavedDataTeleporter forWorld(World world)
{
	// Retrieves the SavedDataTeleporter instance for the given world, creating it if necessary
	MapStorage storage = world.getMapStorage();
	SavedDataTeleporter saver = (SavedDataTeleporter) storage.loadData(SavedDataTeleporter.class, HealMod.MODID);
	if (saver == null)
	{
		saver = new SavedDataTeleporter();
		storage.setData(HealMod.MODID, saver);
	}
	return saver;
}

?

You should not be holding on to the NBT data. Store the proper data in the

WorldSavedData

instance (in your case a

List

of

BlockPos

, why do you have your own custom linked list implementation? :o). Then in

readFromNbt

and

writeToNbt

you decode/encode the NBT data.

Ok, got that thing with decoding/encoding in

readFromNbt

and

writeToNbt

, makes sense.

The linked list implementation: Yeah, I know... I partially did it to just implement something like this by myself to really understand it  ;)

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.