From d23198c4fafcead0e21b1810f8e78b31ce02e179 Mon Sep 17 00:00:00 2001 From: SenseiKiwi Date: Mon, 15 Jul 2013 00:47:32 -0400 Subject: [PATCH] Fixed Selection of Bounds for Custom Dungeons Fixed the selection of boundaries for custom dungeons. The code had a bug that would clip off a portion of dungeons during exporting. Also, permafabric is not used to mark the edges of the dungeon anymore. That means dungeons can contain permafabric now without getting cut off, and the permafabric shells will be included as part of the export. --- .../mod_pocketDim/helpers/DungeonHelper.java | 117 ++++++++---------- 1 file changed, 54 insertions(+), 63 deletions(-) diff --git a/StevenDimDoors/mod_pocketDim/helpers/DungeonHelper.java b/StevenDimDoors/mod_pocketDim/helpers/DungeonHelper.java index 2639f0a..2a384d6 100644 --- a/StevenDimDoors/mod_pocketDim/helpers/DungeonHelper.java +++ b/StevenDimDoors/mod_pocketDim/helpers/DungeonHelper.java @@ -38,6 +38,7 @@ public class DungeonHelper public static final String SCHEMATIC_FILE_EXTENSION = ".schematic"; private static final int DEFAULT_DUNGEON_WEIGHT = 100; public static final int MAX_DUNGEON_WEIGHT = 10000; //Used to prevent overflows and math breaking down + private static final int MAX_EXPORT_RADIUS = 50; private static final String HUB_DUNGEON_TYPE = "Hub"; private static final String TRAP_DUNGEON_TYPE = "Trap"; @@ -375,75 +376,74 @@ public class DungeonHelper registeredDungeons.addAll(hubs); } - public boolean exportDungeon(World world, int xI, int yI, int zI, String exportPath) + public boolean exportDungeonX(World world, int centerX, int centerY, int centerZ, String exportPath) { - int xMin; - int yMin; - int zMin; - - int xMax; - int yMax; - int zMax; - - xMin=xMax=xI; - yMin=yMax=yI; - zMin=zMax=zI; - - for (int count = 0; count < 50; count++) + int xMin, yMin, zMin; + int xMax, yMax, zMax; + int xStart, yStart, zStart; + int xEnd, yEnd, zEnd; + + //Find the smallest bounding box that contains all non-air blocks within a max radius around the player. + xMax = yMax = zMax = Integer.MIN_VALUE; + xMin = yMin = zMin = Integer.MAX_VALUE; + + xStart = centerX - MAX_EXPORT_RADIUS; + zStart = centerZ - MAX_EXPORT_RADIUS; + yStart = Math.max(centerY - MAX_EXPORT_RADIUS, 0); + + xEnd = centerX + MAX_EXPORT_RADIUS; + zEnd = centerZ + MAX_EXPORT_RADIUS; + yEnd = Math.min(centerY - MAX_EXPORT_RADIUS, world.getActualHeight()); + + //This could be done more efficiently, but honestly, this is the simplest approach and it + //makes it easy for us to verify that the code is correct. + for (int x = xStart; x <= xEnd; x++) { - if(world.getBlockId(xMin, yI, zI)!=properties.PermaFabricBlockID) + for (int z = zStart; z <= zEnd; z++) { - xMin--; - } - if(world.getBlockId(xI, yMin, zI)!=properties.PermaFabricBlockID) - { - yMin--; - } - if(world.getBlockId(xI, yI, zMin)!=properties.PermaFabricBlockID) - { - zMin--; - } - if(world.getBlockId(xMax, yI, zI)!=properties.PermaFabricBlockID) - { - xMax++; - } - if(world.getBlockId(xI, yMax, zI)!=properties.PermaFabricBlockID) - { - yMax++; - } - if(world.getBlockId(xI, yI, zMax)!=properties.PermaFabricBlockID) - { - zMax++; + for (int y = yStart; y <= yEnd; y++) + { + if (!world.isAirBlock(x, y, z)) + { + xMax = x > xMax ? x : xMax; + zMax = z > zMax ? z : zMax; + yMax = y > yMax ? y : yMax; + + xMin = x < xMin ? x : xMin; + zMin = z < zMin ? z : zMin; + yMin = y < yMin ? y : yMin; + } + } } } + + //Export all the blocks within our selected bounding box + short width = (short) (xMax - xMin + 1); + short height = (short) (yMax - yMin + 1); + short length = (short) (zMax - zMin + 1); - short width =(short) (xMax-xMin); - short height= (short) (yMax-yMin); - short length= (short) (zMax-zMin); - - //ArrayList tileEntities = new ArrayList(); - ArrayList tileEntites = new ArrayList(); + ArrayList tileEntities = new ArrayList(); byte[] blocks = new byte[width * height * length]; byte[] addBlocks = null; byte[] blockData = new byte[width * height * length]; - for (int x = 0; x < width; ++x) + for (int x = 0; x < width; x++) { - for (int y = 0; y < height; ++y) + for (int z = 0; z < length; z++) { - for (int z = 0; z < length; ++z) + for (int y = 0; y < height; y++) { int index = y * width * length + z * width + x; - int blockID = world.getBlockId(x+xMin, y+yMin, z+zMin); - int meta= world.getBlockMetadata(x+xMin, y+yMin, z+zMin); + int blockID = world.getBlockId(x + xMin, y + yMin, z + zMin); + int metadata = world.getBlockMetadata(x + xMin, y + yMin, z + zMin); - if(blockID==properties.DimensionalDoorID) + if (blockID == properties.DimensionalDoorID) { - blockID=Block.doorIron.blockID; + blockID = Block.doorIron.blockID; } - if(blockID==properties.WarpDoorID) + if (blockID == properties.WarpDoorID) { - blockID=Block.doorWood.blockID; + blockID = Block.doorWood.blockID; } @@ -461,7 +461,7 @@ public class DungeonHelper } blocks[index] = (byte) blockID; - blockData[index] = (byte) meta; + blockData[index] = (byte) metadata; if (Block.blocksList[blockID] instanceof BlockContainer) { @@ -486,16 +486,7 @@ public class DungeonHelper } } } - /** - * - * nbtdata.setShort("Width", width); - nbtdata.setShort("Height", height); - nbtdata.setShort("Length", length); - - nbtdata.setByteArray("Blocks", blocks); - nbtdata.setByteArray("Data", blockData); - */ - + HashMap schematic = new HashMap(); schematic.put("Blocks", new ByteArrayTag("Blocks", blocks)); @@ -504,7 +495,7 @@ public class DungeonHelper schematic.put("Width", new ShortTag("Width", (short) width)); schematic.put("Length", new ShortTag("Length", (short) length)); schematic.put("Height", new ShortTag("Height", (short) height)); - schematic.put("TileEntites", new ListTag("TileEntities", CompoundTag.class,tileEntites)); + schematic.put("TileEntites", new ListTag("TileEntities", CompoundTag.class, tileEntities)); if (addBlocks != null) {