package erebus.world; import java.util.List; import java.util.Random; import erebus.ModBiomes; import erebus.ModBlocks; import erebus.core.handler.configs.ConfigHandler; import erebus.world.biomes.BiomeBaseErebus; import erebus.world.structure.MapGenErebusCaves; import erebus.world.structure.MapGenErebusRavine; import net.minecraft.block.BlockFalling; import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.EnumCreatureType; import net.minecraft.init.Blocks; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.biome.Biome; import net.minecraft.world.biome.Biome.SpawnListEntry; import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.ChunkPrimer; import net.minecraft.world.chunk.IChunkGenerator; import net.minecraft.world.chunk.IChunkProvider; import net.minecraft.world.gen.MapGenBase; import net.minecraft.world.gen.NoiseGeneratorOctaves; import net.minecraft.world.gen.NoiseGeneratorPerlin; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.terraingen.ChunkGeneratorEvent; import net.minecraftforge.fml.common.eventhandler.Event.Result; public class ChunkProviderErebus implements IChunkProvider, IChunkGenerator { private final World worldObj; private final Random rand; private final NoiseGeneratorOctaves noiseGen1; private final NoiseGeneratorOctaves noiseGen2; private final NoiseGeneratorOctaves noiseGen3; private final NoiseGeneratorOctaves noiseGen4; private final NoiseGeneratorOctaves noiseGen5; private final NoiseGeneratorOctaves noiseGen6; private double[] noiseArray; private double[] stoneNoise; private double[] noiseData1; private double[] noiseData2; private double[] noiseData3; private double[] noiseData4; private double[] noiseData5; private NoiseGeneratorPerlin perlinAdditional1; private NoiseGeneratorPerlin perlinAdditional2; private Biome[] biomesForGeneration; private final MapGenBase caveGenerator; private final MapGenBase ravineGenerator; public ChunkProviderErebus(World world, long seed) { worldObj = world; rand = new Random(seed + 1); noiseGen1 = new NoiseGeneratorOctaves(rand, 16); noiseGen2 = new NoiseGeneratorOctaves(rand, 16); noiseGen3 = new NoiseGeneratorOctaves(rand, 8); noiseGen4 = new NoiseGeneratorOctaves(rand, 4); noiseGen5 = new NoiseGeneratorOctaves(rand, 10); noiseGen6 = new NoiseGeneratorOctaves(rand, 16); perlinAdditional1 = new NoiseGeneratorPerlin(rand, 4); perlinAdditional2 = new NoiseGeneratorPerlin(rand, 4); stoneNoise = new double[256]; caveGenerator = new MapGenErebusCaves(); ravineGenerator = new MapGenErebusRavine(); } public void generateTerrain(int x, int z, ChunkPrimer chunkPrimer) { int i = 4; int k = i + 1; int l = 17; int i1 = i + 1; noiseArray = initializeNoiseField(noiseArray, x * i, 0, z * i, k, l, i1); for (int j1 = 0; j1 < i; ++j1) for (int k1 = 0; k1 < i; ++k1) for (int l1 = 0; l1 < 16; ++l1) { double d0 = 0.125D; double d1 = noiseArray[((j1 + 0) * i1 + k1 + 0) * l + l1 + 0]; double d2 = noiseArray[((j1 + 0) * i1 + k1 + 1) * l + l1 + 0]; double d3 = noiseArray[((j1 + 1) * i1 + k1 + 0) * l + l1 + 0]; double d4 = noiseArray[((j1 + 1) * i1 + k1 + 1) * l + l1 + 0]; double d5 = (noiseArray[((j1 + 0) * i1 + k1 + 0) * l + l1 + 1] - d1) * d0; double d6 = (noiseArray[((j1 + 0) * i1 + k1 + 1) * l + l1 + 1] - d2) * d0; double d7 = (noiseArray[((j1 + 1) * i1 + k1 + 0) * l + l1 + 1] - d3) * d0; double d8 = (noiseArray[((j1 + 1) * i1 + k1 + 1) * l + l1 + 1] - d4) * d0; for (int i2 = 0; i2 < 8; ++i2) { double d9 = 0.25D; double d10 = d1; double d11 = d2; double d12 = (d3 - d1) * d9; double d13 = (d4 - d2) * d9; for (int j2 = 0; j2 < 4; ++j2) { double d14 = 0.25D; double d15 = d10; double d16 = (d11 - d10) * d14; for (int k2 = 0; k2 < 4; ++k2) { IBlockState iblockstate = null; if (d15 > 0.0D) iblockstate = ModBlocks.UMBERSTONE.getDefaultState(); int l2 = j2 + j1 * 4; int i3 = i2 + l1 * 8; int j3 = k2 + k1 * 4; chunkPrimer.setBlockState(l2, i3, j3, iblockstate); d15 += d16; } d10 += d12; d11 += d13; } d1 += d5; d2 += d6; d3 += d7; d4 += d8; } } } @Override public Chunk provideChunk(int x, int z) { rand.setSeed(x * 341873128712L + z * 132897987541L); ChunkPrimer chunkprimer = new ChunkPrimer(); biomesForGeneration = worldObj.getBiomeProvider().loadBlockGeneratorData(biomesForGeneration, x * 16, z * 16, 16, 16); generateTerrain(x, z, chunkprimer); replaceBlocksForBiome(x, z, biomesForGeneration, chunkprimer); caveGenerator.generate(worldObj, x, z, chunkprimer); ravineGenerator.generate(worldObj, x, z, chunkprimer); Chunk chunk = new Chunk(worldObj, chunkprimer, x, z); byte[] biomeArrayReference = chunk.getBiomeArray(); for (int a = 0; a < biomeArrayReference.length; ++a) biomeArrayReference[a] = (byte) Biome.getIdForBiome(biomesForGeneration[a]); chunk.generateSkylightMap(); chunk.resetRelightChecks(); return chunk; } private double[] initializeNoiseField(double[] noise, int x, int y, int z, int sizeX, int sizeY, int sizeZ) { if (noise == null) noise = new double[sizeX * sizeY * sizeZ]; double d = 684.412D; double d1 = 2053.236D; noiseData4 = noiseGen5.generateNoiseOctaves(noiseData4, x, y, z, sizeX, 1, sizeZ, 1D, 0D, 1D); noiseData5 = noiseGen6.generateNoiseOctaves(noiseData5, x, y, z, sizeX, 1, sizeZ, 100D, 0D, 100D); noiseData1 = noiseGen3.generateNoiseOctaves(noiseData1, x, y, z, sizeX, sizeY, sizeZ, d * 0.0125D, d1 / 60D, d * 0.0125D); noiseData2 = noiseGen1.generateNoiseOctaves(noiseData2, x, y, z, sizeX, sizeY, sizeZ, d, d1, d); noiseData3 = noiseGen2.generateNoiseOctaves(noiseData3, x, y, z, sizeX, sizeY, sizeZ, d, d1, d); int index = 0; int j = 0; double ad[] = new double[sizeY]; double oneOver512 = 1D / 512D; double groundNoiseMp = 1D / 2048D; for (int k = 0; k < sizeY; ++k) { ad[k] = Math.cos(k * Math.PI * 6D / sizeY) * 2D; double d2 = k; if (k > sizeY / 2) d2 = sizeY - 1 - k; if (d2 < 4D) { d2 = 4D - d2; ad[k] -= d2 * d2 * d2 * 10D; } } for (int xx = 0; xx < sizeX; ++xx) for (int zz = 0; zz < sizeZ; ++zz) { double d3 = (noiseData4[j] + 256D) * oneOver512; if (d3 > 1.0D) d3 = 1.0D; double d4 = 0.0D; double d5 = noiseData5[j] * 0.000125D; if (d5 < 0.0D) d5 = -d5; d5 = d5 * 3D - 3D; if (d5 < 0.0D) { d5 /= 2D; if (d5 < -1D) d5 = -1D; d5 /= 1.4D; d5 *= 0.5D; d3 = 0.0D; } else { if (d5 > 1.0D) d5 = 1.0D; d5 /= 6D; } d3 += 0.5D; d5 = d5 * sizeY * 0.0625D; j++; for (int yy = 0; yy < sizeY; ++yy) { double d6 = 0.0D; double d7 = ad[yy]; double d8 = noiseData2[index] * groundNoiseMp; double d9 = noiseData3[index] * groundNoiseMp; double d10 = (noiseData1[index] * 0.1D + 1.0D) * 0.5D; if (d10 < 0.0D) d6 = d8; else if (d10 > 1.0D) d6 = d9; else d6 = d8 + (d9 - d8) * d10; d6 -= d7; if (yy > sizeY - 4) { double d11 = (yy - (sizeY - 4)) / 3F; d6 = d6 * (1.0D - d11) + -10D * d11; } if (yy < d4) { double d12 = (d4 - yy) * 0.25D; if (d12 < 0.0D) d12 = 0.0D; if (d12 > 1.0D) d12 = 1.0D; d6 = d6 * (1.0D - d12) + -10D * d12; } noise[index] = d6; ++index; } } return noise; } public static int swampWaterHeight = 24; public void replaceBlocksForBiome(int x, int z, Biome[] biomes, ChunkPrimer primer) { ChunkGeneratorEvent.ReplaceBiomeBlocks event = new ChunkGeneratorEvent.ReplaceBiomeBlocks(this, x, z, primer, worldObj); MinecraftForge.EVENT_BUS.post(event); if (event.getResult() == Result.DENY) return; byte var5 = 0; stoneNoise = noiseGen4.generateNoiseOctaves(stoneNoise, x * 16, z * 16, 0, 16, 16, 1, 0.0625D, 0.0625D, 0.0625D); double d0 = 0.03125D; double[] additionalNoise1 = new double[256]; double[] additionalNoise2 = new double[256]; additionalNoise1 = perlinAdditional1.getRegion(additionalNoise1, x * 16, z * 16, 16, 16, d0 * 2.0D, d0 * 2.0D, 1.0D); additionalNoise2 = perlinAdditional2.getRegion(additionalNoise2, x * 16, z * 16, 16, 16, d0 * 2.0D, d0 * 2.0D, 1.0D); for (int zInChunk = 0; zInChunk < 16; ++zInChunk) for (int xInChunk = 0; xInChunk < 16; ++xInChunk) { int horIndex = xInChunk + zInChunk * 16; BiomeBaseErebus biome = (BiomeBaseErebus) biomes[horIndex]; // float temperature = biome.getFloatTemperature(0, 0, 0); int var12 = (int) (stoneNoise[xInChunk + zInChunk * 16] / 3D + 3D + rand.nextDouble() * 0.25D); int var13 = -1; IBlockState topBlock = biome.topBlock; IBlockState fillerBlock = biome.fillerBlock; int preHeightIndex = (xInChunk * 16 + zInChunk) * 128; if (biome == ModBiomes.submergedSwamp) { if (additionalNoise1[horIndex] > 0) { int h = getLowestAirBlock(primer, xInChunk, zInChunk, preHeightIndex, 25, 35); if (h > swampWaterHeight) { for (h += 0; h > 23.08D - additionalNoise1[horIndex]; h--) { if (h == swampWaterHeight) { if(rand.nextInt(32) == 0) primer.setBlockState(xInChunk, h + 1, zInChunk, Blocks.WATERLILY.getDefaultState()); } if (h <= swampWaterHeight) { primer.setBlockState(xInChunk, h, zInChunk, Blocks.WATER.getDefaultState()); if(additionalNoise1[horIndex] < 0.08D) { if(ConfigHandler.INSTANCE.generateVents && rand.nextInt(25) == 0) primer.setBlockState(xInChunk, h, zInChunk, Blocks.LIT_PUMPKIN.getDefaultState()); // SWAMP_VENT else primer.setBlockState(xInChunk, h, zInChunk, ModBlocks.UMBERSTONE.getDefaultState()); } else if(additionalNoise1[horIndex] < 0.5D ) primer.setBlockState(xInChunk, h -1 , zInChunk, Blocks.SAND.getDefaultState()); else if(additionalNoise1[horIndex] <= 2) primer.setBlockState(xInChunk, h - 2, zInChunk, ModBlocks.QUICK_SAND.getDefaultState()); else if(additionalNoise2[horIndex] > 2) primer.setBlockState(xInChunk, h - 3, zInChunk, ModBlocks.MUD.getDefaultState()); else { primer.setBlockState(xInChunk, h - 4, zInChunk, Blocks.CLAY.getDefaultState()); primer.setBlockState(xInChunk, h, zInChunk, Blocks.WATER.getDefaultState()); } } else primer.setBlockState(xInChunk, h, zInChunk, Blocks.AIR.getDefaultState()); } } }/* else if (additionalNoise1[horIndex] > -0.15D) { int h = getLowestAirBlock(primer, xInChunk, zInChunk, preHeightIndex, 25, 35); if (h > swampWaterHeight) { for (h += 0; h >= (22 + h) / 2; h--) primer.setBlockState(xInChunk, h, zInChunk, Blocks.RED_SANDSTONE.getDefaultState()); h++; // if (h >= swampWaterHeight && rand.nextInt(8) == 0 && blocks[preHeightIndex + h] == Blocks.air && blocks[preHeightIndex + h + 1] == Blocks.air) { // blocks[preHeightIndex + h] = blocks[preHeightIndex + h + 1] = ModBlocks.bullrush; // metadata[preHeightIndex + h + 1] = 8; } }*/ } if ((biome == ModBiomes.volcanicDesert || biome == ModBiomes.desertSubCharredForest) && Math.abs(additionalNoise1[horIndex]) < 1) { int h = getLowestAirBlock(primer, xInChunk, zInChunk, preHeightIndex, 25, 32); if (h > 0) { primer.setBlockState(xInChunk, preHeightIndex + h, zInChunk, Blocks.AIR.getDefaultState()); for (int h2 = h - 1; h2 > h - 1 - 3 * (1 - Math.abs(additionalNoise1[horIndex])); h2--) primer.setBlockState(xInChunk, h2, zInChunk, Blocks.FLOWING_LAVA.getDefaultState()); } } for (int yInChunk = 127; yInChunk >= 0; --yInChunk) { int index = (xInChunk * 16 + zInChunk) * 128 + yInChunk; if (yInChunk <= 5 && yInChunk <= 0 + rand.nextInt(5) || yInChunk >= 122 && yInChunk >= 127 - rand.nextInt(5)) primer.setBlockState(xInChunk, yInChunk, zInChunk, Blocks.BEDROCK.getDefaultState()); else { if (biome == ModBiomes.submergedSwamp && yInChunk < swampWaterHeight && primer.getBlockState(xInChunk, yInChunk, zInChunk) == Blocks.AIR) if(primer.getBlockState(xInChunk, yInChunk - 1, zInChunk).isOpaqueCube() && yInChunk < swampWaterHeight - 1) primer.setBlockState(xInChunk, yInChunk, zInChunk, Blocks.WATER.getDefaultState()); IBlockState iblockstate2 = primer.getBlockState(xInChunk, yInChunk, zInChunk); if (iblockstate2.getMaterial() == Material.AIR) var13 = -1; else if (iblockstate2.getBlock().getDefaultState() == ModBlocks.UMBERSTONE.getDefaultState()) if (var13 == -1) { //if (var12 <= 0) { // topBlock = Blocks.air.getDefaultState(); // primer.setBlockState(xInChunk, yInChunk, zInChunk, topBlock); //fillerBlock = ModBlocks.umberstone.getDefaultState(); //} else // if (yInChunk >= var5 + 4 && yInChunk <= var5 + 120) { //topBlock = biome.topBlock; primer.setBlockState(xInChunk, yInChunk + 1, zInChunk, topBlock); // fillerBlock = biome.fillerBlock; //} if (yInChunk < var5 && topBlock.getMaterial() == Material.AIR) //if (temperature < 0.15F) // topBlock = Blocks.ice; //else topBlock = Blocks.WATER.getDefaultState(); var13 = var12; } } } } } private int getLowestAirBlock(ChunkPrimer primer, int xInChunk, int zInChunk, int preHeightIndex, int minH, int maxH) { for (int h = Math.min(minH, maxH); h <= Math.max(minH, maxH); h++) { IBlockState iblockstate = primer.getBlockState(xInChunk, h, zInChunk); if (primer.getBlockState(xInChunk, h, zInChunk).getMaterial() == Material.AIR) return h; } return -1; } @Override public void populate(int x, int z) { BlockFalling.fallInstantly = true; BlockPos blockCoord = new BlockPos(x * 16, 0, z * 16); BlockPos blockCoordOffSet = new BlockPos(blockCoord.getX() + 16, 0, blockCoord.getZ() + 16); //int blockCoordX = x * 16; //int blockCoordZ = z * 16; Biome biomeBase = worldObj.getBiomeGenForCoords(blockCoordOffSet); if (biomeBase instanceof BiomeBaseErebus) { BiomeBaseErebus biome = (BiomeBaseErebus) biomeBase; rand.setSeed(worldObj.getSeed()); rand.setSeed(x * (rand.nextLong() / 2L * 2L + 1L) + z * (rand.nextLong() / 2L * 2L + 1L) ^ worldObj.getSeed()); biome.populate(worldObj, rand, blockCoord.getX(), blockCoord.getZ()); biome.decorate(worldObj, rand, blockCoord.getX(), blockCoord.getZ()); // SpawnerErebus.onChunkPopulate(worldObj, rand, biome, blockCoordX + 8, blockCoordZ + 8); } // for (int attempt = 0; attempt < 14; ++attempt) // new WorldGenSpiderDungeons().generate(worldObj, rand, blockCoordX + rand.nextInt(16) + 8, rand.nextInt(128), blockCoordZ + rand.nextInt(16) + 8); BlockFalling.fallInstantly = false; } // @Override // @SuppressWarnings("rawtypes") // public List getPossibleCreatures(EnumCreatureType creatureType, int x, int y, int z) { // Biome biome = worldObj.getBiomeGenForCoords(x, z); // return biome == null ? null : biome.getSpawnableList(creatureType); // } @Override public String makeString() { return "ErebusRandomLevelSource"; } @Override public Chunk getLoadedChunk(int x, int z) { // TODO Auto-generated method stub return null; } @Override public boolean unloadQueuedChunks() { // TODO Auto-generated method stub return false; } @Override public boolean generateStructures(Chunk chunkIn, int x, int z) { // TODO Auto-generated method stub return false; } @Override public List<SpawnListEntry> getPossibleCreatures(EnumCreatureType creatureType, BlockPos pos) { // TODO Auto-generated method stub return null; } @Override public BlockPos getStrongholdGen(World worldIn, String structureName, BlockPos position) { // TODO Auto-generated method stub return null; } @Override public void recreateStructures(Chunk chunkIn, int x, int z) { // TODO Auto-generated method stub } }