package StevenDimDoors.mod_pocketDim; /** * This class regulates all the operations involving the storage and manipulation of dimensions. It handles saving dim data, teleporting the player, and * creating/registering new dimensions as well as loading old dimensions on startup * @Return */ import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectOutputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.Random; import java.util.Set; import net.minecraft.block.Block; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityList; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.item.EntityMinecart; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.packet.Packet41EntityEffect; import net.minecraft.network.packet.Packet43Experience; import net.minecraft.network.packet.Packet9Respawn; import net.minecraft.potion.PotionEffect; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.MathHelper; import net.minecraft.world.Teleporter; import net.minecraft.world.World; import net.minecraft.world.WorldServer; import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.storage.ExtendedBlockStorage; import net.minecraftforge.common.DimensionManager; import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.relauncher.Side; public class dimHelper extends DimensionManager { /** * HashMap containing all the dims registered with DimDoors, sorted by dim ID. loaded on startup * @Return */ public static HashMap dimList=new HashMap(); public static boolean isSaving=false; /** * ArrayList containing any blocks in limbo that have been placed by the player. Cycled through in the common tick manager * @Return */ public static ArrayList blocksToDecay= new ArrayList(); /** * instance of the dimHelper * @Return */ public static dimHelper instance = new dimHelper(); /** * HashMap for temporary storage of Link Singnature damage hash values. See itemLinkSignature for more details * @Return */ public HashMap interDimLinkList= new HashMap(); /** * ArrayList containing all link data not sorted for easy random access, used for random doors and for recreating rifts if they have a block placed over them. * See the common tick manager and the Chaos door for details on useage * @Return */ public ArrayList linksForRendering =new ArrayList(); Random rand= new Random(); //Stupid function I use because I dont understand bitwise operations yet. Used in door orientation //TODO get rid of this public int flipDoorMetadata(int data) { if(data==0) { return 2; } if(data==1) { return 3; } if(data==2) { return 0; } if(data==3) { return 1; } if(data==4) { return 6; } if(data==5) { return 7; } if(data==6) { return 4; } if(data==7) { return 5; } else return -10; } public int getDimDepth(int DimID) { if(this.dimList.containsKey(DimID)) { return (int)this.dimList.get(DimID).depth; } else return 1; } public void teleportToLimbo(World world,LinkData linkData, EntityPlayer player) { EntityPlayerMP playerMP = (EntityPlayerMP) player; player.fallDistance=-700; //World worldLimbo= this.getWorld(mod_pocketDim.limboDimID); mod_pocketDim.limbo=this.getWorld(mod_pocketDim.limboDimID); if(mod_pocketDim.limbo==null) { this.initDimension(mod_pocketDim.limboDimID); } else if (mod_pocketDim.limbo.provider==null) { this.initDimension(mod_pocketDim.limboDimID); } //System.out.println(worldLimbo.getHeightValue( MathHelper.floor_double(player.posX), MathHelper.floor_double(player.posZ))); playerMP.mcServer.getConfigurationManager().transferPlayerToDimension(playerMP, mod_pocketDim.limboDimID, new pocketTeleporter((WorldServer) this.getWorld(mod_pocketDim.limboDimID), linkData)); } private void teleportEntity(World oldWorld, Entity entity, LinkData link) { if(this.getWorld(link.destDimID)==null) { this.initDimension(link.destDimID); } World newWorld = this.getWorld(link.destDimID); Entity mount = entity.ridingEntity; Entity rider = entity.riddenByEntity; if (entity.ridingEntity != null) { entity.mountEntity(null); mount.riddenByEntity = null; teleportEntity(oldWorld, mount, link); } if (entity.riddenByEntity != null) { rider.mountEntity(null); entity.riddenByEntity = null; teleportEntity(oldWorld, rider, link); } boolean changingworlds = entity.worldObj != newWorld; entity.worldObj.updateEntityWithOptionalForce(entity, false); if ((entity instanceof EntityPlayerMP)) { EntityPlayerMP player = (EntityPlayerMP)entity; player.closeScreen(); if (changingworlds) { player.dimension = link.destDimID; player.playerNetServerHandler.sendPacketToPlayer(new Packet9Respawn(player.dimension, (byte)player.worldObj.difficultySetting, newWorld.getWorldInfo().getTerrainType(), newWorld.getHeight(), player.theItemInWorldManager.getGameType())); ((WorldServer)entity.worldObj).getPlayerManager().removePlayer(player); } } if(changingworlds) { if ((entity instanceof EntityPlayer)) { EntityPlayer player = (EntityPlayer)entity; player.closeScreen(); oldWorld.playerEntities.remove(player); oldWorld.updateAllPlayersSleepingFlag(); } int i = entity.chunkCoordX; int j = entity.chunkCoordZ; if ((entity.addedToChunk) && (oldWorld.getChunkProvider().chunkExists(i, j))) { oldWorld.getChunkFromChunkCoords(i, j).removeEntity(entity); oldWorld.getChunkFromChunkCoords(i, j).isModified = true; } oldWorld.loadedEntityList.remove(entity); oldWorld.releaseEntitySkin(entity); entity.isDead = false; } ((WorldServer)newWorld).theChunkProviderServer.loadChunk(MathHelper.floor_double(entity.posX) >> 4, MathHelper.floor_double(entity.posZ) >> 4); if (changingworlds) { if (!(entity instanceof EntityPlayer)) { NBTTagCompound entityNBT = new NBTTagCompound(); entity.isDead = false; entity.addEntityID(entityNBT); entity.isDead = true; entity = EntityList.createEntityFromNBT(entityNBT, newWorld); if (entity == null) { return; } } newWorld.spawnEntityInWorld(entity); entity.setWorld(newWorld); } if ((entity instanceof EntityPlayerMP)) { EntityPlayerMP player = (EntityPlayerMP)entity; if (changingworlds) { player.mcServer.getConfigurationManager().func_72375_a(player, (WorldServer)newWorld); } } if (((entity instanceof EntityPlayerMP)) && (changingworlds)) { EntityPlayerMP player = (EntityPlayerMP)entity; player.theItemInWorldManager.setWorld((WorldServer)newWorld); player.mcServer.getConfigurationManager().updateTimeAndWeatherForPlayer(player, (WorldServer)newWorld); player.mcServer.getConfigurationManager().syncPlayerInventory(player); Iterator var14 = player.getActivePotionEffects().iterator(); while (var14.hasNext()) { PotionEffect var13 = (PotionEffect)var14.next(); player.playerNetServerHandler.sendPacketToPlayer(new Packet41EntityEffect(player.entityId, var13)); } player.playerNetServerHandler.sendPacketToPlayer(new Packet43Experience(player.experience, player.experienceTotal, player.experienceLevel)); } new pocketTeleporter((WorldServer) newWorld, link).placeInPortal(entity, 0, 0, 0, 0); if ((entity != null) && (mount != null)) { entity.mountEntity(mount); mount.updateRiderPosition(); if ((entity instanceof EntityPlayerMP)) { FMLCommonHandler.instance().getMinecraftServerInstance().getConfigurationManager().serverUpdateMountedMovingPlayer((EntityPlayerMP)entity); } } if ((entity != null) && (rider != null)) { rider.mountEntity(entity); entity.updateRiderPosition(); if ((rider instanceof EntityPlayerMP)) { FMLCommonHandler.instance().getMinecraftServerInstance().getConfigurationManager().serverUpdateMountedMovingPlayer((EntityPlayerMP)rider); } } } /** * Primary function used to teleport the player using doors. Performes numerous null checks, and also generates the destination door/pocket if it has not done so already. * Also ensures correct orientation relative to the door using the pocketTeleporter. * @param world- world the player is currently in * @param linkData- the link the player is using to teleport, sends the player to its dest information. * @param player- the instance of the player to be teleported * @param orientation- the orientation of the door used to teleport, determines player orientation and door placement on arrival * @Return */ public void teleportToPocket(World world,LinkData linkData, Entity entity) { if(linkData!=null) { int destinationID=linkData.destDimID; int x=linkData.destXCoord; int y=linkData.destYCoord; int z=linkData.destZCoord; if(linkData.destDimID==mod_pocketDim.limboDimID&&entity instanceof EntityPlayerMP) { this.teleportToLimbo(world, linkData, EntityPlayerMP.class.cast(entity)); } int depth= this.getDimDepth(world.provider.dimensionId); if(this.dimList.containsKey(destinationID)) { this.generatePocket(linkData); this.generateDoor(world,linkData); this.teleportEntity(world, entity, linkData); entity.worldObj.playSoundEffect(entity.posX, entity.posY, entity.posZ, "mob.endermen.portal", 1.0F, 1.0F); int playerXCoord=MathHelper.floor_double(entity.posX); int playerYCoord=MathHelper.floor_double(entity.posY); int playerZCoord=MathHelper.floor_double(entity.posZ); if(Block.blocksList.length>=entity.worldObj.getBlockId(playerXCoord,playerYCoord+1,playerZCoord)&&!entity.worldObj.isAirBlock(playerXCoord,playerYCoord+1,playerZCoord)) { if(Block.blocksList[entity.worldObj.getBlockId(playerXCoord,playerYCoord+1,playerZCoord)].isOpaqueCube()) { entity.worldObj.setBlockWithNotify(playerXCoord,playerYCoord+1,playerZCoord,0); } } if(entity.worldObj.getBlockId(x, y, z)==mod_pocketDim.dimDoorID||entity.worldObj.getBlockId(x, y, z)==mod_pocketDim.ExitDoorID) { if(this.getLinkDataFromCoords(x, y, z, entity.worldObj)!=null) { //System.out.println("updated link orientation"); this.getLinkDataFromCoords(x, y, z, entity.worldObj).linkOrientation= entity.worldObj.getBlockMetadata(x, y -1, z); } } } } if(!world.isRemote) { } } /** * Creates a link at the location, pointing to the destination. Does NOT create a pair, so must be called twice. * @param locationDimID * @param destinationDimID * @param locationXCoord * @param locationYCoord * @param locationZCoord * @param destinationXCoord * @param destinationYCoord * @param destinationZCoord * @return */ public LinkData createLink( int locationDimID, int destinationDimID, int locationXCoord, int locationYCoord, int locationZCoord, int destinationXCoord, int destinationYCoord, int destinationZCoord) { if(this.getLinkDataFromCoords(locationXCoord, locationYCoord, locationZCoord, locationDimID)!=null) { return this.createLink(locationDimID, destinationDimID, locationXCoord, locationYCoord, locationZCoord, destinationXCoord, destinationYCoord, destinationZCoord, this.getLinkDataFromCoords(locationXCoord, locationYCoord, locationZCoord, locationDimID).linkOrientation); } return this.createLink(locationDimID, destinationDimID, locationXCoord, locationYCoord, locationZCoord, destinationXCoord, destinationYCoord, destinationZCoord, -10); } /** * Creates a link at the location, pointing to the destination. Does NOT create a pair, so must be called twice. * @param locationDimID * @param destinationDimID * @param locationXCoord * @param locationYCoord * @param locationZCoord * @param destinationXCoord * @param destinationYCoord * @param destinationZCoord * @param linkOrientation * @return */ public LinkData createLink( int locationDimID, int destinationDimID, int locationXCoord, int locationYCoord, int locationZCoord, int destinationXCoord, int destinationYCoord, int destinationZCoord,int linkOrientation) { LinkData linkData =new LinkData( locationDimID, destinationDimID, locationXCoord, locationYCoord, locationZCoord, destinationXCoord, destinationYCoord ,destinationZCoord,false); linkData.linkOrientation=linkOrientation; return this.createLink(linkData); } public LinkData createLink(LinkData link) { if(!this.dimList.containsKey(link.locDimID)) { DimData locationDimData= new DimData(link.locDimID, false, 0, link.locDimID,link.locXCoord,link.locYCoord,link.locZCoord); this.dimList.put(link.locDimID, locationDimData); link.isLocPocket=false; } DimData locationDimData= this.dimList.get(link.locDimID); link.isLocPocket=locationDimData.isPocket; locationDimData.addLinkToDim(link); this.linksForRendering.add(link); if(dimHelper.getWorld(link.locDimID)!=null) { //World world =dimHelper.getWorld(link.locDimID); int blocktoReplace = dimHelper.getWorld(link.locDimID).getBlockId(link.locXCoord, link.locYCoord, link.locZCoord); if(!mod_pocketDim.blocksImmuneToRift.contains(blocktoReplace)) { dimHelper.getWorld(link.locDimID).setBlockWithNotify(link.locXCoord, link.locYCoord, link.locZCoord, mod_pocketDim.blockRiftID); } } //Notifies other players that a link has been created. if(FMLCommonHandler.instance().getEffectiveSide()==Side.SERVER) { // System.out.println("Sending link creation packet with orientation "+link.linkOrientation); PacketHandler.onLinkCreatedPacket(link); } return link; } public int getDestOrientation(LinkData link) { if(link !=null) { LinkData destLink = this.getLinkDataFromCoords(link.destXCoord, link.destYCoord, link.destZCoord, link.destDimID); if(destLink!=null) { return destLink.linkOrientation; } else { //System.out.println("Cant find destination link"); return 0; } } else { // System.out.println("sending link is null"); return 0; } } public void removeLink(LinkData link) { this.removeLink(link.locDimID, link.locXCoord, link.locYCoord, link.locZCoord); } /** * properly deletes a link at the given coordinates. used by the rift remover. Also notifies clients of change. * @param locationDimID * @param locationXCoord * @param locationYCoord * @param locationZCoord */ public void removeLink( int locationDimID, int locationXCoord, int locationYCoord, int locationZCoord) { if(!this.dimList.containsKey(locationDimID)) { DimData locationDimData= new DimData(locationDimID, false, 0, locationDimID,locationXCoord,locationYCoord,locationZCoord); this.dimList.put(locationDimID, locationDimData); } LinkData link = this.getLinkDataFromCoords(locationXCoord, locationYCoord, locationZCoord, locationDimID); this.linksForRendering.remove(link); this.dimList.get(locationDimID).removeLinkAtCoords(link); //updates clients that a rift has been removed if(FMLCommonHandler.instance().getEffectiveSide()==Side.SERVER) { PacketHandler.onLinkRemovedPacket(link); this.save(); } } public LinkData findNearestRift(World world, int x, int y, int z, int range) { return this.dimList.get(world).findNearestRift(world, range, x, y, z); } /** * generates a door based on what door was used to teleport. Only funtions once per linking. * @param world- door * @param linkData */ public void generateDoor(World world, LinkData linkData) { int locX = linkData.locXCoord; int locY = linkData.locYCoord; int locZ = linkData.locZCoord; int destX = linkData.destXCoord; int destY = linkData.destYCoord; int destZ = linkData.destZCoord; if(!linkData.hasGennedDoor) { int destinationID = linkData.destDimID; DimData data = this.dimList.get(destinationID); int id =world.getBlockId(locX, locY, locZ); if(id==mod_pocketDim.ExitDoorID||id==mod_pocketDim.dimDoorID) { int doorTypeToPlace=id; // World destWorld = this.getWorld(destinationID); if(this.getWorld(destinationID)==null) { this.initDimension(destinationID); } int blockToReplace= this.getWorld(destinationID).getBlockId(destX, destY, destZ); if(blockToReplace!=mod_pocketDim.dimDoorID&&blockToReplace!=mod_pocketDim.linkExitDoorID&&blockToReplace!=mod_pocketDim.linkDimDoorID&&blockToReplace!=mod_pocketDim.ExitDoorID&&blockToReplace!=mod_pocketDim.transientDoorID) { this.getWorld(destinationID).setBlockAndMetadata(destX, destY-1, destZ, doorTypeToPlace,dimHelper.instance.flipDoorMetadata(world.getBlockMetadata(locX, locY-1, locZ))); this.getWorld(destinationID).setBlockAndMetadata(destX, destY, destZ, doorTypeToPlace,world.getBlockMetadata(locX, locY, locZ)); // System.out.println("Genned door"); } if(id==mod_pocketDim.transientDoorID&&!dimHelper.dimList.get((destinationID)).hasBeenFilled) { this.getWorld(destinationID).setBlockAndMetadata(destX, destY-1, destZ, id,dimHelper.instance.flipDoorMetadata(world.getBlockMetadata(locX, locY-1, locZ))); this.getWorld(destinationID).setBlockAndMetadata(destX, destY, destZ, id,world.getBlockMetadata(locX, locY, locZ)); } linkData.hasGennedDoor=true; } } } /** * Generates the black pocket out of fabric of reality blocks. Placement of the pocket is based off of the orignial doors orientation. Kind of a clunky method, * but is nessesarry to maintain a one to one relationship with the overworld. Is called every teleport, but checks if the dim has been filled first and is a pocket . * Also responsible for generation the random dungeons. * @param world- id of the world TO BE FILLED * @param x * @param y * @param z * @param orientation * @return */ public void generatePocket(LinkData incomingLink) { if(this.getWorld(incomingLink.destDimID)==null) { this.initDimension(incomingLink.destDimID); } if(this.getWorld(incomingLink.destDimID).provider==null) { this.initDimension(incomingLink.destDimID); } // World world = this.getWorld(incomingLink.destDimID); DimData data = this.dimList.get(incomingLink.destDimID); if(!data.hasBeenFilled&&data.isPocket&&!data.isDimRandomRift) { data.hasBeenFilled=true; //System.out.println("genning pocket"); int x = incomingLink.destXCoord; int y = incomingLink.destYCoord; int z = incomingLink.destZCoord; int orientation= (incomingLink.linkOrientation); int depth= this.getDimDepth(incomingLink.locDimID); //x=x*depth; //y=y*depth; //z=z*depth; y=y+13; if(orientation==0) { x=x+15; } else if(orientation==1) { z=z+15; } else if(orientation==2) { x=x-15; } else if(orientation==3) { z=z-15; } int searchRadius=19; if(!this.getWorld(incomingLink.destDimID).isRemote) { int xCount=-searchRadius; int yCount=-searchRadius; int zCount=-searchRadius; while (xCount<=searchRadius) { while(yCount<=searchRadius) { while(zCount<=searchRadius) { if((Math.abs(xCount)>=15||Math.abs(yCount)>=15||Math.abs(zCount)>=15)&&this.getWorld(incomingLink.destDimID).isAirBlock( x+xCount, y+yCount, z+zCount)) { if(Math.abs(xCount)>=19||Math.abs(yCount)>=19||Math.abs(zCount)>=19) { this.setBlockDirectly(this.getWorld(incomingLink.destDimID), x+xCount, y+yCount, z+zCount,mod_pocketDim.blockDimWallPermID,0); } else { this.setBlockDirectly(this.getWorld(incomingLink.destDimID), x+xCount, y+yCount, z+zCount,mod_pocketDim.blockDimWallID,0); if(mod_pocketDim.TNFREAKINGT) { if((Math.abs(xCount)>=16||Math.abs(yCount)>=16||Math.abs(zCount)>=16)&&rand.nextInt(mod_pocketDim.HOW_MUCH_TNT)==1) { this.getWorld(incomingLink.destDimID).setBlock( x+xCount, y+yCount, z+zCount,Block.tnt.blockID); } } } } zCount++; } zCount=-searchRadius; yCount++; } yCount=-searchRadius; xCount++; } } } else if(!data.hasBeenFilled&&data.isPocket&&data.isDimRandomRift) { //System.out.println("genning dungeon pocket"); DungeonGenerator.generateDungeonlink(incomingLink); data.hasBeenFilled=true; } } /** * simple method called on startup to register all dims saved in the dim list. Only tries to register pocket dims, though. Also calls load() * @return */ public void initPockets() { mod_pocketDim.hasInitDims=true; this.load(); if(!this.dimList.isEmpty()) { Set allDimIds=dimList.keySet(); Iterator itr =allDimIds.iterator(); while(itr.hasNext()) { DimData dimData = (DimData) dimList.get(itr.next()); if(dimData.isPocket) { try { this.getNextFreeDimId(); registerDimension(dimData.dimID,mod_pocketDim.providerID); } catch (Exception e) { if(dimData.isPocket) { System.out.println("Warning- could not register dim "+dimData.depth+" . Probably caused by a version update/save data corruption/other mods. "); } } } } } } /** * method called when the client disconects/server stops to unregister dims. * @Return */ public void unregsisterDims() { if(!this.dimList.isEmpty()) { Set allDimIds=dimList.keySet(); Iterator itr =allDimIds.iterator(); while(itr.hasNext()) { DimData dimData = (DimData) dimList.get(itr.next()); if(dimData.isPocket) { try { this.unregisterDimension(dimData.dimID); } catch(Exception e) { System.out.println("Dim-"+String.valueOf(dimData.dimID)+"is already unregistered, ok? Enough with it already."); } // initDimension(dimData.dimID); } } } } /** * Used to associate a damage value on a Rift Signature with a link pair. See LinkSignature for details. * @return */ public int createUniqueInterDimLinkKey() { int linkKey; Random rand= new Random(); do { linkKey=rand.nextInt(30000); } while(this.interDimLinkList.containsKey(linkKey)); return linkKey; } /** * Method used to create and register a new pocket dimension. Called on door placement and rift generation. It does NOT actually generate the structure of the dim, just * registers it with the dimension manager and adds the necessary links and dim info to the dimlist/linklists. * Also registers existing dims with the dimList, so link data can be stored for them. * * Handles the randomization associated with depth as well, going far enough causes the next dims exit link to be randomized. * * @param world- World currently occupied, the parent of the pocket dim to be created. * @param x * @param y * @param z * @param isGoingDown * @param isRandomRift * @param orientation- determines the orientation of the entrance link to this dim. Should be the metaData of the door occupying the rift. -1 if no door. * @return */ public LinkData createPocket(LinkData link , boolean isGoingDown, boolean isRandomRift) { if(this.getWorld(link.locDimID)==null) { this.initDimension(link.locDimID); } int dimensionID; int depth = this.getDimDepth(link.locDimID); // World world = this.getWorld(link.locDimID); dimensionID = getNextFreeDimId(); registerDimension(dimensionID,mod_pocketDim.providerID); DimData locationDimData; DimData destDimData; if(this.dimList.containsKey(link.locDimID)&&!this.getWorld(link.locDimID).isRemote) //checks to see if dim is already registered. If not, it creates a DimData entry for it later { //randomizes exit if deep enough locationDimData= dimList.get(this.getWorld(link.locDimID).provider.dimensionId); if(depth>5) { if(depth>=12) { depth=11; } if(rand.nextInt(13-depth)==0) { boolean foundRandomDest=false; int i=0; int size = dimHelper.instance.linksForRendering.size(); while (!foundRandomDest&&size>0&&i<100) { i++; LinkData link1 = (LinkData) dimHelper.instance.linksForRendering.get(rand.nextInt(size)); if(link1!=null) { if(!link1.isLocPocket) { foundRandomDest=true; locationDimData.exitDimLink=new LinkData(link1.locDimID, link1.locDimID, link1.locXCoord, link1.locYCoord, link1.locZCoord, link1.locXCoord, link1.locYCoord, link1.locZCoord, false); } } } } } if(locationDimData.isPocket) //determines the qualites of the pocket dim being created, based on parent dim. { if(isGoingDown) { destDimData= new DimData(dimensionID, true, locationDimData.depth+1, locationDimData.exitDimLink); } else { destDimData= new DimData(dimensionID, true, locationDimData.depth-1, locationDimData.exitDimLink); } } else { destDimData= new DimData(dimensionID, true, 1, link.locDimID,link.locXCoord,link.locYCoord,link.locZCoord); } } else { locationDimData= new DimData(link.locDimID, false, 0, link.locDimID,link.locXCoord,link.locYCoord,link.locZCoord); destDimData= new DimData(dimensionID, true, 1, link.locDimID,link.locXCoord,link.locYCoord,link.locZCoord); } destDimData.isDimRandomRift=isRandomRift; this.dimList.put(this.getWorld(link.locDimID).provider.dimensionId, locationDimData); this.dimList.put(dimensionID, destDimData); if(FMLCommonHandler.instance().getEffectiveSide()==Side.SERVER)//sends packet to clients notifying them that a new dim has been created. { PacketHandler.onDimCreatedPacket(destDimData); } LinkData linkData = this.createLink(this.getWorld(link.locDimID).provider.dimensionId,dimensionID,link.locXCoord,link.locYCoord,link.locZCoord, link.destXCoord,link.destYCoord,link.destZCoord,link.linkOrientation); //creates and registers the two rifts that link the parent and pocket dim. this.createLink(dimensionID,this.getWorld(link.locDimID).provider.dimensionId, link.destXCoord,link.destYCoord,link.destZCoord, link.locXCoord,link.locYCoord,link.locZCoord, this.flipDoorMetadata(link.linkOrientation)); return link; } /** * function that saves all dim data in a hashMap. Calling too often can cause Concurrent modification exceptions, so be careful. * @return */ //TODO change from saving serialized objects to just saving data for compatabilies sake. public void save() { if(!this.isSaving) { System.out.println("saving"); this.isSaving=true; HashMap comboSave=new HashMap(); comboSave.put("dimList", this.dimList); comboSave.put("interDimLinkList", this.interDimLinkList); comboSave.put("linksForRendering", this.linksForRendering); comboSave.put("blocksToDecay", this.blocksToDecay); FileOutputStream saveFile = null; try { World world=FMLCommonHandler.instance().getMinecraftServerInstance().worldServers[0]; String saveFileName=world.getSaveHandler().getMapFileFromName("idcounts").getParentFile().getParent()+"/DimensionalDoorsDataTEMP"; saveFile = new FileOutputStream(saveFileName); ObjectOutputStream save = new ObjectOutputStream(saveFile); save.writeObject(comboSave); save.close(); saveFile.close(); if(new File(world.getSaveHandler().getMapFileFromName("idcounts").getParentFile().getParent()+"/DimensionalDoorsDataOLD").exists()) { new File(world.getSaveHandler().getMapFileFromName("idcounts").getParentFile().getParent()+"/DimensionalDoorsDataOLD").delete(); } new File(world.getSaveHandler().getMapFileFromName("idcounts").getParentFile().getParent()+"/DimensionalDoorsData").renameTo(new File(world.getSaveHandler().getMapFileFromName("idcounts").getParentFile().getParent()+"/DimensionalDoorsDataOLD")); new File(saveFileName).renameTo( new File(world.getSaveHandler().getMapFileFromName("idcounts").getParentFile().getParent()+"/DimensionalDoorsData")); // System.out.println(String.valueOf(this.dimensionList)); } catch(Exception e) { e.printStackTrace(); System.out.println("Could not save data-- SEVERE"); } this.isSaving=false; } } /** * loads the dim data from the saved hashMap. Also handles compatabilty with old saves, see OldSaveHandler * @return */ //TODO change to loading vars instead of objects public void load() { boolean firstRun=false; System.out.println("Loading DimDoors data"); FileInputStream saveFile = null; try { World world=FMLCommonHandler.instance().getMinecraftServerInstance().worldServers[0]; File dataStore =new File( world.getSaveHandler().getMapFileFromName("idcounts").getParentFile().getParent()+"/DimensionalDoorsData"); if(!dataStore.exists()) { if(!new File( world.getSaveHandler().getMapFileFromName("idcounts").getParentFile().getParent()+"/DimensionalDoorsDataOLD").exists()) { firstRun=true; } } File oldSave=new File( world.getSaveHandler().getMapFileFromName("idcounts").getParent()+"/PocketDimData"); //checks to see if old save data is present if(oldSave.exists()) { OldSaveHandler.handleOldSaveData(oldSave); } saveFile = new FileInputStream(dataStore); ObjectSaveInputStream save = new ObjectSaveInputStream(saveFile); HashMap comboSave =((HashMap)save.readObject()); try { this.interDimLinkList=(HashMap) comboSave.get("interDimLinkList"); } catch(Exception e) { System.out.println("Could not load Link Signature list. Link Sig items will loose restored locations."); } try { this.dimList=(HashMap) comboSave.get("dimList"); } catch(Exception e) { System.out.println("Could not load pocket dim list. Saves probably lost, but repairable. Move the files from indivual pocket dim files to active ones. See MC thread for details."); } try { this.linksForRendering=(ArrayList) comboSave.get("linksForRendering"); } catch(Exception e) { System.out.println("Could not load link rendering list. Not really a big deal."); } try { this.blocksToDecay=(ArrayList) comboSave.get("blocksToDecay"); } catch(Exception e) { System.out.println("Could not load list of blocks to decay in Limbo. Probably because you updated versions, in which case this is normal. "); } save.close(); saveFile.close(); } catch(Exception e4) { try { if(!firstRun) { System.out.println("Save data damaged, trying backup..."); } World world=FMLCommonHandler.instance().getMinecraftServerInstance().worldServers[0]; File dataStore =new File( world.getSaveHandler().getMapFileFromName("idcounts").getParentFile().getParent()+"/DimensionalDoorsDataOLD"); saveFile = new FileInputStream(dataStore); ObjectSaveInputStream save = new ObjectSaveInputStream(saveFile); HashMap comboSave =((HashMap)save.readObject()); try { this.interDimLinkList=(HashMap) comboSave.get("interDimLinkList"); } catch(Exception e) { System.out.println("Could not load Link Signature list. Link Sig items will loose restored locations."); } try { this.dimList=(HashMap) comboSave.get("dimList"); } catch(Exception e) { System.out.println("Could not load pocket dim list. Saves probably lost, but repairable. Move the files from indivual pocket dim files to active ones. See MC thread for details."); } try { this.linksForRendering=(ArrayList) comboSave.get("linksForRendering"); } catch(Exception e) { System.out.println("Could not load link rendering list. Not really a big deal."); } try { this.blocksToDecay=(ArrayList) comboSave.get("blocksToDecay"); } catch(Exception e) { System.out.println("Could not load list of blocks to decay in Limbo. Probably because you updated versions, in which case this is normal. "); } save.close(); saveFile.close(); } catch(Exception e2) { if(!firstRun) { e2.printStackTrace(); System.out.println("Could not read data-- SEVERE"); } } } } /** * gets a link based on coords and a world object * @param x * @param y * @param z * @param par1World * @return */ public LinkData getLinkDataFromCoords(int x, int y, int z, World par1World) { return this.getLinkDataFromCoords(x, y, z, par1World.provider.dimensionId); } /** * gets a link based on coords and a world ID * @param x * @param y * @param z * @param worldID * @return */ public LinkData getLinkDataFromCoords(int x, int y, int z, int worldID) { if(this.dimList.containsKey(worldID)) { DimData dimData=this.dimList.get(worldID); return dimData.findLinkAtCoords(x, y, z); } return null; } /** * function called by rift tile entities and the rift remover to find and spread between rifts. Does not actually de-register the rift data, see deleteRift for that. * @param world * @param x * @param y * @param z * @param range * @param player * @param item * @return */ public static boolean removeRift(World world, int x, int y, int z, int range, EntityPlayer player, ItemStack item) { LinkData nearest=null; float distance=range+1; int i=-range; int j=-range; int k=-range; while (i>4; int cZ=z >>4; int cY=y >>4; Chunk chunk; int chunkX=(x % 16)< 0 ? ((x) % 16)+16 : ((x) % 16); int chunkY=y; int chunkZ=((z) % 16)< 0 ? ((z) % 16)+16 : ((z) % 16); // this.chunk=new EmptyChunk(world,cX, cZ); try { chunk=world.getChunkFromChunkCoords(cX, cZ); if (chunk.getBlockStorageArray()[cY] == null) { chunk.getBlockStorageArray()[cY] = new ExtendedBlockStorage(cY << 4, !world.provider.hasNoSky); } chunk.getBlockStorageArray()[cY].setExtBlockID(chunkX, (y) & 15, chunkZ, id); chunk.getBlockStorageArray()[cY].setExtBlockMetadata(chunkX, (y) & 15, chunkZ, metadata); } catch(Exception e) { e.printStackTrace(); } } public void addDimData(DimData dimData) { this.dimList.put(dimData.dimID, dimData); } }