Posted July 28, 20178 yr 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; } }
July 28, 20178 yr 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 July 30, 20178 yr by xWoom
July 28, 20178 yr Author 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 July 28, 20178 yr by personnedu13
July 28, 20178 yr Author 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 ?
July 28, 20178 yr Author Ok thank you for your help ! But if I want to test whenever I want, I should load the chunk when I update the list ?
July 28, 20178 yr Author ok nice. i'll try to make it work and publish my code to help future person that need help.
July 28, 20178 yr Author 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 Edited July 28, 20178 yr by personnedu13
July 28, 20178 yr Author 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); } } } } }
July 28, 20178 yr Author 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); } } } }
July 28, 20178 yr Author an instance is individual for all object of the class and a static is common ? I mean that static class are made for an unique object. Edited July 28, 20178 yr by personnedu13
July 28, 20178 yr Author //Cannot instanciate type MinecraftServer... World world = (MinecraftServer::getWorldByDim) can I have an exemple plz ? It will be faster... Edited July 28, 20178 yr 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.