package erebus.world.structure;
import java.util.Random;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.chunk.ChunkPrimer;
import net.minecraft.world.gen.MapGenBase;
import erebus.ModBiomes;
import erebus.ModBlocks;
import erebus.world.ChunkProviderErebus;
public class MapGenErebusRavine extends MapGenBase {
protected static final IBlockState BLOCK_AIR = Blocks.AIR.getDefaultState();
private final float[] field_75046_d = new float[1024];
@Override
public void generate(World worldIn, int x, int z, ChunkPrimer primer) {
int i = this.range;
this.worldObj = worldIn;
this.rand.setSeed(worldIn.getSeed());
long j = this.rand.nextLong();
long k = this.rand.nextLong();
for (int l = x - i; l <= x + i; ++l)
{
for (int i1 = z - i; i1 <= z + i; ++i1)
{
long j1 = (long)l * j;
long k1 = (long)i1 * k;
this.rand.setSeed(j1 ^ k1 ^ worldIn.getSeed());
this.recursiveGenerate(worldIn, l, i1, x, z, primer);
}
}
}
protected void generateRavine(long seed, int x, int z, ChunkPrimer chunkPrimer, double par6, double par8, double seed0, float seed2, float seed3, float seed4, int seed5, int seed6, double seed7) {
Random random = new Random(seed);
double blockCoordX = x * 16 + 8;
double blockCoordZ = z * 16 + 8;
float f3 = 0.0F;
float f4 = 0.0F;
if (seed6 <= 0) {
int j1 = range * 16 - 16;
seed6 = j1 - random.nextInt(j1 >> 2);
}
boolean flag = false;
if (seed5 == -1) {
seed5 = seed6 / 2;
flag = true;
}
float f5 = 1.0F;
for (int k1 = 0; k1 < 128; ++k1) {
if (k1 == 0 || random.nextInt(3) == 0)
f5 = 1.0F + random.nextFloat() * random.nextFloat() * 1.0F;
field_75046_d[k1] = f5 * f5;
}
for (; seed5 < seed6; ++seed5) {
double d6 = 1.5D + MathHelper.sin(seed5 * (float) Math.PI / seed6) * seed2 * 1.0F;
double d7 = d6 * seed7;
d6 *= random.nextFloat() * 0.25D + 0.75D;
d7 *= random.nextFloat() * 0.25D + 0.75D;
float f6 = net.minecraft.util.math.MathHelper.cos(seed4);
float f7 = net.minecraft.util.math.MathHelper.sin(seed4);
par6 += MathHelper.cos(seed3) * f6;
par8 += f7;
seed0 += MathHelper.sin(seed3) * f6;
seed4 *= 0.7F;
seed4 += f4 * 0.05F;
seed3 += f3 * 0.05F;
f4 *= 0.8F;
f3 *= 0.5F;
f4 += (random.nextFloat() - random.nextFloat()) * random.nextFloat() * 2.0F;
f3 += (random.nextFloat() - random.nextFloat()) * random.nextFloat() * 4.0F;
if (flag || random.nextInt(4) != 0) {
double d8 = par6 - blockCoordX;
double d9 = seed0 - blockCoordZ;
double d10 = seed6 - seed5;
double d11 = seed2 + 2.0F + 16.0F;
if (d8 * d8 + d9 * d9 - d10 * d10 > d11 * d11)
return;
if (par6 >= blockCoordX - 16.0D - d6 * 2.0D && seed0 >= blockCoordZ - 16.0D - d6 * 2.0D && par6 <= blockCoordX + 16.0D + d6 * 2.0D && seed0 <= blockCoordZ + 16.0D + d6 * 2.0D) {
int minX = MathHelper.floor_double(par6 - d6) - x * 16 - 1;
int maxX = MathHelper.floor_double(par6 + d6) - x * 16 + 1;
int minY = MathHelper.floor_double(par8 - d7) - 1;
int maxY = MathHelper.floor_double(par8 + d7) + 1;
int minZ = MathHelper.floor_double(seed0 - d6) - z * 16 - 1;
int maxZ = MathHelper.floor_double(seed0 + d6) - z * 16 + 1;
if (minX < 0)
minX = 0;
if (maxX > 16)
maxX = 16;
if (minY < 1)
minY = 1;
if (maxY > 120)
maxY = 120;
if (minZ < 0)
minZ = 0;
if (maxZ > 16)
maxZ = 16;
boolean flag1 = false;
for (int posX = minX; !flag1 && posX < maxX; ++posX)
for (int posZ = minZ; !flag1 && posZ < maxZ; ++posZ)
for (int posY = maxY + 1; !flag1 && posY >= minY - 1; --posY)
if (posY >= 0 && posY < 128) {
if (isOceanBlock(chunkPrimer, posX, posY, posZ, x, z))
flag1 = true;
if (posY != minY - 1 && posX != minX && posX != maxX - 1 && posZ != minZ && posZ != maxZ - 1)
posY = minY;
}
if (!flag1) {
for (int posX = minX; posX < maxX; ++posX) {
double d12 = (posX + x * 16 + 0.5D - par6) / d6;
for (int posZ = minZ; posZ < maxZ; ++posZ) {
double d13 = (posZ + z * 16 + 0.5D - seed0) / d6;
boolean flag2 = false;
if (d12 * d12 + d13 * d13 < 1.0D)
for (int posY = maxY - 1; posY >= minY; --posY) {
double d14 = (posY + 0.5D - par8) / d7;
if ((d12 * d12 + d13 * d13) * field_75046_d[posY] + d14 * d14 / 6.0D < 1.0D) {
if (isTopBlock(chunkPrimer, posX, posY, posZ, x, z))
flag2 = true;
digBlock(chunkPrimer, posX, posY, posZ, x, z, flag2);
}
}
}
}
if (flag)
break;
}
}
}
}
}
@Override
protected void recursiveGenerate(World world, int x, int z, int par4, int par5, ChunkPrimer chunkPrimerIn) {
if (rand.nextInt(50) == 0) {
double d0 = x * 16 + rand.nextInt(16);
double d1 = rand.nextInt(rand.nextInt(28) + 8) + 10;
double d2 = z * 16 + rand.nextInt(16);
float f = rand.nextFloat() * (float) Math.PI * 2.0F;
float f1 = (rand.nextFloat() - 0.5F) * 2.0F / 8.0F;
float f2 = (rand.nextFloat() * 2.0F + rand.nextFloat()) * 2.0F;
generateRavine(rand.nextLong(), par4, par5, chunkPrimerIn, d0, d1, d2, f2, f, f1, 0, 0, 1.0D);
}
}
protected boolean isOceanBlock(ChunkPrimer data, int x, int y, int z, int chunkX, int chunkZ) {
net.minecraft.block.Block block = data.getBlockState(x, y, z).getBlock();
return block == Blocks.FLOWING_WATER || block == Blocks.WATER;
}
private boolean isExceptionBiome(Biome biome) {
// this may do something at some point
return false;
}
private boolean isTopBlock(ChunkPrimer data, int x, int y, int z, int chunkX, int chunkZ) {
Biome biome = worldObj.getBiomeGenForCoords(new BlockPos(x + chunkX * 16, 0, z + chunkZ * 16));
IBlockState state = data.getBlockState(x, y, z);
return isExceptionBiome(biome) ? state.getBlock() == Blocks.GRASS : state.getBlock() == biome.topBlock;
}
protected void digBlock(ChunkPrimer data, int x, int y, int z, int chunkX, int chunkZ, boolean foundTop) {
Biome biome = worldObj.getBiomeGenForCoords(new BlockPos(x + chunkX * 16, 0, z + chunkZ * 16));
IBlockState top = isExceptionBiome(biome) ? Blocks.GRASS.getDefaultState() : biome.topBlock;
IBlockState filler = isExceptionBiome(biome) ? Blocks.DIRT.getDefaultState() : biome.fillerBlock;
IBlockState state = data.getBlockState(x, y, z);
if (state.getBlock() == ModBlocks.UMBERSTONE || state.getBlock() == top.getBlock() || state.getBlock() == filler.getBlock()) {
if (y < 3)
data.setBlockState(x, y, z, Blocks.BEDROCK.getDefaultState());
else if (y < 4)
data.setBlockState(x, y, z, ModBlocks.UMBERSTONE.getDefaultState());
else if (y < 10 && Biome.getIdForBiome(biome) == Biome.getIdForBiome(ModBiomes.volcanicDesert))
data.setBlockState(x, y, z, Blocks.FLOWING_LAVA.getDefaultState());
else if (y < ChunkProviderErebus.swampWaterHeight - 1 && Biome.getIdForBiome(biome) == Biome.getIdForBiome(ModBiomes.submergedSwamp))
data.setBlockState(x, y, z, Blocks.FLOWING_WATER.getDefaultState());
else {
data.setBlockState(x, y, z, Blocks.AIR.getDefaultState());
if (foundTop && data.getBlockState(x, y - 1, z).getBlock() == filler.getBlock())
data.setBlockState(x, y - 1, z, top.getBlock().getDefaultState());
}
}
}
}