Completed Doorway Placement

All doorways are placed sensibly now, including vertical passages
between different floors.
This commit is contained in:
SenseiKiwi 2013-12-30 19:59:17 -04:00
parent 3e33b94c98
commit 5e60960661
2 changed files with 183 additions and 75 deletions

View file

@ -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<PartitionNode, DoorwayData> roomGraph, World world, Point3D offset)
{
for (IGraphNode<PartitionNode, DoorwayData> node : roomGraph.nodes())
@ -36,14 +39,11 @@ public class MazeBuilder
}
}
private static void carveDoorways(DirectedGraph<PartitionNode, DoorwayData> roomGraph, World world, Point3D offset, Random random)
{
final int MIN_DOUBLE_DOOR_SPAN = 10;
int gap;
private static void carveDoorways(DirectedGraph<PartitionNode, DoorwayData> roomGraph, World world,
Point3D offset, SphereDecayOperation decay, Random random)
{
char axis;
Point3D lower;
Point3D upper;
DoorwayData doorway;
for (IGraphNode<PartitionNode, DoorwayData> 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)
{

View file

@ -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;
}
}