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.



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • I tried installing forge for 1.20.6 and for some reason when i open it, it says: "Java Virtual Machine Launcher": Error: Unable to acces jarfile C:\Users\PC\OneDrive\???????????\forge-1.20.6-50.1.0-installer.jar. I dont have any idea what to do. Can anyone help?
    • Update I seem to have fixed it by removing the folders made when the server first starts (e.g. config, world) and starting it all again.  
    • Good days im working on this Costume underground dungeon the plan is creating a mineshaft tunel whit fully functional railway and rail switchs going deep down into the ground      My hypothesis its than than the rails get created before the supporting stone blocks   i was setting blocks whit  Level.setBlock(pos,blkstate,2)  in mode 2 i change it to 10 but the problem persist  in the doorblock class it uses 3 as flag   level.setBlock(p_52750_.above(), p_52751_.setValue(HALF, DoubleBlockHalf.UPPER), 3); i set 3 as flag the problem continues (i du not know what 3 means) this numbers are basically a mistery ===> i need the number mode to set a block into the world whithout doing any checks or triggering neighbors blocks  ############# The nbt class has an Enum to make more redable the code  is in "import net.minecraft.nbt.Tag;" nbtpos = entitydata.getList("blockPos", Tag.TAG_INT);// blockdata contains pos;   if theres something like this for the setBlockMode that would be nice           
    • this is a really old resurrected post  anyway    //values to nbt  ListTag nbtblockpos = new ListTag(); nbtblockpos.add(IntTag.valueOf(blockPos.getX())); nbtblockpos.add(IntTag.valueOf(blockPos.getY())); nbtblockpos.add(IntTag.valueOf(blockPos.getZ())); entitydata.put("blockPos", nbtblockpos); ListTag nbtpos = new ListTag(); nbtpos.add(DoubleTag.valueOf(Pos.x)); nbtpos.add(DoubleTag.valueOf(Pos.y)); nbtpos.add(DoubleTag.valueOf(Pos.z)); entitydata.put("pos", nbtpos);   //getting things back if(entitydata.contains("blockPos")) { nbtpos = entitydata.getList("blockPos", Tag.TAG_INT);// blockdata contains pos this.blockPos = new BlockPos( nbtpos.getInt(0), nbtpos.getInt(1), nbtpos.getInt(2) ); } this.pos = null; if(entitydata.contains("pos")) { nbtpos = entitydata.getList("pos", Tag.TAG_DOUBLE);// blockdata contains pos this.Pos = new Vec3( nbtpos.getDouble(0), nbtpos.getDouble(1), nbtpos.getDouble(2) ); }    
  • Topics

×
×
  • Create New...

Important Information

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