Jump to content

Recommended Posts

Posted

Hi,

I'm trying to save data using the WorldSavedData system and it work as long as I dont quit the game (not the world).

Here is my code :

Spoiler

package com.personnedu13.test.world;

import java.util.ArrayList;
import java.util.List;

import com.personnedu13.test.Main;
import com.personnedu13.test.blocks.BlockSave;
import com.personnedu13.test.tileentity.TileEntityTeleporter;

import net.minecraft.client.Minecraft;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.WorldProvider;
import net.minecraft.world.WorldProviderEnd;
import net.minecraft.world.WorldSavedData;
import net.minecraft.world.storage.MapStorage;

public class ModWorldSavedData extends WorldSavedData{
	
	private static final String TELEPORTER = Main.MODID + "_Teleporter";
	
	public static List<BlockSave> teleporterList = new ArrayList<BlockSave>();


	public ModWorldSavedData() {
		super(TELEPORTER);
	}
	public ModWorldSavedData(String name) {
		super(name);
	}
	
	@Override
	public void readFromNBT(NBTTagCompound nbt) {
		teleporterList.clear();
		int j = nbt.getInteger("size");
		if(j > 0) {
			for(int i = 0 ; i < j; i++) {
				int[] k = nbt.getIntArray("block_" + i);
				int dim = k[0];
				int posX = k[1];
				int posY = k[2];
				int posZ = k[3];
				BlockSave block = new BlockSave(dim, posX, posY, posZ);
				addTeleporterToList(block);
			}
		}
	}

	@Override
	public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
		int j = teleporterList.size();
		nbt.setInteger("size", j);
		if(j > 0) {
			for(int i = 0 ; i < j; i++) {
				BlockSave l = teleporterList.get(i);
				int[] k = new int[4];
				k[0] = l.getDim();
				k[1] = l.getPos().getX();
				k[2] = l.getPos().getY();
				k[3] = l.getPos().getZ();
				nbt.setIntArray("block_" + i,k);
			}
		}
		return nbt;
	}
	
	public static void addTeleporterToList(BlockSave block) {
		if(teleporterList.size() > 0) {
			for (int i = 0; i < teleporterList.size(); i++) {
				if (block.getDim() == (teleporterList.get(i).getDim()) && block.getPos().equals(teleporterList.get(i).getPos())) {
					teleporterList.remove(i);
				}
			}
		}
		teleporterList.add(block);
		System.out.println(teleporterList);
	}
	
	public static ModWorldSavedData get(World world) {
		  MapStorage storage = world.getMapStorage();
		  ModWorldSavedData instance = (ModWorldSavedData) storage.getOrLoadData(ModWorldSavedData.class, TELEPORTER);

		  if (instance == null) {
		    instance = new ModWorldSavedData();
		    storage.setData(TELEPORTER, instance);
		  }
		  return instance;
		}
}

 

 

 

Posted (edited)

use the events WorldEvent.Load to load and WorldEvent.Save to save.             

 

this is an example:

 

	@SubscribeEvent
	public void onWorldLoad(WorldEvent.Load event) {
		ModWorldSavedData.get(event.getWorld());
	}

	@SubscribeEvent
	public void onWorldSave(WorldEvent.Save event) {
		ModWorldSavedData.get(event.getWorld()).markDirty();
	}

 

Edited by xWoom
Posted (edited)

Thx for your replies, i'll try to apply your advice and see if it work.

The List is static to enable the addBlock method to be call from another class but its a bad idea, I think I should use a packet to send the infos to the ModWorldSavedData class.

Edited by personnedu13
Posted

Ok now it work, when I place the block, the onBlockAdded method add the dim and the pos of the block to the addblocktolist method(server side only) and marked with markdirty for a further save.

I want to implant 2 other method, one of them is UpdateList that test if all block in the list exist(by testing if the block in the dimension is a teleporter), but how can I get the current world to test with the dimension ?

Posted (edited)
36 minutes ago, diesieben07 said:

You can use MinecraftServer::getWorld which will automatically load the world if it's not loaded.

Dont find it....

Spoiler

AAEAAQAAAAAAAAZQAAAAJGZiZWNkMzYxLTI5ZjMt

  

 

Edited by personnedu13
Posted
Spoiler

 


ublic void updateTeleporterList() {
		if( teleporterList.size() > 0 ) {
			for (int i = 0; i < teleporterList.size(); i++) {
				BlockSave block = teleporterList.get(i);
				World world = MinecraftServer.getWorld(block.getDim());
				if (!world.isRemote) {
					if (world.getTileEntity(block.getPos()) == null) {
						teleporterList.remove(i);
					}
					else if (!world.getTileEntity(block.getPos()).getClass().equals(TileEntityTeleporter.class)) {
						teleporterList.remove(i);
					}
				}
			}
		}
	}

 

Posted

I rarely used this syntax (MinecraftServer::getWorld) so I really dont know how to do ^^

Spoiler

public void updateTeleporterList() {
		if( teleporterList.size() > 0 ) {
			for (BlockSave block : teleporterList) {
				World world = new MinecraftServer()::worldServerForDimension(0);
						DimensionManager.getWorld(block.getDim());
				if (!(world.getTileEntity(block.getPos()) instanceof TileEntityTeleporter)) {
					teleporterList.remove(block);
				}
			}
		}
	}

 

 

Posted (edited)

//Cannot instanciate type MinecraftServer...

World world = (MinecraftServer::getWorldByDim)

can I have an exemple plz ? It will be faster...

Edited by personnedu13

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.