Added First Step of Maze Generation
Added classes for generating maze dungeons. At the moment, the dungeons are generated in place of our pocket dimensions to make testing easy. We'll need to restore pocket generation later and integrate the mazes into the dungeon packs later. Currently, the structures are very incomplete (they don't even have doorways), but this is only the first step.
This commit is contained in:
parent
72196c6afd
commit
820e72f17a
3 changed files with 282 additions and 0 deletions
172
src/main/java/StevenDimDoors/experimental/MazeGenerator.java
Normal file
172
src/main/java/StevenDimDoors/experimental/MazeGenerator.java
Normal file
|
@ -0,0 +1,172 @@
|
|||
package StevenDimDoors.experimental;
|
||||
|
||||
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;
|
||||
import StevenDimDoors.mod_pocketDim.Point3D;
|
||||
|
||||
public class MazeGenerator
|
||||
{
|
||||
public static final int ROOT_WIDTH = 40;
|
||||
public static final int ROOT_LENGTH = 40;
|
||||
public static final int ROOT_HEIGHT = 19;
|
||||
private static final int MIN_HEIGHT = 4;
|
||||
private static final int MIN_SIDE = 3;
|
||||
private static final int SPLIT_COUNT = 8;
|
||||
|
||||
private MazeGenerator() { }
|
||||
|
||||
public static void generate(World world, int x, int y, int z, Random random)
|
||||
{
|
||||
SpatialNode root = partitionRooms(ROOT_WIDTH, ROOT_HEIGHT, ROOT_LENGTH, SPLIT_COUNT, random);
|
||||
buildRooms(root, world, new Point3D(x - ROOT_WIDTH / 2, y - ROOT_HEIGHT - 1, z - ROOT_WIDTH / 2));
|
||||
|
||||
}
|
||||
|
||||
private static SpatialNode partitionRooms(int width, int height, int length, int maxLevels, Random random)
|
||||
{
|
||||
SpatialNode root = new SpatialNode(width, height, length);
|
||||
splitByRandomX(root, maxLevels, random);
|
||||
return root;
|
||||
}
|
||||
|
||||
private static void splitByRandomX(SpatialNode node, int levels, Random random)
|
||||
{
|
||||
if (node.width() >= 2 * MIN_SIDE)
|
||||
{
|
||||
node.splitByX(MathHelper.getRandomIntegerInRange(random,
|
||||
node.minCorner().getX() + MIN_SIDE, node.maxCorner().getX() - MIN_SIDE + 1));
|
||||
|
||||
if (levels > 1)
|
||||
{
|
||||
splitByRandomZ(node.leftChild(), levels - 1, random);
|
||||
splitByRandomZ(node.rightChild(), levels - 1, random);
|
||||
}
|
||||
}
|
||||
else if (levels > 1)
|
||||
{
|
||||
splitByRandomZ(node, levels - 1, random);
|
||||
}
|
||||
}
|
||||
|
||||
private static void splitByRandomZ(SpatialNode node, int levels, Random random)
|
||||
{
|
||||
if (node.length() >= 2 * MIN_SIDE)
|
||||
{
|
||||
node.splitByZ(MathHelper.getRandomIntegerInRange(random,
|
||||
node.minCorner().getZ() + MIN_SIDE, node.maxCorner().getZ() - MIN_SIDE + 1));
|
||||
|
||||
if (levels > 1)
|
||||
{
|
||||
splitByRandomY(node.leftChild(), levels - 1, random);
|
||||
splitByRandomY(node.rightChild(), levels - 1, random);
|
||||
}
|
||||
}
|
||||
else if (levels > 1)
|
||||
{
|
||||
splitByRandomY(node, levels - 1, random);
|
||||
}
|
||||
}
|
||||
|
||||
private static void splitByRandomY(SpatialNode node, int levels, Random random)
|
||||
{
|
||||
if (node.height() >= 2 * MIN_HEIGHT)
|
||||
{
|
||||
node.splitByY(MathHelper.getRandomIntegerInRange(random,
|
||||
node.minCorner().getY() + MIN_HEIGHT, node.maxCorner().getY() - MIN_HEIGHT + 1));
|
||||
|
||||
if (levels > 1)
|
||||
{
|
||||
splitByRandomX(node.leftChild(), levels - 1, random);
|
||||
splitByRandomX(node.rightChild(), levels - 1, random);
|
||||
}
|
||||
}
|
||||
else if (levels > 1)
|
||||
{
|
||||
splitByRandomX(node, levels - 1, random);
|
||||
}
|
||||
}
|
||||
|
||||
private static void buildRooms(SpatialNode node, World world, Point3D offset)
|
||||
{
|
||||
if (node.isLeaf())
|
||||
{
|
||||
buildBox(world, offset, node.minCorner(), node.maxCorner());
|
||||
}
|
||||
else
|
||||
{
|
||||
buildRooms(node.leftChild(), world, offset);
|
||||
buildRooms(node.rightChild(), world, offset);
|
||||
}
|
||||
}
|
||||
|
||||
private static void buildBox(World world, Point3D offset, Point3D minCorner, Point3D maxCorner)
|
||||
{
|
||||
int minX = minCorner.getX() + offset.getX();
|
||||
int minY = minCorner.getY() + offset.getY();
|
||||
int minZ = minCorner.getZ() + offset.getZ();
|
||||
|
||||
int maxX = maxCorner.getX() + offset.getX();
|
||||
int maxY = maxCorner.getY() + offset.getY();
|
||||
int maxZ = maxCorner.getZ() + offset.getZ();
|
||||
|
||||
int x, y, z;
|
||||
int blockID = Block.stoneBrick.blockID;
|
||||
|
||||
for (x = minX; x <= maxX; x++)
|
||||
{
|
||||
for (z = minZ; z <= maxZ; z++)
|
||||
{
|
||||
setBlockDirectly(world, x, minY, z, blockID, 0);
|
||||
setBlockDirectly(world, x, maxY, z, blockID, 0);
|
||||
}
|
||||
}
|
||||
for (x = minX; x <= maxX; x++)
|
||||
{
|
||||
for (y = minY; y <= maxY; y++)
|
||||
{
|
||||
setBlockDirectly(world, x, y, minZ, blockID, 0);
|
||||
setBlockDirectly(world, x, y, maxZ, blockID, 0);
|
||||
}
|
||||
}
|
||||
for (z = minZ; z <= maxZ; z++)
|
||||
{
|
||||
for (y = minY; y <= maxY; y++)
|
||||
{
|
||||
setBlockDirectly(world, minX, y, z, blockID, 0);
|
||||
setBlockDirectly(world, maxX, y, z, blockID, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private 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;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
105
src/main/java/StevenDimDoors/experimental/SpatialNode.java
Normal file
105
src/main/java/StevenDimDoors/experimental/SpatialNode.java
Normal file
|
@ -0,0 +1,105 @@
|
|||
package StevenDimDoors.experimental;
|
||||
|
||||
import StevenDimDoors.mod_pocketDim.Point3D;
|
||||
|
||||
public class SpatialNode
|
||||
{
|
||||
private Point3D minCorner;
|
||||
private Point3D maxCorner;
|
||||
private SpatialNode leftChild = null;
|
||||
private SpatialNode rightChild = null;
|
||||
|
||||
public SpatialNode(int width, int height, int length)
|
||||
{
|
||||
minCorner = new Point3D(0, 0, 0);
|
||||
maxCorner = new Point3D(width - 1, height - 1, length - 1);
|
||||
}
|
||||
|
||||
private SpatialNode(Point3D minCorner, Point3D maxCorner)
|
||||
{
|
||||
this.minCorner = minCorner;
|
||||
this.maxCorner = maxCorner;
|
||||
}
|
||||
|
||||
public int width()
|
||||
{
|
||||
return (maxCorner.getX() - minCorner.getX() + 1);
|
||||
}
|
||||
|
||||
public int height()
|
||||
{
|
||||
return (maxCorner.getY() - minCorner.getY() + 1);
|
||||
}
|
||||
|
||||
public int length()
|
||||
{
|
||||
return (maxCorner.getZ() - minCorner.getZ() + 1);
|
||||
}
|
||||
|
||||
public boolean isLeaf()
|
||||
{
|
||||
return (leftChild == null);
|
||||
}
|
||||
|
||||
public SpatialNode leftChild()
|
||||
{
|
||||
return leftChild;
|
||||
}
|
||||
|
||||
public SpatialNode rightChild()
|
||||
{
|
||||
return rightChild;
|
||||
}
|
||||
|
||||
public Point3D minCorner()
|
||||
{
|
||||
return minCorner;
|
||||
}
|
||||
|
||||
public Point3D maxCorner()
|
||||
{
|
||||
return maxCorner;
|
||||
}
|
||||
|
||||
public void splitByX(int rightStart)
|
||||
{
|
||||
if (leftChild != null)
|
||||
{
|
||||
throw new IllegalStateException("This node has already been split.");
|
||||
}
|
||||
if (rightStart <= minCorner.getX() || rightStart > maxCorner.getX())
|
||||
{
|
||||
throw new IllegalArgumentException("The specified cutting plane is invalid.");
|
||||
}
|
||||
leftChild = new SpatialNode(minCorner, new Point3D(rightStart - 1, maxCorner.getY(), maxCorner.getZ()));
|
||||
rightChild = new SpatialNode(new Point3D(rightStart, minCorner.getY(), minCorner.getZ()), maxCorner);
|
||||
}
|
||||
|
||||
public void splitByY(int rightStart)
|
||||
{
|
||||
if (leftChild != null)
|
||||
{
|
||||
throw new IllegalStateException("This node has already been split.");
|
||||
}
|
||||
if (rightStart <= minCorner.getY() || rightStart > maxCorner.getY())
|
||||
{
|
||||
throw new IllegalArgumentException("The specified cutting plane is invalid.");
|
||||
}
|
||||
leftChild = new SpatialNode(minCorner, new Point3D(maxCorner.getX(), rightStart - 1, maxCorner.getZ()));
|
||||
rightChild = new SpatialNode(new Point3D(minCorner.getX(), rightStart, minCorner.getZ()), maxCorner);
|
||||
}
|
||||
|
||||
public void splitByZ(int rightStart)
|
||||
{
|
||||
if (leftChild != null)
|
||||
{
|
||||
throw new IllegalStateException("This node has already been split.");
|
||||
}
|
||||
if (rightStart <= minCorner.getZ() || rightStart > maxCorner.getZ())
|
||||
{
|
||||
throw new IllegalArgumentException("The specified cutting plane is invalid.");
|
||||
}
|
||||
leftChild = new SpatialNode(minCorner, new Point3D(maxCorner.getX(), maxCorner.getY(), rightStart - 1));
|
||||
rightChild = new SpatialNode(new Point3D(minCorner.getX(), minCorner.getY(), rightStart), maxCorner);
|
||||
}
|
||||
}
|
|
@ -8,6 +8,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.MazeGenerator;
|
||||
import StevenDimDoors.mod_pocketDim.DDProperties;
|
||||
import StevenDimDoors.mod_pocketDim.Point3D;
|
||||
import StevenDimDoors.mod_pocketDim.blocks.IDimDoor;
|
||||
|
@ -472,6 +473,7 @@ public class PocketBuilder
|
|||
Point3D door = new Point3D(x, y, z);
|
||||
BlockRotator.transformPoint(center, door, orientation - BlockRotator.EAST_DOOR_METADATA, door);
|
||||
|
||||
/*
|
||||
//Build the outer layer of Eternal Fabric
|
||||
buildBox(world, center.getX(), center.getY(), center.getZ(), (size / 2), properties.PermaFabricBlockID, false, 0);
|
||||
|
||||
|
@ -481,6 +483,9 @@ public class PocketBuilder
|
|||
buildBox(world, center.getX(), center.getY(), center.getZ(), (size / 2) - layer, properties.FabricBlockID,
|
||||
layer < (wallThickness - 1) && properties.TNFREAKINGT_Enabled, properties.NonTntWeight);
|
||||
}
|
||||
*/
|
||||
|
||||
MazeGenerator.generate(world, x, y, z, random);
|
||||
|
||||
//Build the door
|
||||
int doorOrientation = BlockRotator.transformMetadata(BlockRotator.EAST_DOOR_METADATA, orientation - BlockRotator.EAST_DOOR_METADATA + 2, properties.DimensionalDoorID);
|
||||
|
|
Loading…
Add table
Reference in a new issue