diff --git a/StevenDimDoors/mod_pocketDim/helpers/dimHelper.java b/StevenDimDoors/mod_pocketDim/helpers/dimHelper.java index 5e7bf63..7f0f8f9 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;