package com.pam.harvestcraft.worldgen; import java.util.Random; import com.pam.harvestcraft.HarvestCraft; import com.pam.harvestcraft.blocks.BlockRegistry; import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.biome.Biome; import net.minecraft.world.chunk.IChunkGenerator; import net.minecraft.world.chunk.IChunkProvider; import net.minecraftforge.common.BiomeDictionary; import net.minecraftforge.fml.common.IWorldGenerator; public class BeehiveWorldGen implements IWorldGenerator { @Override public void generate(Random random, int chunkX, int chunkZ, World world, IChunkGenerator chunkGenerator, IChunkProvider chunkProvider) { if (!HarvestCraft.config.enableBeehiveGeneration) return; final Biome biome = world.getBiomeForCoordsBody(new BlockPos(chunkX, 0, chunkZ)); if (BiomeDictionary.hasType(biome, BiomeDictionary.Type.END) || BiomeDictionary.hasType(biome, BiomeDictionary.Type.NETHER)) { return; } tryGenerateBeehives(world, random, chunkX * 16 + 8, chunkZ * 16 + 8); } private static void tryGenerateBeehives(World world, Random random, int chunkX, int chunkZ) { final BlockPos.MutableBlockPos variableBlockPos = new BlockPos.MutableBlockPos(); if (random.nextFloat() < HarvestCraft.config.beehiveRarity / 33.0f) { int x = chunkX + random.nextInt(16); int z = chunkZ + random.nextInt(16); int y = world.getHeight(x, z) - 1; // if there is a tree, world height will be just above the top leaves of the tree. variableBlockPos.setPos(x, y, z); if (!isBlockLeaves(world, variableBlockPos)) return; int newY = getHeightBelowLeaves(world, x, y, z); if (newY < 0) return; variableBlockPos.setY(newY); world.setBlockState(variableBlockPos, BlockRegistry.beehive.getDefaultState()); } } private static boolean isBlockLeaves(World world, BlockPos blockPos) { IBlockState blockState = world.getBlockState(blockPos); final Block block = blockState.getBlock(); return block.isLeaves(blockState, world, blockPos); } private static int getHeightBelowLeaves(World world, int posX, int posY, int posZ) { final BlockPos.MutableBlockPos variableBlockPos = new BlockPos.MutableBlockPos(); variableBlockPos.setPos(posX, posY, posZ); // Starting from a known leaves block, descend until air block is reached. // If another block is reached (non-leaves, non-air), abort and return -1. for (int y = posY, sealevel = world.getSeaLevel(); y >= sealevel; --y) { variableBlockPos.setY(y); final IBlockState blockState = world.getBlockState(variableBlockPos); final Block block = blockState.getBlock(); if (block.isLeaves(blockState, world, variableBlockPos)) continue; if (world.isAirBlock(variableBlockPos)) return y; return -1; } return -1; } }