package micdoodle8.mods.galacticraft.core.world.gen; import micdoodle8.mods.galacticraft.api.prefab.world.gen.MapGenBaseMeta; import micdoodle8.mods.galacticraft.core.GCBlocks; import micdoodle8.mods.galacticraft.core.blocks.BlockBasicMoon; import micdoodle8.mods.galacticraft.core.perlin.NoiseModule; import micdoodle8.mods.galacticraft.core.perlin.generator.Gradient; import micdoodle8.mods.galacticraft.core.util.ConfigManagerCore; import micdoodle8.mods.galacticraft.core.world.gen.dungeon.DungeonConfiguration; import micdoodle8.mods.galacticraft.core.world.gen.dungeon.MapGenDungeon; import micdoodle8.mods.galacticraft.core.world.gen.dungeon.RoomBoss; import micdoodle8.mods.galacticraft.core.world.gen.dungeon.RoomTreasure; import net.minecraft.block.BlockFalling; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.EnumCreatureType; import net.minecraft.init.Blocks; import net.minecraft.util.BlockPos; import net.minecraft.util.IProgressUpdate; import net.minecraft.world.ChunkCoordIntPair; import net.minecraft.world.World; import net.minecraft.world.biome.BiomeGenBase; import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.ChunkPrimer; import net.minecraft.world.chunk.IChunkProvider; import net.minecraft.world.gen.ChunkProviderGenerate; import java.util.List; import java.util.Random; public class ChunkProviderMoon extends ChunkProviderGenerate { private final IBlockState BLOCK_TOP = GCBlocks.blockMoon.getDefaultState().withProperty(BlockBasicMoon.BASIC_TYPE_MOON, BlockBasicMoon.EnumBlockBasicMoon.MOON_TURF); private final IBlockState BLOCK_FILL = GCBlocks.blockMoon.getDefaultState().withProperty(BlockBasicMoon.BASIC_TYPE_MOON, BlockBasicMoon.EnumBlockBasicMoon.MOON_DIRT); private final IBlockState BLOCK_LOWER = GCBlocks.blockMoon.getDefaultState().withProperty(BlockBasicMoon.BASIC_TYPE_MOON, BlockBasicMoon.EnumBlockBasicMoon.MOON_STONE); private final Random rand; private final NoiseModule noiseGen1; private final NoiseModule noiseGen2; private final NoiseModule noiseGen3; private final NoiseModule noiseGen4; private final World worldObj; private final MapGenVillageMoon villageGenerator = new MapGenVillageMoon(); private final MapGenDungeon dungeonGeneratorMoon = new MapGenDungeon(new DungeonConfiguration(GCBlocks.blockMoon.getDefaultState().withProperty(BlockBasicMoon.BASIC_TYPE_MOON, BlockBasicMoon.EnumBlockBasicMoon.MOON_DUNGEON_BRICK), 25, 8, 16, 5, 6, RoomBoss.class, RoomTreasure.class)); private BiomeGenBase[] biomesForGeneration = { BiomeGenBaseMoon.moonFlat }; private final MapGenBaseMeta caveGenerator = new MapGenCavesMoon(); private static final int CRATER_PROB = 300; // DO NOT CHANGE private static final int MID_HEIGHT = 63; private static final int CHUNK_SIZE_X = 16; private static final int CHUNK_SIZE_Y = 128; private static final int CHUNK_SIZE_Z = 16; public ChunkProviderMoon(World par1World, long par2, boolean par4) { super(par1World, par2, par4, ""); this.worldObj = par1World; this.rand = new Random(par2); this.noiseGen1 = new Gradient(this.rand.nextLong(), 4, 0.25F); this.noiseGen2 = new Gradient(this.rand.nextLong(), 4, 0.25F); this.noiseGen3 = new Gradient(this.rand.nextLong(), 1, 0.25F); this.noiseGen4 = new Gradient(this.rand.nextLong(), 1, 0.25F); } @Override public void setBlocksInChunk(int chunkX, int chunkZ, ChunkPrimer primer) { this.noiseGen1.setFrequency(0.0125F); this.noiseGen2.setFrequency(0.015F); this.noiseGen3.setFrequency(0.01F); this.noiseGen4.setFrequency(0.02F); for (int x = 0; x < ChunkProviderMoon.CHUNK_SIZE_X; x++) { for (int z = 0; z < ChunkProviderMoon.CHUNK_SIZE_Z; z++) { final double d = this.noiseGen1.getNoise(x + chunkX * 16, z + chunkZ * 16) * 8; final double d2 = this.noiseGen2.getNoise(x + chunkX * 16, z + chunkZ * 16) * 24; double d3 = this.noiseGen3.getNoise(x + chunkX * 16, z + chunkZ * 16) - 0.1; d3 *= 4; double yDev; if (d3 < 0.0D) { yDev = d; } else if (d3 > 1.0D) { yDev = d2; } else { yDev = d + (d2 - d) * d3; } for (int y = 0; y < ChunkProviderMoon.CHUNK_SIZE_Y; y++) { if (y < ChunkProviderMoon.MID_HEIGHT + yDev) { primer.setBlockState(getIndex(x, y, z), BLOCK_LOWER); } } } } } @Override public void replaceBlocksForBiome(int par1, int par2, ChunkPrimer primer, BiomeGenBase[] par4ArrayOfBiomeGenBase) { final int var5 = 20; for (int var8 = 0; var8 < 16; ++var8) { for (int var9 = 0; var9 < 16; ++var9) { final int var12 = (int) (this.noiseGen4.getNoise(var8 + par1 * 16, var9 * par2 * 16) / 3.0D + 3.0D + this.rand.nextDouble() * 0.25D); int var13 = -1; IBlockState state0 = BLOCK_TOP; IBlockState state1 = BLOCK_FILL; for (int var16 = 127; var16 >= 0; --var16) { final int index = this.getIndex(var8, var16, var9); if (var16 <= this.rand.nextInt(5)) { primer.setBlockState(index, Blocks.bedrock.getDefaultState()); } else { IBlockState var18 = primer.getBlockState(index); if (Blocks.air == var18) { var13 = -1; } else if (var18 == BLOCK_LOWER) { if (var13 == -1) { if (var12 <= 0) { state0 = Blocks.air.getDefaultState(); state1 = BLOCK_LOWER; } else if (var16 >= var5 - -16 && var16 <= var5 + 1) { state0 = BLOCK_FILL; } var13 = var12; if (var16 >= var5 - 1) { primer.setBlockState(index, state0); } else if (var16 < var5 - 1 && var16 >= var5 - 2) { primer.setBlockState(index, state1); } } else if (var13 > 0) { --var13; primer.setBlockState(index, state1); } } } } } } } @Override public Chunk provideChunk(int x, int z) { this.rand.setSeed((long) x * 341873128712L + (long) z * 132897987541L); ChunkPrimer chunkprimer = new ChunkPrimer(); this.setBlocksInChunk(x, z, chunkprimer); this.biomesForGeneration = this.worldObj.getWorldChunkManager().loadBlockGeneratorData(this.biomesForGeneration, x * 16, z * 16, 16, 16); this.createCraters(x, z, chunkprimer); this.replaceBlocksForBiome(x, z, chunkprimer, this.biomesForGeneration); this.caveGenerator.generate(this, this.worldObj, x, z, chunkprimer); this.dungeonGeneratorMoon.generate(this, this.worldObj, x, z, chunkprimer); this.villageGenerator.generate(this, this.worldObj, x, z, chunkprimer); Chunk chunk = new Chunk(this.worldObj, chunkprimer, x, z); byte[] abyte = chunk.getBiomeArray(); for (int i = 0; i < abyte.length; ++i) { abyte[i] = (byte) this.biomesForGeneration[i].biomeID; } chunk.generateSkylightMap(); return chunk; } private void createCraters(int chunkX, int chunkZ, ChunkPrimer primer) { for (int cx = chunkX - 2; cx <= chunkX + 2; cx++) { for (int cz = chunkZ - 2; cz <= chunkZ + 2; cz++) { for (int x = 0; x < ChunkProviderMoon.CHUNK_SIZE_X; x++) { for (int z = 0; z < ChunkProviderMoon.CHUNK_SIZE_Z; z++) { if (Math.abs(this.randFromPoint(cx * 16 + x, (cz * 16 + z) * 1000)) < this.noiseGen4.getNoise(x * ChunkProviderMoon.CHUNK_SIZE_X + x, cz * ChunkProviderMoon.CHUNK_SIZE_Z + z) / ChunkProviderMoon.CRATER_PROB) { final Random random = new Random(cx * 16 + x + (cz * 16 + z) * 5000); final EnumCraterSize cSize = EnumCraterSize.sizeArray[random.nextInt(EnumCraterSize.sizeArray.length)]; final int size = random.nextInt(cSize.MAX_SIZE - cSize.MIN_SIZE) + cSize.MIN_SIZE; this.makeCrater(cx * 16 + x, cz * 16 + z, chunkX * 16, chunkZ * 16, size, primer); } } } } } } private void makeCrater(int craterX, int craterZ, int chunkX, int chunkZ, int size, ChunkPrimer primer) { for (int x = 0; x < ChunkProviderMoon.CHUNK_SIZE_X; x++) { for (int z = 0; z < ChunkProviderMoon.CHUNK_SIZE_Z; z++) { double xDev = craterX - (chunkX + x); double zDev = craterZ - (chunkZ + z); if (xDev * xDev + zDev * zDev < size * size) { xDev /= size; zDev /= size; final double sqrtY = xDev * xDev + zDev * zDev; double yDev = sqrtY * sqrtY * 6; yDev = 5 - yDev; int helper = 0; for (int y = 127; y > 0; y--) { if (Blocks.air != primer.getBlockState(this.getIndex(x, y, z)).getBlock() && helper <= yDev) { primer.setBlockState(this.getIndex(x, y, z), Blocks.air.getDefaultState()); helper++; } if (helper > yDev) { break; } } } } } } @Override public boolean chunkExists(int par1, int par2) { return true; } @Override public boolean unloadQueuedChunks() { return false; } @Override public int getLoadedChunkCount() { return 0; } private int getIndex(int x, int y, int z) { return (x * 16 + z) * 256 + y; } private double randFromPoint(int x, int z) { int n; n = x + z * 57; n = n << 13 ^ n; return 1.0 - (n * (n * n * 15731 + 789221) + 1376312589 & 0x7fffffff) / 1073741824.0; } @Override public void populate(IChunkProvider chunkProvider, int x, int z) { BlockFalling.fallInstantly = true; int i = x * 16; int j = z * 16; BlockPos blockpos = new BlockPos(i, 0, j); BiomeGenBase biomegenbase = this.worldObj.getBiomeGenForCoords(blockpos.add(16, 0, 16)); this.rand.setSeed(this.worldObj.getSeed()); long k = this.rand.nextLong() / 2L * 2L + 1L; long l = this.rand.nextLong() / 2L * 2L + 1L; this.rand.setSeed((long) x * k + (long) z * l ^ this.worldObj.getSeed()); if (!ConfigManagerCore.disableMoonVillageGen) { this.villageGenerator.generateStructure(this.worldObj, this.rand, new ChunkCoordIntPair(x, z)); } this.dungeonGeneratorMoon.generateStructure(this.worldObj, this.rand, new ChunkCoordIntPair(x, z)); biomegenbase.decorate(this.worldObj, this.rand, new BlockPos(i, 0, j)); BlockFalling.fallInstantly = false; } @Override public boolean saveChunks(boolean par1, IProgressUpdate par2IProgressUpdate) { return true; } @Override public boolean canSave() { return true; } @Override public String makeString() { return "MoonLevelSource"; } @SuppressWarnings({ "unchecked", "rawtypes" }) @Override public List<BiomeGenBase.SpawnListEntry> getPossibleCreatures(EnumCreatureType creatureType, BlockPos pos) { if (creatureType == EnumCreatureType.MONSTER) { return BiomeGenBaseMoon.moonFlat.getSpawnableList(creatureType); } else { return null; } } @Override public void recreateStructures(Chunk chunk, int x, int z) { if (!ConfigManagerCore.disableMoonVillageGen) { this.villageGenerator.generate(this, this.worldObj, x, z, null); } this.dungeonGeneratorMoon.generate(this, this.worldObj, x, z, null); } }