Everything posted by tommyte
-
How to check which chunks are unloaded when the world unloads
Alright, I think I got a problem with NBT now. It doesn't seem to save very well. Gets called after initialization of the Multiblock public void writeToNBT() { NBTTagCompound compound = WorldSavedData.get(worldObj).getNBTForBlock(worldObj.getChunkFromBlockCoords(pos).xPosition, worldObj.getChunkFromBlockCoords(pos).zPosition, pos); compound.setIntArray("pos", new int[]{pos.getX(), pos.getY(), pos.getZ()}); compound.setInteger("facing", facing.getIndex()); compound.setString("id", classToNameMap.get(this.getClass())); WorldSavedData.get(worldObj).say(worldObj.getChunkFromBlockCoords(pos).xPosition, worldObj.getChunkFromBlockCoords(pos).zPosition); WorldSavedData.get(worldObj).markDirty(); } WorldSavedData: package com.tommyte.skymod.main; import java.util.ArrayList; import java.util.Hashtable; import java.util.List; import javax.annotation.Nullable; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.chunk.Chunk; import net.minecraft.world.storage.MapStorage; public class WorldSavedData extends net.minecraft.world.WorldSavedData{ private NBTTagCompound worldData = new NBTTagCompound(); private String tagKey = new String("savedData"); private Hashtable<int[], String> chunks = new Hashtable<int[], String>(); public WorldSavedData() { super(Main.MODID + "_saved_data"); } @Override public void readFromNBT(NBTTagCompound nbt) { worldData = nbt.getCompoundTag(tagKey); } @Override public NBTTagCompound writeToNBT(NBTTagCompound compound) { compound.setTag(tagKey, worldData); return compound; } public NBTTagCompound getNBT() { return worldData; } public NBTTagCompound getNBTForBlock(int x, int z, BlockPos pos) { if(!worldData.hasKey(getStringFromChunk(x, z))) { worldData.setTag(getStringFromChunk(x, z), new NBTTagCompound()); } NBTTagCompound chunkTag = (NBTTagCompound) worldData.getTag(getStringFromChunk(x, z)); if(!chunkTag.hasKey(getStringFromPos(pos))) { chunkTag.setTag(getStringFromPos(pos), new NBTTagCompound()); } NBTTagCompound posTag = (NBTTagCompound) chunkTag.getTag(getStringFromPos(pos)); System.out.println(posTag); return posTag; } public NBTTagCompound[] getMultiblocksInChunk(int CX, int CZ) { List<NBTTagCompound> compound = new ArrayList<NBTTagCompound>(); if(worldData.hasKey(getStringFromChunk(CX, CZ))) { System.out.println("yes 1"); NBTTagCompound chunkTag = worldData.getCompoundTag(getStringFromChunk(CX, CZ)); for(int i = 0; i < chunkTag.getKeySet().size(); i++) { compound.add(chunkTag.getKeySet().toArray(new NBTTagCompound[]{})[i]); } } return compound.toArray(new NBTTagCompound[]{}); } public static String getStringFromPos(BlockPos pos) { return "blockpos: "+pos.getX()+"_"+pos.getY()+"_"+pos.getZ(); } public static BlockPos getPosFromString(String string) { int x = Integer.parseInt(string.substring(13, 14)); int y = Integer.parseInt(string.substring(15, 16)); int z = Integer.parseInt(string.substring(16, 17)); return new BlockPos(x,y,z); } public static String getStringFromChunk(int x, int z) { return "chunkpos: "+x+"_"+z; } public static int[] getChunkFromString(String string) { int x = Integer.parseInt(string.substring(12, 13)); int z = Integer.parseInt(string.substring(14, 15)); return new int[]{x,z}; } public static WorldSavedData get(World worldIn) { MapStorage storage = worldIn.getMapStorage(); WorldSavedData instance = (WorldSavedData) storage.getOrLoadData(WorldSavedData.class, "TSkyBlock"); if (instance == null) { instance = new WorldSavedData(); storage.setData("TSkyBlock", instance); } return instance; } public void say(int x, int z) { for(int i = 0; i < worldData.getKeySet().size(); i ++) { System.out.println(worldData.getKeySet().toArray(new String[]{})[i]); for(int j = 0; j < ((NBTTagCompound) worldData.getTag(worldData.getKeySet().toArray(new String[]{})[i])).getKeySet().size(); j++) { System.out.println(((NBTTagCompound) worldData.getTag(worldData.getKeySet().toArray(new String[]{})[i])).getKeySet().toArray(new String[]{})[j]); } } if(worldData.hasKey(getStringFromChunk(x,z))) { System.out.println("yes 2"); } } } EventClass: package com.tommyte.skymod.main; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Set; import com.google.common.collect.ImmutableMultiset; import com.tommyte.skymod.multiblocks.Multiblock; import net.minecraft.client.Minecraft; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.ChunkPos; import net.minecraft.world.World; import net.minecraftforge.event.world.ChunkDataEvent; import net.minecraftforge.event.world.ChunkEvent; import net.minecraftforge.event.world.WorldEvent; import net.minecraftforge.fml.common.eventhandler.EventPriority; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; public class SkyblockWorldEvent { @SubscribeEvent public void onChunkLoad(ChunkEvent.Load event) { if(!event.getWorld().isRemote) { NBTTagCompound[] compounds = WorldSavedData.get(event.getWorld()).getMultiblocksInChunk(event.getChunk().xPosition, event.getChunk().zPosition); for(int i = 0; i < compounds.length; i ++) { System.out.println(compounds[i]); Multiblock.multiblockCreate(event.getWorld(), compounds[i]); } } } @SubscribeEvent public void onChunkUnload(ChunkEvent.Unload event) { if(!event.getWorld().isRemote) { NBTTagCompound[] compounds = WorldSavedData.get(event.getWorld()).getMultiblocksInChunk(event.getChunk().xPosition, event.getChunk().zPosition); for(int i = 0; i < compounds.length; i ++) { System.out.println(compounds); BlockPos pos = new BlockPos(compounds[i].getIntArray("pos")[0], compounds[i].getIntArray("pos")[1], compounds[i].getIntArray("pos")[2]); Multiblock.multiblocks.get(pos).markMultiblockDestroy(); } } } @SubscribeEvent public void onWorldUnload(WorldEvent.Unload event) { Collection<Multiblock> collection = Multiblock.multiblocks.values(); for(int i = 0; i < collection.size(); i++) { System.out.println(WorldSavedData.get(event.getWorld()).getNBT().getKeySet()); ((Multiblock)collection.toArray()[i]).markMultiblockDestroy(); } } } After the Multiblock is initialized, the say(x,z) method does print everything in there. So a tag has been created and filled. But.. When I reload my world, I basically get no feedback, so my data seems to be empty again.
-
How to check which chunks are unloaded when the world unloads
But 'ChunkEvent.Unload' doesn't seem to fire when I close the world. This is a problem for me. I'll try to use 'WorldEvent.Unload' at the same time. Maybe that will work.
-
How to check which chunks are unloaded when the world unloads
Hello there, I am trying to create a multiblock structure, which will have to disassemble when the world(or the chunk it is in) unloads. I am trying to use events for this, because I'd like my multiblock to be independant of tileentities, which is more of a challnge for me than something functional. Anyways, loading it seems to work fine, but unloading is an issue. Event class: package com.tommyte.skymod.main; import java.util.ArrayList; import java.util.List; import java.util.Set; import com.google.common.collect.ImmutableMultiset; import com.tommyte.skymod.multiblocks.Multiblock; import net.minecraft.client.Minecraft; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.ChunkPos; import net.minecraft.world.World; import net.minecraftforge.event.world.ChunkDataEvent; import net.minecraftforge.event.world.ChunkEvent; import net.minecraftforge.event.world.WorldEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; public class SkyblockWorldEvent { @SubscribeEvent public void onChunkLoad(ChunkEvent.Load event) { onLoad(event.getWorld(), event.getChunk().xPosition, event.getChunk().zPosition); } @SubscribeEvent public void onWorldload(WorldEvent.Load event) { ChunkPos[] key = event.getWorld().getPersistentChunks().keys().toArray(new ChunkPos[]{}); for(int i = 0; i < key.length; i++) { onLoad(event.getWorld(), key[i].chunkXPos, key[i].chunkZPos); } } private void onLoad(World worldIn, int x, int z) { NBTTagCompound[] nbtArray = WorldSavedData.get(worldIn).getMultiblocksInChunk(x, z); System.out.println("load"); for(int i = 0; i < nbtArray.length; i++) { Multiblock.multiblockCreate(worldIn, nbtArray[i]); } } @SubscribeEvent public void onChunkUnload(ChunkEvent.Unload event) { onUnload(event.getWorld(), event.getChunk().xPosition, event.getChunk().zPosition); } @SubscribeEvent public void onWorldUnload(WorldEvent.Unload event) { System.out.println("duut"); ChunkPos[] key = event.getWorld().getPersistentChunks().keys().toArray(new ChunkPos[]{}); for(int i = 0; i < key.length; i++) { onUnload(event.getWorld(), key[i].chunkXPos, key[i].chunkZPos); } } private void onUnload(World worldIn, int x, int z) { System.out.println("unload"); NBTTagCompound nbt = WorldSavedData.get(worldIn).getNBT(); if(nbt.hasKey(WorldSavedData.getStringFromChunk(x, z))) { NBTTagCompound chunkTag = nbt.getCompoundTag(WorldSavedData.getStringFromChunk(x, z)); for(int i = 0; i < chunkTag.getKeySet().size(); i++) { Multiblock block = Multiblock.multiblocks.get(chunkTag.getKeySet().toArray(new BlockPos[]{})[i]); block.markMultiblockDestroy(); } } } } So, how should I detect which chunks are still loaded (and should be unloaded) when the world is unloading. Then I can save my multiblock to the chunk. Also, I have no idea what 'getPersistentChunks()' really is, so it might help if someone would explain that too (: Thanks! ps. the console prints 'duut', but not 'unload', so it probably has to do with getPersistentChunks().keys().toArray(new ChunkPos[]{}); returning an empty array.
IPS spam blocked by CleanTalk.