From 9bba789f0b940a30f8dd20495f7b02fda77d208e Mon Sep 17 00:00:00 2001 From: SenseiKiwi Date: Thu, 6 Mar 2014 11:33:45 -0400 Subject: [PATCH 1/2] Updated Limbo Decay Immunity Updated the list of blocks that are immune to Limbo decay to include Golden Doors and Golden Dimensional Doors. --- .../java/StevenDimDoors/mod_pocketDim/ticking/LimboDecay.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/ticking/LimboDecay.java b/src/main/java/StevenDimDoors/mod_pocketDim/ticking/LimboDecay.java index 31fc1fe..c325109 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; -- 2.39.5 From bbd0b1d0fe547c07127e448dce87b3877c48fe12 Mon Sep 17 00:00:00 2001 From: SenseiKiwi Date: Thu, 6 Mar 2014 13:44:31 -0400 Subject: [PATCH 2/2] Fixed Client Gateway Notification and NPE Fixed the issue with clients not receiving notifications of gateways being built into the world because we were modifying chunk data directly. Our schematic classes now support building through World instead of directly writing to the underlying chunks. Also fixed an NPE that was introduced last night when I changed which line GatewayGenerator was initialized on in mod_pocketDim. --- .../dungeon/DungeonSchematic.java | 41 ++++++++++---- .../mod_pocketDim/mod_pocketDim.java | 7 +-- .../schematic/ChunkBlockSetter.java | 46 +++++++++++++++ .../mod_pocketDim/schematic/IBlockSetter.java | 8 +++ .../mod_pocketDim/schematic/Schematic.java | 56 ++++++------------- .../schematic/WorldBlockSetter.java | 26 +++++++++ .../mod_pocketDim/world/PocketBuilder.java | 4 +- .../world/gateways/BaseGateway.java | 2 +- 8 files changed, 131 insertions(+), 59 deletions(-) create mode 100644 src/main/java/StevenDimDoors/mod_pocketDim/schematic/ChunkBlockSetter.java create mode 100644 src/main/java/StevenDimDoors/mod_pocketDim/schematic/IBlockSetter.java create mode 100644 src/main/java/StevenDimDoors/mod_pocketDim/schematic/WorldBlockSetter.java diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/dungeon/DungeonSchematic.java b/src/main/java/StevenDimDoors/mod_pocketDim/dungeon/DungeonSchematic.java index cc74b94..8395d9b 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 389496b..c52aa5f 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 0000000..e7203fb --- /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 0000000..5eedbb3 --- /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 a746535..8bf7dbb 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 0000000..3ac4563 --- /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/world/PocketBuilder.java b/src/main/java/StevenDimDoors/mod_pocketDim/world/PocketBuilder.java index 3a26038..8a30d34 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 9dfae59..0a2b47d 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); -- 2.39.5