Jump to content

[1.10.2] WorldSavedData dont save after closing game


personnedu13

Recommended Posts

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;
		}
}

 

 

 

Link to comment
Share on other sites

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
Link to comment
Share on other sites

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
Link to comment
Share on other sites

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 ?

Link to comment
Share on other sites

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);
					}
				}
			}
		}
	}

 

Link to comment
Share on other sites

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);
				}
			}
		}
	}

 

 

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.