diff --git a/build.gradle b/build.gradle index 2cbcf59f..15559345 100644 --- a/build.gradle +++ b/build.gradle @@ -13,14 +13,15 @@ buildscript { apply plugin: 'forge' - - -version = "2.2.3-" + System.getenv("BUILD_NUMBER") -group= "com.stevenrs11.dimdoors" // http://maven.apache.org/guides/mini/guide-naming-conventions.html +version = "2.2.4-" + System.getenv("BUILD_NUMBER") +group = "com.stevenrs11.dimdoors" // http://maven.apache.org/guides/mini/guide-naming-conventions.html archivesBaseName = "DimensionalDoors" minecraft { - version = "1.6.4-9.11.1.964" + version = "1.6.4-9.11.1.964" + + replaceIn "mod_pocketDim.java" + replace "@VERSION@", project.version } targetCompatibility = '1.6' @@ -28,15 +29,15 @@ sourceCompatibility = '1.6' processResources { - // replace stuff in mcmod.info, nothing else + // Replace stuff $version and $mcversion in mcmod.info from(sourceSets.main.resources.srcDirs) { include 'mcmod.info' - - // replace version and mcversion + + // Replace version and mcversion expand 'version':project.version, 'mcversion':project.minecraft.version } - // copy everything else, thats not the mcmod.info + // Copy everything else from(sourceSets.main.resources.srcDirs) { exclude 'mcmod.info' } diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/ConnectionHandler.java b/src/main/java/StevenDimDoors/mod_pocketDim/ConnectionHandler.java index 9a8a17a2..156ecce0 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/ConnectionHandler.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/ConnectionHandler.java @@ -1,17 +1,11 @@ package StevenDimDoors.mod_pocketDim; -import java.io.ByteArrayOutputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.network.INetworkManager; import net.minecraft.network.NetLoginHandler; import net.minecraft.network.packet.NetHandler; import net.minecraft.network.packet.Packet1Login; import net.minecraft.network.packet.Packet250CustomPayload; import net.minecraft.server.MinecraftServer; -import net.minecraft.server.integrated.IntegratedServer; import net.minecraftforge.common.DimensionManager; import net.minecraftforge.common.network.ForgePacket; import net.minecraftforge.common.network.packet.DimensionRegisterPacket; @@ -65,7 +59,8 @@ public class ConnectionHandler implements IConnectionHandler @Override public void playerLoggedIn(Player player, NetHandler netHandler, INetworkManager manager) { - PocketManager.getDimwatcher().onCreated(new ClientDimData(PocketManager.getDimensionData(0))); + // Hax... please don't do this! >_< + PocketManager.getDimwatcher().onCreated(new ClientDimData(PocketManager.createDimensionDataDangerously(0))); } } \ No newline at end of file diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/EventHookContainer.java b/src/main/java/StevenDimDoors/mod_pocketDim/EventHookContainer.java index d03adb81..a9862ddb 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/EventHookContainer.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/EventHookContainer.java @@ -4,10 +4,11 @@ import net.minecraft.client.audio.SoundManager; import net.minecraft.client.audio.SoundPoolEntry; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemDoor; import net.minecraft.item.ItemStack; import net.minecraft.util.DamageSource; import net.minecraft.world.World; +import net.minecraft.world.WorldProvider; +import net.minecraft.world.chunk.Chunk; import net.minecraftforge.client.event.sound.PlayBackgroundMusicEvent; import net.minecraftforge.client.event.sound.SoundLoadEvent; import net.minecraftforge.event.EventPriority; @@ -17,15 +18,18 @@ import net.minecraftforge.event.entity.living.LivingFallEvent; import net.minecraftforge.event.entity.player.PlayerInteractEvent; import net.minecraftforge.event.entity.player.PlayerInteractEvent.Action; import net.minecraftforge.event.terraingen.InitMapGenEvent; +import net.minecraftforge.event.world.ChunkEvent; import net.minecraftforge.event.world.WorldEvent; -import StevenDimDoors.mod_pocketDim.blocks.TransTrapdoor; import StevenDimDoors.mod_pocketDim.config.DDProperties; +import StevenDimDoors.mod_pocketDim.config.DDWorldProperties; import StevenDimDoors.mod_pocketDim.core.DDTeleporter; +import StevenDimDoors.mod_pocketDim.core.DimLink; import StevenDimDoors.mod_pocketDim.core.DimensionType; import StevenDimDoors.mod_pocketDim.core.NewDimData; import StevenDimDoors.mod_pocketDim.core.PocketManager; import StevenDimDoors.mod_pocketDim.items.BaseItemDoor; import StevenDimDoors.mod_pocketDim.items.ItemWarpDoor; +import StevenDimDoors.mod_pocketDim.ticking.RiftRegenerator; import StevenDimDoors.mod_pocketDim.util.Point4D; import StevenDimDoors.mod_pocketDim.world.LimboProvider; import StevenDimDoors.mod_pocketDim.world.PocketProvider; @@ -35,12 +39,25 @@ import cpw.mods.fml.relauncher.SideOnly; public class EventHookContainer { + private static final int MAX_FOOD_LEVEL = 20; + private final DDProperties properties; + private DDWorldProperties worldProperties; + private RiftRegenerator regenerator; public EventHookContainer(DDProperties properties) { this.properties = properties; } + + public void setSessionFields(DDWorldProperties worldProperties, RiftRegenerator regenerator) + { + // SenseiKiwi: + // Why have a setter rather than accessing mod_pocketDim directly? + // I want to make this dependency explicit in our code. + this.worldProperties = worldProperties; + this.regenerator = regenerator; + } @ForgeSubscribe(priority = EventPriority.LOW) public void onInitMapGen(InitMapGenEvent event) @@ -101,7 +118,7 @@ public class EventHookContainer { NewDimData data = PocketManager.getDimensionData(world); - if(data.getDimensionType() == DimensionType.PERSONAL) + if(data.type() == DimensionType.PERSONAL) { mod_pocketDim.sendChat(event.entityPlayer,("Something prevents the Warp Door from tunneling out here")); event.setCanceled(true); @@ -153,7 +170,7 @@ public class EventHookContainer Entity entity = event.entity; if (properties.LimboEnabled && properties.LimboReturnsInventoryEnabled && - entity instanceof EntityPlayer) + entity instanceof EntityPlayer && isValidSourceForLimbo(entity.worldObj.provider)) { if(entity.worldObj.provider instanceof PocketProvider) { @@ -186,7 +203,7 @@ public class EventHookContainer Entity entity = event.entity; - if (entity instanceof EntityPlayer && entity.worldObj.provider instanceof PocketProvider) + if (entity instanceof EntityPlayer && isValidSourceForLimbo(entity.worldObj.provider)) { EntityPlayer player = (EntityPlayer) entity; mod_pocketDim.deathTracker.addUsername(player.username); @@ -201,12 +218,24 @@ public class EventHookContainer } return true; } + + private boolean isValidSourceForLimbo(WorldProvider provider) + { + // Returns whether a given world is a valid place for sending a player + // to Limbo. We can send someone to Limbo from a certain dimension if + // Universal Limbo is enabled and the source dimension is not Limbo, or + // if the source dimension is a pocket dimension. + + return (worldProperties.UniversalLimboEnabled && provider.dimensionId != properties.LimboDimensionID) || + (provider instanceof PocketProvider); + } private void revivePlayerInLimbo(EntityPlayer player) { player.extinguish(); player.clearActivePotions(); player.setHealth(player.getMaxHealth()); + player.getFoodStats().addStats(MAX_FOOD_LEVEL, 0); Point4D destination = LimboProvider.getLimboSkySpawn(player, properties); DDTeleporter.teleportEntity(player, destination, false); } @@ -224,6 +253,25 @@ public class EventHookContainer } } } + + @ForgeSubscribe + public void onChunkLoad(ChunkEvent.Load event) + { + // Schedule rift regeneration for any links located in this chunk. + // This event runs on both the client and server. Allow server only. + // Also, check that PocketManager is loaded, because onChunkLoad() can + // fire while chunks are being initialized in a new world, before + // onWorldLoad() fires. + Chunk chunk = event.getChunk(); + if (!chunk.worldObj.isRemote && PocketManager.isLoaded()) + { + NewDimData dimension = PocketManager.createDimensionData(chunk.worldObj); + for (DimLink link : dimension.getChunkLinks(chunk.xPosition, chunk.zPosition)) + { + regenerator.scheduleSlowRegeneration(link); + } + } + } public void playMusicForDim(World world) { diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/IChunkLoader.java b/src/main/java/StevenDimDoors/mod_pocketDim/IChunkLoader.java index bbe989ee..06f00592 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/IChunkLoader.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/IChunkLoader.java @@ -4,5 +4,6 @@ import net.minecraftforge.common.ForgeChunkManager.Ticket; public interface IChunkLoader { - public void forceChunkLoading(Ticket ticket,int x, int z); + public boolean isInitialized(); + public void initialize(Ticket ticket); } diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/blocks/BaseDimDoor.java b/src/main/java/StevenDimDoors/mod_pocketDim/blocks/BaseDimDoor.java index 9fc2901b..b6d24e58 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/blocks/BaseDimDoor.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/blocks/BaseDimDoor.java @@ -32,9 +32,9 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn protected final DDProperties properties; @SideOnly(Side.CLIENT) - private Icon[] upperTextures; + protected Icon[] upperTextures; @SideOnly(Side.CLIENT) - private Icon[] lowerTextures; + protected Icon[] lowerTextures; public BaseDimDoor(int blockID, Material material, DDProperties properties) { @@ -172,16 +172,13 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn reversed = !reversed; } } - if (isUpperDoorBlock(fullMetadata)) + { return this.upperTextures[reversed ? 1 : 0]; - else - return this.lowerTextures[reversed ? 1 : 0]; - } - else - { - return this.lowerTextures[0]; + } + return this.lowerTextures[reversed ? 1 : 0]; } + return this.lowerTextures[0]; } //Called to update the render information on the tile entity. Could probably implement a data watcher, @@ -189,6 +186,14 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn public BaseDimDoor updateAttachedTile(World world, int x, int y, int z) { mod_pocketDim.proxy.updateDoorTE(this, world, x, y, z); + TileEntity tile = world.getBlockTileEntity(x, y, z); + if (tile instanceof TileEntityDimDoor) + { + int metadata = world.getBlockMetadata(x, y, z); + TileEntityDimDoor dimTile = (TileEntityDimDoor) tile; + dimTile.openOrClosed = isDoorOnRift(world, x, y, z) && isUpperDoorBlock(metadata); + dimTile.orientation = this.getFullMetadata(world, x, y, z) & 7; + } return this; } @@ -196,6 +201,7 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn { return this.getLink(world, x, y, z) != null; } + public DimLink getLink(World world, int x, int y, int z) { DimLink link= PocketManager.getLink(x, y, z, world.provider.dimensionId); @@ -336,7 +342,7 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn { if (world.getBlockId(x, y - 1, z) != this.blockID) { - world.setBlock(x, y, z, 0); + world.setBlockToAir(x, y, z); } if (neighborID > 0 && neighborID != this.blockID) { @@ -347,7 +353,7 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn { if (world.getBlockId(x, y + 1, z) != this.blockID) { - world.setBlock(x, y, z, 0); + world.setBlockToAir(x, y, z); if (!world.isRemote) { this.dropBlockAsItem(world, x, y, z, metadata, 0); @@ -369,31 +375,20 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn */ @Override @SideOnly(Side.CLIENT) - public int idPicked(World par1World, int par2, int par3, int par4) + public int idPicked(World world, int x, int y, int z) { - return this.getDrops(); + return this.getDoorItem(); } /** * Returns the ID of the items to drop on destruction. */ - public int idDropped(int metadata, Random random, int fortune) + @Override + public int idDropped(int metadata, Random random, int fortune) { return isUpperDoorBlock(metadata) ? 0 : this.getDrops(); } - /** - * Called when the block is attempted to be harvested - */ - @Override - public void onBlockHarvested(World par1World, int par2, int par3, int par4, int par5, EntityPlayer par6EntityPlayer) - { - if (par6EntityPlayer.capabilities.isCreativeMode && (par5 & 8) != 0 && par1World.getBlockId(par2, par3 - 1, par4) == this.blockID) - { - par1World.setBlock(par2, par3 - 1, par4, 0); - } - } - @Override public TileEntity createNewTileEntity(World world) { @@ -534,4 +529,18 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn world.setBlockTileEntity(x, y, z, te); return te; } + + @Override + public void breakBlock(World world, int x, int y, int z, int oldBlockID, int oldMeta) + { + // This function runs on the server side after a block is replaced + // We MUST call super.breakBlock() since it involves removing tile entities + super.breakBlock(world, x, y, z, oldBlockID, oldMeta); + + // Schedule rift regeneration for this block if it was replaced + if (world.getBlockId(x, y, z) != oldBlockID) + { + mod_pocketDim.riftRegenerator.scheduleFastRegeneration(x, y, z, world); + } + } } \ No newline at end of file diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/blocks/BlockDimWall.java b/src/main/java/StevenDimDoors/mod_pocketDim/blocks/BlockDimWall.java index d51c9b1a..f17ef8ed 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/blocks/BlockDimWall.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/blocks/BlockDimWall.java @@ -106,6 +106,7 @@ public class BlockDimWall extends Block subItems.add(new ItemStack(this, 1, ix)); } } + @Override public void onBlockDestroyedByPlayer(World par1World, int par2, int par3, int par4, int par5) {} diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/blocks/BlockDoorGold.java b/src/main/java/StevenDimDoors/mod_pocketDim/blocks/BlockDoorGold.java index 9a1845e1..f535db3b 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/blocks/BlockDoorGold.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/blocks/BlockDoorGold.java @@ -2,17 +2,16 @@ package StevenDimDoors.mod_pocketDim.blocks; import java.util.Random; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -import StevenDimDoors.mod_pocketDim.mod_pocketDim; -import StevenDimDoors.mod_pocketDim.config.DDProperties; import net.minecraft.block.BlockDoor; import net.minecraft.block.material.Material; import net.minecraft.client.renderer.IconFlipped; import net.minecraft.client.renderer.texture.IconRegister; -import net.minecraft.item.Item; import net.minecraft.util.Icon; import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; +import StevenDimDoors.mod_pocketDim.mod_pocketDim; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; public class BlockDoorGold extends BlockDoor { diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/blocks/BlockGoldDimDoor.java b/src/main/java/StevenDimDoors/mod_pocketDim/blocks/BlockGoldDimDoor.java index 0812354c..22055a98 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/blocks/BlockGoldDimDoor.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/blocks/BlockGoldDimDoor.java @@ -25,7 +25,7 @@ public class BlockGoldDimDoor extends BaseDimDoor { if (!world.isRemote && world.getBlockId(x, y - 1, z) == this.blockID) { - NewDimData dimension = PocketManager.getDimensionData(world); + NewDimData dimension = PocketManager.createDimensionData(world); DimLink link = dimension.getLink(x, y, z); if (link == null) { @@ -34,6 +34,12 @@ public class BlockGoldDimDoor extends BaseDimDoor } } + @Override + public int getDoorItem() + { + return mod_pocketDim.itemGoldenDimensionalDoor.itemID; + } + @Override public int getDrops() { diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/blocks/BlockLimbo.java b/src/main/java/StevenDimDoors/mod_pocketDim/blocks/BlockLimbo.java index 8da0dfec..07f1247b 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/blocks/BlockLimbo.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/blocks/BlockLimbo.java @@ -9,7 +9,7 @@ import net.minecraft.util.Icon; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; import StevenDimDoors.mod_pocketDim.mod_pocketDim; -import StevenDimDoors.mod_pocketDim.ticking.LimboDecay; +import StevenDimDoors.mod_pocketDim.world.LimboDecay; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/blocks/BlockRift.java b/src/main/java/StevenDimDoors/mod_pocketDim/blocks/BlockRift.java index 7749a65c..987e0c50 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/blocks/BlockRift.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/blocks/BlockRift.java @@ -47,14 +47,28 @@ public class BlockRift extends Block implements ITileEntityProvider public static final int MAX_WORLD_THREAD_DROP_CHANCE = 1000; private final DDProperties properties; - private final ArrayList blocksImmuneToRift; + private final ArrayList blocksImmuneToRift; // List of Vanilla blocks immune to rifts + private final ArrayList modBlocksImmuneToRift; // List of DD blocks immune to rifts public BlockRift(int i, int j, Material par2Material, DDProperties properties) { super(i, par2Material); this.setTickRandomly(true); this.properties = properties; + this.modBlocksImmuneToRift = new ArrayList(); + this.modBlocksImmuneToRift.add(properties.FabricBlockID); + this.modBlocksImmuneToRift.add(properties.PermaFabricBlockID); + this.modBlocksImmuneToRift.add(properties.DimensionalDoorID); + this.modBlocksImmuneToRift.add(properties.WarpDoorID); + this.modBlocksImmuneToRift.add(properties.TransTrapdoorID); + this.modBlocksImmuneToRift.add(properties.UnstableDoorID); + this.modBlocksImmuneToRift.add(properties.RiftBlockID); + this.modBlocksImmuneToRift.add(properties.TransientDoorID); + this.modBlocksImmuneToRift.add(properties.GoldenDimensionalDoorID); + this.modBlocksImmuneToRift.add(properties.GoldenDoorID); + this.blocksImmuneToRift = new ArrayList(); + this.blocksImmuneToRift.add(properties.FabricBlockID); this.blocksImmuneToRift.add(properties.PermaFabricBlockID); this.blocksImmuneToRift.add(properties.DimensionalDoorID); @@ -66,7 +80,6 @@ public class BlockRift extends Block implements ITileEntityProvider this.blocksImmuneToRift.add(properties.GoldenDimensionalDoorID); this.blocksImmuneToRift.add(properties.GoldenDoorID); this.blocksImmuneToRift.add(properties.PersonalDimDoorID); - this.blocksImmuneToRift.add(Block.blockLapis.blockID); this.blocksImmuneToRift.add(Block.blockIron.blockID); this.blocksImmuneToRift.add(Block.blockGold.blockID); @@ -85,9 +98,6 @@ public class BlockRift extends Block implements ITileEntityProvider { return false; } - - @Override - public void onBlockDestroyedByPlayer(World par1World, int par2, int par3, int par4, int par5) {} @Override public boolean isOpaqueCube() @@ -114,10 +124,10 @@ public class BlockRift extends Block implements ITileEntityProvider return true; } - //this doesnt do anything yet. @Override public int getRenderType() { + // This doesn't do anything yet if (mod_pocketDim.isPlayerWearingGoogles) { return 0; @@ -221,7 +231,7 @@ public class BlockRift extends Block implements ITileEntityProvider return targets; } - private void dropWorldThread(int blockID, World world, int x, int y, int z, Random random) + public void dropWorldThread(int blockID, World world, int x, int y, int z, Random random) { if (blockID != 0 && (random.nextInt(MAX_WORLD_THREAD_DROP_CHANCE) < properties.WorldThreadDropChance) && !(Block.blocksList[blockID] instanceof BlockFlowing || @@ -233,7 +243,7 @@ public class BlockRift extends Block implements ITileEntityProvider } } - private void addAdjacentBlocks(int x, int y, int z, int distance, HashMap pointDistances, Queue points) + private static void addAdjacentBlocks(int x, int y, int z, int distance, HashMap pointDistances, Queue points) { Point3D[] neighbors = new Point3D[] { new Point3D(x - 1, y, z), @@ -252,16 +262,6 @@ public class BlockRift extends Block implements ITileEntityProvider } } } - - public void regenerateRift(World world, int x, int y, int z, Random random) - { - if (!this.isBlockImmune(world, x, y, z) && world.getChunkProvider().chunkExists(x >> 4, z >> 4)) - { - int blockID = world.getBlockId(x, y, z); - if (world.setBlock(x, y, z, properties.RiftBlockID)) - dropWorldThread(blockID, world, x, y, z, random); - } - } public boolean spreadRift(NewDimData dimension, DimLink parent, World world, Random random) { @@ -413,6 +413,15 @@ public class BlockRift extends Block implements ITileEntityProvider } } } + + public boolean tryPlacingRift(World world, int x, int y, int z) + { + if (world != null && !isBlockImmune(world, x, y, z)) + { + return world.setBlock(x, y, z, mod_pocketDim.blockRift.blockID); + } + return false; + } public boolean isBlockImmune(World world, int x, int y, int z) { @@ -425,7 +434,21 @@ public class BlockRift extends Block implements ITileEntityProvider // is designed to receive an entity, the source of the blast. We have no entity so // I've set this to access blockResistance directly. Might need changing later. - return (block.blockResistance >= MIN_IMMUNE_RESISTANCE || blocksImmuneToRift.contains(block.blockID)); + return (block.blockResistance >= MIN_IMMUNE_RESISTANCE || + modBlocksImmuneToRift.contains(block.blockID) || + blocksImmuneToRift.contains(block.blockID)); + } + return false; + } + + public boolean isModBlockImmune(World world, int x, int y, int z) + { + // Check whether the block at the specified location is one of the + // rift-resistant blocks from DD. + Block block = Block.blocksList[world.getBlockId(x, y, z)]; + if (block != null) + { + return modBlocksImmuneToRift.contains(block.blockID); } return false; } @@ -447,4 +470,18 @@ public class BlockRift extends Block implements ITileEntityProvider { return new TileEntityRift(); } + + @Override + public void breakBlock(World world, int x, int y, int z, int oldBlockID, int oldMeta) + { + // This function runs on the server side after a block is replaced + // We MUST call super.breakBlock() since it involves removing tile entities + super.breakBlock(world, x, y, z, oldBlockID, oldMeta); + + // Schedule rift regeneration for this block if it was changed + if (world.getBlockId(x, y, z) != oldBlockID) + { + mod_pocketDim.riftRegenerator.scheduleSlowRegeneration(x, y, z, world); + } + } } \ No newline at end of file diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/blocks/DimensionalDoor.java b/src/main/java/StevenDimDoors/mod_pocketDim/blocks/DimensionalDoor.java index 3aceab99..8416f5fc 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/blocks/DimensionalDoor.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/blocks/DimensionalDoor.java @@ -3,16 +3,15 @@ package StevenDimDoors.mod_pocketDim.blocks; import net.minecraft.block.material.Material; import net.minecraft.item.Item; import net.minecraft.world.World; +import StevenDimDoors.mod_pocketDim.mod_pocketDim; import StevenDimDoors.mod_pocketDim.config.DDProperties; import StevenDimDoors.mod_pocketDim.core.DimLink; import StevenDimDoors.mod_pocketDim.core.LinkType; import StevenDimDoors.mod_pocketDim.core.NewDimData; import StevenDimDoors.mod_pocketDim.core.PocketManager; -@SuppressWarnings("deprecation") public class DimensionalDoor extends BaseDimDoor { - public DimensionalDoor(int blockID, Material material, DDProperties properties) { super(blockID, material, properties); @@ -23,7 +22,7 @@ public class DimensionalDoor extends BaseDimDoor { if (!world.isRemote && world.getBlockId(x, y - 1, z) == this.blockID) { - NewDimData dimension = PocketManager.getDimensionData(world); + NewDimData dimension = PocketManager.createDimensionData(world); DimLink link = dimension.getLink(x, y, z); if (link == null) { @@ -31,6 +30,13 @@ public class DimensionalDoor extends BaseDimDoor } } } + + @Override + public int getDoorItem() + { + return mod_pocketDim.itemDimensionalDoor.itemID; + } + @Override public int getDrops() { diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/blocks/IDimDoor.java b/src/main/java/StevenDimDoors/mod_pocketDim/blocks/IDimDoor.java index 942af4ed..608eeb33 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/blocks/IDimDoor.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/blocks/IDimDoor.java @@ -27,6 +27,8 @@ public interface IDimDoor public int getDrops(); + public int getDoorItem(); + public TileEntity initDoorTE(World world, int x, int y, int z); /** diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/blocks/PersonalDimDoor.java b/src/main/java/StevenDimDoors/mod_pocketDim/blocks/PersonalDimDoor.java index e3ae0140..4dfb5015 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/blocks/PersonalDimDoor.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/blocks/PersonalDimDoor.java @@ -2,6 +2,7 @@ package StevenDimDoors.mod_pocketDim.blocks; import net.minecraft.block.material.Material; import net.minecraft.world.World; +import StevenDimDoors.mod_pocketDim.mod_pocketDim; import StevenDimDoors.mod_pocketDim.config.DDProperties; import StevenDimDoors.mod_pocketDim.core.DimLink; import StevenDimDoors.mod_pocketDim.core.LinkType; @@ -34,8 +35,13 @@ public class PersonalDimDoor extends BaseDimDoor @Override public int getDrops() { - // TODO Auto-generated method stub - return 0; + return mod_pocketDim.itemQuartzDoor.itemID; + } + + @Override + public int getDoorItem() + { + return mod_pocketDim.itemPersonalDoor.itemID; } } diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/blocks/TransTrapdoor.java b/src/main/java/StevenDimDoors/mod_pocketDim/blocks/TransTrapdoor.java index 5d864f0f..453569bf 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/blocks/TransTrapdoor.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/blocks/TransTrapdoor.java @@ -2,6 +2,9 @@ package StevenDimDoors.mod_pocketDim.blocks; import java.util.Random; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + import net.minecraft.block.Block; import net.minecraft.block.BlockTrapDoor; import net.minecraft.block.ITileEntityProvider; @@ -111,14 +114,6 @@ public class TransTrapdoor extends BlockTrapDoor implements IDimDoor, ITileEntit { this.placeLink(world, x, y, z); world.setBlockTileEntity(x, y, z, this.createNewTileEntity(world)); - this.updateAttachedTile(world, x, y, z); - } - - @Override - public void updateTick(World world, int x, int y, int z, Random random) - { - TileEntityTransTrapdoor tile = (TileEntityTransTrapdoor) world.getBlockTileEntity(x, y, z); - tile.hasRift = PocketManager.getLink(x, y, z, world) != null; } @Override @@ -126,23 +121,13 @@ public class TransTrapdoor extends BlockTrapDoor implements IDimDoor, ITileEntit { return new TileEntityTransTrapdoor(); } - - public void updateAttachedTile(World world, int x, int y, int z) - { - TileEntity tile = world.getBlockTileEntity(x, y, z); - if (tile instanceof TileEntityTransTrapdoor) - { - TileEntityTransTrapdoor trapdoorTile = (TileEntityTransTrapdoor) tile; - trapdoorTile.hasRift = (PocketManager.getLink(x, y, z, world) != null); - } - } @Override public void placeLink(World world, int x, int y, int z) { if (!world.isRemote) { - NewDimData dimension = PocketManager.getDimensionData(world); + NewDimData dimension = PocketManager.createDimensionData(world); DimLink link = dimension.getLink(x, y, z); if (link == null && dimension.isPocketDimension()) { @@ -150,18 +135,30 @@ public class TransTrapdoor extends BlockTrapDoor implements IDimDoor, ITileEntit } } } - + + @Override + @SideOnly(Side.CLIENT) + public int idPicked(World world, int x, int y, int z) + { + return this.getDoorItem(); + } @Override public int idDropped(int metadata, Random random, int fortuneLevel) { - return getDrops(); + return this.getDrops(); } + + @Override + public int getDoorItem() + { + return mod_pocketDim.transTrapdoor.blockID; + } @Override public int getDrops() { - return Block.trapdoor.blockID; + return Block.trapdoor.blockID; } public static boolean isTrapdoorSetLow(int metadata) @@ -182,4 +179,18 @@ public class TransTrapdoor extends BlockTrapDoor implements IDimDoor, ITileEntit { return PocketManager.getLink(x, y, z, world)!=null; } + + @Override + public void breakBlock(World world, int x, int y, int z, int oldBlockID, int oldMeta) + { + // This function runs on the server side after a block is replaced + // We MUST call super.breakBlock() since it involves removing tile entities + super.breakBlock(world, x, y, z, oldBlockID, oldMeta); + + // Schedule rift regeneration for this block if it was replaced + if (world.getBlockId(x, y, z) != oldBlockID) + { + mod_pocketDim.riftRegenerator.scheduleFastRegeneration(x, y, z, world); + } + } } \ No newline at end of file diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/blocks/TransientDoor.java b/src/main/java/StevenDimDoors/mod_pocketDim/blocks/TransientDoor.java index b5f7576a..8364733c 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/blocks/TransientDoor.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/blocks/TransientDoor.java @@ -64,7 +64,7 @@ public class TransientDoor extends BaseDimDoor { if (!world.isRemote && world.getBlockId(x, y - 1, z) == this.blockID) { - NewDimData dimension = PocketManager.getDimensionData(world); + NewDimData dimension = PocketManager.createDimensionData(world); DimLink link = dimension.getLink(x, y, z); if (link == null && dimension.isPocketDimension()) { @@ -72,6 +72,12 @@ public class TransientDoor extends BaseDimDoor } } } + + @Override + public int getDoorItem() + { + return 0; + } @Override public int getDrops() diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/blocks/UnstableDoor.java b/src/main/java/StevenDimDoors/mod_pocketDim/blocks/UnstableDoor.java index a4a7e8af..76b9911d 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/blocks/UnstableDoor.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/blocks/UnstableDoor.java @@ -3,6 +3,7 @@ package StevenDimDoors.mod_pocketDim.blocks; import net.minecraft.block.material.Material; import net.minecraft.item.Item; import net.minecraft.world.World; +import StevenDimDoors.mod_pocketDim.mod_pocketDim; import StevenDimDoors.mod_pocketDim.config.DDProperties; import StevenDimDoors.mod_pocketDim.core.LinkType; import StevenDimDoors.mod_pocketDim.core.NewDimData; @@ -24,6 +25,13 @@ public class UnstableDoor extends BaseDimDoor dimension.createLink(x, y, z, LinkType.RANDOM,world.getBlockMetadata(x, y - 1, z)); } } + + @Override + public int getDoorItem() + { + return mod_pocketDim.itemUnstableDoor.itemID; + } + @Override public int getDrops() { diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/blocks/WarpDoor.java b/src/main/java/StevenDimDoors/mod_pocketDim/blocks/WarpDoor.java index cb215982..45357e97 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/blocks/WarpDoor.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/blocks/WarpDoor.java @@ -3,6 +3,7 @@ package StevenDimDoors.mod_pocketDim.blocks; import net.minecraft.block.material.Material; import net.minecraft.item.Item; import net.minecraft.world.World; +import StevenDimDoors.mod_pocketDim.mod_pocketDim; import StevenDimDoors.mod_pocketDim.config.DDProperties; import StevenDimDoors.mod_pocketDim.core.DimLink; import StevenDimDoors.mod_pocketDim.core.LinkType; @@ -21,7 +22,7 @@ public class WarpDoor extends BaseDimDoor { if (!world.isRemote && world.getBlockId(x, y - 1, z) == this.blockID) { - NewDimData dimension = PocketManager.getDimensionData(world); + NewDimData dimension = PocketManager.createDimensionData(world); DimLink link = dimension.getLink(x, y, z); if (link == null && dimension.isPocketDimension()) { @@ -30,6 +31,12 @@ public class WarpDoor extends BaseDimDoor } } + @Override + public int getDoorItem() + { + return mod_pocketDim.itemWarpDoor.itemID; + } + @Override public int getDrops() { diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/commands/CommandCreateDungeonRift.java b/src/main/java/StevenDimDoors/mod_pocketDim/commands/CommandCreateDungeonRift.java index c6065b8b..4fa55a38 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/commands/CommandCreateDungeonRift.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/commands/CommandCreateDungeonRift.java @@ -1,5 +1,9 @@ package StevenDimDoors.mod_pocketDim.commands; +import java.util.Collection; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.MathHelper; import StevenDimDoors.mod_pocketDim.mod_pocketDim; import StevenDimDoors.mod_pocketDim.core.DimLink; import StevenDimDoors.mod_pocketDim.core.LinkType; @@ -9,12 +13,6 @@ import StevenDimDoors.mod_pocketDim.dungeon.DungeonData; import StevenDimDoors.mod_pocketDim.helpers.DungeonHelper; import StevenDimDoors.mod_pocketDim.world.PocketBuilder; -import java.util.Collection; - -import net.minecraft.command.ICommandSender; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.util.MathHelper; - public class CommandCreateDungeonRift extends DDCommandBase { private static CommandCreateDungeonRift instance = null; @@ -38,10 +36,6 @@ public class CommandCreateDungeonRift extends DDCommandBase NewDimData dimension; DungeonHelper dungeonHelper = DungeonHelper.instance(); - if (sender.worldObj.isRemote) - { - return DDCommandResult.SUCCESS; - } if (command.length == 0) { return DDCommandResult.TOO_FEW_ARGUMENTS; @@ -69,6 +63,7 @@ public class CommandCreateDungeonRift extends DDCommandBase { dimension = PocketManager.getDimensionData(sender.worldObj); link = dimension.createLink(x, y + 1, z, LinkType.DUNGEON, orientation); + if (PocketBuilder.generateSelectedDungeonPocket(link, mod_pocketDim.properties, result)) { // Create a rift to our selected dungeon and notify the player diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/commands/CommandCreatePocket.java b/src/main/java/StevenDimDoors/mod_pocketDim/commands/CommandCreatePocket.java index b2843a63..9de7a3ac 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/commands/CommandCreatePocket.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/commands/CommandCreatePocket.java @@ -1,6 +1,5 @@ package StevenDimDoors.mod_pocketDim.commands; -import net.minecraft.command.ICommandSender; import net.minecraft.entity.player.EntityPlayer; import StevenDimDoors.mod_pocketDim.helpers.DungeonHelper; @@ -24,26 +23,21 @@ public class CommandCreatePocket extends DDCommandBase @Override protected DDCommandResult processCommand(EntityPlayer sender, String[] command) { - //TODO: Some commands have isRemote checks, some do not. Why? Can commands even run locally anyway? - //What does it mean when you run a command locally? ~SenseiKiwi - - if (!sender.worldObj.isRemote) + if (command.length > 0) { - if (command.length > 0) - { - return DDCommandResult.TOO_MANY_ARGUMENTS; - } - - //Place a door leading to a pocket dimension where the player is standing. - //The pocket dimension will serve as a room for the player to build a dungeon. - int x = (int) sender.posX; - int y = (int) sender.posY; - int z = (int) sender.posZ; - DungeonHelper.instance().createCustomDungeonDoor(sender.worldObj, x, y, z); - - //Notify the player - sendChat(sender,("Created a door to a pocket dimension. Please build your dungeon there.")); + return DDCommandResult.TOO_MANY_ARGUMENTS; } + + //Place a door leading to a pocket dimension where the player is standing. + //The pocket dimension will serve as a room for the player to build a dungeon. + int x = (int) sender.posX; + int y = (int) sender.posY; + int z = (int) sender.posZ; + DungeonHelper.instance().createCustomDungeonDoor(sender.worldObj, x, y, z); + + //Notify the player + sendChat(sender, "Created a door to a pocket dimension. Please build your dungeon there."); + return DDCommandResult.SUCCESS; } } \ No newline at end of file diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/commands/CommandCreateRandomRift.java b/src/main/java/StevenDimDoors/mod_pocketDim/commands/CommandCreateRandomRift.java index 6250c147..0c6672f4 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/commands/CommandCreateRandomRift.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/commands/CommandCreateRandomRift.java @@ -38,11 +38,7 @@ public class CommandCreateRandomRift extends DDCommandBase { NewDimData dimension; DungeonHelper dungeonHelper = DungeonHelper.instance(); - - if (sender.worldObj.isRemote) - { - return DDCommandResult.SUCCESS; - } + if (command.length > 1) { return DDCommandResult.TOO_MANY_ARGUMENTS; @@ -59,6 +55,7 @@ public class CommandCreateRandomRift extends DDCommandBase { dimension = PocketManager.getDimensionData(sender.worldObj); link = dimension.createLink(x, y + 1, z, LinkType.DUNGEON, orientation); + sender.worldObj.setBlock(x, y + 1, z,mod_pocketDim.blockRift.blockID, 0, 3); sendChat(sender, "Created a rift to a random dungeon."); } @@ -75,6 +72,7 @@ public class CommandCreateRandomRift extends DDCommandBase { dimension = PocketManager.getDimensionData(sender.worldObj); link = dimension.createLink(x, y + 1, z, LinkType.DUNGEON, orientation); + if (PocketBuilder.generateSelectedDungeonPocket(link, mod_pocketDim.properties, result)) { // Create a rift to our selected dungeon and notify the player @@ -118,9 +116,6 @@ public class CommandCreateRandomRift extends DDCommandBase { return null; } - else - { - return matches.get( random.nextInt(matches.size()) ); - } + return matches.get( random.nextInt(matches.size()) ); } } \ No newline at end of file diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/commands/CommandDeleteAllLinks.java b/src/main/java/StevenDimDoors/mod_pocketDim/commands/CommandDeleteAllLinks.java deleted file mode 100644 index 317b101e..00000000 --- a/src/main/java/StevenDimDoors/mod_pocketDim/commands/CommandDeleteAllLinks.java +++ /dev/null @@ -1,69 +0,0 @@ -package StevenDimDoors.mod_pocketDim.commands; - -import StevenDimDoors.mod_pocketDim.core.DimLink; -import StevenDimDoors.mod_pocketDim.core.NewDimData; -import StevenDimDoors.mod_pocketDim.core.PocketManager; - -import java.util.ArrayList; - -import net.minecraft.command.ICommandSender; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.world.World; - -@SuppressWarnings("deprecation") -public class CommandDeleteAllLinks extends DDCommandBase -{ - private static CommandDeleteAllLinks instance = null; - - private CommandDeleteAllLinks() - { - super("dd-deletelinks", "???"); - } - - public static CommandDeleteAllLinks instance() - { - if (instance == null) - instance = new CommandDeleteAllLinks(); - - return instance; - } - - @Override - protected DDCommandResult processCommand(EntityPlayer sender, String[] command) - { - int linksRemoved=0; - int targetDim; - boolean shouldGo= true; - - if(command.length==1) - { - targetDim = parseInt(sender, command[0]); - } - else - { - targetDim=0; - shouldGo=false; - sendChat(sender, ("Error-Invalid argument, delete_all_links ")); - } - - if(shouldGo) - { - - NewDimData dim = PocketManager.getDimensionData(targetDim); - ArrayList linksInDim = dim.getAllLinks(); - - for (DimLink link : linksInDim) - { - World targetWorld = PocketManager.loadDimension(targetDim); - targetWorld.setBlock(link.source().getX(), link.source().getY(), link.source().getZ(), 0); - dim.deleteLink(link); - //TODO Probably should check what the block is, but thats annoying so Ill do it later. - - linksRemoved++; - } - sendChat(sender,("Removed " + linksRemoved + " links.")); - - } - return DDCommandResult.SUCCESS; //TEMPORARY HACK - } -} \ No newline at end of file diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/commands/CommandDeleteRifts.java b/src/main/java/StevenDimDoors/mod_pocketDim/commands/CommandDeleteRifts.java index 328576cb..9a508570 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/commands/CommandDeleteRifts.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/commands/CommandDeleteRifts.java @@ -2,22 +2,21 @@ package StevenDimDoors.mod_pocketDim.commands; import java.util.ArrayList; -import net.minecraft.command.ICommandSender; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.world.World; import StevenDimDoors.mod_pocketDim.mod_pocketDim; import StevenDimDoors.mod_pocketDim.core.DimLink; import StevenDimDoors.mod_pocketDim.core.NewDimData; import StevenDimDoors.mod_pocketDim.core.PocketManager; +import StevenDimDoors.mod_pocketDim.util.Point4D; -@SuppressWarnings("deprecation") public class CommandDeleteRifts extends DDCommandBase { private static CommandDeleteRifts instance = null; private CommandDeleteRifts() { - super("dd-???", "???"); + super("dd-deleterifts", "[dimension number]"); } public static CommandDeleteRifts instance() @@ -31,47 +30,64 @@ public class CommandDeleteRifts extends DDCommandBase @Override protected DDCommandResult processCommand(EntityPlayer sender, String[] command) { - int linksRemoved=0; - int targetDim; - boolean shouldGo= true; + int linksRemoved = 0; + int targetDimension; - if(command.length==1) + if (command.length > 1) { - targetDim = parseInt(sender, command[0]); + return DDCommandResult.TOO_MANY_ARGUMENTS; + } + if (command.length == 0) + { + targetDimension = sender.worldObj.provider.dimensionId; } else { - targetDim=0; - shouldGo=false; - sendChat(sender,("Error-Invalid argument, delete_all_links ")); + try + { + targetDimension = Integer.parseInt(command[0]); + } + catch (NumberFormatException e) + { + return DDCommandResult.INVALID_DIMENSION_ID; + } } - if(shouldGo) + World world = PocketManager.loadDimension(targetDimension); + if (world == null) { - - NewDimData dim = PocketManager.getDimensionData(targetDim); - ArrayList linksInDim = dim.getAllLinks(); - - for (DimLink link : linksInDim) - { - World targetWorld = PocketManager.loadDimension(targetDim); - - if(!mod_pocketDim.blockRift.isBlockImmune(sender.worldObj,link.source().getX(), link.source().getY(), link.source().getZ())|| - (targetWorld.getBlockId(link.source().getX(), link.source().getY(), link.source().getZ())==mod_pocketDim.blockRift.blockID)) - { - linksRemoved++; - targetWorld.setBlock(link.source().getX(), link.source().getY(), link.source().getZ(), 0); - dim.deleteLink(link); - - - } - //TODO Probably should check what the block is, but thats annoying so Ill do it later. - - - } - sendChat(sender,("Removed " + linksRemoved + " links.")); - + return DDCommandResult.UNREGISTERED_DIMENSION; } - return DDCommandResult.SUCCESS; //TEMPORARY HACK + + int x; + int y; + int z; + Point4D location; + NewDimData dimension = PocketManager.createDimensionData(world); + ArrayList links = dimension.getAllLinks(); + for (DimLink link : links) + { + location = link.source(); + x = location.getX(); + y = location.getY(); + z = location.getZ(); + if (world.getBlockId(x, y, z) == mod_pocketDim.blockRift.blockID) + { + // Remove the rift and its link + world.setBlockToAir(x, y, z); + dimension.deleteLink(link); + linksRemoved++; + } + else if (!mod_pocketDim.blockRift.isBlockImmune(world, x, y, z)) + { + // If a block is not immune, then it must not be a DD block. + // The link would regenerate into a rift eventually. + // We only need to remove the link. + dimension.deleteLink(link); + linksRemoved++; + } + } + sendChat(sender, "Removed " + linksRemoved + " links."); + return DDCommandResult.SUCCESS; } } \ No newline at end of file diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/commands/CommandExportDungeon.java b/src/main/java/StevenDimDoors/mod_pocketDim/commands/CommandExportDungeon.java index 4c0ad4dd..84b95849 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/commands/CommandExportDungeon.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/commands/CommandExportDungeon.java @@ -2,7 +2,6 @@ package StevenDimDoors.mod_pocketDim.commands; import java.io.File; -import net.minecraft.command.ICommandSender; import net.minecraft.entity.player.EntityPlayer; import StevenDimDoors.mod_pocketDim.config.DDProperties; import StevenDimDoors.mod_pocketDim.helpers.DungeonHelper; @@ -60,66 +59,51 @@ public class CommandExportDungeon extends DDCommandBase //Export the schematic return exportDungeon(sender, command[0]); } - else - { - //The schematic name contains illegal characters. Inform the user. - return new DDCommandResult("Error: Invalid schematic name. Please use only letters, numbers, dashes, and underscores."); - } - } - else - { - //The command is malformed in some way. Assume that the user meant to use - //the 3-argument version and report an error. - return DDCommandResult.TOO_FEW_ARGUMENTS; + //The schematic name contains illegal characters. Inform the user. + return new DDCommandResult("Error: Invalid schematic name. Please use only letters, numbers, dashes, and underscores."); } + //The command is malformed in some way. Assume that the user meant to use + //the 3-argument version and report an error. + return DDCommandResult.TOO_FEW_ARGUMENTS; } //The user must have used the 3-argument version of this command - //TODO: Why do we check remoteness here but not before? And why not for the other export case? - //Something feels wrong... ~SenseiKiwi - if (!sender.worldObj.isRemote) + //TODO: This validation should be in DungeonHelper or in another class. We should move it + //during the save file format rewrite. ~SenseiKiwi + + if (!dungeonHelper.validateDungeonType(command[0], dungeonHelper.getDungeonPack("ruins"))) { - //TODO: This validation should be in DungeonHelper or in another class. We should move it - //during the save file format rewrite. ~SenseiKiwi - - if (!dungeonHelper.validateDungeonType(command[0], dungeonHelper.getDungeonPack("ruins"))) - { - return new DDCommandResult("Error: Invalid dungeon type. Please use one of the existing types."); - } - if (!DungeonHelper.DUNGEON_NAME_PATTERN.matcher(command[1]).matches()) - { - return new DDCommandResult("Error: Invalid dungeon name. Please use only letters, numbers, and dashes."); - } - if (!command[2].equalsIgnoreCase("open") && !command[2].equalsIgnoreCase("closed")) - { - return new DDCommandResult("Error: Please specify whether the dungeon is 'open' or 'closed'."); - } - - //If there are no more arguments, export the dungeon. - if (command.length == 3) - { - return exportDungeon(sender, join(command, "_", 0, 3)); - } - else - { - //Validate the weight argument - try - { - int weight = Integer.parseInt(command[3]); - if (weight >= DungeonHelper.MIN_DUNGEON_WEIGHT && weight <= DungeonHelper.MAX_DUNGEON_WEIGHT) - { - return exportDungeon(sender, join(command, "_", 0, 4)); - } - } - catch (Exception e) { } - } - - //If we've reached this point, then we must have an invalid weight. - return new DDCommandResult("Invalid dungeon weight. Please specify a weight between " - + DungeonHelper.MIN_DUNGEON_WEIGHT + " and " + DungeonHelper.MAX_DUNGEON_WEIGHT + ", inclusive."); + return new DDCommandResult("Error: Invalid dungeon type. Please use one of the existing types."); + } + if (!DungeonHelper.DUNGEON_NAME_PATTERN.matcher(command[1]).matches()) + { + return new DDCommandResult("Error: Invalid dungeon name. Please use only letters, numbers, and dashes."); + } + if (!command[2].equalsIgnoreCase("open") && !command[2].equalsIgnoreCase("closed")) + { + return new DDCommandResult("Error: Please specify whether the dungeon is 'open' or 'closed'."); } - return DDCommandResult.SUCCESS; + //If there are no more arguments, export the dungeon. + if (command.length == 3) + { + return exportDungeon(sender, join(command, "_", 0, 3)); + } + + //Validate the weight argument + try + { + int weight = Integer.parseInt(command[3]); + if (weight >= DungeonHelper.MIN_DUNGEON_WEIGHT && weight <= DungeonHelper.MAX_DUNGEON_WEIGHT) + { + return exportDungeon(sender, join(command, "_", 0, 4)); + } + } + catch (Exception e) { } + + //If we've reached this point, then we must have an invalid weight. + return new DDCommandResult("Invalid dungeon weight. Please specify a weight between " + + DungeonHelper.MIN_DUNGEON_WEIGHT + " and " + DungeonHelper.MAX_DUNGEON_WEIGHT + ", inclusive."); } private static DDCommandResult exportDungeon(EntityPlayer player, String name) @@ -137,10 +121,7 @@ public class CommandExportDungeon extends DDCommandBase dungeonHelper.registerDungeon(exportPath, dungeonHelper.getDungeonPack("ruins"), false, true); return DDCommandResult.SUCCESS; } - else - { - return new DDCommandResult("Error: Failed to save dungeon schematic!"); - } + return new DDCommandResult("Error: Failed to save dungeon schematic!"); } private static String join(String[] source, String delimiter, int start, int end) diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/commands/CommandListDungeons.java b/src/main/java/StevenDimDoors/mod_pocketDim/commands/CommandListDungeons.java index 043d0fd3..222b4814 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/commands/CommandListDungeons.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/commands/CommandListDungeons.java @@ -31,10 +31,6 @@ public class CommandListDungeons extends DDCommandBase int pageCount; ArrayList dungeonNames; - if (sender.worldObj.isRemote) - { - return DDCommandResult.SUCCESS; - } if (command.length > 1) { return DDCommandResult.TOO_MANY_ARGUMENTS; diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/commands/CommandResetDungeons.java b/src/main/java/StevenDimDoors/mod_pocketDim/commands/CommandResetDungeons.java index 3c84bdf2..b1ccadc1 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/commands/CommandResetDungeons.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/commands/CommandResetDungeons.java @@ -1,15 +1,14 @@ package StevenDimDoors.mod_pocketDim.commands; import java.util.ArrayList; +import java.util.HashSet; import net.minecraft.entity.player.EntityPlayer; -import net.minecraftforge.common.DimensionManager; import StevenDimDoors.mod_pocketDim.core.DimLink; import StevenDimDoors.mod_pocketDim.core.DimensionType; import StevenDimDoors.mod_pocketDim.core.LinkType; import StevenDimDoors.mod_pocketDim.core.NewDimData; import StevenDimDoors.mod_pocketDim.core.PocketManager; -@SuppressWarnings("deprecation") public class CommandResetDungeons extends DDCommandBase { private static CommandResetDungeons instance = null; @@ -30,61 +29,78 @@ public class CommandResetDungeons extends DDCommandBase @Override protected DDCommandResult processCommand(EntityPlayer sender, String[] command) { - if(sender.worldObj.isRemote) - { - return DDCommandResult.SUCCESS; - } if (command.length > 0) { - return DDCommandResult.TOO_FEW_ARGUMENTS; + return DDCommandResult.TOO_MANY_ARGUMENTS; + } + + int id; + int resetCount = 0; + int dungeonCount = 0; + HashSet deletedDimensions = new HashSet(); + ArrayList loadedDungeons = new ArrayList(); + + // Copy the list of dimensions to iterate over the copy. Otherwise, + // we would trigger an exception by modifying the original list. + ArrayList dimensions = new ArrayList(); + for (NewDimData dimension : PocketManager.getDimensions()) + { + + dimensions.add(dimension); } - int dungeonCount = 0; - int resetCount = 0; - ArrayList dimsToDelete = new ArrayList(); - ArrayList dimsToFix = new ArrayList(); - - for (NewDimData data : PocketManager.getDimensions()) + // Iterate over the list of dimensions. Check which ones are dungeons. + // If a dungeon is found, try to delete it. If it can't be deleted, + // then it must be loaded and needs to be updated to prevent bugs. + for (NewDimData dimension : dimensions) { - - if(DimensionManager.getWorld(data.id())==null&&data.getDimensionType() == DimensionType.DUNGEON) + if (dimension.type() == DimensionType.DUNGEON) { - resetCount++; dungeonCount++; - dimsToDelete.add(data.id()); - } - else if(data.getDimensionType() == DimensionType.DUNGEON) - { - dimsToFix.add(data.id()); - dungeonCount++; - for(DimLink link : data.links()) + id = dimension.id(); + if (PocketManager.deletePocket(dimension, true)) { - if(link.linkType()==LinkType.REVERSE) + resetCount++; + deletedDimensions.add(id); + } + else + { + loadedDungeons.add(dimension); + } + } + + } + + // Modify the loaded dungeons to prevent bugs + for (NewDimData dungeon : loadedDungeons) + { + // Find top-most loaded dungeons and update their parents. + // They will automatically update their children. + // Dungeons with non-dungeon parents don't need to be fixed. + if (dungeon.parent() == null) + { + dungeon.setParentToRoot(); + } + + // Links to any deleted dungeons must be replaced + for (DimLink link : dungeon.links()) + { + if (link.hasDestination() && deletedDimensions.contains(link.destination().getDimension())) + { + + if (link.linkType() == LinkType.DUNGEON) { - data.createLink(link.source(), LinkType.DUNGEON_EXIT, link.orientation(), null); + dungeon.createLink(link.source(), LinkType.DUNGEON, link.orientation(), null); } - if(link.linkType()==LinkType.DUNGEON) + else if (link.linkType() == LinkType.REVERSE) { - data.createLink(link.source(), LinkType.DUNGEON, link.orientation(), null); + dungeon.createLink(link.source(), LinkType.DUNGEON_EXIT, link.orientation(), null); } } } } - - for(Integer dimID:dimsToDelete) - { - PocketManager.deletePocket(PocketManager.getDimensionData(dimID), true); - } - /** - * temporary workaround - */ - for(Integer dimID: dimsToFix) - { - PocketManager.getDimensionData(dimID).setParentToRoot(); - } - //TODO- for some reason the parent field of loaded dimenions get reset to null if I call .setParentToRoot() before I delete the pockets. - //TODO implement blackList - //Notify the user of the results + + // Notify the user of the results sendChat(sender,("Reset complete. " + resetCount + " out of " + dungeonCount + " dungeons were reset.")); return DDCommandResult.SUCCESS; } diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/commands/CommandTeleportPlayer.java b/src/main/java/StevenDimDoors/mod_pocketDim/commands/CommandTeleportPlayer.java index 1b29999f..b001c7a9 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/commands/CommandTeleportPlayer.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/commands/CommandTeleportPlayer.java @@ -1,23 +1,23 @@ package StevenDimDoors.mod_pocketDim.commands; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.server.MinecraftServer; +import net.minecraft.world.World; import StevenDimDoors.mod_pocketDim.core.DDTeleporter; +import StevenDimDoors.mod_pocketDim.core.NewDimData; import StevenDimDoors.mod_pocketDim.core.PocketManager; import StevenDimDoors.mod_pocketDim.util.Point4D; -import java.util.Arrays; -import java.util.List; - -import net.minecraft.command.ICommandSender; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraftforge.common.DimensionManager; - public class CommandTeleportPlayer extends DDCommandBase { private static CommandTeleportPlayer instance = null; private CommandTeleportPlayer() { - super("dd-tp", new String[] {" "," "} ); + super("dd-tp", new String[] { + " ", + " ", + " "} ); } public static CommandTeleportPlayer instance() @@ -28,110 +28,119 @@ public class CommandTeleportPlayer extends DDCommandBase return instance; } - /** - * TODO- Change to accept variety of input, like just coords, just dim ID, or two player names. - */ @Override protected DDCommandResult processCommand(EntityPlayer sender, String[] command) { - EntityPlayer targetPlayer = sender; - int dimDestinationID = sender.worldObj.provider.dimensionId; + int x; + int y; + int z; + World world; + int dimensionID; + Point4D destination; + NewDimData dimension; + boolean checkOrientation; + EntityPlayer targetPlayer; - if(command.length == 5) + if (command.length < 2) { - for(int i= 1; i <5;i++) - { - if(!isInteger(command[i])) - { - return DDCommandResult.INVALID_ARGUMENTS; - } - } - if(sender.worldObj.getPlayerEntityByName(command[0])!=null) //Gets the targeted player - { - targetPlayer = sender.worldObj.getPlayerEntityByName(command[0]); - } - else - { - return DDCommandResult.INVALID_ARGUMENTS; - } - dimDestinationID=Integer.parseInt(command[1]);//gets the target dim ID from the command string - - if(!DimensionManager.isDimensionRegistered(dimDestinationID)) - { - return DDCommandResult.INVALID_DIMENSION_ID; - } - - PocketManager.loadDimension(dimDestinationID); - Point4D destination = new Point4D(Integer.parseInt(command[2]),Integer.parseInt(command[3]),Integer.parseInt(command[4]),dimDestinationID); - DDTeleporter.teleportEntity(targetPlayer, destination, false); + return DDCommandResult.TOO_FEW_ARGUMENTS; } - else if(command.length == 2 && isInteger(command[1])) + if (command.length > 5) { - if(sender.worldObj.getPlayerEntityByName(command[0])!=null) //Gets the targeted player - { - targetPlayer = sender.worldObj.getPlayerEntityByName(command[0]); - } - else - { - return DDCommandResult.INVALID_ARGUMENTS; - } - dimDestinationID=Integer.parseInt(command[1]);//gets the target dim ID from the command string - - if(!DimensionManager.isDimensionRegistered(dimDestinationID)) - { - return DDCommandResult.INVALID_DIMENSION_ID; - } - - - Point4D destination = PocketManager.getDimensionData(dimDestinationID).origin(); - if(!PocketManager.getDimensionData(dimDestinationID).isPocketDimension()) - { - destination = new Point4D(destination.getX(),PocketManager.loadDimension(dimDestinationID).getTopSolidOrLiquidBlock( - destination.getX(), destination.getZ()), - destination.getZ(),destination.getDimension()); - } - DDTeleporter.teleportEntity(targetPlayer, destination, false); + return DDCommandResult.TOO_MANY_ARGUMENTS; } - else if(command.length == 1 && isInteger(command[0])) - { - - targetPlayer = sender; - - dimDestinationID=Integer.parseInt(command[0]);//gets the target dim ID from the command string - - if(!DimensionManager.isDimensionRegistered(dimDestinationID)) - { - return DDCommandResult.INVALID_DIMENSION_ID; - } - - - Point4D destination = PocketManager.getDimensionData(dimDestinationID).origin(); - if(!PocketManager.getDimensionData(dimDestinationID).isPocketDimension()) - { - destination = new Point4D(destination.getX(),PocketManager.loadDimension(dimDestinationID).getTopSolidOrLiquidBlock( - destination.getX(), destination.getZ()), - destination.getZ(),destination.getDimension()); - } - DDTeleporter.teleportEntity(targetPlayer, destination, false); - } - else + if (command.length == 3) { return DDCommandResult.INVALID_ARGUMENTS; } + // Check that all arguments after the username are integers + for (int k = 1; k < command.length; k++) + { + if (!isInteger(command[k])) + { + return DDCommandResult.INVALID_ARGUMENTS; + } + } + // Check if the target player is logged in + targetPlayer = MinecraftServer.getServer().getConfigurationManager().getPlayerForUsername(command[0]); + if (targetPlayer == null) + { + return DDCommandResult.PLAYER_OFFLINE; + } + // If a dimension ID was provided, try to load it + if (command.length != 4) + { + dimensionID = Integer.parseInt(command[1]); + world = PocketManager.loadDimension(dimensionID); + if (world == null) + { + return DDCommandResult.UNREGISTERED_DIMENSION; + } + } + else + { + dimensionID = targetPlayer.worldObj.provider.dimensionId; + world = targetPlayer.worldObj; + } + + // If we teleport to a pocket dimension, set checkOrientation to true + // so the player is placed correctly relative to the entrance door. + checkOrientation = false; + + // Parse or calculate the destination as necessary + // The Y coordinate must be increased by 1 because of the way that + // DDTeleporter considers destination points. It assumes that the + // point provided is the upper block of a door. + if (command.length == 2) + { + // Check if the destination is a pocket dimension + dimension = PocketManager.createDimensionData(world); + if (dimension.isPocketDimension()) + { + // The destination is a pocket dimension. + // Teleport the player to its original entrance (the origin). + destination = dimension.origin(); + checkOrientation = true; + } + else + { + // The destination is not a pocket dimension, which means we + // don't automatically know a safe location where we can send + // the player. Send the player to (0, Y, 0), where Y is chosen + // by searching. Add 2 to place the player ABOVE the top block. + y = world.getTopSolidOrLiquidBlock(0, 0) + 2; + destination = new Point4D(0, y, 0, dimensionID); + } + } + else if (command.length == 4) + { + x = Integer.parseInt(command[1]); + y = Integer.parseInt(command[2]) + 1; // Correct the Y value + z = Integer.parseInt(command[3]); + destination = new Point4D(x, y, z, dimensionID); + } + else + { + x = Integer.parseInt(command[2]); + y = Integer.parseInt(command[3]) + 1; // Correct the Y value + z = Integer.parseInt(command[4]); + destination = new Point4D(x, y, z, dimensionID); + } + // Teleport! + DDTeleporter.teleportEntity(targetPlayer, destination, checkOrientation); return DDCommandResult.SUCCESS; } - public boolean isInteger( String input ) - { - try - { - Integer.parseInt( input ); - return true; - } - catch(Exception e ) - { - return false; - } - } - + private static boolean isInteger(String input) + { + try + { + Integer.parseInt(input); + return true; + } + catch(Exception e) + { + return false; + } + } } \ No newline at end of file diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/commands/DDCommandBase.java b/src/main/java/StevenDimDoors/mod_pocketDim/commands/DDCommandBase.java index b62cc86d..badb0a25 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/commands/DDCommandBase.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/commands/DDCommandBase.java @@ -5,7 +5,6 @@ import net.minecraft.command.ICommand; import net.minecraft.command.ICommandSender; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.util.ChatMessageComponent; -import cpw.mods.fml.common.event.FMLServerStartingEvent; /* * An abstract base class for our Dimensional Doors commands. This cleans up the code a little and provides @@ -96,13 +95,15 @@ public abstract class DDCommandBase extends CommandBase * that Dryware and Technic Jenkins don't have those functions defined. How in the world? * I have no idea. But it's breaking our builds. -_- ~SenseiKiwi */ - public int compareTo(ICommand par1ICommand) + @Override + public int compareTo(ICommand command) { - return this.getCommandName().compareTo(par1ICommand.getCommandName()); + return this.getCommandName().compareTo(command.getCommandName()); } - public int compareTo(Object par1Obj) + @Override + public int compareTo(Object other) { - return this.compareTo((ICommand)par1Obj); + return this.compareTo((ICommand) other); } } diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/commands/DDCommandResult.java b/src/main/java/StevenDimDoors/mod_pocketDim/commands/DDCommandResult.java index 9ec0cf73..b6a31b93 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/commands/DDCommandResult.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/commands/DDCommandResult.java @@ -8,7 +8,8 @@ public class DDCommandResult { public static final DDCommandResult TOO_MANY_ARGUMENTS = new DDCommandResult(2, "Error: Too many arguments passed to the command", true); public static final DDCommandResult INVALID_DIMENSION_ID = new DDCommandResult(3, "Error: Invalid dimension ID", true); public static final DDCommandResult UNREGISTERED_DIMENSION = new DDCommandResult(4, "Error: Dimension is not registered", false); - public static final DDCommandResult INVALID_ARGUMENTS = new DDCommandResult(5, "Error: Invalid arguments passed to the command.", true); + public static final DDCommandResult INVALID_ARGUMENTS = new DDCommandResult(5, "Error: Invalid arguments passed to the command", true); + public static final DDCommandResult PLAYER_OFFLINE = new DDCommandResult(6, "Error: Player is not online", false); public static final int CUSTOM_ERROR_CODE = -1; diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/config/DDWorldProperties.java b/src/main/java/StevenDimDoors/mod_pocketDim/config/DDWorldProperties.java index db2a4988..b2a4569d 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/config/DDWorldProperties.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/config/DDWorldProperties.java @@ -9,7 +9,6 @@ public class DDWorldProperties /** * World Generation Settings */ - public final DimensionFilter RiftClusterDimensions; public final DimensionFilter RiftGatewayDimensions; @@ -17,7 +16,7 @@ public class DDWorldProperties * General Flags */ public final boolean LimboEscapeEnabled; - + public final boolean UniversalLimboEnabled; //Names of categories private static final String CATEGORY_WORLD_GENERATION = "world generation"; @@ -44,6 +43,12 @@ public class DDWorldProperties "generates near the bottom of the dimension. If disabled, players could still leave through " + "dungeons in Limbo or by dying (if Hardcore Limbo is disabled). The default value is true.").getBoolean(true); + UniversalLimboEnabled = config.get(Configuration.CATEGORY_GENERAL, "Enable Universal Limbo", false, + "Sets whether players are teleported to Limbo when they die in any dimension (except Limbo). " + + "Normally, players only go to Limbo if they die in a pocket dimension. This setting will not " + + "affect deaths in Limbo, which can be set with the Hardcore Limbo option. " + + "The default value is false.").getBoolean(false); + config.save(); } diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/core/DDTeleporter.java b/src/main/java/StevenDimDoors/mod_pocketDim/core/DDTeleporter.java index 15fa8488..3096f35f 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/core/DDTeleporter.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/core/DDTeleporter.java @@ -25,7 +25,6 @@ import StevenDimDoors.mod_pocketDim.blocks.BaseDimDoor; import StevenDimDoors.mod_pocketDim.blocks.IDimDoor; import StevenDimDoors.mod_pocketDim.config.DDProperties; import StevenDimDoors.mod_pocketDim.helpers.yCoordHelper; -import StevenDimDoors.mod_pocketDim.items.ItemDimensionalDoor; import StevenDimDoors.mod_pocketDim.schematic.BlockRotator; import StevenDimDoors.mod_pocketDim.tileentities.TileEntityDimDoor; import StevenDimDoors.mod_pocketDim.util.Point4D; @@ -52,59 +51,49 @@ public class DDTeleporter private DDTeleporter() { } - /**Checks if the destination supplied is valid, ie, filled by any non-replaceable block. - * - * @param entity - * @param world - * @param destination - * @param properties - * @return + /** + * Checks if the destination supplied is safe (i.e. filled by any replaceable or non-opaque blocks) */ - private static boolean checkDestination(Entity entity, WorldServer world, Point4D destination,DDProperties properties) + private static boolean checkDestination(WorldServer world, Point4D destination, int orientation) { int x = destination.getX(); int y = destination.getY(); int z = destination.getZ(); int blockIDTop; - int blockIDBottom; - + int blockIDBottom; Point3D point; - - int orientation; - orientation = getDestinationOrientation(destination, properties); - entity.rotationYaw = (orientation * 90) + 90; switch (orientation) { case 0: - point = new Point3D(MathHelper.floor_double(x - 0.5), y - 1, MathHelper.floor_double(z + 0.5)); + point = new Point3D(x - 1, y - 1, z); break; case 1: - point = new Point3D(MathHelper.floor_double(x + 0.5), y - 1, MathHelper.floor_double(z - 0.5)); + point = new Point3D(x, y - 1, z - 1); break; case 2: - point = new Point3D(MathHelper.floor_double(x + 1.5), y - 1, MathHelper.floor_double(z + 0.5)); + point = new Point3D(x + 1, y - 1, z); break; case 3: - point = new Point3D(MathHelper.floor_double(x + 0.5), y - 1, MathHelper.floor_double(z + 1.5)); + point = new Point3D(x, y - 1, z + 1); break; default: point = new Point3D(x, y - 1, z); break; } blockIDBottom = world.getBlockId(point.getX(), point.getY(), point.getZ()); - blockIDTop = world.getBlockId(point.getX(), point.getY()+1, point.getZ()); + blockIDTop = world.getBlockId(point.getX(), point.getY() + 1, point.getZ()); if (Block.blocksList[blockIDBottom] != null) { - if(!Block.blocksList[blockIDBottom].isBlockReplaceable(world, point.getX(), point.getY(), point.getZ())&&world.isBlockOpaqueCube(point.getX(), point.getY(), point.getZ())) + if (!Block.blocksList[blockIDBottom].isBlockReplaceable(world, point.getX(), point.getY(), point.getZ()) && world.isBlockOpaqueCube(point.getX(), point.getY(), point.getZ())) { return false; } } if (Block.blocksList[blockIDTop] != null) { - if (!Block.blocksList[blockIDTop].isBlockReplaceable(world, point.getX(), point.getY()+1, point.getZ())) + if (!Block.blocksList[blockIDTop].isBlockReplaceable(world, point.getX(), point.getY() + 1, point.getZ())) { return false; } @@ -126,56 +115,37 @@ public class DDTeleporter } else { - //Teleport the entity to the precise destination point + // Teleport the entity to the precise destination point orientation = -1; } - if (!checkDestination(entity, world, destination, properties)) - { - if (entity instanceof EntityPlayerMP) - { - EntityPlayer player = (EntityPlayer) entity; - player.rotationYaw = (orientation * 90) + 90; - switch (orientation) - { - case 0: - player.setPositionAndUpdate(x + 0.5, y - 1, z + 0.5); - break; - case 1: - player.setPositionAndUpdate(x + 0.5, y - 1, z + 0.5); - break; - case 2: - player.setPositionAndUpdate(x + 0.5, y - 1, z + 0.5); - break; - case 3: - player.setPositionAndUpdate(x + 0.5, y - 1, z + 0.5); - break; - default: - player.setPositionAndUpdate(x, y - 1, z); - break; - } - } - } - else if (entity instanceof EntityPlayer) + if (entity instanceof EntityPlayer) { EntityPlayer player = (EntityPlayer) entity; - switch (orientation) + if (checkDestination(world, destination, orientation)) { - case 0: - player.setPositionAndUpdate(x - 0.5, y - 1, z + 0.5); - break; - case 1: - player.setPositionAndUpdate(x + 0.5, y - 1, z - 0.5); - break; - case 2: - player.setPositionAndUpdate(x + 1.5, y - 1, z + 0.5); - break; - case 3: - player.setPositionAndUpdate(x + 0.5, y - 1, z + 1.5); - break; - default: - player.setPositionAndUpdate(x + 0.5, y - 1, z + 0.5); - break; + switch (orientation) + { + case 0: + player.setPositionAndUpdate(x - 0.5, y - 1, z + 0.5); + break; + case 1: + player.setPositionAndUpdate(x + 0.5, y - 1, z - 0.5); + break; + case 2: + player.setPositionAndUpdate(x + 1.5, y - 1, z + 0.5); + break; + case 3: + player.setPositionAndUpdate(x + 0.5, y - 1, z + 1.5); + break; + default: + player.setPositionAndUpdate(x + 0.5, y - 1, z + 0.5); + break; + } + } + else + { + player.setPositionAndUpdate(x + 0.5, y - 1, z + 0.5); } } else if (entity instanceof EntityMinecart) @@ -201,7 +171,7 @@ public class DDTeleporter entity.worldObj.updateEntityWithOptionalForce(entity, false); break; case 3: - DDTeleporter.setEntityPosition(entity, x + 0.5, y, z + 1.5 ); + DDTeleporter.setEntityPosition(entity, x + 0.5, y, z + 1.5); entity.motionZ = 0.39; entity.worldObj.updateEntityWithOptionalForce(entity, false); break; @@ -255,7 +225,7 @@ public class DDTeleporter if (block==null || !(block instanceof IDimDoor)) { //Return the pocket's orientation instead - return PocketManager.getDimensionData(door.getDimension()).orientation(); + return PocketManager.createDimensionData(world).orientation(); } @@ -323,7 +293,7 @@ public class DDTeleporter // to prevent us from doing bad things. Moreover, no dimension is being created, so if we ever // tie code to that, it could cause confusing bugs. // No hacky for you! ~SenseiKiwi - PocketManager.getDimwatcher().onCreated(new ClientDimData(PocketManager.getDimensionData(destination.getDimension()))); + PocketManager.getDimwatcher().onCreated(new ClientDimData(PocketManager.createDimensionData(newWorld))); // Set the new dimension and inform the client that it's moving to a new world. player.dimension = destination.getDimension(); @@ -482,9 +452,34 @@ public class DDTeleporter { if (link.hasDestination()&&link.linkType()!=LinkType.PERSONAL) { - if(PocketManager.isBlackListed(link.destination().getDimension())) + if (PocketManager.isBlackListed(link.destination().getDimension())) { - link=PocketManager.getDimensionData(link.source().getDimension()).createLink(link.point,LinkType.SAFE_EXIT,link.orientation, null); + + // This link leads to a dimension that has been blacklisted. + // That means that it was a pocket and it was deleted. + // Depending on the link type, we must overwrite it or cancel + // the teleport operation. We don't need to assign 'link' with + // a different value. NewDimData will overwrite it in-place. + NewDimData start = PocketManager.getDimensionData(link.source().getDimension()); + if (link.linkType() == LinkType.DUNGEON) + { + // Ovewrite the link into a dungeon link with no destination + start.createLink(link.source(), LinkType.DUNGEON, link.orientation(), null); + } + else + { + if (start.isPocketDimension()) + { + // Ovewrite the link into a safe exit link, because + // this could be the only way out from a pocket. + start.createLink(link.source(), LinkType.SAFE_EXIT, link.orientation(), null); + } + else + { + // Cancel the teleport attempt + return false; + } + } } else { @@ -568,10 +563,7 @@ public class DDTeleporter { return matches.get( random.nextInt(matches.size()) ); } - else - { - return null; - } + return null; } private static boolean generateUnsafeExit(DimLink link) @@ -586,6 +578,7 @@ public class DDTeleporter // already in a non-pocket dimension. NewDimData current = PocketManager.getDimensionData(link.point.getDimension()); + if (current.isPocketDimension()) { Point4D source = link.source(); @@ -639,6 +632,7 @@ public class DDTeleporter } } } + private static boolean generateSafeExit(DimLink link, DDProperties properties) { NewDimData current = PocketManager.getDimensionData(link.point.getDimension()); @@ -653,6 +647,7 @@ public class DDTeleporter // to compensate for servers with many Mystcraft ages or other worlds. NewDimData current = PocketManager.getDimensionData(link.point.getDimension()); + ArrayList roots = PocketManager.getRootDimensions(); int shiftChance = START_ROOT_SHIFT_CHANCE + ROOT_SHIFT_CHANCE_PER_LEVEL * (current.packDepth() - 1); @@ -660,11 +655,11 @@ public class DDTeleporter { if (current.root().id() != OVERWORLD_DIMENSION_ID && random.nextInt(MAX_OVERWORLD_EXIT_CHANCE) < OVERWORLD_EXIT_CHANCE) { - return generateSafeExit(PocketManager.getDimensionData(OVERWORLD_DIMENSION_ID), link, properties); + return generateSafeExit(PocketManager.createDimensionDataDangerously(OVERWORLD_DIMENSION_ID), link, properties); } if (current.root().id() != NETHER_DIMENSION_ID && random.nextInt(MAX_NETHER_EXIT_CHANCE) < NETHER_EXIT_CHANCE) { - return generateSafeExit(PocketManager.getDimensionData(NETHER_DIMENSION_ID), link, properties); + return generateSafeExit(PocketManager.createDimensionDataDangerously(NETHER_DIMENSION_ID), link, properties); } for (int attempts = 0; attempts < 10; attempts++) { @@ -769,11 +764,12 @@ public class DDTeleporter int orientation = getDestinationOrientation(source, properties); NewDimData sourceDim = PocketManager.getDimensionData(link.source().getDimension()); DimLink reverse = destinationDim.createLink(x, y + 2, z, LinkType.REVERSE,orientation); + sourceDim.setLinkDestination(reverse, source.getX(), source.getY(), source.getZ()); // Set up the warp door at the destination orientation = BlockRotator.transformMetadata(orientation, 2, properties.WarpDoorID); - ItemDimensionalDoor.placeDoorBlock(world, x, y + 1, z, orientation, mod_pocketDim.warpDoor); + ItemDoor.placeDoorBlock(world, x, y + 1, z, orientation, mod_pocketDim.warpDoor); // Complete the link to the destination // This comes last so the destination isn't set unless everything else works first diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/core/DimLink.java b/src/main/java/StevenDimDoors/mod_pocketDim/core/DimLink.java index 4fe1888d..bed50a61 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/core/DimLink.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/core/DimLink.java @@ -3,7 +3,7 @@ package StevenDimDoors.mod_pocketDim.core; import java.util.LinkedList; import java.util.List; import net.minecraft.item.ItemStack; -import StevenDimDoors.mod_pocketDim.items.ItemDDKey; +import net.minecraft.world.ChunkCoordIntPair; import StevenDimDoors.mod_pocketDim.util.Point4D; public abstract class DimLink @@ -87,12 +87,12 @@ public abstract class DimLink public int getDestinationOrientation() { - DimLink link = PocketManager.getLink(this.destination().getX(), this.destination().getY(), this.destination().getZ(), this.destination().getDimension()); - if(link !=null) + DimLink destinationLink = PocketManager.getLink(tail.getDestination()); + if (destinationLink != null) { - return link.orientation(); + return destinationLink.orientation(); } - return (this.orientation()+2)%4; + return (orientation + 2) % 4; } public boolean hasDestination() @@ -120,11 +120,6 @@ public abstract class DimLink return tail.getLinkType(); } - @Override - public String toString() - { - return point + " -> " + (hasDestination() ? destination() : ""); - } /** * Tries to open this lock. Returns true if the lock is open or if the key can open it @@ -170,4 +165,15 @@ public abstract class DimLink { return this.lock; } + + public ChunkCoordIntPair getChunkCoordinates() + { + return new ChunkCoordIntPair(point.getX() >> 4, point.getZ() >> 4); + } + + @Override + public String toString() + { + return point + " -> " + (hasDestination() ? destination() : "()"); + } } diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/core/NewDimData.java b/src/main/java/StevenDimDoors/mod_pocketDim/core/NewDimData.java index 5ba86cda..f0b646ec 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/core/NewDimData.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/core/NewDimData.java @@ -1,13 +1,16 @@ package StevenDimDoors.mod_pocketDim.core; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Random; +import java.util.Stack; import java.util.TreeMap; import StevenDimDoors.mod_pocketDim.watcher.ClientLinkData; import net.minecraft.item.ItemStack; +import net.minecraft.world.ChunkCoordIntPair; import net.minecraft.world.World; import StevenDimDoors.mod_pocketDim.Point3D; import StevenDimDoors.mod_pocketDim.config.DDProperties; @@ -19,6 +22,7 @@ import StevenDimDoors.mod_pocketDim.saving.PackedDungeonData; import StevenDimDoors.mod_pocketDim.saving.PackedLinkData; import StevenDimDoors.mod_pocketDim.saving.PackedLinkTail; import StevenDimDoors.mod_pocketDim.util.Point4D; +import StevenDimDoors.mod_pocketDim.watcher.ClientLinkData; import StevenDimDoors.mod_pocketDim.watcher.IUpdateWatcher; public abstract class NewDimData implements IPackable @@ -133,6 +137,9 @@ public abstract class NewDimData implements IPackable } } + + + private static int EXPECTED_LINKS_PER_CHUNK = 2; protected static Random random = new Random(); protected int id; @@ -151,6 +158,10 @@ public abstract class NewDimData implements IPackable protected boolean modified; public IUpdateWatcher linkWatcher; + + // Don't write this field to a file - it should be recreated on startup + private Map> chunkMapping; + protected NewDimData(int id, NewDimData parent, DimensionType type, IUpdateWatcher linkWatcher) { if (type != DimensionType.ROOT && (parent == null)) @@ -170,6 +181,7 @@ public abstract class NewDimData implements IPackable this.origin = null; this.dungeon = null; this.linkWatcher = linkWatcher; + this.chunkMapping = new HashMap>(); this.modified = true; //Register with parent @@ -210,28 +222,26 @@ public abstract class NewDimData implements IPackable this.linkWatcher = null; this.depth = 0; this.root = root; + this.chunkMapping = null; } public DimLink findNearestRift(World world, int range, int x, int y, int z) { - //TODO: Rewrite this later to use an octtree - - //Sanity check... + // Sanity check... if (world.provider.dimensionId != id) { throw new IllegalArgumentException("Attempted to search for links in a World instance for a different dimension!"); } - //Note: Only detect rifts at a distance > 1, so we ignore the rift - //that called this function and any adjacent rifts. - - DimLink nearest = null; + // Note: Only detect rifts at a distance > 0, so we ignore the rift + // at the center of the search space. DimLink link; - + DimLink nearest = null; + + int i, j, k; int distance; int minDistance = Integer.MAX_VALUE; - int i, j, k; DDProperties properties = DDProperties.instance(); for (i = -range; i <= range; i++) @@ -243,7 +253,7 @@ public abstract class NewDimData implements IPackable distance = getAbsoluteSum(i, j, k); if (distance > 0 && distance < minDistance && world.getBlockId(x + i, y + j, z + k) == properties.RiftBlockID) { - link = getLink(x+i, y+j, z+k); + link = getLink(x + i, y + j, z + k); if (link != null) { nearest = link; @@ -259,24 +269,20 @@ public abstract class NewDimData implements IPackable public ArrayList findRiftsInRange(World world, int range, int x, int y, int z) { - ArrayList links = new ArrayList(); - //TODO: Rewrite this later to use an octtree - - //Sanity check... + // Sanity check... if (world.provider.dimensionId != id) { throw new IllegalArgumentException("Attempted to search for links in a World instance for a different dimension!"); } - - //Note: Only detect rifts at a distance > 1, so we ignore the rift - //that called this function and any adjacent rifts. - - DimLink link; - - int distance; - int i, j, k; - DDProperties properties = DDProperties.instance(); + // Note: Only detect rifts at a distance > 0, so we ignore the rift + // at the center of the search space. + int i, j, k; + int distance; + DimLink link; + DDProperties properties = DDProperties.instance(); + ArrayList links = new ArrayList(); + for (i = -range; i <= range; i++) { for (j = -range; j <= range; j++) @@ -286,7 +292,7 @@ public abstract class NewDimData implements IPackable distance = getAbsoluteSum(i, j, k); if (distance > 0 && world.getBlockId(x + i, y + j, z + k) == properties.RiftBlockID) { - link = getLink(x+i, y+j, z+k); + link = getLink(x + i, y + j, z + k); if (link != null) { links.add(link); @@ -311,13 +317,26 @@ public abstract class NewDimData implements IPackable public DimLink createLink(Point4D source, LinkType linkType, int orientation, DDLock locked) { - //Return an existing link if there is one to avoid creating multiple links starting at the same point. + // Return an existing link if there is one to avoid creating multiple links starting at the same point. InnerDimLink link = linkMapping.get(source); if (link == null) { link = new InnerDimLink(source, linkType, orientation, locked); linkMapping.put(source, link); linkList.add(link); + + // If this code is running on the server side, add this link to chunkMapping. + if (linkType != LinkType.CLIENT) + { + ChunkCoordIntPair chunk = link.getChunkCoordinates(); + List chunkLinks = chunkMapping.get(chunk); + if (chunkLinks == null) + { + chunkLinks = new ArrayList(EXPECTED_LINKS_PER_CHUNK); + chunkMapping.put(chunk, chunkLinks); + } + chunkLinks.add(link); + } } else { @@ -327,6 +346,7 @@ public abstract class NewDimData implements IPackable //Link created! if (linkType != LinkType.CLIENT) + { linkWatcher.onCreated(new ClientLinkData(link)); } @@ -340,8 +360,8 @@ public abstract class NewDimData implements IPackable public DimLink createChildLink(Point4D source, DimLink parent, DDLock locked) { - //To avoid having multiple links at a single point, if we find an existing link then we overwrite - //its destination data instead of creating a new instance. + // To avoid having multiple links at a single point, if we find an existing link then we overwrite + // its destination data instead of creating a new instance. if (parent == null) { @@ -354,7 +374,22 @@ public abstract class NewDimData implements IPackable linkMapping.put(source, link); linkList.add(link); - //Link created! + + // If this code is running on the server side, add this link to chunkMapping. + // Granted, the client side code should never create child links anyway... + if (link.linkType() != LinkType.CLIENT) + { + ChunkCoordIntPair chunk = link.getChunkCoordinates(); + List chunkLinks = chunkMapping.get(chunk); + if (chunkLinks == null) + { + chunkLinks = new ArrayList(EXPECTED_LINKS_PER_CHUNK); + chunkMapping.put(chunk, chunkLinks); + } + chunkLinks.add(link); + } + + // Link created! linkWatcher.onCreated(new ClientLinkData(link)); } else @@ -379,7 +414,19 @@ public abstract class NewDimData implements IPackable if (target != null) { linkList.remove(target); - //Raise deletion event + + // If this code is running on the server side, remove this link to chunkMapping. + if (link.linkType() != LinkType.CLIENT) + { + ChunkCoordIntPair chunk = target.getChunkCoordinates(); + List chunkLinks = chunkMapping.get(chunk); + if (chunkLinks != null) + { + chunkLinks.remove(target); + } + } + + // Raise deletion event linkWatcher.onDeleted(new ClientLinkData(link)); target.clear(); modified = true; @@ -389,7 +436,10 @@ public abstract class NewDimData implements IPackable public boolean deleteLink(int x, int y, int z) { - Point4D location = new Point4D(x, y, z, id); + return this.deleteLink(this.getLink(x, y, z)); + } + public boolean deleteLink(Point4D location) + { return this.deleteLink(this.getLink(location)); } @@ -401,7 +451,7 @@ public abstract class NewDimData implements IPackable public DimLink getLink(Point3D location) { - return linkMapping.get(new Point4D(location.getX(),location.getY(),location.getZ(),this.id)); + return linkMapping.get(new Point4D(location.getX(), location.getY(), location.getZ(), this.id)); } public DimLink getLink(Point4D location) @@ -424,7 +474,7 @@ public abstract class NewDimData implements IPackable return (root != this); } - public DimensionType getDimensionType() + public DimensionType type() { return this.type; } @@ -526,11 +576,42 @@ public abstract class NewDimData implements IPackable */ public void setParentToRoot() { + // Update this dimension's information + if (parent != null) + { + parent.children.remove(this); + } this.depth = 1; this.parent = this.root; this.root.children.add(this); this.root.modified = true; this.modified = true; + if (this.type == DimensionType.DUNGEON) + { + this.packDepth = calculatePackDepth(this.parent, this.dungeon); + } + + // Update the depths for child dimensions using a depth-first traversal + Stack ordering = new Stack(); + ordering.addAll(this.children); + + while (!ordering.isEmpty()) + { + NewDimData current = ordering.pop(); + current.resetDepth(); + ordering.addAll(current.children); + } + } + + private void resetDepth() + { + // We assume that this is only applied to dimensions with parents + this.depth = this.parent.depth + 1; + if (this.type == DimensionType.DUNGEON) + { + this.packDepth = calculatePackDepth(this.parent, this.dungeon); + } + this.modified = true; } public static int calculatePackDepth(NewDimData parent, DungeonData current) @@ -559,10 +640,7 @@ public abstract class NewDimData implements IPackable { return parent.packDepth + 1; } - else - { - return 1; - } + return 1; } public void initializePocket(int originX, int originY, int originZ, int orientation, DimLink incoming) @@ -627,10 +705,17 @@ public abstract class NewDimData implements IPackable { return linkList.get(random.nextInt(linkList.size())); } - else + return linkList.get(0); + } + + public Iterable getChunkLinks(int chunkX, int chunkZ) + { + List chunkLinks = chunkMapping.get(new ChunkCoordIntPair(chunkX, chunkZ)); + if (chunkLinks != null) { - return linkList.get(0); + return chunkLinks; } + return new ArrayList(0); } public boolean isModified() @@ -737,7 +822,7 @@ public abstract class NewDimData implements IPackable return String.valueOf(id); } - + @Override public String toString() { return "DimID= " + this.id; diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/core/PocketManager.java b/src/main/java/StevenDimDoors/mod_pocketDim/core/PocketManager.java index b609b70a..177e456c 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/core/PocketManager.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/core/PocketManager.java @@ -112,14 +112,14 @@ public class PocketManager // having to instantiate a bunch of data containers and without exposing an "unsafe" // creation method for anyone to call. Integrity protection for the win! It's like // exposing a private constructor ONLY to a very specific trusted class. - + @Override public NewDimData registerDimension(int dimensionID, int rootID, DimensionType type) { return registerClientDimension(dimensionID, rootID, type); } } - + private static int OVERWORLD_DIMENSION_ID = 0; private static volatile boolean isLoading = false; @@ -161,12 +161,13 @@ public class PocketManager return; } isLoading = true; - + dimensionData = new HashMap(); rootDimensions = new ArrayList(); dimensionIDBlackList = new ArrayList(); personalPocketsMapping = new HashMap(); + if(FMLCommonHandler.instance().getEffectiveSide().isClient()) { //Shouldnt try to load everything if we are a client @@ -179,18 +180,18 @@ public class PocketManager DDProperties properties = DDProperties.instance(); registerDimension(properties.LimboDimensionID, null, DimensionType.ROOT); + loadInternal(); - + //Register pocket dimensions registerPockets(properties); - + isLoaded = true; isLoading = false; } - + public static boolean registerPackedDimData(PackedDimData packedData) { - InnerDimData dimData; DimensionType type = DimensionType.getTypeFromIndex(packedData.DimensionType); if(type == null) @@ -215,8 +216,8 @@ public class PocketManager dimData = new InnerDimData(packedData.ID, test, type, linkWatcher); dimData.isFilled=packedData.IsFilled; dimData.origin = new Point4D(packedData.Origin.getX(),packedData.Origin.getY(),packedData.Origin.getZ(),packedData.ID); - dimData.root=PocketManager.getDimensionData(packedData.RootID); - + dimData.root = PocketManager.createDimensionData(packedData.RootID); + if(packedData.DungeonData!=null) { dimData.dungeon=DDSaveHandler.unpackDungeonData(packedData.DungeonData); @@ -228,7 +229,7 @@ public class PocketManager return true; } - + public static boolean deletePocket(NewDimData target, boolean deleteFolder) { // We can't delete the dimension if it's currently loaded or if it's not actually a pocket. @@ -239,46 +240,50 @@ public class PocketManager { if (deleteFolder) { - deleteDimensionFiles(target); + deleteDimensionFiles(dimension); } + // Note: We INTENTIONALLY don't unregister the dimensions that we + // delete with Forge. Instead, we keep them registered to stop Forge + // from reallocating those IDs to other mods such as Mystcraft. This + // is to prevent bugs. Blacklisted dimensions are still properly + // unregistered when the server shuts down. dimensionIDBlackList.add(dimension.id); - deleteDimensionData(dimension.id); + deleteDimensionData(dimension); return true; } return false; } - - private static boolean deleteDimensionFiles(NewDimData target) - { - InnerDimData dimension = (InnerDimData) target; - if (dimension.isPocketDimension() && DimensionManager.getWorld(dimension.id()) == null) - { - String saveRootPath = DimensionManager.getCurrentSaveRootDirectory().getAbsolutePath(); - File saveDirectory = new File(saveRootPath + "/DimensionalDoors/pocketDimID" + dimension.id()); - DeleteFolder.deleteFolder(saveDirectory); - File dataFile = new File(saveRootPath + "/DimensionalDoors/data/dim_" + dimension.id() + ".txt"); - dataFile.delete(); - return true; - } - return false; - } - - private static boolean deleteDimensionData(int dimensionID) - { - if (dimensionData.containsKey(dimensionID) && DimensionManager.getWorld(dimensionID) == null) - { - NewDimData target = PocketManager.getDimensionData(dimensionID); - InnerDimData dimension = (InnerDimData) target; - dimensionData.remove(dimensionID); + private static void deleteDimensionFiles(InnerDimData dimension) + { + // We assume that the caller checks if the dimension is loaded, for the + // sake of efficiency. Don't call this on a loaded dimension or bad + // things will happen! + String saveRootPath = DimensionManager.getCurrentSaveRootDirectory().getAbsolutePath(); + File saveDirectory = new File(saveRootPath + "/DimensionalDoors/pocketDimID" + dimension.id()); + DeleteFolder.deleteFolder(saveDirectory); + File dataFile = new File(saveRootPath + "/DimensionalDoors/data/dim_" + dimension.id() + ".txt"); + dataFile.delete(); + } + + private static void deleteDimensionData(InnerDimData dimension) + { + // We assume that the caller checks if the dimension is loaded, for the + // sake of efficiency. Don't call this on a loaded dimension or bad + // things will happen! + if (dimensionData.remove(dimension.id()) != null) + { // Raise the dim deleted event getDimwatcher().onDeleted(new ClientDimData(dimension)); dimension.clear(); - return true; } - return false; + else + { + // This should never happen. A simple sanity check. + throw new IllegalArgumentException("The specified dimension is not listed with PocketManager."); + } } - + private static void registerPockets(DDProperties properties) { for (NewDimData dimension : dimensionData.values()) @@ -340,9 +345,7 @@ public class PocketManager * loads the dim data from the saved hashMap. Also handles compatibility with old saves, see OldSaveHandler */ private static void loadInternal() - { - //System.out.println(!FMLCommonHandler.instance().getSide().isClient()); - + { File saveDir = DimensionManager.getCurrentSaveRootDirectory(); if (saveDir != null) { @@ -355,7 +358,7 @@ public class PocketManager { System.out.println("Importing old DD save data..."); OldSaveImporter.importOldSave(oldSaveData); - + oldSaveData.renameTo(new File(oldSaveData.getAbsolutePath()+"_IMPORTED")); System.out.println("Import Succesful!"); @@ -368,7 +371,7 @@ public class PocketManager } return; } - + // Load save data System.out.println("Loading Dimensional Doors save data..."); if (DDSaveHandler.loadAll()) @@ -377,7 +380,7 @@ public class PocketManager } } } - + public static void save(boolean checkModified) { if (!isLoaded) @@ -390,7 +393,7 @@ public class PocketManager return; } isSaving = true; - + try { DDSaveHandler.saveAll(dimensionData.values(), dimensionIDBlackList, checkModified); @@ -407,9 +410,14 @@ public class PocketManager isSaving = false; } } - + public static WorldServer loadDimension(int id) { + if (!DimensionManager.isDimensionRegistered(id)) + { + return null; + } + WorldServer world = DimensionManager.getWorld(id); if (world == null) { @@ -478,6 +486,7 @@ public class PocketManager { return registerPocket(parent, type, null); } + /** * Registers a dimension with DD but NOT with forge. * @param dimensionID @@ -503,21 +512,22 @@ public class PocketManager rootDimensions.add(dimension); } getDimwatcher().onCreated(new ClientDimData(dimension)); - + return dimension; } - + @SideOnly(Side.CLIENT) private static NewDimData registerClientDimension(int dimensionID, int rootID, DimensionType type) - { - System.out.println("Registered dim "+dimensionID+" on the client."); - // No need to raise events heres since this code should only run on the client side - // getDimensionData() always handles root dimensions properly, even if the weren't defined before - // SenseiKiwi: I'm a little worried about how getDimensionData will raise + { + // No need to raise events heres since this code should only run on the + // client side. createDimensionData() always handles root dimensions + // properly, even if they weren't defined before. + + // SenseiKiwi: I'm a little worried about how createDimensionData will raise // an event when it creates any root dimensions... Needs checking later. - - InnerDimData root = (InnerDimData) getDimensionData(rootID); + + InnerDimData root = (InnerDimData) createDimensionData(rootID); InnerDimData dimension; if (rootID != dimensionID) @@ -533,37 +543,45 @@ public class PocketManager { dimension = root; } - if(dimension.isPocketDimension()&&!DimensionManager.isDimensionRegistered(dimension.id())) + if (dimension.isPocketDimension() && !DimensionManager.isDimensionRegistered(dimension.id())) { //Im registering pocket dims here. I *think* we can assume that if its a pocket and we are //registering its dim data, we also need to register it with forge. - + //New packet stuff prevents this from always being true, unfortuantly. I send the dimdata to the client when they teleport. //Steven DimensionManager.registerDimension(dimensionID, mod_pocketDim.properties.PocketProviderID); } - return dimension; + return dimension; } - - public static NewDimData getDimensionData(World world) - { - return getDimensionData(world.provider.dimensionId); - } - + public static NewDimData getDimensionData(int dimensionID) { - //Retrieve the data for a dimension. If we don't have a record for that dimension, - //assume it's a non-pocket dimension that hasn't been initialized with us before - //and create a NewDimData instance for it. - //Any pocket dimension must be listed with PocketManager to have a dimension ID - //assigned, so it's safe to assume that any unknown dimensions don't belong to us. - - //FIXME: What's the point of this condition? Most calls to this function will crash anyway! ~SenseiKiwi - if(PocketManager.dimensionData == null) - { - System.out.println("Something odd happend during shutdown"); - return null; - } + return PocketManager.dimensionData.get(dimensionID); + } + + public static NewDimData getDimensionData(World dimension) + { + return PocketManager.dimensionData.get(dimension.provider.dimensionId); + } + + public static NewDimData createDimensionData(World world) + { + return createDimensionData(world.provider.dimensionId); + } + + public static NewDimData createDimensionDataDangerously(int dimensionID) + { + // Same as createDimensionData(int), but public. Meant to discourage anyone from + // using it unless absolutely needed! We'll probably phase this out eventually. + return createDimensionData(dimensionID); + } + + protected static NewDimData createDimensionData(int dimensionID) + { + // Retrieve the data for a dimension. If we don't have a record for that dimension, + // assume it's a non-pocket dimension that hasn't been initialized with us before + // and create a NewDimData instance for it. NewDimData dimension = PocketManager.dimensionData.get(dimensionID); // if we do not have a record of it, then it must be a root @@ -592,7 +610,7 @@ public class PocketManager { throw new IllegalStateException("Pocket dimensions have already been unloaded!"); } - + unregisterPockets(); dimensionData = null; personalPocketsMapping = null; @@ -600,7 +618,7 @@ public class PocketManager isLoaded = false; isConnected = false; } - + public static DimLink getLink(int x, int y, int z, World world) { return getLink(x, y, z, world.provider.dimensionId); @@ -610,7 +628,7 @@ public class PocketManager { return getLink(point.getX(), point.getY(), point.getZ(), point.getDimension()); } - + public static DimLink getLink(int x, int y, int z, int dimensionID) { NewDimData dimension = dimensionData.get(dimensionID); @@ -618,12 +636,9 @@ public class PocketManager { return dimension.getLink(x, y, z); } - else - { - return null; - } + return null; } - + public static boolean isBlackListed(int dimensionID) { return PocketManager.dimensionIDBlackList.contains(dimensionID); @@ -636,12 +651,12 @@ public class PocketManager { return getDimwatcher().unregisterReceiver(watcher); } - + public static void registerLinkWatcher(IUpdateWatcher watcher) { linkWatcher.registerReceiver(watcher); } - + public static boolean unregisterLinkWatcher(IUpdateWatcher watcher) { return linkWatcher.unregisterReceiver(watcher); @@ -651,18 +666,18 @@ public class PocketManager { updateSource.registerWatchers(new ClientDimWatcher(), new ClientLinkWatcher()); } - + public static void writePacket(DataOutputStream output) throws IOException { // Write a very compact description of our dimensions and links to be sent to a client Compactor.write(dimensionData.values(), output); } - + public static boolean isRegisteredInternally(int dimensionID) { return dimensionData.containsKey(dimensionID); } - + public static void createAndRegisterBlacklist(List blacklist) { //TODO - create a special blacklist provider @@ -686,10 +701,7 @@ public class PocketManager // Load compacted client-side dimension data load(); Compactor.readDimensions(input, new DimRegistrationCallback()); - - // Register pocket dimensions - DDProperties properties = DDProperties.instance(); - + isLoaded = true; isLoading = false; isConnected = true; diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/dungeon/DungeonSchematic.java b/src/main/java/StevenDimDoors/mod_pocketDim/dungeon/DungeonSchematic.java index 179996c1..afcbc0ec 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/dungeon/DungeonSchematic.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/dungeon/DungeonSchematic.java @@ -161,7 +161,7 @@ public class DungeonSchematic extends Schematic { applyFilter(standardizer); } - private Map getAssignedToStandardIDMapping(DDProperties properties) + private static Map getAssignedToStandardIDMapping(DDProperties properties) { //If we ever need this broadly or support other mods, this should be moved to a separate class TreeMap mapping = new TreeMap(); @@ -246,7 +246,7 @@ public class DungeonSchematic extends Schematic { world.setBlockTileEntity(pocketPoint.getX(), pocketPoint.getY(), pocketPoint.getZ(), TileEntity.createAndLoadEntity(tileTag)); } - setUpDungeon(PocketManager.getDimensionData(world), world, pocketCenter, turnAngle, entryLink, random, properties, blockSetter); + setUpDungeon(PocketManager.createDimensionData(world), world, pocketCenter, turnAngle, entryLink, random, properties, blockSetter); } private void setUpDungeon(NewDimData dimension, World world, Point3D pocketCenter, int turnAngle, DimLink entryLink, Random random, DDProperties properties, IBlockSetter blockSetter) diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/helpers/ChunkLoaderHelper.java b/src/main/java/StevenDimDoors/mod_pocketDim/helpers/ChunkLoaderHelper.java index 06d22d58..6483afd3 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/helpers/ChunkLoaderHelper.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/helpers/ChunkLoaderHelper.java @@ -1,54 +1,98 @@ package StevenDimDoors.mod_pocketDim.helpers; -import StevenDimDoors.mod_pocketDim.IChunkLoader; -import StevenDimDoors.mod_pocketDim.mod_pocketDim; -import StevenDimDoors.mod_pocketDim.core.NewDimData; -import StevenDimDoors.mod_pocketDim.core.PocketManager; - -import cpw.mods.fml.common.event.FMLServerStartingEvent; - import java.io.File; import java.util.List; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.ChunkCoordIntPair; import net.minecraft.world.World; import net.minecraftforge.common.DimensionManager; import net.minecraftforge.common.ForgeChunkManager; import net.minecraftforge.common.ForgeChunkManager.LoadingCallback; import net.minecraftforge.common.ForgeChunkManager.Ticket; +import net.minecraftforge.common.ForgeChunkManager.Type; +import StevenDimDoors.experimental.BoundingBox; +import StevenDimDoors.mod_pocketDim.IChunkLoader; +import StevenDimDoors.mod_pocketDim.Point3D; +import StevenDimDoors.mod_pocketDim.mod_pocketDim; +import StevenDimDoors.mod_pocketDim.core.NewDimData; +import StevenDimDoors.mod_pocketDim.core.PocketManager; +import StevenDimDoors.mod_pocketDim.world.PocketBuilder; +import cpw.mods.fml.common.event.FMLServerStartingEvent; public class ChunkLoaderHelper implements LoadingCallback { - @Override public void ticketsLoaded(List tickets, World world) { for (Ticket ticket : tickets) { - int goldDimDoorX = ticket.getModData().getInteger("goldDimDoorX"); - int goldDimDoorY = ticket.getModData().getInteger("goldDimDoorY"); - int goldDimDoorZ = ticket.getModData().getInteger("goldDimDoorZ"); - if(world.getBlockId(goldDimDoorX, goldDimDoorY, goldDimDoorZ) != mod_pocketDim.properties.GoldenDimensionalDoorID) + boolean loaded = false; + int x = ticket.getModData().getInteger("goldDimDoorX"); + int y = ticket.getModData().getInteger("goldDimDoorY"); + int z = ticket.getModData().getInteger("goldDimDoorZ"); + + if (world.getBlockId(x, y, z) == mod_pocketDim.properties.GoldenDimensionalDoorID) + { + IChunkLoader loader = (IChunkLoader) world.getBlockTileEntity(x, y, z); + if (!loader.isInitialized()) + { + loader.initialize(ticket); + loaded = true; + } + } + if (!loaded) { ForgeChunkManager.releaseTicket(ticket); } - else - { - IChunkLoader tile = (IChunkLoader) world.getBlockTileEntity(goldDimDoorX, goldDimDoorY, goldDimDoorZ); - tile.forceChunkLoading(ticket,goldDimDoorX,goldDimDoorZ); - } } } - public static void loadChunkForcedWorlds(FMLServerStartingEvent event) + public static Ticket createTicket(int x, int y, int z, World world) { - for(NewDimData data : PocketManager.getDimensions()) + NBTTagCompound data; + Ticket ticket = ForgeChunkManager.requestTicket(mod_pocketDim.instance, world, Type.NORMAL); + if (ticket != null) + { + data = ticket.getModData(); + data.setInteger("goldDimDoorX", x); + data.setInteger("goldDimDoorY", y); + data.setInteger("goldDimDoorZ", z); + } + return ticket; + } + + public static void forcePocketChunks(NewDimData pocket, Ticket ticket) + { + BoundingBox bounds = PocketBuilder.calculateDefaultBounds(pocket); + Point3D minCorner = bounds.minCorner(); + Point3D maxCorner = bounds.maxCorner(); + int minX = minCorner.getX() >> 4; + int minZ = minCorner.getZ() >> 4; + int maxX = maxCorner.getX() >> 4; + int maxZ = maxCorner.getZ() >> 4; + int chunkX; + int chunkZ; + + for (chunkX = minX; chunkX <= maxX; chunkX++) + { + for (chunkZ = minZ; chunkZ <= maxZ; chunkZ++) + { + ForgeChunkManager.forceChunk(ticket, new ChunkCoordIntPair(chunkX, chunkZ)); + } + } + } + + public static void loadForcedChunkWorlds(FMLServerStartingEvent event) + { + for (NewDimData data : PocketManager.getDimensions()) { if(data.isPocketDimension()) { String chunkDir = DimensionManager.getCurrentSaveRootDirectory()+"/DimensionalDoors/pocketDimID" + data.id(); - + File file = new File(chunkDir); - + if(file.exists()) { if(ForgeChunkManager.savedWorldHasForcedChunkTickets(file)) diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/helpers/DeleteFolder.java b/src/main/java/StevenDimDoors/mod_pocketDim/helpers/DeleteFolder.java index 3f835bef..495ca6b0 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/helpers/DeleteFolder.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/helpers/DeleteFolder.java @@ -2,31 +2,33 @@ package StevenDimDoors.mod_pocketDim.helpers; import java.io.File; - public class DeleteFolder { - public static boolean deleteFolder(File file) + public static boolean deleteFolder(File directory) { try { - File[] files = file.listFiles(); - - if(files==null) + File[] contents = directory.listFiles(); + if (contents != null) { - file.delete(); - return true; + for (File entry : contents) + { + if (entry.isDirectory()) + { + deleteFolder(entry); + } + else + { + entry.delete(); + } + } } - for(File inFile : files) - { - DeleteFolder.deleteFolder(inFile); - } - + return directory.delete(); } catch (Exception e) { e.printStackTrace(); return false; } - return true; } } \ No newline at end of file diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/helpers/DungeonHelper.java b/src/main/java/StevenDimDoors/mod_pocketDim/helpers/DungeonHelper.java index 9c7c6300..05a9b649 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/helpers/DungeonHelper.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/helpers/DungeonHelper.java @@ -264,7 +264,7 @@ public class DungeonHelper //Create a link above the specified position. Link to a new pocket dimension. NewDimData dimension = PocketManager.getDimensionData(world); DimLink link = dimension.createLink(x, y + 1, z, LinkType.POCKET, 3); - + //Place a Warp Door linked to that pocket ItemDimensionalDoor.placeDoorBlock(world, x, y, z, 3, mod_pocketDim.warpDoor); diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/helpers/yCoordHelper.java b/src/main/java/StevenDimDoors/mod_pocketDim/helpers/yCoordHelper.java index 3810c8b9..26aa1788 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/helpers/yCoordHelper.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/helpers/yCoordHelper.java @@ -215,10 +215,7 @@ public class yCoordHelper { for (int dz = -1; dz <= 1; dz++) { - if (!provider.chunkExists(chunkX + dx, chunkZ + dz)) - { - provider.loadChunk(chunkX, chunkZ); - } + provider.loadChunk(chunkX, chunkZ); } } return target; diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/items/ItemRiftSignature.java b/src/main/java/StevenDimDoors/mod_pocketDim/items/ItemRiftSignature.java index d2090fbd..c3b58d8d 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/items/ItemRiftSignature.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/items/ItemRiftSignature.java @@ -70,41 +70,37 @@ public class ItemRiftSignature extends Item int orientation = MathHelper.floor_double(((player.rotationYaw + 180.0F) * 4.0F / 360.0F) - 0.5D) & 3; if (source != null) { - //The link was used before and already has an endpoint stored. Create links connecting the two endpoints. + // The link was used before and already has an endpoint stored. + // Create links connecting the two endpoints. NewDimData sourceDimension = PocketManager.getDimensionData(source.getDimension()); NewDimData destinationDimension = PocketManager.getDimensionData(world); DimLink link = sourceDimension.createLink(source.getX(), source.getY(), source.getZ(), LinkType.NORMAL,source.getOrientation()); DimLink reverse = destinationDimension.createLink(x, adjustedY, z, LinkType.NORMAL,orientation); + destinationDimension.setLinkDestination(link, x, adjustedY, z); sourceDimension.setLinkDestination(reverse, source.getX(), source.getY(), source.getZ()); - //Try placing a rift at the destination point - if (!mod_pocketDim.blockRift.isBlockImmune(world, x, adjustedY, z)) - { - world.setBlock(x, adjustedY, z, mod_pocketDim.blockRift.blockID); - } + // Try placing a rift at the destination point + mod_pocketDim.blockRift.tryPlacingRift(world, x, adjustedY, z); - //Try placing a rift at the source point, but check if its world is loaded first + // Try placing a rift at the source point + // We don't need to check if sourceWorld is null - that's already handled. World sourceWorld = DimensionManager.getWorld(sourceDimension.id()); - if (sourceWorld != null && - !mod_pocketDim.blockRift.isBlockImmune(sourceWorld, source.getX(), source.getY(), source.getZ())) - { - sourceWorld.setBlock(source.getX(), source.getY(), source.getZ(), mod_pocketDim.blockRift.blockID); - } + mod_pocketDim.blockRift.tryPlacingRift(sourceWorld, source.getX(), source.getY(), source.getZ()); if (!player.capabilities.isCreativeMode) { stack.stackSize--; } clearSource(stack); - mod_pocketDim.sendChat(player,("Rift Created")); - world.playSoundAtEntity(player,mod_pocketDim.modid+":riftEnd", 0.6f, 1); + mod_pocketDim.sendChat(player, "Rift Created"); + world.playSoundAtEntity(player, mod_pocketDim.modid + ":riftEnd", 0.6f, 1); } else { //The link signature has not been used. Store its current target as the first location. - setSource(stack, x, adjustedY, z,orientation, PocketManager.getDimensionData(world)); + setSource(stack, x, adjustedY, z, orientation, PocketManager.createDimensionData(world)); mod_pocketDim.sendChat(player,("Location Stored in Rift Signature")); world.playSoundAtEntity(player,mod_pocketDim.modid+":riftStart", 0.6f, 1); } diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/items/ItemStabilizedRiftSignature.java b/src/main/java/StevenDimDoors/mod_pocketDim/items/ItemStabilizedRiftSignature.java index f53acd56..f97bb8c0 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/items/ItemStabilizedRiftSignature.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/items/ItemStabilizedRiftSignature.java @@ -53,7 +53,7 @@ public class ItemStabilizedRiftSignature extends ItemRiftSignature // Yes, it's initialized. NewDimData sourceDimension = PocketManager.getDimensionData(source.getDimension()); - NewDimData destinationDimension = PocketManager.getDimensionData(world); + NewDimData destinationDimension = PocketManager.createDimensionData(world); DimLink reverse = destinationDimension.getLink(x, adjustedY, z); DimLink link; @@ -90,28 +90,23 @@ public class ItemStabilizedRiftSignature extends ItemRiftSignature sourceDimension.setLinkDestination(reverse, source.getX(), source.getY(), source.getZ()); // Try placing a rift at the destination point - if (!mod_pocketDim.blockRift.isBlockImmune(world, x, adjustedY, z)) - { - world.setBlock(x, adjustedY, z, mod_pocketDim.blockRift.blockID); - } + mod_pocketDim.blockRift.tryPlacingRift(world, x, adjustedY, z); } - - // Try placing a rift at the source point, but check if its world is loaded first + + // Try placing a rift at the source point + // We don't need to check if sourceWorld is null - that's already handled. World sourceWorld = DimensionManager.getWorld(sourceDimension.id()); - if (sourceWorld != null && - !mod_pocketDim.blockRift.isBlockImmune(sourceWorld, source.getX(), source.getY(), source.getZ())) - { - sourceWorld.setBlock(source.getX(), source.getY(), source.getZ(), mod_pocketDim.blockRift.blockID); - } + + mod_pocketDim.blockRift.tryPlacingRift(sourceWorld, source.getX(), source.getY(), source.getZ()); mod_pocketDim.sendChat(player, "Rift Created"); world.playSoundAtEntity(player, "mods.DimDoors.sfx.riftEnd", 0.6f, 1); } else { // The link signature has not been used. Store its current target as the first location. - setSource(stack, x, adjustedY, z, orientation, PocketManager.getDimensionData(world)); - mod_pocketDim.sendChat(player,"Location Stored in Stabilized Rift Signature"); - world.playSoundAtEntity(player,"mods.DimDoors.sfx.riftStart", 0.6f, 1); + setSource(stack, x, adjustedY, z, orientation, PocketManager.createDimensionData(world)); + mod_pocketDim.sendChat(player, "Location Stored in Stabilized Rift Signature"); + world.playSoundAtEntity(player, "mods.DimDoors.sfx.riftStart", 0.6f, 1); } return true; } @@ -134,7 +129,7 @@ public class ItemStabilizedRiftSignature extends ItemRiftSignature if (source != null) { NewDimData sourceDimension = PocketManager.getDimensionData(source.getDimension()); - NewDimData destinationDimension = PocketManager.getDimensionData(world); + NewDimData destinationDimension = PocketManager.createDimensionData(world); DimLink reverse = destinationDimension.getLink(x, adjustedY, z); DimLink link; @@ -147,14 +142,11 @@ public class ItemStabilizedRiftSignature extends ItemRiftSignature // Only the source-to-destination link is needed. link = sourceDimension.createLink(source.getX(), source.getY(), source.getZ(), LinkType.NORMAL, source.getOrientation()); destinationDimension.setLinkDestination(link, x, adjustedY, z); - - // Try placing a rift at the source point, but check if its world is loaded first + + // Try placing a rift at the source point + // We don't need to check if sourceWorld is null - that's already handled. World sourceWorld = DimensionManager.getWorld(sourceDimension.id()); - if (sourceWorld != null && - !mod_pocketDim.blockRift.isBlockImmune(sourceWorld, source.getX(), source.getY(), source.getZ())) - { - sourceWorld.setBlock(source.getX(), source.getY(), source.getZ(), mod_pocketDim.blockRift.blockID); - } + mod_pocketDim.blockRift.tryPlacingRift(sourceWorld, source.getX(), source.getY(), source.getZ()); // This call doesn't seem to be working... world.playSoundEffect(x + 0.5, adjustedY + 0.5, z + 0.5, "mods.DimDoors.sfx.riftEnd", 0.6f, 1); diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/items/itemRiftRemover.java b/src/main/java/StevenDimDoors/mod_pocketDim/items/itemRiftRemover.java index c95b4725..e1ecef90 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/items/itemRiftRemover.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/items/itemRiftRemover.java @@ -54,7 +54,7 @@ public class itemRiftRemover extends Item int hx = hit.blockX; int hy = hit.blockY; int hz = hit.blockZ; - NewDimData dimension = PocketManager.getDimensionData(world); + NewDimData dimension = PocketManager.createDimensionData(world); DimLink link = dimension.getLink(hx, hy, hz); if (world.getBlockId(hx, hy, hz) == mod_pocketDim.blockRift.blockID && link != null && player.canPlayerEdit(hx, hy, hz, hit.sideHit, stack)) @@ -85,7 +85,7 @@ public class itemRiftRemover extends Item y = hit.blockY; z = hit.blockZ; - NewDimData dimension = PocketManager.getDimensionData(world); + NewDimData dimension = PocketManager.createDimensionData(world); DimLink link = dimension.getLink(x, y, z); if (world.getBlockId(x, y, z) == mod_pocketDim.blockRift.blockID && link != null && player.canPlayerEdit(x, y, z, side, stack)) diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/mod_pocketDim.java b/src/main/java/StevenDimDoors/mod_pocketDim/mod_pocketDim.java index f3742cce..c22b4c28 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/mod_pocketDim.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/mod_pocketDim.java @@ -31,7 +31,6 @@ import StevenDimDoors.mod_pocketDim.blocks.WarpDoor; import StevenDimDoors.mod_pocketDim.commands.CommandCreateDungeonRift; import StevenDimDoors.mod_pocketDim.commands.CommandCreatePocket; import StevenDimDoors.mod_pocketDim.commands.CommandCreateRandomRift; -import StevenDimDoors.mod_pocketDim.commands.CommandDeleteAllLinks; import StevenDimDoors.mod_pocketDim.commands.CommandDeleteRifts; import StevenDimDoors.mod_pocketDim.commands.CommandExportDungeon; import StevenDimDoors.mod_pocketDim.commands.CommandListDungeons; @@ -57,12 +56,11 @@ import StevenDimDoors.mod_pocketDim.items.ItemUnstableDoor; import StevenDimDoors.mod_pocketDim.items.ItemWarpDoor; import StevenDimDoors.mod_pocketDim.items.ItemWorldThread; import StevenDimDoors.mod_pocketDim.items.itemRiftRemover; -import StevenDimDoors.mod_pocketDim.ticking.CommonTickHandler; import StevenDimDoors.mod_pocketDim.ticking.CustomLimboPopulator; -import StevenDimDoors.mod_pocketDim.ticking.FastRiftRegenerator; -import StevenDimDoors.mod_pocketDim.ticking.LimboDecay; +import StevenDimDoors.mod_pocketDim.ticking.LimboDecayScheduler; import StevenDimDoors.mod_pocketDim.ticking.MobMonolith; import StevenDimDoors.mod_pocketDim.ticking.RiftRegenerator; +import StevenDimDoors.mod_pocketDim.ticking.ServerTickHandler; import StevenDimDoors.mod_pocketDim.tileentities.TileEntityDimDoor; import StevenDimDoors.mod_pocketDim.tileentities.TileEntityDimDoorGold; import StevenDimDoors.mod_pocketDim.tileentities.TileEntityRift; @@ -70,12 +68,12 @@ import StevenDimDoors.mod_pocketDim.tileentities.TileEntityTransTrapdoor; import StevenDimDoors.mod_pocketDim.world.BiomeGenLimbo; import StevenDimDoors.mod_pocketDim.world.BiomeGenPocket; import StevenDimDoors.mod_pocketDim.world.DDBiomeGenBase; +import StevenDimDoors.mod_pocketDim.world.LimboDecay; import StevenDimDoors.mod_pocketDim.world.LimboProvider; import StevenDimDoors.mod_pocketDim.world.PersonalPocketProvider; import StevenDimDoors.mod_pocketDim.world.PocketProvider; import StevenDimDoors.mod_pocketDim.world.gateways.GatewayGenerator; import StevenDimDoors.mod_pocketDimClient.ClientPacketHandler; -import StevenDimDoors.mod_pocketDimClient.ClientTickHandler; import cpw.mods.fml.common.Mod; import cpw.mods.fml.common.Mod.EventHandler; import cpw.mods.fml.common.Mod.Instance; @@ -103,7 +101,7 @@ serverPacketHandlerSpec = @SidedPacketHandler(channels = {PacketConstants.CHANNEL_NAME}, packetHandler = ServerPacketHandler.class)) public class mod_pocketDim { - public static final String version = "1.6.4-R2.2.3"; + public static final String version = "@VERSION@"; public static final String modid = "dimdoors"; //TODO need a place to stick all these constants @@ -113,8 +111,8 @@ public class mod_pocketDim @SidedProxy(clientSide = "StevenDimDoors.mod_pocketDimClient.ClientProxy", serverSide = "StevenDimDoors.mod_pocketDim.CommonProxy") public static CommonProxy proxy; - @Instance("PocketDimensions") - public static mod_pocketDim instance = new mod_pocketDim(); + @Instance(mod_pocketDim.modid) + public static mod_pocketDim instance; public static Block quartzDoor; public static Block personalDimDoor; @@ -154,9 +152,13 @@ public class mod_pocketDim public static DDProperties properties; public static DDWorldProperties worldProperties; public static CustomLimboPopulator spawner; //Added this field temporarily. Will be refactored out later. - public static FastRiftRegenerator fastRiftRegenerator; + public static RiftRegenerator riftRegenerator; public static GatewayGenerator gatewayGenerator; public static DeathTracker deathTracker; + private static ServerTickHandler serverTickHandler; + private static LimboDecayScheduler limboDecayScheduler; + private static LimboDecay limboDecay; + private static EventHookContainer hooks; //TODO this is a temporary workaround for saving data private String currrentSaveRootDirectory; @@ -179,14 +181,13 @@ public class mod_pocketDim @EventHandler public void onPreInitialization(FMLPreInitializationEvent event) { - instance = this; //This should be the FIRST thing that gets done. String path = event.getSuggestedConfigurationFile().getAbsolutePath().replace(modid, "DimDoors"); properties = DDProperties.initialize(new File(path)); //Now do other stuff - EventHookContainer hooks = new EventHookContainer(properties); + hooks = new EventHookContainer(properties); MinecraftForge.EVENT_BUS.register(hooks); MinecraftForge.TERRAIN_GEN_BUS.register(hooks); } @@ -194,17 +195,14 @@ public class mod_pocketDim @EventHandler public void onInitialization(FMLInitializationEvent event) { - CommonTickHandler commonTickHandler = new CommonTickHandler(); - TickRegistry.registerTickHandler(new ClientTickHandler(), Side.CLIENT); - TickRegistry.registerTickHandler(commonTickHandler, Side.SERVER); - - //MonolithSpawner should be initialized before any provider instances are created - //Register the other regular tick receivers as well - spawner = new CustomLimboPopulator(commonTickHandler, properties); - new RiftRegenerator(commonTickHandler); //No need to store the reference - LimboDecay decay = new LimboDecay(commonTickHandler, properties); - fastRiftRegenerator = new FastRiftRegenerator(commonTickHandler); + // Initialize ServerTickHandler instance + serverTickHandler = new ServerTickHandler(); + TickRegistry.registerTickHandler(serverTickHandler, Side.SERVER); + + // Initialize LimboDecay instance: required for BlockLimbo + limboDecay = new LimboDecay(properties); + // Initialize blocks and items transientDoor = new TransientDoor(properties.TransientDoorID, Material.iron, properties).setHardness(1.0F) .setUnlocalizedName("transientDoor"); goldenDimensionalDoor = new BlockGoldDimDoor(properties.GoldenDimensionalDoorID, Material.iron, properties).setHardness(1.0F) .setUnlocalizedName("dimDoorGold"); @@ -216,7 +214,7 @@ public class mod_pocketDim blockDimWallPerm = (new BlockDimWallPerm(properties.PermaFabricBlockID, 0, Material.iron)).setLightValue(1.0F).setBlockUnbreakable().setResistance(6000000.0F).setUnlocalizedName("blockDimWallPerm"); warpDoor = new WarpDoor(properties.WarpDoorID, Material.wood, properties).setHardness(1.0F) .setUnlocalizedName("dimDoorWarp"); blockRift = (BlockRift) (new BlockRift(properties.RiftBlockID, 0, Material.air, properties).setHardness(1.0F) .setUnlocalizedName("rift")); - blockLimbo = new BlockLimbo(properties.LimboBlockID, 15, Material.iron, properties.LimboDimensionID, decay).setHardness(.2F).setUnlocalizedName("BlockLimbo").setLightValue(.0F); + blockLimbo = new BlockLimbo(properties.LimboBlockID, 15, Material.iron, properties.LimboDimensionID, limboDecay).setHardness(.2F).setUnlocalizedName("BlockLimbo").setLightValue(.0F); unstableDoor = (new UnstableDoor(properties.UnstableDoorID, Material.iron, properties).setHardness(.2F).setUnlocalizedName("chaosDoor").setLightValue(.0F) ); dimensionalDoor = (DimensionalDoor) (new DimensionalDoor(properties.DimensionalDoorID, Material.iron, properties).setHardness(1.0F).setResistance(2000.0F) .setUnlocalizedName("dimDoor")); transTrapdoor = (TransTrapdoor) (new TransTrapdoor(properties.TransTrapdoorID, Material.wood).setHardness(1.0F) .setUnlocalizedName("dimHatch")); @@ -347,7 +345,14 @@ public class mod_pocketDim deathTracker.writeToFile(); deathTracker = null; worldProperties = null; - this.currrentSaveRootDirectory=null; + currrentSaveRootDirectory = null; + + // Unregister all tick receivers from serverTickHandler to avoid leaking + // scheduled tasks between single-player game sessions + serverTickHandler.unregisterReceivers(); + spawner = null; + riftRegenerator = null; + limboDecayScheduler = null; } catch (Exception e) { @@ -362,9 +367,17 @@ public class mod_pocketDim // Load the config file that's specific to this world worldProperties = new DDWorldProperties(new File(currrentSaveRootDirectory + "/DimensionalDoors/DimDoorsWorld.cfg")); - + // Initialize a new DeathTracker deathTracker = new DeathTracker(currrentSaveRootDirectory + "/DimensionalDoors/data/deaths.txt"); + + // Register regular tick receivers + // CustomLimboPopulator should be initialized before any provider instances are created + spawner = new CustomLimboPopulator(serverTickHandler, properties); + riftRegenerator = new RiftRegenerator(serverTickHandler, blockRift); + limboDecayScheduler = new LimboDecayScheduler(serverTickHandler, limboDecay); + + hooks.setSessionFields(worldProperties, riftRegenerator); } @EventHandler @@ -375,19 +388,14 @@ public class mod_pocketDim event.registerServerCommand( CommandCreateDungeonRift.instance() ); event.registerServerCommand( CommandListDungeons.instance() ); event.registerServerCommand( CommandCreateRandomRift.instance() ); - event.registerServerCommand( CommandDeleteAllLinks.instance() ); - //CommandDeleteDimensionData.instance().register(event); event.registerServerCommand( CommandDeleteRifts.instance() ); event.registerServerCommand( CommandExportDungeon.instance() ); - //CommandPrintDimensionData.instance().register(event); - //CommandPruneDimensions.instance().register(event); event.registerServerCommand( CommandCreatePocket.instance() ); event.registerServerCommand( CommandTeleportPlayer.instance() ); - try { - ChunkLoaderHelper.loadChunkForcedWorlds(event); + ChunkLoaderHelper.loadForcedChunkWorlds(event); } catch (Exception e) { diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/saving/DDSaveHandler.java b/src/main/java/StevenDimDoors/mod_pocketDim/saving/DDSaveHandler.java index 9803f8b7..0d9cd8ad 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/saving/DDSaveHandler.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/saving/DDSaveHandler.java @@ -210,12 +210,13 @@ public class DDSaveHandler { NewDimData data = PocketManager.getDimensionData(packedLink.source.getDimension()); LinkType linkType = LinkType.getLinkTypeFromIndex(packedLink.tail.linkType); + DimLink link = data.createLink(packedLink.source, linkType, packedLink.orientation, packedLink.lock); Point4D destination = packedLink.tail.destination; if(destination!=null) { - PocketManager.getDimensionData(destination.getDimension()).setLinkDestination(link, destination.getX(),destination.getY(),destination.getZ()); + PocketManager.createDimensionDataDangerously(destination.getDimension()).setLinkDestination(link, destination.getX(),destination.getY(),destination.getZ()); } unpackedLinks.add(packedLink); } @@ -227,7 +228,7 @@ public class DDSaveHandler { for(PackedLinkData packedLink : linksToUnpack) { - NewDimData data = PocketManager.getDimensionData(packedLink.source.getDimension()); + NewDimData data = PocketManager.createDimensionDataDangerously(packedLink.source.getDimension()); if(data.getLink(packedLink.parent)!=null) { data.createChildLink(packedLink.source, data.getLink(packedLink.parent), packedLink.lock); diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/ticking/CustomLimboPopulator.java b/src/main/java/StevenDimDoors/mod_pocketDim/ticking/CustomLimboPopulator.java index ddc018cf..231eec2a 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/ticking/CustomLimboPopulator.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/ticking/CustomLimboPopulator.java @@ -30,7 +30,7 @@ public class CustomLimboPopulator implements IRegularTickReceiver { { this.properties = properties; this.locations = new ConcurrentLinkedQueue(); - sender.registerForTicking(this, MONOLITH_SPAWNING_INTERVAL, false); + sender.registerReceiver(this, MONOLITH_SPAWNING_INTERVAL, false); } @Override diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/ticking/FastRiftRegenerator.java b/src/main/java/StevenDimDoors/mod_pocketDim/ticking/FastRiftRegenerator.java deleted file mode 100644 index b0f203ff..00000000 --- a/src/main/java/StevenDimDoors/mod_pocketDim/ticking/FastRiftRegenerator.java +++ /dev/null @@ -1,53 +0,0 @@ -package StevenDimDoors.mod_pocketDim.ticking; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Random; - -import net.minecraft.world.World; -import net.minecraftforge.common.DimensionManager; -import StevenDimDoors.mod_pocketDim.mod_pocketDim; -import StevenDimDoors.mod_pocketDim.core.PocketManager; -import StevenDimDoors.mod_pocketDim.util.Point4D; - -public class FastRiftRegenerator implements IRegularTickReceiver { - - private static final int RIFT_REGENERATION_INTERVAL = 10; //Regenerate scheduled rifts every 10 ticks - private static Random random = new Random(); - - private ArrayList locationsToRegen = new ArrayList(); - - public FastRiftRegenerator(IRegularTickSender sender) - { - sender.registerForTicking(this, RIFT_REGENERATION_INTERVAL, false); - } - - @Override - public void notifyTick() - { - regenerateScheduledRifts(); - } - - public void regenerateScheduledRifts() - { - if (!locationsToRegen.isEmpty()) - { - List loadedWorlds = (List) Arrays.asList(DimensionManager.getIDs()); - for (Point4D point: locationsToRegen) - { - if (loadedWorlds.contains(point.getDimension()) && PocketManager.getLink(point) != null) - { - World world = DimensionManager.getWorld(point.getDimension()); - mod_pocketDim.blockRift.regenerateRift(world, point.getX(), point.getY(), point.getZ(), random); - } - } - locationsToRegen.clear(); - } - } - - public void registerRiftForRegen(int x, int y, int z, int dimID) - { - this.locationsToRegen.add(new Point4D(x, y, z, dimID)); - } -} diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/ticking/IRegularTickSender.java b/src/main/java/StevenDimDoors/mod_pocketDim/ticking/IRegularTickSender.java index 6ed2dcaf..7b5502c4 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/ticking/IRegularTickSender.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/ticking/IRegularTickSender.java @@ -3,6 +3,7 @@ package StevenDimDoors.mod_pocketDim.ticking; public interface IRegularTickSender { - public void registerForTicking(IRegularTickReceiver receiver, int interval, boolean onTickStart); + public void registerReceiver(IRegularTickReceiver receiver, int interval, boolean onTickStart); + public void unregisterReceivers(); } diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/ticking/LimboDecayScheduler.java b/src/main/java/StevenDimDoors/mod_pocketDim/ticking/LimboDecayScheduler.java new file mode 100644 index 00000000..73f275cd --- /dev/null +++ b/src/main/java/StevenDimDoors/mod_pocketDim/ticking/LimboDecayScheduler.java @@ -0,0 +1,28 @@ +package StevenDimDoors.mod_pocketDim.ticking; + +import StevenDimDoors.mod_pocketDim.world.LimboDecay; + +/** + * Handles scheduling of periodic fast Limbo decay operations. + */ +public class LimboDecayScheduler implements IRegularTickReceiver { + + private static final int LIMBO_DECAY_INTERVAL = 10; //Apply fast decay every 10 ticks + + private LimboDecay decay; + + public LimboDecayScheduler(IRegularTickSender tickSender, LimboDecay decay) + { + this.decay = decay; + tickSender.registerReceiver(this, LIMBO_DECAY_INTERVAL, false); + } + + /** + * Applies fast Limbo decay periodically. + */ + @Override + public void notifyTick() + { + decay.applyRandomFastDecay(); + } +} diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/ticking/MobMonolith.java b/src/main/java/StevenDimDoors/mod_pocketDim/ticking/MobMonolith.java index f54f5159..279c1234 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/ticking/MobMonolith.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/ticking/MobMonolith.java @@ -21,9 +21,9 @@ import StevenDimDoors.mod_pocketDim.world.PocketProvider; public class MobMonolith extends EntityFlying implements IMob { - private static final short MAX_AGGRO = 200; - private static final short MAX_AGGRO_CAP = 80; - private static final short MIN_AGGRO_CAP = 20; + private static final short MAX_AGGRO = 250; + private static final short MAX_AGGRO_CAP = 100; + private static final short MIN_AGGRO_CAP = 25; private static final int MAX_TEXTURE_STATE = 18; private static final int MAX_SOUND_COOLDOWN = 200; private static final int MAX_AGGRO_RANGE = 35; diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/ticking/RiftRegenerator.java b/src/main/java/StevenDimDoors/mod_pocketDim/ticking/RiftRegenerator.java index 192669cc..f23c38c3 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/ticking/RiftRegenerator.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/ticking/RiftRegenerator.java @@ -1,56 +1,121 @@ package StevenDimDoors.mod_pocketDim.ticking; -import java.util.Arrays; -import java.util.List; +import java.util.PriorityQueue; import java.util.Random; +import net.minecraft.util.MathHelper; import net.minecraft.world.World; import net.minecraftforge.common.DimensionManager; -import StevenDimDoors.mod_pocketDim.mod_pocketDim; +import StevenDimDoors.mod_pocketDim.blocks.BlockRift; import StevenDimDoors.mod_pocketDim.core.DimLink; -import StevenDimDoors.mod_pocketDim.core.NewDimData; import StevenDimDoors.mod_pocketDim.core.PocketManager; import StevenDimDoors.mod_pocketDim.util.Point4D; public class RiftRegenerator implements IRegularTickReceiver { - private static final int RIFT_REGENERATION_INTERVAL = 200; //Regenerate random rifts every 200 ticks - private static final int RIFTS_REGENERATED_PER_DIMENSION = 5; + // Ranges of regeneration delays, in seconds + private static final int MIN_FAST_DELAY = 1; + private static final int MAX_FAST_DELAY = 3; + private static final int MIN_SLOW_DELAY = 5; + private static final int MAX_SLOW_DELAY = 15; + private static final int MIN_RESCHEDULE_DELAY = 4 * 60; + private static final int MAX_RESCHEDULE_DELAY = 6 * 60; + + private static final int TICKS_PER_SECOND = 20; + private static final int RIFT_REGENERATION_INTERVAL = 1; // Check the regeneration queue every tick private static Random random = new Random(); - public RiftRegenerator(IRegularTickSender sender) + private long tickCount = 0; + private PriorityQueue ticketQueue; + private BlockRift blockRift; + + public RiftRegenerator(IRegularTickSender sender, BlockRift blockRift) { - sender.registerForTicking(this, RIFT_REGENERATION_INTERVAL, false); + this.ticketQueue = new PriorityQueue(); + this.blockRift = blockRift; + sender.registerReceiver(this, RIFT_REGENERATION_INTERVAL, false); } @Override public void notifyTick() { - regenerateRiftsInLoadedWorlds(); + processTicketQueue(); + tickCount++; } - private static void regenerateRiftsInLoadedWorlds() + public void scheduleSlowRegeneration(DimLink link) { - // Regenerate rifts that have been replaced (not permanently removed) by players - // Only do this in dimensions that are currently loaded - List loadedWorlds = Arrays.asList(DimensionManager.getIDs()); - for (Integer dimensionID : loadedWorlds) - { - NewDimData dimension = PocketManager.getDimensionData(dimensionID); - if (dimension.linkCount() > 0) - { - World world = DimensionManager.getWorld(dimension.id()); - - if (world != null) - { - for (int count = 0; count < RIFTS_REGENERATED_PER_DIMENSION; count++) - { - DimLink link = dimension.getRandomLink(); - Point4D source = link.source(); - mod_pocketDim.blockRift.regenerateRift(world, source.getX(), source.getY(), source.getZ(), random); - } - } - } - } + scheduleRegeneration(link, MIN_SLOW_DELAY, MAX_SLOW_DELAY); } + + public void scheduleSlowRegeneration(int x, int y, int z, World world) + { + scheduleRegeneration(PocketManager.getLink(x, y, z, world), MIN_SLOW_DELAY, MAX_SLOW_DELAY); + } + + public void scheduleFastRegeneration(int x, int y, int z, World world) + { + scheduleRegeneration(PocketManager.getLink(x, y, z, world), MIN_FAST_DELAY, MAX_FAST_DELAY); + } + + private void scheduleRegeneration(DimLink link, int minDelay, int maxDelay) + { + if (link != null) + { + int tickDelay = MathHelper.getRandomIntegerInRange(random, minDelay * TICKS_PER_SECOND, maxDelay * TICKS_PER_SECOND); + ticketQueue.add(new RiftTicket(link.source(), tickCount + tickDelay)); + } + } + + private void processTicketQueue() + { + RiftTicket ticket; + while (!ticketQueue.isEmpty() && ticketQueue.peek().timestamp() <= tickCount) + { + ticket = ticketQueue.remove(); + regenerateRift(ticket.location()); + } + } + + private void regenerateRift(Point4D location) + { + int x = location.getX(); + int y = location.getY(); + int z = location.getZ(); + + // Try to regenerate a rift, or possibly reschedule its regeneration. + // The world for the given location must be loaded. + World world = DimensionManager.getWorld(location.getDimension()); + if (world == null) + return; + + // There must be a link at the given location. + DimLink link = PocketManager.getLink(location); + if (link == null) + return; + + // The chunk at the given location must be loaded. + // Note: ChunkProviderServer.chunkExists() returns whether a chunk is + // loaded, not whether it has already been created. + if (!world.getChunkProvider().chunkExists(x >> 4, z >> 4)) + return; + + // If the location is occupied by an immune DD block, then don't regenerate. + if (blockRift.isModBlockImmune(world, x, y, z)) + return; + + // If the location is occupied by an immune block, then reschedule. + if (blockRift.isBlockImmune(world, x, y, z)) + { + scheduleRegeneration(link, MIN_RESCHEDULE_DELAY, MAX_RESCHEDULE_DELAY); + } + else + { + // All of the necessary conditions have been met. Restore the rift! + int blockID = world.getBlockId(x, y, z); + if (world.setBlock(x, y, z, blockRift.blockID)) + blockRift.dropWorldThread(blockID, world, x, y, z, random); + } + } + } diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/ticking/RiftTicket.java b/src/main/java/StevenDimDoors/mod_pocketDim/ticking/RiftTicket.java new file mode 100644 index 00000000..d618a517 --- /dev/null +++ b/src/main/java/StevenDimDoors/mod_pocketDim/ticking/RiftTicket.java @@ -0,0 +1,40 @@ +package StevenDimDoors.mod_pocketDim.ticking; + +import StevenDimDoors.mod_pocketDim.util.Point4D; + +public class RiftTicket implements Comparable { + + private long timestamp; + private Point4D location; + + public RiftTicket(Point4D location, long timestamp) + { + this.timestamp = timestamp; + this.location = location; + } + + @Override + public int compareTo(RiftTicket other) + { + if (this.timestamp < other.timestamp) + { + return -1; + } + else if (this.timestamp > other.timestamp) + { + return 1; + } + return 0; + } + + public long timestamp() + { + return timestamp; + } + + public Point4D location() + { + return location; + } + +} diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/ticking/CommonTickHandler.java b/src/main/java/StevenDimDoors/mod_pocketDim/ticking/ServerTickHandler.java similarity index 85% rename from src/main/java/StevenDimDoors/mod_pocketDim/ticking/CommonTickHandler.java rename to src/main/java/StevenDimDoors/mod_pocketDim/ticking/ServerTickHandler.java index 26057b48..58da365f 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/ticking/CommonTickHandler.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/ticking/ServerTickHandler.java @@ -7,25 +7,30 @@ import StevenDimDoors.mod_pocketDim.core.DDTeleporter; import cpw.mods.fml.common.ITickHandler; import cpw.mods.fml.common.TickType; -public class CommonTickHandler implements ITickHandler, IRegularTickSender +public class ServerTickHandler implements ITickHandler, IRegularTickSender { - private static final String PROFILING_LABEL = "Dimensional Doors: Common Tick"; + private static final String PROFILING_LABEL = "Dimensional Doors: Server Tick"; private int tickCount = 0; private ArrayList receivers; - - public CommonTickHandler() + public ServerTickHandler() { this.receivers = new ArrayList(); } @Override - public void registerForTicking(IRegularTickReceiver receiver, int interval, boolean onTickStart) + public void registerReceiver(IRegularTickReceiver receiver, int interval, boolean onTickStart) { RegularTickReceiverInfo info = new RegularTickReceiverInfo(receiver, interval, onTickStart); receivers.add(info); } + + @Override + public void unregisterReceivers() + { + receivers.clear(); + } @Override public void tickStart(EnumSet type, Object... tickData) diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/tileentities/TileEntityDimDoor.java b/src/main/java/StevenDimDoors/mod_pocketDim/tileentities/TileEntityDimDoor.java index e566f63b..57c10a8b 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/tileentities/TileEntityDimDoor.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/tileentities/TileEntityDimDoor.java @@ -1,11 +1,14 @@ package StevenDimDoors.mod_pocketDim.tileentities; import java.util.Random; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.packet.Packet; import StevenDimDoors.mod_pocketDim.ServerPacketHandler; import StevenDimDoors.mod_pocketDim.mod_pocketDim; -import StevenDimDoors.mod_pocketDim.blocks.IDimDoor; -import StevenDimDoors.mod_pocketDim.core.NewDimData; +import StevenDimDoors.mod_pocketDim.core.DimLink; import StevenDimDoors.mod_pocketDim.core.PocketManager; + import StevenDimDoors.mod_pocketDim.watcher.ClientLinkData; import net.minecraft.block.Block; import net.minecraft.nbt.NBTTagCompound; @@ -14,6 +17,8 @@ import net.minecraft.network.packet.Packet130UpdateSign; import net.minecraft.network.packet.Packet250CustomPayload; import net.minecraft.tileentity.TileEntity; + + public class TileEntityDimDoor extends DDTileEntityBase { public boolean openOrClosed; @@ -38,19 +43,6 @@ public class TileEntityDimDoor extends DDTileEntityBase } return null; } - - public void invalidate() - { - this.tileEntityInvalid = true; - - if(this.worldObj.getBlockId(xCoord, yCoord, zCoord)==0&&!this.worldObj.isRemote) - { - if(PocketManager.getLink(xCoord, yCoord, zCoord, worldObj)!=null) - { - mod_pocketDim.instance.fastRiftRegenerator.registerRiftForRegen(xCoord, yCoord, zCoord, this.worldObj.provider.dimensionId); - } - } - } @Override public void readFromNBT(NBTTagCompound nbt) @@ -75,7 +67,7 @@ public class TileEntityDimDoor extends DDTileEntityBase public void writeToNBT(NBTTagCompound nbt) { super.writeToNBT(nbt); - + nbt.setBoolean("openOrClosed", this.openOrClosed); nbt.setBoolean("hasExit", this.hasExit); nbt.setInteger("orientation", this.orientation); diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/tileentities/TileEntityDimDoorGold.java b/src/main/java/StevenDimDoors/mod_pocketDim/tileentities/TileEntityDimDoorGold.java index 7dc1c64c..6b9696e6 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/tileentities/TileEntityDimDoorGold.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/tileentities/TileEntityDimDoorGold.java @@ -1,85 +1,93 @@ package StevenDimDoors.mod_pocketDim.tileentities; -import net.minecraft.world.ChunkCoordIntPair; import net.minecraftforge.common.ForgeChunkManager; import net.minecraftforge.common.ForgeChunkManager.Ticket; -import net.minecraftforge.common.ForgeChunkManager.Type; import StevenDimDoors.mod_pocketDim.IChunkLoader; -import StevenDimDoors.mod_pocketDim.mod_pocketDim; +import StevenDimDoors.mod_pocketDim.core.NewDimData; import StevenDimDoors.mod_pocketDim.core.PocketManager; -import StevenDimDoors.mod_pocketDim.util.Point4D; +import StevenDimDoors.mod_pocketDim.helpers.ChunkLoaderHelper; import StevenDimDoors.mod_pocketDim.world.PocketBuilder; public class TileEntityDimDoorGold extends TileEntityDimDoor implements IChunkLoader { private Ticket chunkTicket; + private boolean initialized = false; @Override public boolean canUpdate() { - return true; + return !initialized; + } + + @Override + public boolean isInitialized() + { + return initialized; } @Override public void updateEntity() - { // every tick? - if (PocketManager.getDimensionData(this.worldObj) != null && - PocketManager.getDimensionData(this.worldObj).isPocketDimension() && - !this.worldObj.isRemote) - { - if(PocketManager.getLink(this.xCoord,this.yCoord,this.zCoord,this.worldObj)==null) + { + if (!initialized) + { + initialize(null); + } + } + + @Override + public void initialize(Ticket ticket) + { + initialized = true; + chunkTicket = ticket; + + // Only do anything if this function is running on the server side + // NOTE: We don't have to check whether this block is the upper door + // block or the lower one because only one of them should have a + // link associated with it. + if (!worldObj.isRemote) + { + NewDimData dimension = PocketManager.createDimensionData(worldObj); + + // Check whether a ticket has already been assigned to this door + if (chunkTicket == null) { - return; - } - if (this.chunkTicket == null) - { - chunkTicket = ForgeChunkManager.requestTicket(mod_pocketDim.instance, worldObj, Type.NORMAL); - if(chunkTicket == null) + // No ticket yet. + // Check if this area should be loaded and request a new ticket. + if (isValidChunkLoaderSetup(dimension)) { - return; + chunkTicket = ChunkLoaderHelper.createTicket(xCoord, yCoord, zCoord, worldObj); } - chunkTicket.getModData().setInteger("goldDimDoorX", xCoord); - chunkTicket.getModData().setInteger("goldDimDoorY", yCoord); - chunkTicket.getModData().setInteger("goldDimDoorZ", zCoord); - forceChunkLoading(chunkTicket,this.xCoord,this.zCoord); + } + else + { + // A ticket has already been provided. + // Check if this area should be loaded. If not, release the ticket. + if (!isValidChunkLoaderSetup(dimension)) + { + ForgeChunkManager.releaseTicket(chunkTicket); + chunkTicket = null; + } + } + + // If chunkTicket isn't null at this point, then this is a valid door setup. + // The last step is to request force loading of the pocket's chunks. + if (chunkTicket != null) + { + ChunkLoaderHelper.forcePocketChunks(dimension, chunkTicket); } } } - - @Override - public void forceChunkLoading(Ticket chunkTicket,int x,int z) + + private boolean isValidChunkLoaderSetup(NewDimData dimension) { - Point4D origin = PocketManager.getDimensionData(this.worldObj).origin(); - int orientation = PocketManager.getDimensionData(this.worldObj).orientation(); + // Check the various conditions that make this a valid door setup. + // 1. The door must be inside the pocket's XZ boundaries, + // to prevent loading of chunks with a distant door + // 2. The dimension must be a pocket dimension + // 3. The door must be linked so that it's clear that it's not a normal door - int xOffset=0; - int zOffset=0; - - switch(orientation) - { - case 0: - xOffset = PocketBuilder.DEFAULT_POCKET_SIZE/2; - break; - case 1: - zOffset = PocketBuilder.DEFAULT_POCKET_SIZE/2; - - break; - case 2: - xOffset = -PocketBuilder.DEFAULT_POCKET_SIZE/2; - - break; - case 3: - zOffset = -PocketBuilder.DEFAULT_POCKET_SIZE/2; - - break; - } - for(int chunkX = -2; chunkX<3;chunkX++) - { - for(int chunkZ = -2; chunkZ<3;chunkZ++) - { - ForgeChunkManager.forceChunk(chunkTicket, new ChunkCoordIntPair((origin.getX()+xOffset >> 4)+chunkX, (origin.getZ()+zOffset >> 4)+chunkZ)); - } - } + return (dimension.isPocketDimension() && dimension.getLink(xCoord, yCoord, zCoord) != null && + PocketBuilder.calculateDefaultBounds(dimension).contains(xCoord, yCoord, zCoord)); } @Override diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/tileentities/TileEntityRift.java b/src/main/java/StevenDimDoors/mod_pocketDim/tileentities/TileEntityRift.java index 251b79e5..db31843f 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/tileentities/TileEntityRift.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/tileentities/TileEntityRift.java @@ -1,6 +1,5 @@ package StevenDimDoors.mod_pocketDim.tileentities; -import java.util.ArrayList; import java.util.List; import java.util.Random; @@ -43,8 +42,7 @@ public class TileEntityRift extends DDTileEntityBase public int yOffset = 0; public int zOffset = 0; public boolean shouldClose = false; - - public DimLink nearestRiftData; + public Point4D nearestRiftLocation = null; public int spawnedEndermenID = 0; public TileEntityRift() @@ -65,20 +63,20 @@ public class TileEntityRift extends DDTileEntityBase } else { - this.invalidate(); + invalidate(); } return; } if (worldObj.getBlockId(xCoord, yCoord, zCoord) != mod_pocketDim.blockRift.blockID) { - this.invalidate(); + invalidate(); return; } // Check if this rift should render white closing particles and // spread the closing effect to other rifts nearby. - if (this.shouldClose) + if (shouldClose) { closeRift(); return; @@ -86,13 +84,13 @@ public class TileEntityRift extends DDTileEntityBase if (updateTimer >= UPDATE_PERIOD) { - this.spawnEndermen(mod_pocketDim.properties); + spawnEndermen(mod_pocketDim.properties); updateTimer = 0; } else if (updateTimer == UPDATE_PERIOD / 2) { - this.calculateParticleOffsets(); - this.spread(mod_pocketDim.properties); + updateNearestRift(); + spread(mod_pocketDim.properties); } updateTimer++; } @@ -137,57 +135,60 @@ public class TileEntityRift extends DDTileEntityBase } } } - - public boolean updateNearestRift() - { - nearestRiftData = PocketManager.getDimensionData(worldObj).findNearestRift(this.worldObj, 5, xCoord, yCoord, zCoord); - return (nearestRiftData != null); - } private void closeRift() { - NewDimData dimension = PocketManager.getDimensionData(worldObj); + NewDimData dimension = PocketManager.createDimensionData(worldObj); if (closeTimer == CLOSING_PERIOD / 2) { - ArrayList riftLinks = dimension.findRiftsInRange(worldObj, 6, xCoord, yCoord, zCoord); - if (riftLinks.size() > 0) + for (DimLink riftLink : dimension.findRiftsInRange(worldObj, 6, xCoord, yCoord, zCoord)) { - for (DimLink riftLink : riftLinks) + Point4D location = riftLink.source(); + TileEntityRift rift = (TileEntityRift) worldObj.getBlockTileEntity(location.getX(), location.getY(), location.getZ()); + if (rift != null && !rift.shouldClose) { - Point4D location = riftLink.source(); - TileEntityRift rift = (TileEntityRift) worldObj.getBlockTileEntity(location.getX(), location.getY(), location.getZ()); - if (rift != null) - { - rift.shouldClose = true; - rift.onInventoryChanged(); - } + rift.shouldClose = true; + rift.onInventoryChanged(); } } } - if (closeTimer >= CLOSING_PERIOD) + if (closeTimer >= CLOSING_PERIOD && !worldObj.isRemote) { - if (!this.worldObj.isRemote) + DimLink link = PocketManager.getLink(this.xCoord, this.yCoord, this.zCoord, worldObj); + if (link != null) { - DimLink link = PocketManager.getLink(this.xCoord, this.yCoord, this.zCoord, worldObj); - if (link != null) - { - dimension.deleteLink(link); - } + dimension.deleteLink(link); } worldObj.setBlockToAir(xCoord, yCoord, zCoord); worldObj.playSound(xCoord + 0.5, yCoord + 0.5, zCoord + 0.5, "mods.DimDoors.sfx.riftClose", 0.7f, 1, false); } closeTimer++; } - - private void calculateParticleOffsets() + + public boolean updateNearestRift() { - if (updateNearestRift()) + Point4D previousNearest = nearestRiftLocation; + DimLink nearestRiftLink = PocketManager.createDimensionData(worldObj).findNearestRift( + worldObj, RIFT_INTERACTION_RANGE, xCoord, yCoord, zCoord); + + nearestRiftLocation = (nearestRiftLink == null) ? null : nearestRiftLink.source(); + + // If the nearest rift location changed, then update particle offsets + if (previousNearest != nearestRiftLocation && + (previousNearest == null || nearestRiftLocation == null || !previousNearest.equals(nearestRiftLocation))) { - Point4D location = nearestRiftData.source(); - this.xOffset = this.xCoord - location.getX(); - this.yOffset = this.yCoord - location.getY(); - this.zOffset = this.zCoord - location.getZ(); + updateParticleOffsets(); + } + return (nearestRiftLocation != null); + } + + private void updateParticleOffsets() + { + if (nearestRiftLocation != null) + { + this.xOffset = this.xCoord - nearestRiftLocation.getX(); + this.yOffset = this.yCoord - nearestRiftLocation.getY(); + this.zOffset = this.zCoord - nearestRiftLocation.getZ(); } else { @@ -221,7 +222,7 @@ public class TileEntityRift extends DDTileEntityBase return; } - NewDimData dimension = PocketManager.getDimensionData(worldObj); + NewDimData dimension = PocketManager.createDimensionData(worldObj); DimLink link = dimension.getLink(xCoord, yCoord, zCoord); if (link.childCount() >= MAX_CHILD_LINKS || countAncestorLinks(link) >= MAX_ANCESTOR_LINKS) diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/tileentities/TileEntityTransTrapdoor.java b/src/main/java/StevenDimDoors/mod_pocketDim/tileentities/TileEntityTransTrapdoor.java index d26b46fd..3df7f6c5 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/tileentities/TileEntityTransTrapdoor.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/tileentities/TileEntityTransTrapdoor.java @@ -1,14 +1,11 @@ package StevenDimDoors.mod_pocketDim.tileentities; import java.util.Random; + import StevenDimDoors.mod_pocketDim.mod_pocketDim; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.tileentity.TileEntity; public class TileEntityTransTrapdoor extends DDTileEntityBase { - public boolean hasRift; - @Override public boolean canUpdate() { diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/watcher/ClientDimData.java b/src/main/java/StevenDimDoors/mod_pocketDim/watcher/ClientDimData.java index 666e28ca..aaf6aef5 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/watcher/ClientDimData.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/watcher/ClientDimData.java @@ -24,7 +24,7 @@ public class ClientDimData { ID = dimension.id(); this.rootID = dimension.root().id(); - this.type = dimension.getDimensionType(); + this.type = dimension.type(); } public void write(DataOutputStream output) throws IOException diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/ticking/LimboDecay.java b/src/main/java/StevenDimDoors/mod_pocketDim/world/LimboDecay.java similarity index 91% rename from src/main/java/StevenDimDoors/mod_pocketDim/ticking/LimboDecay.java rename to src/main/java/StevenDimDoors/mod_pocketDim/world/LimboDecay.java index e5c9420e..13edb19e 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/ticking/LimboDecay.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/world/LimboDecay.java @@ -1,4 +1,4 @@ -package StevenDimDoors.mod_pocketDim.ticking; +package StevenDimDoors.mod_pocketDim.world; import java.util.Random; @@ -13,13 +13,12 @@ import StevenDimDoors.mod_pocketDim.config.DDProperties; * Provides methods for applying Limbo decay. Limbo decay refers to the effect that most blocks placed in Limbo * naturally change into stone, then cobble, then gravel, and finally Unraveled Fabric as time passes. */ -public class LimboDecay implements IRegularTickReceiver { +public class LimboDecay { private static final int MAX_DECAY_SPREAD_CHANCE = 100; private static final int DECAY_SPREAD_CHANCE = 50; private static final int CHUNK_SIZE = 16; private static final int SECTION_HEIGHT = 16; - private static final int LIMBO_DECAY_INTERVAL = 10; //Apply spread decay every 10 ticks //Provides a reversed list of the block IDs that blocks cycle through during decay. private final int[] decaySequence; @@ -28,7 +27,7 @@ public class LimboDecay implements IRegularTickReceiver { private final DDProperties properties; private final int[] blocksImmuneToDecay; - public LimboDecay(IRegularTickSender tickSender, DDProperties properties) + public LimboDecay(DDProperties properties) { decaySequence = new int[] { properties.LimboBlockID, @@ -51,16 +50,6 @@ public class LimboDecay implements IRegularTickReceiver { this.properties = properties; this.random = new Random(); - tickSender.registerForTicking(this, LIMBO_DECAY_INTERVAL, false); - } - - /** - * Applies fast Limbo decay periodically. - */ - @Override - public void notifyTick() - { - applyRandomFastDecay(); } /** @@ -88,7 +77,7 @@ public class LimboDecay implements IRegularTickReceiver { * Picks random blocks from each active chunk in Limbo and, if decay is applicable, converts them directly to Unraveled Fabric. * This decay method is designed to stop players from avoiding Limbo decay by building floating structures. */ - private void applyRandomFastDecay() + public void applyRandomFastDecay() { int x, y, z; int sectionY; diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/world/PocketBuilder.java b/src/main/java/StevenDimDoors/mod_pocketDim/world/PocketBuilder.java index 5fd4b87a..6f9b946b 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/world/PocketBuilder.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/world/PocketBuilder.java @@ -9,6 +9,7 @@ import net.minecraft.world.World; import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.storage.ExtendedBlockStorage; import net.minecraftforge.common.DimensionManager; +import StevenDimDoors.experimental.BoundingBox; import StevenDimDoors.mod_pocketDim.Point3D; import StevenDimDoors.mod_pocketDim.mod_pocketDim; import StevenDimDoors.mod_pocketDim.blocks.IDimDoor; @@ -29,7 +30,7 @@ import StevenDimDoors.mod_pocketDim.util.Pair; import StevenDimDoors.mod_pocketDim.util.Point4D; public class PocketBuilder -{ +{ public static final int MIN_POCKET_SIZE = 5; public static final int MAX_POCKET_SIZE = 51; public static final int DEFAULT_POCKET_SIZE = 39; @@ -474,6 +475,7 @@ public class PocketBuilder //Build the door int doorOrientation = BlockRotator.transformMetadata(BlockRotator.EAST_DOOR_METADATA, orientation - BlockRotator.EAST_DOOR_METADATA + 2, doorBlock.blockID); ItemDimensionalDoor.placeDoorBlock(world, x, y - 1, z, doorOrientation, doorBlock); + } private static void buildBox(World world, int centerX, int centerY, int centerZ, int radius, int blockID, int metadata, boolean placeTnt, int nonTntWeight) @@ -553,4 +555,39 @@ public class PocketBuilder extBlockStorage.setExtBlockMetadata(localX, y & 15, localZ, metadata); chunk.setChunkModified(); } + + public static BoundingBox calculateDefaultBounds(NewDimData pocket) + { + // Calculate the XZ bounds of this pocket assuming that it has the default size + // The Y bounds will be set to encompass the height of a chunk. + + int minX = 0; + int minZ = 0; + Point4D origin = pocket.origin(); + int orientation = pocket.orientation(); + if (orientation < 0 || orientation > 3) + { + throw new IllegalArgumentException("pocket has an invalid orientation value."); + } + switch (orientation) + { + case 0: + minX = origin.getX() - DEFAULT_POCKET_WALL_THICKNESS + 1; + minZ = origin.getZ() - DEFAULT_POCKET_SIZE / 2; + break; + case 1: + minX = origin.getX() - DEFAULT_POCKET_SIZE / 2; + minZ = origin.getZ() - DEFAULT_POCKET_WALL_THICKNESS + 1; + break; + case 2: + minX = origin.getX() + DEFAULT_POCKET_WALL_THICKNESS - DEFAULT_POCKET_SIZE; + minZ = origin.getZ() - DEFAULT_POCKET_SIZE / 2; + break; + case 3: + minX = origin.getX() - DEFAULT_POCKET_SIZE / 2; + minZ = origin.getZ() + DEFAULT_POCKET_WALL_THICKNESS - DEFAULT_POCKET_SIZE; + break; + } + return new BoundingBox(minX, 0, minZ, DEFAULT_POCKET_SIZE, 255, DEFAULT_POCKET_SIZE); + } } diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/world/PocketGenerator.java b/src/main/java/StevenDimDoors/mod_pocketDim/world/PocketGenerator.java index 22996776..df99d038 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/world/PocketGenerator.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/world/PocketGenerator.java @@ -68,7 +68,7 @@ public class PocketGenerator extends ChunkProviderGenerate @Override public List getPossibleCreatures(EnumCreatureType var1, int var2, int var3, int var4) { - NewDimData dimension = PocketManager.getDimensionData(this.worldObj); + NewDimData dimension = PocketManager.createDimensionData(this.worldObj); if (dimension != null && dimension.dungeon() != null && !dimension.dungeon().isOpen()) { return this.worldObj.getBiomeGenForCoords(var2, var3).getSpawnableList(var1); diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/world/PocketProvider.java b/src/main/java/StevenDimDoors/mod_pocketDim/world/PocketProvider.java index 04d16a4a..dd6e787e 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/world/PocketProvider.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/world/PocketProvider.java @@ -7,7 +7,6 @@ import net.minecraft.world.WorldProvider; import net.minecraft.world.biome.WorldChunkManagerHell; import net.minecraft.world.chunk.IChunkProvider; import net.minecraftforge.client.IRenderHandler; -import net.minecraftforge.common.DimensionManager; import StevenDimDoors.mod_pocketDim.CloudRenderBlank; import StevenDimDoors.mod_pocketDim.mod_pocketDim; import StevenDimDoors.mod_pocketDim.config.DDProperties; @@ -90,7 +89,7 @@ public class PocketProvider extends WorldProvider @Override protected void generateLightBrightnessTable() { - if(PocketManager.getDimensionData(this.dimensionId).getDimensionType() == DimensionType.POCKET) + if(PocketManager.getDimensionData(this.dimensionId).type() == DimensionType.POCKET) { super.generateLightBrightnessTable(); return; @@ -126,11 +125,8 @@ public class PocketProvider extends WorldProvider { respawnDim = PocketManager.getDimensionData(this.dimensionId).root().id(); } - - if (DimensionManager.getWorld(respawnDim) == null) - { - DimensionManager.initDimension(respawnDim); - } + // TODO: Are we sure we need to load the dimension as well? Why can't the game handle that? + PocketManager.loadDimension(respawnDim); return respawnDim; } diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/world/fortresses/ComponentNetherGateway.java b/src/main/java/StevenDimDoors/mod_pocketDim/world/fortresses/ComponentNetherGateway.java index b2176a22..245071ed 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/world/fortresses/ComponentNetherGateway.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/world/fortresses/ComponentNetherGateway.java @@ -65,7 +65,8 @@ public class ComponentNetherGateway extends StructureComponent * second Part of Structure generating, this for example places Spiderwebs, Mob Spawners, it closes Mineshafts at * the end, it adds Fences... */ - public boolean addComponentParts(World world, Random random, StructureBoundingBox bounds) + @Override + public boolean addComponentParts(World world, Random random, StructureBoundingBox bounds) { int NETHER_SLAB_METADATA = 6; @@ -152,7 +153,7 @@ public class ComponentNetherGateway extends StructureComponent if (bounds.isVecInside(x, y, z) && bounds.isVecInside(x, y + 1, z)) { orientation = this.getMetadataWithOffset(Block.doorWood.blockID, 1); - dimension = PocketManager.getDimensionData(world); + dimension = PocketManager.createDimensionData(world); link = dimension.getLink(x, y + 1, z); if (link == null) { diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/world/fortresses/DDNetherFortressGenerator.java b/src/main/java/StevenDimDoors/mod_pocketDim/world/fortresses/DDNetherFortressGenerator.java index 644a5c1b..95319394 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/world/fortresses/DDNetherFortressGenerator.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/world/fortresses/DDNetherFortressGenerator.java @@ -18,7 +18,8 @@ public class DDNetherFortressGenerator extends MapGenNetherBridge MapGenStructureIO.func_143034_b(DDStructureNetherBridgeStart.class, "Fortress"); } - protected StructureStart getStructureStart(int chunkX, int chunkZ) + @Override + protected StructureStart getStructureStart(int chunkX, int chunkZ) { return new DDStructureNetherBridgeStart(this.worldObj, this.rand, chunkX, chunkZ, DDProperties.instance()); } diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/world/fortresses/DDStructureNetherBridgeStart.java b/src/main/java/StevenDimDoors/mod_pocketDim/world/fortresses/DDStructureNetherBridgeStart.java index bc7cc065..27781970 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/world/fortresses/DDStructureNetherBridgeStart.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/world/fortresses/DDStructureNetherBridgeStart.java @@ -105,7 +105,8 @@ public class DDStructureNetherBridgeStart extends StructureNetherBridgeStart /** * Keeps iterating Structure Pieces and spawning them until the checks tell it to stop */ - public void generateStructure(World world, Random random, StructureBoundingBox generationBounds) + @Override + public void generateStructure(World world, Random random, StructureBoundingBox generationBounds) { if (hasGateway) { diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/world/gateways/BaseSchematicGateway.java b/src/main/java/StevenDimDoors/mod_pocketDim/world/gateways/BaseSchematicGateway.java index 486923c3..e0d86340 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/world/gateways/BaseSchematicGateway.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/world/gateways/BaseSchematicGateway.java @@ -45,7 +45,7 @@ public abstract class BaseSchematicGateway extends BaseGateway // Generate a dungeon link in the door PocketManager.getDimensionData(world).createLink(x, y + doorLocation.getY(), z, LinkType.DUNGEON, orientation); - + return true; } diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/world/gateways/GatewayLimbo.java b/src/main/java/StevenDimDoors/mod_pocketDim/world/gateways/GatewayLimbo.java index ef8f9a62..6a3ec048 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/world/gateways/GatewayLimbo.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/world/gateways/GatewayLimbo.java @@ -31,6 +31,7 @@ public class GatewayLimbo extends BaseGateway world.setBlock(x, y + 1, z + 1, blockID, 0, 3); PocketManager.getDimensionData(world).createLink(x, y + 2, z, LinkType.DUNGEON, 0); + ItemDoor.placeDoorBlock(world, x, y + 1, z, 0, mod_pocketDim.transientDoor); return true; } diff --git a/src/main/java/StevenDimDoors/mod_pocketDimClient/ClientTickHandler.java b/src/main/java/StevenDimDoors/mod_pocketDimClient/ClientTickHandler.java deleted file mode 100644 index cece273d..00000000 --- a/src/main/java/StevenDimDoors/mod_pocketDimClient/ClientTickHandler.java +++ /dev/null @@ -1,65 +0,0 @@ -package StevenDimDoors.mod_pocketDimClient; -import java.util.EnumSet; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiScreen; -import cpw.mods.fml.common.ITickHandler; -import cpw.mods.fml.common.TickType; - -public class ClientTickHandler implements ITickHandler -{ - - @Override - public void tickStart(EnumSet type, Object... tickData) {} - - @Override - public void tickEnd(EnumSet type, Object... tickData) - { - if (type.equals(EnumSet.of(TickType.RENDER))) - { - onRenderTick(); - } - else if (type.equals(EnumSet.of(TickType.CLIENT))) - { - GuiScreen guiscreen = Minecraft.getMinecraft().currentScreen; - if (guiscreen != null) - { - onTickInGUI(guiscreen); - } else { - onTickInGame(); - } - } - } - - @Override - public EnumSet ticks() - { - return EnumSet.of(TickType.RENDER, TickType.CLIENT); - // In my testing only RENDER, CLIENT, & PLAYER did anything on the client side. - // Read 'cpw.mods.fml.common.TickType.java' for a full list and description of available types - } - - @Override - public String getLabel() { return null; } - - - public void onRenderTick() - { - //System.out.println("onRenderTick"); - //TODO: Your Code Here - } - - public void onTickInGUI(GuiScreen guiscreen) - { - //System.out.println("onTickInGUI"); - //TODO: Your Code Here - } - - public void onTickInGame() - { - - - //System.out.println("onTickInGame"); - //TODO: Your Code Here - } -} \ No newline at end of file diff --git a/src/main/java/StevenDimDoors/mod_pocketDimClient/ClosingRiftFX.java b/src/main/java/StevenDimDoors/mod_pocketDimClient/ClosingRiftFX.java index 2ea32391..a36d77c8 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDimClient/ClosingRiftFX.java +++ b/src/main/java/StevenDimDoors/mod_pocketDimClient/ClosingRiftFX.java @@ -100,7 +100,7 @@ public class ClosingRiftFX extends EntityFX float var15 = (float)(this.prevPosZ + (this.posZ - this.prevPosZ) * par2 - interpPosZ); float var16 = 0.8F; - if (PocketManager.getDimensionData(worldObj).isPocketDimension()) + if (PocketManager.createDimensionData(worldObj).isPocketDimension()) { var16 = 0.4F; } diff --git a/src/main/java/StevenDimDoors/mod_pocketDimClient/GoggleRiftFX.java b/src/main/java/StevenDimDoors/mod_pocketDimClient/GoggleRiftFX.java index 069d58ff..9845af8e 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDimClient/GoggleRiftFX.java +++ b/src/main/java/StevenDimDoors/mod_pocketDimClient/GoggleRiftFX.java @@ -54,7 +54,7 @@ public class GoggleRiftFX extends EntityFireworkSparkFX float var15 = (float)(this.prevPosZ + (this.posZ - this.prevPosZ) * par2 - interpPosZ); float var16 = .0F; - if (PocketManager.getDimensionData(worldObj).isPocketDimension()) + if (PocketManager.createDimensionData(worldObj).isPocketDimension()) { var16 = .7F; } diff --git a/src/main/java/StevenDimDoors/mod_pocketDimClient/RenderTransTrapdoor.java b/src/main/java/StevenDimDoors/mod_pocketDimClient/RenderTransTrapdoor.java index 0f3ea97d..98f8e886 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDimClient/RenderTransTrapdoor.java +++ b/src/main/java/StevenDimDoors/mod_pocketDimClient/RenderTransTrapdoor.java @@ -3,6 +3,7 @@ package StevenDimDoors.mod_pocketDimClient; import java.nio.FloatBuffer; import java.util.Random; +import net.minecraft.block.BlockTrapDoor; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.GLAllocation; import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; @@ -38,21 +39,6 @@ public class RenderTransTrapdoor extends TileEntitySpecialRenderer */ public void renderTransTrapdoorTileEntity(TileEntityTransTrapdoor tile, double x, double y, double z, float par8) { - try - { - mod_pocketDim.transTrapdoor.updateAttachedTile(tile.worldObj, tile.xCoord, tile.yCoord, tile.zCoord); - } - catch(Exception e) - { - e.printStackTrace(); - } - - - // float playerX = (float)this.tileEntityRenderer.playerX; - // float playerY = (float)this.tileEntityRenderer.playerY; - // float playerZ = (float)this.tileEntityRenderer.playerZ; - - //float distance = (float) tile.getDistanceFrom(playerX, playerY, playerZ); GL11.glDisable(GL11.GL_LIGHTING); Random random = new Random(31100L); int metadata = tile.worldObj.getBlockMetadata(tile.xCoord, tile.yCoord, tile.zCoord); @@ -77,7 +63,6 @@ public class RenderTransTrapdoor extends TileEntitySpecialRenderer if (count == 1) { this.bindTexture(warpPath); - // move files into assets/modid and change to new ResourceLocation(modid:/WARP.png) GL11.glEnable(GL11.GL_BLEND); GL11.glBlendFunc(GL11.GL_ONE, GL11.GL_ONE); var16 = .5F; @@ -127,7 +112,7 @@ public class RenderTransTrapdoor extends TileEntitySpecialRenderer GL11.glColor4d(var21 * var17, var22 * var17, var23 * var17, 1.0F); if (TransTrapdoor.isTrapdoorSetLow(metadata)) { - if (TransTrapdoor.isTrapdoorOpen(metadata)) + if (BlockTrapDoor.isTrapdoorOpen(metadata)) { GL11.glVertex3d(x, y+0.2, z); GL11.glVertex3d(x, y+0.2, z+1); @@ -144,7 +129,7 @@ public class RenderTransTrapdoor extends TileEntitySpecialRenderer } else { - if (TransTrapdoor.isTrapdoorOpen(metadata)) + if (BlockTrapDoor.isTrapdoorOpen(metadata)) { GL11.glVertex3d(x, y+0.95, z); GL11.glVertex3d(x, y+0.95, z+1); @@ -180,7 +165,8 @@ public class RenderTransTrapdoor extends TileEntitySpecialRenderer return this.field_76908_a; } - public void renderTileEntityAt(TileEntity par1TileEntity, double par2, double par4, double par6, float par8) + @Override + public void renderTileEntityAt(TileEntity par1TileEntity, double par2, double par4, double par6, float par8) { if (properties.DoorRenderingEnabled) { diff --git a/src/main/java/StevenDimDoors/mod_pocketDimClient/RiftFX.java b/src/main/java/StevenDimDoors/mod_pocketDimClient/RiftFX.java index 7f4dc941..f564180c 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDimClient/RiftFX.java +++ b/src/main/java/StevenDimDoors/mod_pocketDimClient/RiftFX.java @@ -111,7 +111,7 @@ public class RiftFX extends EntityFX float f13 = (float)(this.prevPosZ + (this.posZ - this.prevPosZ) * par2 - interpPosZ); float f14 = 0F; - if (PocketManager.getDimensionData(worldObj).isPocketDimension()) + if (PocketManager.createDimensionData(worldObj).isPocketDimension()) { f14 = 0.7F; } diff --git a/src/main/resources/mcmod.info b/src/main/resources/mcmod.info index 4687d325..7a43be90 100644 --- a/src/main/resources/mcmod.info +++ b/src/main/resources/mcmod.info @@ -6,10 +6,10 @@ "modid": "dimdoors", "name": "Dimensional Doors", "description": "Bend and twist reality itself, creating pocket dimensions, rifts, and much more", -"version": "1.6.4-R2.2.3", +"version": "$version", "credits": "Created by StevenRS11, Coded by StevenRS11 and SenseiKiwi, Logo and Testing by Jaitsu", "logoFile": "/dimdoors_logo.png", -"mcversion": "", +"mcversion": "$mcversion", "url": "http://www.minecraftforum.net/topic/1650007-147smpssplan-dimensional-doors-v110-physics-what-physics-updated-with-fancy-opengl/", "updateUrl": "", "authors": [ "StevenRS11", "SenseiKiwi" ],