From 40ae8a06bdf3eb74830cab9c8f0157e467b6cab0 Mon Sep 17 00:00:00 2001 From: GreyMario Date: Sun, 18 Aug 2013 02:38:23 -0700 Subject: [PATCH 1/5] Fixed the NEI breaking bug (and an undiscovered bug involving sleeping and entering pocket dimensions) --- .../mod_pocketDim/helpers/dimHelper.java | 98 +++++++++++++------ 1 file changed, 69 insertions(+), 29 deletions(-) diff --git a/StevenDimDoors/mod_pocketDim/helpers/dimHelper.java b/StevenDimDoors/mod_pocketDim/helpers/dimHelper.java index 5e7bf63c..7f0f8f9b 100644 --- a/StevenDimDoors/mod_pocketDim/helpers/dimHelper.java +++ b/StevenDimDoors/mod_pocketDim/helpers/dimHelper.java @@ -102,28 +102,37 @@ public class dimHelper extends DimensionManager else return 1; } - private Entity teleportEntity(World oldWorld, Entity entity, LinkData link) //this beautiful teleport method is based off of xCompWiz's teleport function. - { - Entity cart=entity.ridingEntity; - if(entity.riddenByEntity!=null) + // GreyMaria: My god, what a mess. Here, let me clean it up a bit. + private Entity teleportEntity(World world, Entity entity, LinkData link) //this beautiful teleport method is based off of xCompWiz's teleport function. + { + // GreyMaria: Added to simplify some code further in. + WorldServer oldWorld = (WorldServer)world; + + // Is something riding? Handle it first. + if(entity.riddenByEntity != null) { return this.teleportEntity(oldWorld,entity.riddenByEntity, link); } - if (entity.ridingEntity != null) + // Are we riding something? Dismount and tell the mount to go first. + Entity cart = entity.ridingEntity; + if (cart != null) { entity.mountEntity(null); cart = teleportEntity(oldWorld, cart, link); + // We keep track of both so we can remount them on the other side. } WorldServer newWorld; + // Destination doesn't exist? We need to make it. if(DimensionManager.getWorld(link.destDimID)==null) { DimensionManager.initDimension(link.destDimID); } - boolean difDest = link.destDimID != link.locDimID; + // Determine if our destination's in another realm. + boolean difDest = link.destDimID != link.locDimID; if(difDest) { newWorld = DimensionManager.getWorld(link.destDimID); @@ -133,40 +142,53 @@ public class dimHelper extends DimensionManager newWorld=(WorldServer)oldWorld; } + // GreyMaria: What is this even accomplishing? We're doing the exact same thing at the end of this all. + // TODO Check to see if this is actually vital. mod_pocketDim.teleporter.placeInPortal(entity, newWorld, link); - if ((entity instanceof EntityPlayerMP)) - { - EntityPlayerMP player = (EntityPlayerMP)entity; - if (difDest) - { - GameRegistry.onPlayerChangedDimension((EntityPlayer)entity); - + // We'll need to know if we're teleporting a player entity. + // If this value is NULL, then we're not teleporting a player entity. + EntityPlayerMP player = null; + if (entity instanceof EntityPlayerMP) player = (EntityPlayerMP)entity; + + if (difDest) // Are we moving our target to a new dimension? + { + if(player != null) // Are we working with a player? + { + // We need to do all this special stuff to move a player between dimensions. + + // Set the new dimension and inform the client that it's moving to a new world. player.dimension = link.destDimID; player.playerNetServerHandler.sendPacketToPlayer(new Packet9Respawn(player.dimension, (byte)player.worldObj.difficultySetting, newWorld.getWorldInfo().getTerrainType(), newWorld.getHeight(), player.theItemInWorldManager.getGameType())); - WorldServer.class.cast(oldWorld).removeEntity(player); + // GreyMaria: Used the safe player entity remover. + // This should fix an apparently unreported bug where + // the last non-sleeping player leaves the Overworld + // for a pocket dimension, causing all sleeping players + // to remain asleep instead of progressing to day. + oldWorld.removePlayerEntityDangerously(player); player.isDead=false; - oldWorld.playerEntities.remove(player); - WorldServer.class.cast(oldWorld).getPlayerManager().removePlayer(player); + // Creates sanity by ensuring that we're only known to exist where we're supposed to be known to exist. + oldWorld.getPlayerManager().removePlayer(player); newWorld.getPlayerManager().addPlayer(player); player.theItemInWorldManager.setWorld((WorldServer)newWorld); + // Synchronize with the server so the client knows what time it is and what it's holding. player.mcServer.getConfigurationManager().updateTimeAndWeatherForPlayer(player, (WorldServer)newWorld); player.mcServer.getConfigurationManager().syncPlayerInventory(player); - for(Object potionEffect : player.getActivePotionEffects()) { PotionEffect effect = (PotionEffect)potionEffect; player.playerNetServerHandler.sendPacketToPlayer(new Packet41EntityEffect(player.entityId, effect)); } - player.playerNetServerHandler.sendPacketToPlayer(new Packet43Experience(player.experience, player.experienceTotal, player.experienceLevel)); - } - } - if(difDest) - { + + // GreyMaria: Can someone tell me why we need this? I'm commenting it out for now. We'll see if it causes problems. + //player.playerNetServerHandler.sendPacketToPlayer(new Packet43Experience(player.experience, player.experienceTotal, player.experienceLevel)); + } + + // Creates sanity by removing the entity from its old location's chunk entity list, if applicable. int entX = entity.chunkCoordX; int entZ = entity.chunkCoordZ; if ((entity.addedToChunk) && (oldWorld.getChunkProvider().chunkExists(entX, entZ))) @@ -174,8 +196,10 @@ public class dimHelper extends DimensionManager oldWorld.getChunkFromChunkCoords(entX, entZ).removeEntity(entity); oldWorld.getChunkFromChunkCoords(entX, entZ).isModified = true; } + // Memory concerns. oldWorld.releaseEntitySkin(entity); - if (!(entity instanceof EntityPlayer)) + + if (player == null) // Are we NOT working with a player? { NBTTagCompound entityNBT = new NBTTagCompound(); entity.isDead = false; @@ -183,26 +207,42 @@ public class dimHelper extends DimensionManager entity.isDead = true; entity = EntityList.createEntityFromNBT(entityNBT, newWorld); - if (entity == null) - { - + if (entity == null) + { // TODO FIXME IMPLEMENT NULL CHECKS THAT ACTUALLY DO SOMETHING. + /* + * shit ourselves in an organized fashion, preferably + * in a neat pile instead of all over our users' games + */ } + } + + // Finally, respawn the entity in its new home. newWorld.spawnEntityInWorld(entity); entity.setWorld(newWorld); } entity.worldObj.updateEntityWithOptionalForce(entity, false); - if ((entity != null) && (cart != null)) + + // Hey, remember me? It's time to remount. + if (cart != null) { - if ((entity instanceof EntityPlayerMP)) + // Was there a player teleported? If there was, it's important that we update shit. + if (player != null) { entity.worldObj.updateEntityWithOptionalForce(entity, true); } entity.mountEntity(cart); } - if(entity instanceof EntityPlayerMP) + + // Did we teleport a player? Load the chunk for them. + if(player != null) { WorldServer.class.cast(newWorld).getChunkProvider().loadChunk(MathHelper.floor_double(entity.posX) >> 4, MathHelper.floor_double(entity.posZ) >> 4); + + // Tell Forge we're moving its players so everyone else knows. + // Let's try doing this down here in case this is what's killing NEI. + GameRegistry.onPlayerChangedDimension((EntityPlayer)entity); + } mod_pocketDim.teleporter.placeInPortal(entity, newWorld, link); return entity; From 2d6194d5999dd7c20f5b8d64ec6273b952e4f0ae Mon Sep 17 00:00:00 2001 From: GreyMario Date: Sun, 18 Aug 2013 02:42:07 -0700 Subject: [PATCH 2/5] Fixed the NEI breaking bug. Whoops. We needed that experience packet. --- StevenDimDoors/mod_pocketDim/helpers/dimHelper.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/StevenDimDoors/mod_pocketDim/helpers/dimHelper.java b/StevenDimDoors/mod_pocketDim/helpers/dimHelper.java index 7f0f8f9b..5b55199f 100644 --- a/StevenDimDoors/mod_pocketDim/helpers/dimHelper.java +++ b/StevenDimDoors/mod_pocketDim/helpers/dimHelper.java @@ -184,8 +184,7 @@ public class dimHelper extends DimensionManager player.playerNetServerHandler.sendPacketToPlayer(new Packet41EntityEffect(player.entityId, effect)); } - // GreyMaria: Can someone tell me why we need this? I'm commenting it out for now. We'll see if it causes problems. - //player.playerNetServerHandler.sendPacketToPlayer(new Packet43Experience(player.experience, player.experienceTotal, player.experienceLevel)); + player.playerNetServerHandler.sendPacketToPlayer(new Packet43Experience(player.experience, player.experienceTotal, player.experienceLevel)); } // Creates sanity by removing the entity from its old location's chunk entity list, if applicable. From 40310688edd538a9457566e834e9eb607ab64dc2 Mon Sep 17 00:00:00 2001 From: GreyMario Date: Sun, 18 Aug 2013 14:11:51 -0700 Subject: [PATCH 3/5] yCoordhelper: added top-down search (may be redundant) This is used for the code that determines where to come out of Limbo in. It tries to search from the top down to find a solid block to stand on. Isn't complete, though. This code does need some considerations put in, though... I'm concerned about Natura's clouds, for instance. --- .../mod_pocketDim/helpers/yCoordHelper.java | 27 +++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/StevenDimDoors/mod_pocketDim/helpers/yCoordHelper.java b/StevenDimDoors/mod_pocketDim/helpers/yCoordHelper.java index be3e878c..dd148382 100644 --- a/StevenDimDoors/mod_pocketDim/helpers/yCoordHelper.java +++ b/StevenDimDoors/mod_pocketDim/helpers/yCoordHelper.java @@ -21,6 +21,9 @@ public class yCoordHelper } public static int getFirstUncovered(int worldID, int x, int yStart, int z) + { return getFirstUncovered(worldID, x, yStart, z, false); } + + public static int getFirstUncovered(int worldID, int x, int yStart, int z, boolean fromTop) { if (dimHelper.getWorld(worldID) == null || dimHelper.getWorld(worldID).provider == null) @@ -28,10 +31,13 @@ public class yCoordHelper dimHelper.initDimension(worldID); } - return yCoordHelper.getFirstUncovered(dimHelper.getWorld(worldID), x, yStart, z); + return yCoordHelper.getFirstUncovered(dimHelper.getWorld(worldID), x, yStart, z, fromTop); } public static int getFirstUncovered(World world, int x, int yStart, int z) + { return getFirstUncovered(world, x, yStart, z, false); } + + public static int getFirstUncovered(World world, int x, int yStart, int z, boolean fromTop) { Chunk chunk = world.getChunkProvider().loadChunk(x >> 4, z >> 4); @@ -40,10 +46,21 @@ public class yCoordHelper int height = MAXIMUM_UNCOVERED_Y; //world.getHeight(); int y; - boolean covered = true; - for (y = yStart; y < height && covered; y++) + if(!fromTop) { - covered = IsCoveredBlock(chunk, localX, y - 1, localZ) || IsCoveredBlock(chunk, localX, y, localZ); + boolean covered = true; + for (y = yStart; y < height && covered; y++) + { + covered = IsCoveredBlock(chunk, localX, y - 1, localZ) || IsCoveredBlock(chunk, localX, y, localZ); + } + } else { + boolean covered = false; + for (y = MAXIMUM_UNCOVERED_Y; y > 1 && !covered; y--) + { + covered = IsCoveredBlock(chunk, localX, y - 1, localZ); + } + if (!covered) y = 63; + y++; } return y; @@ -69,4 +86,4 @@ public class yCoordHelper material = block.blockMaterial; return (material.isLiquid() || !material.isReplaceable()); } -} \ No newline at end of file +} From 740ba51a04859e8fa4adc4059cb06d0821f9f772 Mon Sep 17 00:00:00 2001 From: GreyMario Date: Sun, 18 Aug 2013 14:13:23 -0700 Subject: [PATCH 4/5] BlockDimWallPerm: Sped up transition from Limbo to Overworld Hijacking teleportEntity seems to make this faster. --- .../mod_pocketDim/blocks/BlockDimWallPerm.java | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/StevenDimDoors/mod_pocketDim/blocks/BlockDimWallPerm.java b/StevenDimDoors/mod_pocketDim/blocks/BlockDimWallPerm.java index 46b43cef..95289a98 100644 --- a/StevenDimDoors/mod_pocketDim/blocks/BlockDimWallPerm.java +++ b/StevenDimDoors/mod_pocketDim/blocks/BlockDimWallPerm.java @@ -56,6 +56,8 @@ public class BlockDimWallPerm extends Block { link =new LinkData(0,0,0,0); } + link.destDimID = 0; + link.locDimID = par1World.provider.dimensionId; if(dimHelper.getWorld(0)==null) @@ -74,22 +76,27 @@ public class BlockDimWallPerm extends Block x = x + (x >> 4); z = z + (z >> 4); - int y = yCoordHelper.getFirstUncovered(0, x, 63, z); + int y = yCoordHelper.getFirstUncovered(0, x, 63, z, true); EntityPlayer.class.cast(par5Entity).setPositionAndUpdate( x, y, z ); //this complicated chunk teleports the player back to the overworld at some random location. Looks funky becaue it has to load the chunk - - FMLCommonHandler.instance().getMinecraftServerInstance().getConfigurationManager().transferPlayerToDimension((EntityPlayerMP) par5Entity, 0,new BlankTeleporter((WorldServer)par5Entity.worldObj)); + link.destXCoord = x; + link.destYCoord = y; + link.destZCoord = z; + dimHelper.instance.teleportEntity(par1World, par5Entity, link); + //FMLCommonHandler.instance().getMinecraftServerInstance().getConfigurationManager().transferPlayerToDimension((EntityPlayerMP) par5Entity, 0,new BlankTeleporter((WorldServer)par5Entity.worldObj)); //dimHelper.instance.teleportToPocket(par1World, new LinkData(par1World.provider.dimensionId,0,x,y,z,link.locXCoord,link.locYCoord,link.locZCoord,link.isLocPocket,0), // EntityPlayer.class.cast(par5Entity)); EntityPlayer.class.cast(par5Entity).setPositionAndUpdate( x, y, z ); - //makes sure they can breath when they teleport + // Make absolutely sure the player doesn't spawn inside blocks, though to be honest this shouldn't ever have to be a problem... dimHelper.getWorld(0).setBlock(x, y, z, 0); + dimHelper.getWorld(0).setBlock(x, y+1, z, 0); + int i=x; - int j=y-1; + int j=y; int k=z; From 0deb4b89174bebd6384c81e2cdc33cf700cfe672 Mon Sep 17 00:00:00 2001 From: GreyMario Date: Sun, 18 Aug 2013 14:14:36 -0700 Subject: [PATCH 5/5] dimHelper: changed teleportEntity to public This enables use in BlockDimWallPerm for escaping Limbo quickly. --- .../mod_pocketDim/helpers/dimHelper.java | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/StevenDimDoors/mod_pocketDim/helpers/dimHelper.java b/StevenDimDoors/mod_pocketDim/helpers/dimHelper.java index 5b55199f..10a61513 100644 --- a/StevenDimDoors/mod_pocketDim/helpers/dimHelper.java +++ b/StevenDimDoors/mod_pocketDim/helpers/dimHelper.java @@ -103,17 +103,28 @@ public class dimHelper extends DimensionManager } // GreyMaria: My god, what a mess. Here, let me clean it up a bit. - private Entity teleportEntity(World world, Entity entity, LinkData link) //this beautiful teleport method is based off of xCompWiz's teleport function. - { - // GreyMaria: Added to simplify some code further in. + public Entity teleportEntity(World world, Entity entity, LinkData link) //this beautiful teleport method is based off of xCompWiz's teleport function. + { WorldServer oldWorld = (WorldServer)world; + WorldServer newWorld; + EntityPlayerMP player = (entity instanceof EntityPlayerMP) ? (EntityPlayerMP)entity : null; - // Is something riding? Handle it first. + /*// SPECIAL CASE: Is our link null? If so, we've likely come from Limbo. Ensure this is the case. + if(link == null) + { + if(world.provider.dimensionId == DDProperties.instance().LimboDimensionID) + { + link = new LinkData(0, 0, 0, 0); + // Find destination point. + } + }*/ + + + // Is something riding? Handle it first. if(entity.riddenByEntity != null) { return this.teleportEntity(oldWorld,entity.riddenByEntity, link); } - // Are we riding something? Dismount and tell the mount to go first. Entity cart = entity.ridingEntity; if (cart != null) @@ -123,8 +134,6 @@ public class dimHelper extends DimensionManager // We keep track of both so we can remount them on the other side. } - WorldServer newWorld; - // Destination doesn't exist? We need to make it. if(DimensionManager.getWorld(link.destDimID)==null) { @@ -146,12 +155,7 @@ public class dimHelper extends DimensionManager // TODO Check to see if this is actually vital. mod_pocketDim.teleporter.placeInPortal(entity, newWorld, link); - // We'll need to know if we're teleporting a player entity. - // If this value is NULL, then we're not teleporting a player entity. - EntityPlayerMP player = null; - if (entity instanceof EntityPlayerMP) player = (EntityPlayerMP)entity; - - if (difDest) // Are we moving our target to a new dimension? + if (difDest) // Are we moving our target to a new dimension? { if(player != null) // Are we working with a player? {