Overhauled RiftGenerator
Overhauled RIftGenerator. The code is significantly more readable now. It's commented and much more compact. I also removed all fields from RiftGenerator - they were unnecessary and using them increased the risk of buggy code. Made the code rely solely on the Random instance provided by MC, meaning our rifts and gateways will be tied to the world seed. Tweaked the code slightly so that clusters of rifts and gateways can never generate in the same chunk. This was previously possible, although highly unlikely. It's a work of art now. <3
This commit is contained in:
parent
8dce8c1c26
commit
b2f5c4ea4e
1 changed files with 107 additions and 111 deletions
|
@ -12,31 +12,14 @@ import cpw.mods.fml.common.IWorldGenerator;
|
|||
|
||||
public class RiftGenerator implements IWorldGenerator
|
||||
{
|
||||
//TODO: Stop the madness here...
|
||||
//Based on reviewing the code in this mod, I believe that all IWorldGenerators
|
||||
//must work as singletons. Given that each call that comes into them is independent,
|
||||
//we shouldn't have ANY fields in here! At best they will end up causing bugs.
|
||||
//In particular, using our own instance of Random instead of one derived from the world
|
||||
//seed means that our chunk generation isn't linked to the world seed. Bad, very bad!
|
||||
//I'm going to fix this later. <_<;; ~SenseiKiwi
|
||||
|
||||
private int minableBlockId;
|
||||
private int numberOfBlocks;
|
||||
int cycles=40;
|
||||
boolean shouldSave = false;
|
||||
int count = 0;
|
||||
int i;
|
||||
int k;
|
||||
int j;
|
||||
Random rand = new Random();
|
||||
boolean shouldGenHere = true;
|
||||
LinkData link;
|
||||
DimData dimData;
|
||||
|
||||
public static final int MAX_GATEWAY_GENERATION_CHANCE = 10000;
|
||||
public static final int MAX_CLUSTER_GENERATION_CHANCE = 10000;
|
||||
private static final int CLUSTER_GROWTH_CHANCE = 80;
|
||||
private static final int MAX_CLUSTER_GROWTH_CHANCE = 100;
|
||||
private static final int MIN_RIFT_Y = 21;
|
||||
private static final int MAX_RIFT_Y = 250;
|
||||
private static final int CHUNK_LENGTH = 16;
|
||||
private static final int GATEWAY_RADIUS = 3;
|
||||
private static DDProperties properties = null;
|
||||
|
||||
public RiftGenerator()
|
||||
|
@ -48,106 +31,119 @@ public class RiftGenerator implements IWorldGenerator
|
|||
@Override
|
||||
public void generate(Random random, int chunkX, int chunkZ, World world, IChunkProvider chunkGenerator, IChunkProvider chunkProvider)
|
||||
{
|
||||
//TODO: This code could really use some cleaning up... ~SenseiKiwi
|
||||
|
||||
shouldGenHere = properties.WorldRiftGenerationEnabled && !(world.provider instanceof pocketProvider) && !world.isRemote;
|
||||
|
||||
if (shouldGenHere && random.nextInt(MAX_CLUSTER_GENERATION_CHANCE) < properties.ClusterGenerationChance)
|
||||
//Don't generate rifts or gateways if the rift generation flag is disabled,
|
||||
//the current world is a pocket dimension, or the world is remote.
|
||||
if (!properties.WorldRiftGenerationEnabled || world.provider instanceof pocketProvider || world.isRemote)
|
||||
{
|
||||
i = chunkX * 16 - random.nextInt(16);
|
||||
k = chunkZ * 16 - random.nextInt(16);
|
||||
j = world.getHeightValue(i, k);
|
||||
return;
|
||||
}
|
||||
|
||||
if (j > 20 && world.getBlockId(i, j, k) == 0)
|
||||
int x, y, z;
|
||||
int blockID;
|
||||
LinkData link;
|
||||
|
||||
//Randomly decide whether to place a cluster of rifts here
|
||||
if (random.nextInt(MAX_CLUSTER_GENERATION_CHANCE) < properties.ClusterGenerationChance)
|
||||
{
|
||||
// System.out.println(String.valueOf(i)+"x "+String.valueOf(j)+"y "+String.valueOf(k)+"z"+"Large gen");
|
||||
link = null;
|
||||
do
|
||||
{
|
||||
//Pick a random point on the surface of the chunk
|
||||
x = chunkX * CHUNK_LENGTH - random.nextInt(CHUNK_LENGTH);
|
||||
z = chunkZ * CHUNK_LENGTH - random.nextInt(CHUNK_LENGTH);
|
||||
y = world.getHeightValue(x, z);
|
||||
|
||||
link = new LinkData(world.provider.dimensionId, 0, i, j+1, k, i, j+1, k, true,rand.nextInt(4));
|
||||
//If the point is within the acceptable altitude range and the block above is empty, then place a rift
|
||||
if (y >= MIN_RIFT_Y && y <= MAX_RIFT_Y && world.isAirBlock(x, y + 1, z))
|
||||
{
|
||||
//Create a link. If this is the first time, create a dungeon pocket and create a two-way link.
|
||||
//Otherwise, create a one-way link and connect to the destination of the first link.
|
||||
if (link == null)
|
||||
{
|
||||
link = new LinkData(world.provider.dimensionId, 0, x, y + 1, z, x, y + 1, z, true, random.nextInt(4));
|
||||
link = dimHelper.instance.createPocket(link, true, true);
|
||||
this.shouldSave=true;
|
||||
|
||||
// SchematicLoader loader = new SchematicLoader();
|
||||
// loader.init(link);
|
||||
// loader.generateSchematic(link);
|
||||
count = 0;
|
||||
while (random.nextInt(MAX_CLUSTER_GROWTH_CHANCE) < CLUSTER_GROWTH_CHANCE)
|
||||
}
|
||||
else
|
||||
{
|
||||
i = chunkX * 16 - random.nextInt(16);
|
||||
k = chunkZ * 16 - random.nextInt(16);
|
||||
link = dimHelper.instance.createLink(link.locDimID, link.destDimID, x, y + 1, z, link.destXCoord, link.destYCoord, link.destZCoord);
|
||||
}
|
||||
}
|
||||
}
|
||||
//Randomly decide whether to repeat the process and add another rift to the cluster
|
||||
while (random.nextInt(MAX_CLUSTER_GROWTH_CHANCE) < CLUSTER_GROWTH_CHANCE);
|
||||
}
|
||||
|
||||
j = world.getHeightValue(i, k);
|
||||
|
||||
if (world.isAirBlock(i, j + 1, k))
|
||||
//Randomly decide whether to place a Rift Gateway here.
|
||||
//This only happens if a rift cluster was NOT generated.
|
||||
else if (random.nextInt(MAX_GATEWAY_GENERATION_CHANCE) < properties.GatewayGenerationChance)
|
||||
{
|
||||
link = dimHelper.instance.createLink(link.locDimID,link.destDimID, i, j+1, k,link.destXCoord,link.destYCoord,link.destZCoord);
|
||||
//Pick a random point on the surface of the chunk
|
||||
x = chunkX * CHUNK_LENGTH - random.nextInt(CHUNK_LENGTH);
|
||||
z = chunkZ * CHUNK_LENGTH - random.nextInt(CHUNK_LENGTH);
|
||||
y = world.getHeightValue(x, z);
|
||||
|
||||
//Check if the point is within the acceptable altitude range, the block above that point is empty,
|
||||
//and at least one of the two blocks under that point are opaque
|
||||
if (y >= MIN_RIFT_Y && y <= MAX_RIFT_Y && world.isAirBlock(x, y + 1, z) &&
|
||||
world.isBlockOpaqueCube(x, y - 2, z) || world.isBlockOpaqueCube(x, y - 1, z))
|
||||
{
|
||||
//Create a two-way link between the upper block of the gateway and a pocket dimension
|
||||
//That pocket dimension is where we'll start a dungeon!
|
||||
link = new LinkData(world.provider.dimensionId, 0, x, y + 1, z, x, y + 1, z, true, random.nextInt(4));
|
||||
link = dimHelper.instance.createPocket(link, true, true);
|
||||
|
||||
//If the current dimension isn't Limbo, build a Rift Gateway out of Stone Bricks
|
||||
if (world.provider.dimensionId != properties.LimboDimensionID)
|
||||
{
|
||||
blockID = Block.stoneBrick.blockID;
|
||||
|
||||
//Replace some of the ground around the gateway with bricks
|
||||
for (int xc = -GATEWAY_RADIUS; xc <= GATEWAY_RADIUS; xc++)
|
||||
{
|
||||
for (int zc= -GATEWAY_RADIUS; zc <= GATEWAY_RADIUS; zc++)
|
||||
{
|
||||
//Check that the block is supported by an opaque block.
|
||||
//This prevents us from building over a cliff, on the peak of a mountain,
|
||||
//or the surface of the ocean or a frozen lake.
|
||||
if (world.isBlockOpaqueCube(x + xc, y - 2, z + zc))
|
||||
{
|
||||
//Randomly choose whether to place bricks or not. The math is designed so that the
|
||||
//chances of placing a block decrease as we get farther from the gateway's center.
|
||||
if (Math.abs(xc) + Math.abs(zc) < random.nextInt(3) + 2)
|
||||
{
|
||||
//Place Stone Bricks
|
||||
world.setBlock(x + xc, y - 1, z + zc, blockID);
|
||||
}
|
||||
else if (Math.abs(xc) + Math.abs(zc) < random.nextInt(3) + 3)
|
||||
{
|
||||
//Place Cracked Stone Bricks
|
||||
world.setBlock(x + xc, y - 1, z + zc, blockID, 2, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldGenHere && random.nextInt(MAX_GATEWAY_GENERATION_CHANCE) < properties.GatewayGenerationChance)
|
||||
{
|
||||
// System.out.println("tryingToGen");
|
||||
int blockID = Block.stoneBrick.blockID;
|
||||
if (world.provider.dimensionId == properties.LimboDimensionID)
|
||||
//Use Chiseled Stone Bricks to top off the pillars around the door
|
||||
world.setBlock(x, y + 2, z + 1, blockID, 3, 1);
|
||||
world.setBlock(x, y + 2, z - 1, blockID, 3, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Build the gateway out of Unraveled Fabric. Since nearly all the blocks in Limbo are of
|
||||
//that type, there is no point replacing the ground. Just build the tops of the columns here.
|
||||
blockID = properties.LimboBlockID;
|
||||
}
|
||||
i=chunkX*16-random.nextInt(16);
|
||||
k=chunkZ*16-random.nextInt(16);
|
||||
|
||||
j= world.getHeightValue(i, k);
|
||||
if(j>20 && world.getBlockId(i, j, k)==0)
|
||||
{
|
||||
//System.out.println(String.valueOf(i)+"x "+String.valueOf(j)+"y "+String.valueOf(k)+"z"+"small gen");
|
||||
count=0;
|
||||
|
||||
if(world.isAirBlock(i, j+1, k))
|
||||
{
|
||||
if(world.isBlockOpaqueCube(i, j-2, k)||world.isBlockOpaqueCube(i, j-1, k))
|
||||
{
|
||||
link = new LinkData(world.provider.dimensionId, 0, i, j+1, k, i, j+1, k, true,rand.nextInt(4));
|
||||
link =dimHelper.instance.createPocket(link,true, true);
|
||||
|
||||
for(int xc=-3;xc<4;xc++)
|
||||
{
|
||||
for(int zc=-3;zc<4;zc++)
|
||||
{
|
||||
for(int yc=0;yc<200;yc++)
|
||||
{
|
||||
if(yc==0&&world.isBlockOpaqueCube(i+xc, j-2,k +zc))
|
||||
{
|
||||
|
||||
if(Math.abs(xc)+Math.abs(zc)<rand.nextInt(3)+2)
|
||||
{
|
||||
world.setBlock(i+xc, j-1+yc, k+zc, blockID);
|
||||
}
|
||||
else if(Math.abs(xc)+Math.abs(zc)<rand.nextInt(3)+3)
|
||||
|
||||
{
|
||||
world.setBlock(i+xc, j-1+yc, k+zc, blockID,2,1);
|
||||
|
||||
}
|
||||
world.setBlock(x, y + 2, z + 1, blockID, 0, 1);
|
||||
world.setBlock(x, y + 2, z - 1, blockID, 0, 1);
|
||||
}
|
||||
|
||||
}
|
||||
//Place the shiny transient door into a dungeon
|
||||
ItemRiftBlade.placeDoorBlock(world, x, y + 1, z, 0, mod_pocketDim.transientDoor);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
ItemRiftBlade.placeDoorBlock(world, i, j+1, k, 0, mod_pocketDim.transientDoor);
|
||||
|
||||
{
|
||||
world.setBlock(i, j+1, k-1, blockID,0,1);
|
||||
world.setBlock(i, j+1, k+1, blockID,0,1);
|
||||
world.setBlock(i, j, k-1, blockID,0,1);
|
||||
world.setBlock(i, j, k+1, blockID,0,1);
|
||||
world.setBlock(i, j+2, k+1, blockID,3,1);
|
||||
world.setBlock(i, j+2, k-1, blockID,3,1);
|
||||
}
|
||||
this.shouldSave = true;
|
||||
}
|
||||
}
|
||||
//Build the columns around the door
|
||||
world.setBlock(x, y + 1, z - 1, blockID, 0, 1);
|
||||
world.setBlock(x, y + 1, z + 1, blockID, 0, 1);
|
||||
world.setBlock(x, y, z - 1, blockID, 0, 1);
|
||||
world.setBlock(x, y, z + 1, blockID, 0, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue