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 WorldGenStalagmite extends WorldGenerator {
protected final List<WeightedRandomBlock> cluster;
protected final WeightedRandomBlock[] baseBlock;
protected final WeightedRandomBlock[] genBlock;
public int minHeight = 7;
public int heightVariance = 4;
public int sizeVariance = 2;
public int heightMod = 5;
public int genSize = 0;
public boolean smooth = false;
public boolean fat = true;
public boolean altSinc = false;
public WorldGenStalagmite(List<WeightedRandomBlock> resource, List<WeightedRandomBlock> block, List<WeightedRandomBlock> gblock) {
cluster = resource;
baseBlock = block.toArray(new WeightedRandomBlock[block.size()]);
genBlock = gblock.toArray(new WeightedRandomBlock[gblock.size()]);
}
protected int getHeight(int x, int z, int size, Random rand, int height) {
if (smooth) {
if ((x*x + z*z) * 4 >= size * size * 5) return 0;
final double lim = (altSinc ? 600f : (fat ? 1f : .5f) * 400f) / size;
final double pi = Math.PI;
double r;
r = Math.sqrt((r=((x*lim)/pi))*r + (r=((z*lim)/pi))*r) * pi/180;
if (altSinc && (x*x + z*z) < (size*1.1f))
r = size * 0.0082;
if (r == 0) return height;
if (!altSinc)
return (int)Math.round(height * (fat ? Math.sin(r) / r : Math.sin(r=r*pi) / r));
double sinc = (Math.sin(r) / r);
return (int)Math.round(Math.min(sinc*height+3, height*(sinc*2+(rand.nextGaussian()*.65*Math.sin(r=r*(pi*4))/r))/2.3));
} else {
int absx = x < 0 ? -x : x, absz = (z < 0 ? -z : z);
int dist = fat ? (absx < absz ? absz + absx / 2 : absx + absz / 2) : absx + absz;
if (dist == 0) return height;
return rand.nextInt(height / dist);
}
}
@Override
public boolean generate(World world, Random rand, int xStart, int yStart, int zStart) {
while (world.isAirBlock(xStart, yStart, zStart) && yStart > 0) {
--yStart;
}
if (!canGenerateInBlock(world, xStart, yStart++, zStart, baseBlock)) {
return false;
}
int maxHeight = (heightVariance > 0 ? rand.nextInt(heightVariance) : 0) + minHeight;
int size = (genSize > 0 ? genSize : maxHeight / heightMod);
if (sizeVariance > 0) size += rand.nextInt(sizeVariance);
boolean r = false;
for (int x = -size; x <= size; ++x) {
for (int z = -size; z <= size; ++z) {
if (!canGenerateInBlock(world, xStart + x, yStart - 1, zStart + z, baseBlock)) {
continue;
}
int height = getHeight(x, z, size, rand, maxHeight);
for (int y = 0; y < height; ++y) {
r |= generateBlock(world, xStart + x, yStart + y, zStart + z, genBlock, cluster);
}
}
}
return r;
}
}