package cofh.lib.world;
import static cofh.lib.world.WorldGenMinableCluster.*;
import cofh.lib.util.WeightedRandomBlock;
import java.util.List;
import java.util.Random;
import net.minecraft.world.World;
import net.minecraft.world.gen.feature.WorldGenerator;
public class WorldGenGeode extends WorldGenerator
{
private final List<WeightedRandomBlock> cluster;
private final List<WeightedRandomBlock> outline;
private final WeightedRandomBlock[] genBlock;
public List<WeightedRandomBlock> fillBlock = null;
public boolean hollow = false;
public int width = 16;
public int height = 8;
public WorldGenGeode(List<WeightedRandomBlock> resource,
List<WeightedRandomBlock> material, List<WeightedRandomBlock> cover) {
cluster = resource;
genBlock = material.toArray(new WeightedRandomBlock[material.size()]);
outline = cover;
}
@Override
public boolean generate(World world, Random rand, int xStart, int yStart, int zStart) {
int heightOff = height / 2;
int widthOff = width / 2;
xStart -= widthOff;
zStart -= widthOff;
if (yStart <= heightOff)
return false;
yStart -= heightOff;
boolean[] spawnBlock = new boolean[width * width * height];
boolean[] hollowBlock = new boolean[width * width * height];
int W = width - 1, H = height - 1;
for (int i = 0, e = rand.nextInt(4) + 4; i < e; ++i) {
double xSize = rand.nextDouble() * 6.0D + 3.0D;
double ySize = rand.nextDouble() * 4.0D + 2.0D;
double zSize = rand.nextDouble() * 6.0D + 3.0D;
double xCenter = rand.nextDouble() * (width - xSize - 2.0D) + 1.0D + xSize / 2.0D;
double yCenter = rand.nextDouble() * (height - ySize - 4.0D) + 2.0D + ySize / 2.0D;
double zCenter = rand.nextDouble() * (width - zSize - 2.0D) + 1.0D + zSize / 2.0D;
double minDist = hollow ? rand.nextGaussian() * 0.15 + 0.4 : 0;
for (int x = 1; x < W; ++x) {
for (int z = 1; z < W; ++z) {
for (int y = 1; y < H; ++y) {
double xDist = (x - xCenter) / (xSize / 2.0D);
double yDist = (y - yCenter) / (ySize / 2.0D);
double zDist = (z - zCenter) / (zSize / 2.0D);
double dist = xDist * xDist + yDist * yDist + zDist * zDist;
if (dist < 1.0D)
spawnBlock[(x * width + z) * height + y] = hollow ? dist > minDist : true;
if (hollow)
hollowBlock[(x * width + z) * height + y] = dist <= minDist;
}
}
}
}
int x;
int y;
int z;
for (x = 0; x < width; ++x) {
for (z = 0; z < width; ++z) {
for (y = 0; y < height; ++y) {
boolean flag = (fillBlock != null &&
hollowBlock[(x * width + z) * height + y]) ||
spawnBlock[(x * width + z) * height + y] || (
(x < W && spawnBlock[((x + 1) * width + z) * height + y]) ||
(x > 0 && spawnBlock[((x - 1) * width + z) * height + y]) ||
(z < W && spawnBlock[(x * width + (z + 1)) * height + y]) ||
(z > 0 && spawnBlock[(x * width + (z - 1)) * height + y]) ||
(y < H && spawnBlock[(x * width + z) * height + (y + 1)]) ||
(y > 0 && spawnBlock[(x * width + z) * height + (y - 1)]));
if (flag && !canGenerateInBlock(world, xStart + x, yStart + y, zStart + z, genBlock)) {
return false;
}
}
}
}
boolean r = false;
for (x = 0; x < width; ++x) {
for (z = 0; z < width; ++z) {
for (y = 0; y < height; ++y) {
if (spawnBlock[(x * width + z) * height + y]) {
boolean t = generateBlock(world, xStart + x, yStart + y, zStart + z, cluster);
r |= t;
if (!t) {
spawnBlock[(x * width + z) * height + y] = false;
}
}
}
}
}
for (x = 0; x < width; ++x) {
for (z = 0; z < width; ++z) {
for (y = 0; y < height; ++y) {
if (fillBlock != null && hollowBlock[(x * width + z) * height + y]) {
r |= generateBlock(world, xStart + x, yStart + y, zStart + z, fillBlock);
} else {
boolean flag = !spawnBlock[(x * width + z) * height + y] && (
(x < W && spawnBlock[((x + 1) * width + z) * height + y]) ||
(x > 0 && spawnBlock[((x - 1) * width + z) * height + y]) ||
(z < W && spawnBlock[(x * width + (z + 1)) * height + y]) ||
(z > 0 && spawnBlock[(x * width + (z - 1)) * height + y]) ||
(y < H && spawnBlock[(x * width + z) * height + (y + 1)]) ||
(y > 0 && spawnBlock[(x * width + z) * height + (y - 1)]));
if (flag) {
r |= generateBlock(world, xStart + x, yStart + y, zStart + z, outline);
}
}
}
}
}
return r;
}
}