diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/dungeon/DungeonSchematic.java b/src/main/java/StevenDimDoors/mod_pocketDim/dungeon/DungeonSchematic.java index cc74b94f..8395d9b6 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/dungeon/DungeonSchematic.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/dungeon/DungeonSchematic.java @@ -24,12 +24,15 @@ import StevenDimDoors.mod_pocketDim.core.LinkTypes; import StevenDimDoors.mod_pocketDim.core.NewDimData; import StevenDimDoors.mod_pocketDim.core.PocketManager; import StevenDimDoors.mod_pocketDim.schematic.BlockRotator; +import StevenDimDoors.mod_pocketDim.schematic.ChunkBlockSetter; import StevenDimDoors.mod_pocketDim.schematic.CompoundFilter; +import StevenDimDoors.mod_pocketDim.schematic.IBlockSetter; import StevenDimDoors.mod_pocketDim.schematic.InvalidSchematicException; import StevenDimDoors.mod_pocketDim.schematic.ReplacementFilter; import StevenDimDoors.mod_pocketDim.schematic.Schematic; -import StevenDimDoors.mod_pocketDim.ticking.MobMonolith; +import StevenDimDoors.mod_pocketDim.schematic.WorldBlockSetter; import StevenDimDoors.mod_pocketDim.ticking.CustomLimboPopulator; +import StevenDimDoors.mod_pocketDim.ticking.MobMonolith; import StevenDimDoors.mod_pocketDim.util.Point4D; public class DungeonSchematic extends Schematic { @@ -176,7 +179,21 @@ public class DungeonSchematic extends Schematic { return new DungeonSchematic(Schematic.copyFromWorld(world, x, y, z, width, height, length, doCompactBounds)); } - public void copyToWorld(World world, Point3D pocketCenter, int targetOrientation, DimLink entryLink, Random random, DDProperties properties) + public void copyToWorld(World world, Point3D pocketCenter, int targetOrientation, DimLink entryLink, + Random random, DDProperties properties, boolean notifyClients) + { + if (notifyClients) + { + copyToWorld(world, pocketCenter, targetOrientation, entryLink, random, properties, new WorldBlockSetter(false, true)); + } + else + { + copyToWorld(world, pocketCenter, targetOrientation, entryLink, random, properties, new ChunkBlockSetter()); + } + } + + public void copyToWorld(World world, Point3D pocketCenter, int targetOrientation, DimLink entryLink, + Random random, DDProperties properties, IBlockSetter blockSetter) { //TODO: This function is an improvised solution so we can get the release moving. In the future, //we should generalize block transformations and implement support for them at the level of Schematic, @@ -208,7 +225,7 @@ public class DungeonSchematic extends Schematic { blockMeta = BlockRotator.transformMetadata(metadata[index], turnAngle, blockID); //In the future, we might want to make this more efficient by building whole chunks at a time - setBlockDirectly(world, pocketPoint.getX(), pocketPoint.getY(), pocketPoint.getZ(), blockID, blockMeta); + blockSetter.setBlock(world, pocketPoint.getX(), pocketPoint.getY(), pocketPoint.getZ(), blockID, blockMeta); index++; } } @@ -230,10 +247,10 @@ 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); + setUpDungeon(PocketManager.getDimensionData(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) + private void setUpDungeon(NewDimData dimension, World world, Point3D pocketCenter, int turnAngle, DimLink entryLink, Random random, DDProperties properties, IBlockSetter blockSetter) { //Transform dungeon corners Point3D minCorner = new Point3D(0, 0, 0); @@ -256,14 +273,14 @@ public class DungeonSchematic extends Schematic { //Set up link data for exit door for (Point3D location : exitDoorLocations) { - createExitDoorLink(world, dimension, location, entranceDoorLocation, turnAngle, pocketCenter); + createExitDoorLink(world, dimension, location, entranceDoorLocation, turnAngle, pocketCenter, blockSetter); } //Remove end portal frames and spawn Monoliths, if allowed boolean canSpawn = CustomLimboPopulator.isMobSpawningAllowed(); for (Point3D location : monolithSpawnLocations) { - spawnMonolith(world, location, entranceDoorLocation, turnAngle, pocketCenter, canSpawn); + spawnMonolith(world, location, entranceDoorLocation, turnAngle, pocketCenter, canSpawn, blockSetter); } // If this is a Nether dungeon, search for a sign near the entry door and write the dimension's depth. @@ -312,7 +329,7 @@ public class DungeonSchematic extends Schematic { initDoorTileEntity(world, pocketCenter); } - private static void createExitDoorLink(World world, NewDimData dimension, Point3D point, Point3D entrance, int rotation, Point3D pocketCenter) + private static void createExitDoorLink(World world, NewDimData dimension, Point3D point, Point3D entrance, int rotation, Point3D pocketCenter, IBlockSetter blockSetter) { //Transform the door's location to the pocket coordinate system Point3D location = point.clone(); @@ -327,7 +344,7 @@ public class DungeonSchematic extends Schematic { { int blockID = world.getBlockId(x, y, z); int metadata = world.getBlockMetadata(x, y, z); - setBlockDirectly(world, x, y + 1, z, blockID, metadata); + blockSetter.setBlock(world, x, y + 1, z, blockID, metadata); } initDoorTileEntity(world, location); } @@ -343,13 +360,13 @@ public class DungeonSchematic extends Schematic { initDoorTileEntity(world, location); } - private static void spawnMonolith(World world, Point3D point, Point3D entrance, int rotation, Point3D pocketCenter, boolean canSpawn) + private static void spawnMonolith(World world, Point3D point, Point3D entrance, int rotation, Point3D pocketCenter, boolean canSpawn, IBlockSetter blockSetter) { //Transform the frame block's location to the pocket coordinate system Point3D location = point.clone(); BlockRotator.transformPoint(location, entrance, rotation, pocketCenter); //Remove frame block - setBlockDirectly(world, location.getX(), location.getY(), location.getZ(), 0, 0); + blockSetter.setBlock(world, location.getX(), location.getY(), location.getZ(), 0, 0); //Spawn Monolith if (canSpawn) { @@ -377,7 +394,7 @@ public class DungeonSchematic extends Schematic { private static void writeDepthSign(World world, Point3D pocketCenter, int depth) { - final int SEARCH_RANGE = 5; + final int SEARCH_RANGE = 6; int x, y, z, block; int dx, dy, dz; diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/mod_pocketDim.java b/src/main/java/StevenDimDoors/mod_pocketDim/mod_pocketDim.java index 389496b8..c52aa5fe 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/mod_pocketDim.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/mod_pocketDim.java @@ -210,8 +210,6 @@ public class mod_pocketDim mod_pocketDim.limboBiome = (new BiomeGenLimbo(properties.LimboBiomeID)); mod_pocketDim.pocketBiome = (new BiomeGenPocket(properties.PocketBiomeID)); - GameRegistry.registerWorldGenerator(mod_pocketDim.gatewayGenerator); - GameRegistry.registerBlock(goldenDoor, "Golden Door"); GameRegistry.registerBlock(goldenDimensionalDoor, "Golden Dimensional Door"); GameRegistry.registerBlock(unstableDoor, "Unstable Door"); @@ -253,14 +251,12 @@ public class mod_pocketDim LanguageRegistry.addName(itemRiftBlade, "Rift Blade"); LanguageRegistry.addName(itemWorldThread, "World Thread"); - /** * Add names for multiblock inventory item */ LanguageRegistry.addName(new ItemStack(blockDimWall, 1, 0), "Fabric of Reality"); LanguageRegistry.addName(new ItemStack(blockDimWall, 1, 1), "Ancient Fabric"); - LanguageRegistry.instance().addStringLocalization("itemGroup.dimDoorsCustomTab", "en_US", "Dimensional Doors Items"); GameRegistry.registerTileEntity(TileEntityDimDoor.class, "TileEntityDimDoor"); @@ -274,8 +270,9 @@ public class mod_pocketDim LanguageRegistry.instance().addStringLocalization("entity.DimDoors.Obelisk.name", "Monolith"); CraftingManager.registerRecipes(properties); - DungeonHelper.initialize(); + DungeonHelper.initialize(); gatewayGenerator = new GatewayGenerator(properties); + GameRegistry.registerWorldGenerator(mod_pocketDim.gatewayGenerator); // Register loot chests DDLoot.registerInfo(properties); diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/schematic/ChunkBlockSetter.java b/src/main/java/StevenDimDoors/mod_pocketDim/schematic/ChunkBlockSetter.java new file mode 100644 index 00000000..e7203fb4 --- /dev/null +++ b/src/main/java/StevenDimDoors/mod_pocketDim/schematic/ChunkBlockSetter.java @@ -0,0 +1,46 @@ +package StevenDimDoors.mod_pocketDim.schematic; + +import net.minecraft.block.Block; +import net.minecraft.world.World; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.chunk.storage.ExtendedBlockStorage; + +public class ChunkBlockSetter implements IBlockSetter +{ + public ChunkBlockSetter() { } + + public void setBlock(World world, int x, int y, int z, int blockID, int metadata) + { + if (blockID != 0 && Block.blocksList[blockID] == null) + { + return; + } + + int cX = x >> 4; + int cZ = z >> 4; + int cY = y >> 4; + Chunk chunk; + + int localX = (x % 16) < 0 ? (x % 16) + 16 : (x % 16); + int localZ = (z % 16) < 0 ? (z % 16) + 16 : (z % 16); + ExtendedBlockStorage extBlockStorage; + + try + { + chunk = world.getChunkFromChunkCoords(cX, cZ); + extBlockStorage = chunk.getBlockStorageArray()[cY]; + if (extBlockStorage == null) + { + extBlockStorage = new ExtendedBlockStorage(cY << 4, !world.provider.hasNoSky); + chunk.getBlockStorageArray()[cY] = extBlockStorage; + } + extBlockStorage.setExtBlockID(localX, y & 15, localZ, blockID); + extBlockStorage.setExtBlockMetadata(localX, y & 15, localZ, metadata); + chunk.setChunkModified(); + } + catch(Exception e) + { + e.printStackTrace(); + } + } +} diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/schematic/IBlockSetter.java b/src/main/java/StevenDimDoors/mod_pocketDim/schematic/IBlockSetter.java new file mode 100644 index 00000000..5eedbb38 --- /dev/null +++ b/src/main/java/StevenDimDoors/mod_pocketDim/schematic/IBlockSetter.java @@ -0,0 +1,8 @@ +package StevenDimDoors.mod_pocketDim.schematic; + +import net.minecraft.world.World; + +public interface IBlockSetter +{ + public void setBlock(World world, int x, int y, int z, int blockID, int metadata); +} diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/schematic/Schematic.java b/src/main/java/StevenDimDoors/mod_pocketDim/schematic/Schematic.java index a746535f..8bf7dbbc 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/schematic/Schematic.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/schematic/Schematic.java @@ -118,7 +118,7 @@ public class Schematic { public static Schematic readFromFile(File schematicFile) throws FileNotFoundException, InvalidSchematicException { - // TODO: fix resource leaks here + // There is no resource leak... readFromStream() closes the stream TWICE. return readFromStream(new FileInputStream(schematicFile)); } @@ -362,14 +362,26 @@ public class Schematic { return filter.apply(this, this.blocks, this.metadata); } - public void copyToWorld(World world, int x, int y, int z) + public void copyToWorld(World world, int x, int y, int z, boolean notifyClients) + { + if (notifyClients) + { + copyToWorld(world, x, y, z, new WorldBlockSetter(false, true)); + } + else + { + copyToWorld(world, x, y, z, new ChunkBlockSetter()); + } + } + + protected void copyToWorld(World world, int x, int y, int z, IBlockSetter blockSetter) { //This isn't implemented as a WorldOperation because it doesn't quite fit the structure of those operations. //It's not worth the trouble in this case. int index; int count; int dx, dy, dz; - + //Copy blocks and metadata into the world index = 0; for (dy = 0; dy < height; dy++) @@ -378,11 +390,12 @@ public class Schematic { { for (dx = 0; dx < width; dx++) { - setBlockDirectly(world, x + dx, y + dy, z + dz, blocks[index], metadata[index]); + blockSetter.setBlock(world, x + dx, y + dy, z + dz, blocks[index], metadata[index]); index++; } } } + //Copy tile entities into the world count = tileEntities.tagCount(); for (index = 0; index < count; index++) @@ -399,39 +412,4 @@ public class Schematic { world.setBlockTileEntity(dx, dy, dz, TileEntity.createAndLoadEntity(tileTag)); } } - - protected static void setBlockDirectly(World world, int x, int y, int z, int blockID, int metadata) - { - if (blockID != 0 && Block.blocksList[blockID] == null) - { - return; - } - - int cX = x >> 4; - int cZ = z >> 4; - int cY = y >> 4; - Chunk chunk; - - int localX = (x % 16) < 0 ? (x % 16) + 16 : (x % 16); - int localZ = (z % 16) < 0 ? (z % 16) + 16 : (z % 16); - ExtendedBlockStorage extBlockStorage; - - try - { - chunk = world.getChunkFromChunkCoords(cX, cZ); - extBlockStorage = chunk.getBlockStorageArray()[cY]; - if (extBlockStorage == null) - { - extBlockStorage = new ExtendedBlockStorage(cY << 4, !world.provider.hasNoSky); - chunk.getBlockStorageArray()[cY] = extBlockStorage; - } - extBlockStorage.setExtBlockID(localX, y & 15, localZ, blockID); - extBlockStorage.setExtBlockMetadata(localX, y & 15, localZ, metadata); - chunk.setChunkModified(); - } - catch(Exception e) - { - e.printStackTrace(); - } - } } diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/schematic/WorldBlockSetter.java b/src/main/java/StevenDimDoors/mod_pocketDim/schematic/WorldBlockSetter.java new file mode 100644 index 00000000..3ac4563e --- /dev/null +++ b/src/main/java/StevenDimDoors/mod_pocketDim/schematic/WorldBlockSetter.java @@ -0,0 +1,26 @@ +package StevenDimDoors.mod_pocketDim.schematic; + +import net.minecraft.block.Block; +import net.minecraft.world.World; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.chunk.storage.ExtendedBlockStorage; + +public class WorldBlockSetter implements IBlockSetter +{ + public final int BLOCK_UPDATES_FLAG = 1; + public final int NOTIFY_CLIENT_FLAG = 2; + + private int flags; + + public WorldBlockSetter(boolean doBlockUpdates, boolean notifyClients) + { + flags = 0; + flags += doBlockUpdates ? BLOCK_UPDATES_FLAG : 0; + flags += notifyClients ? NOTIFY_CLIENT_FLAG : 0; + } + + public void setBlock(World world, int x, int y, int z, int blockID, int metadata) + { + world.setBlock(x, y, z, blockID, metadata, flags); + } +} diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/ticking/LimboDecay.java b/src/main/java/StevenDimDoors/mod_pocketDim/ticking/LimboDecay.java index 31fc1fee..c3251090 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/ticking/LimboDecay.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/ticking/LimboDecay.java @@ -44,7 +44,9 @@ public class LimboDecay implements IRegularTickReceiver { properties.DimensionalDoorID, properties.WarpDoorID, properties.RiftBlockID, - properties.UnstableDoorID + properties.UnstableDoorID, + properties.GoldenDoorID, + properties.GoldenDimensionalDoorID }; this.properties = properties; diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/world/PocketBuilder.java b/src/main/java/StevenDimDoors/mod_pocketDim/world/PocketBuilder.java index 3a26038b..8a30d344 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/world/PocketBuilder.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/world/PocketBuilder.java @@ -105,7 +105,7 @@ public class PocketBuilder } Point3D destination = new Point3D(incomingLink.destination()); - loadAndValidateDungeon(dimension.dungeon(), properties).copyToWorld(world, destination, originLink.orientation(), incomingLink, random, properties); + loadAndValidateDungeon(dimension.dungeon(), properties).copyToWorld(world, destination, originLink.orientation(), incomingLink, random, properties, false); dimension.setFilled(true); return true; } @@ -136,7 +136,7 @@ public class PocketBuilder destination.setY( yCoordHelper.adjustDestinationY(destination.getY(), world.getHeight(), schematic.getEntranceDoorLocation().getY(), schematic.getHeight()) ); //Generate the dungeon - schematic.copyToWorld(world, destination, orientation, link, random, properties); + schematic.copyToWorld(world, destination, orientation, link, random, properties, false); //Finish up destination initialization dimension.initializeDungeon(destination.getX(), destination.getY(), destination.getZ(), orientation, link, dungeon); diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/world/gateways/BaseGateway.java b/src/main/java/StevenDimDoors/mod_pocketDim/world/gateways/BaseGateway.java index 9dfae595..0a2b47da 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/world/gateways/BaseGateway.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/world/gateways/BaseGateway.java @@ -67,7 +67,7 @@ public abstract class BaseGateway // messes up the calculation. ~SenseiKiwi //schematic.copyToWorld(world, x - doorLocation.getX(), y, z - doorLocation.getZ()); - schematic.copyToWorld(world, x - doorLocation.getX(), y + 1 - doorLocation.getY(), z - doorLocation.getZ()); + schematic.copyToWorld(world, x - doorLocation.getX(), y + 1 - doorLocation.getY(), z - doorLocation.getZ(), true); } this.generateRandomBits(world, x, y, z);