From 5e60960661461d6ac17d40278ed60cf74f2bed0b Mon Sep 17 00:00:00 2001 From: SenseiKiwi Date: Mon, 30 Dec 2013 19:59:17 -0400 Subject: [PATCH] Completed Doorway Placement All doorways are placed sensibly now, including vertical passages between different floors. --- .../experimental/MazeBuilder.java | 174 ++++++++++-------- .../experimental/SphereDecayOperation.java | 84 +++++++++ 2 files changed, 183 insertions(+), 75 deletions(-) create mode 100644 src/main/java/StevenDimDoors/experimental/SphereDecayOperation.java diff --git a/src/main/java/StevenDimDoors/experimental/MazeBuilder.java b/src/main/java/StevenDimDoors/experimental/MazeBuilder.java index e4ea77a..aa469a4 100644 --- a/src/main/java/StevenDimDoors/experimental/MazeBuilder.java +++ b/src/main/java/StevenDimDoors/experimental/MazeBuilder.java @@ -1,14 +1,8 @@ package StevenDimDoors.experimental; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.Queue; import java.util.Random; import net.minecraft.block.Block; -import net.minecraft.util.MathHelper; import net.minecraft.world.World; import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.storage.ExtendedBlockStorage; @@ -22,11 +16,20 @@ public class MazeBuilder { MazeDesign design = MazeDesigner.generate(random); Point3D offset = new Point3D(x - design.width() / 2, y - design.height() - 1, z - design.length() / 2); + SphereDecayOperation decay = new SphereDecayOperation(random, 0, 0, Block.stoneBrick.blockID, 2); buildRooms(design.getRoomGraph(), world, offset); - carveDoorways(design.getRoomGraph(), world, offset, random); + carveDoorways(design.getRoomGraph(), world, offset, decay, random); + + applyRandomDestruction(design, world, offset, decay, random); } + private static void applyRandomDestruction(MazeDesign design, World world, + Point3D offset, SphereDecayOperation decay, Random random) + { + //final int DECAY_BOX_SIZE = 8 + } + private static void buildRooms(DirectedGraph roomGraph, World world, Point3D offset) { for (IGraphNode node : roomGraph.nodes()) @@ -36,14 +39,11 @@ public class MazeBuilder } } - private static void carveDoorways(DirectedGraph roomGraph, World world, Point3D offset, Random random) - { - final int MIN_DOUBLE_DOOR_SPAN = 10; - - int gap; + private static void carveDoorways(DirectedGraph roomGraph, World world, + Point3D offset, SphereDecayOperation decay, Random random) + { char axis; Point3D lower; - Point3D upper; DoorwayData doorway; for (IGraphNode node : roomGraph.nodes()) @@ -53,72 +53,95 @@ public class MazeBuilder doorway = passage.data(); axis = doorway.axis(); lower = doorway.minCorner(); - upper = doorway.maxCorner(); - - switch (axis) - { - case DoorwayData.X_AXIS: - if (doorway.length() >= MIN_DOUBLE_DOOR_SPAN) - { - gap = (doorway.length() - 2) / 3; - carveDoorAlongX(world, offset.getX() + lower.getX(), offset.getY() + lower.getY() + 1, offset.getZ() + lower.getZ() + gap); - carveDoorAlongX(world, offset.getX() + lower.getX(), offset.getY() + lower.getY() + 1, offset.getZ() + upper.getZ() - gap); - } - else if (doorway.length() > 3) - { - switch (random.nextInt(3)) - { - case 0: - carveDoorAlongX(world, offset.getX() + lower.getX(), offset.getY() + lower.getY() + 1, offset.getZ() + (lower.getZ() + upper.getZ()) / 2); - break; - case 1: - carveDoorAlongX(world, offset.getX() + lower.getX(), offset.getY() + lower.getY() + 1, offset.getZ() + lower.getZ() + 2); - break; - case 2: - carveDoorAlongX(world, offset.getX() + lower.getX(), offset.getY() + lower.getY() + 1, offset.getZ() + upper.getZ() - 2); - break; - } - } - else - { - carveDoorAlongX(world, offset.getX() + lower.getX(), offset.getY() + lower.getY() + 1, offset.getZ() + lower.getZ() + 1); - } - break; - case DoorwayData.Z_AXIS: - if (doorway.width() >= MIN_DOUBLE_DOOR_SPAN) - { - gap = (doorway.width() - 2) / 3; - carveDoorAlongZ(world, offset.getX() + lower.getX() + gap, offset.getY() + lower.getY() + 1, offset.getZ() + lower.getZ()); - carveDoorAlongZ(world, offset.getX() + upper.getX() - gap, offset.getY() + lower.getY() + 1, offset.getZ() + lower.getZ()); - } - else if (doorway.length() > 3) - { - switch (random.nextInt(3)) - { - case 0: - carveDoorAlongZ(world, offset.getX() + (lower.getX() + upper.getX()) / 2, offset.getY() + lower.getY() + 1, offset.getZ() + lower.getZ()); - break; - case 1: - carveDoorAlongZ(world, offset.getX() + lower.getX() + 2, offset.getY() + lower.getY() + 1, offset.getZ() + lower.getZ()); - break; - case 2: - carveDoorAlongZ(world, offset.getX() + upper.getX() - 2, offset.getY() + lower.getY() + 1, offset.getZ() + lower.getZ()); - break; - } - } - else - { - carveDoorAlongZ(world, offset.getX() + lower.getX() + 1, offset.getY() + lower.getY() + 1, offset.getZ() + lower.getZ()); - } - break; - case DoorwayData.Y_AXIS: - carveHole(world, offset.getX() + lower.getX() + 1, offset.getY() + lower.getY(), offset.getZ() + lower.getZ() + 1); - break; - } + carveDoorway(world, axis, offset.getX() + lower.getX(), offset.getY() + lower.getY(), + offset.getZ() + lower.getZ(), doorway.width(), doorway.height(), doorway.length(), + decay, random); } } } + private static void carveDoorway(World world, char axis, int x, int y, int z, int width, int height, + int length, SphereDecayOperation decay, Random random) + { + final int MIN_DOUBLE_DOOR_SPAN = 10; + + int gap; + switch (axis) + { + case DoorwayData.X_AXIS: + if (length >= MIN_DOUBLE_DOOR_SPAN) + { + gap = (length - 2) / 3; + carveDoorAlongX(world, x, y + 1, z + gap); + carveDoorAlongX(world, x, y + 1, z + length - gap - 1); + } + else if (length > 3) + { + switch (random.nextInt(3)) + { + case 0: + carveDoorAlongX(world, x, y + 1, z + (length - 1) / 2); + break; + case 1: + carveDoorAlongX(world, x, y + 1, z + 2); + break; + case 2: + carveDoorAlongX(world, x, y + 1, z + length - 3); + break; + } + } + else + { + carveDoorAlongX(world, x, y + 1, z + 1); + } + break; + case DoorwayData.Z_AXIS: + if (width >= MIN_DOUBLE_DOOR_SPAN) + { + gap = (width - 2) / 3; + carveDoorAlongZ(world, x + gap, y + 1, z); + carveDoorAlongZ(world, x + width - gap - 1, y + 1, z); + } + else if (length > 3) + { + switch (random.nextInt(3)) + { + case 0: + carveDoorAlongZ(world, x + (width - 1) / 2, y + 1, z); + break; + case 1: + carveDoorAlongZ(world, x + 2, y + 1, z); + break; + case 2: + carveDoorAlongZ(world, x + width - 3, y + 1, z); + break; + } + } + else + { + carveDoorAlongZ(world, x + 1, y + 1, z); + } + break; + case DoorwayData.Y_AXIS: + gap = Math.min(width, length) - 2; + if (gap > 1) + { + if (gap > 6) + { + gap = 6; + } + decay.apply(world, + x + random.nextInt(width - gap - 1) + 1, y - 1, + z + random.nextInt(length - gap - 1) + 1, gap, 4, gap); + } + else + { + carveHole(world, x + 1, y, z + 1); + } + break; + } + } + private static void carveDoorAlongX(World world, int x, int y, int z) { setBlockDirectly(world, x, y, z, 0, 0); @@ -140,6 +163,7 @@ public class MazeBuilder setBlockDirectly(world, x, y, z, 0, 0); setBlockDirectly(world, x, y + 1, z, 0, 0); } + private static void buildBox(World world, Point3D offset, Point3D minCorner, Point3D maxCorner, int blockID, int metadata) { diff --git a/src/main/java/StevenDimDoors/experimental/SphereDecayOperation.java b/src/main/java/StevenDimDoors/experimental/SphereDecayOperation.java new file mode 100644 index 0000000..95587b6 --- /dev/null +++ b/src/main/java/StevenDimDoors/experimental/SphereDecayOperation.java @@ -0,0 +1,84 @@ +package StevenDimDoors.experimental; + +import java.util.Random; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockContainer; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.tileentity.TileEntityChest; +import net.minecraft.tileentity.TileEntityDispenser; +import net.minecraft.world.World; +import StevenDimDoors.mod_pocketDim.DDLoot; +import StevenDimDoors.mod_pocketDim.DDProperties; +import StevenDimDoors.mod_pocketDim.Point3D; +import StevenDimDoors.mod_pocketDim.schematic.WorldOperation; + +/** + * Provides an operation for damaging structures based on a spherical area. The chance of damage decreases + * with the square of the distance from the center of the sphere. + * @author SenseiKiwi + * + */ +public class SphereDecayOperation extends WorldOperation +{ + private Random random; + private double scaling; + private double centerX; + private double centerY; + private double centerZ; + private int primaryBlockID; + private int primaryMetadata; + private int secondaryBlockID; + private int secondaryMetadata; + + public SphereDecayOperation(Random random, int primaryBlockID, int primaryMetadata, int secondaryBlockID, int secondaryMetadata) + { + super("SphereDecayOperation"); + this.random = random; + this.primaryBlockID = primaryBlockID; + this.primaryMetadata = primaryMetadata; + this.secondaryBlockID = secondaryBlockID; + this.secondaryMetadata = secondaryMetadata; + } + + @Override + protected boolean initialize(World world, int x, int y, int z, int width, int height, int length) + { + // Calculate a scaling factor so that the probability of decay + // at the edge of the largest dimension of our bounds is 20%. + scaling = Math.max(width - 1, Math.max(height - 1, length - 1)) / 2.0; + scaling *= scaling * 0.20; + + centerX = x + width / 2.0; + centerY = y + height / 2.0; + centerZ = z + length / 2.0; + return true; + } + + @Override + protected boolean applyToBlock(World world, int x, int y, int z) + { + // Don't raise any notifications. This operation is only designed to run + // when a dimension is being generated, which means there are no players around. + if (!world.isAirBlock(x, y, z)) + { + double dx = (centerX - x - 0.5); + double dy = (centerY - y - 0.5); + double dz = (centerZ - z - 0.5); + double squareDistance = dx * dx + dy * dy + dz * dz; + + if (squareDistance < 0.5 || random.nextDouble() < scaling / squareDistance) + { + world.setBlock(x, y, z, primaryBlockID, primaryMetadata, 1); + } + else if (random.nextDouble() < scaling / squareDistance) + { + world.setBlock(x, y, z, secondaryBlockID, secondaryMetadata, 1); + } + } + return true; + } +}