package net.glowstone.block.blocktype; import net.glowstone.EventFactory; import net.glowstone.GlowWorld; import net.glowstone.block.GlowBlock; import net.glowstone.block.GlowBlockState; import net.glowstone.block.ItemTable; import net.glowstone.entity.GlowPlayer; import net.glowstone.generator.populators.overworld.FlowerForestPopulator; import org.bukkit.GrassSpecies; import org.bukkit.Material; import org.bukkit.block.BlockFace; import org.bukkit.event.block.BlockFadeEvent; import org.bukkit.event.block.BlockGrowEvent; import org.bukkit.event.block.BlockSpreadEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.material.LongGrass; public class BlockGrass extends BlockType implements IBlockGrowable { public BlockGrass() { setDrops(new ItemStack(Material.DIRT, 1)); } @Override public boolean isFertilizable(GlowBlock block) { return true; } @Override public boolean canTickRandomly() { return true; } @Override public boolean canGrowWithChance(GlowBlock block) { return true; } @Override public void grow(GlowPlayer player, GlowBlock block) { final GlowWorld world = block.getWorld(); int i = 0; do { int j = 0; while (true) { // if there's available space if (block.getRelative(BlockFace.UP).getType() == Material.AIR) { final GlowBlock b = block.getRelative(BlockFace.UP); final GlowBlockState blockState = b.getState(); if (random.nextFloat() < 0.125D) { // sometimes grow random flower // would be better to call a method that choose a random // flower depending on the biome Material flower = FlowerForestPopulator.FLOWERS[random.nextInt(FlowerForestPopulator.FLOWERS.length)].getType(); if (ItemTable.instance().getBlock(flower).canPlaceAt(b, BlockFace.DOWN)) { blockState.setType(flower); } } else { final Material tallGrass = Material.LONG_GRASS; if (ItemTable.instance().getBlock(tallGrass).canPlaceAt(b, BlockFace.DOWN)) { // grow tall grass if possible blockState.setType(tallGrass); blockState.setData(new LongGrass(GrassSpecies.NORMAL)); } } BlockGrowEvent growEvent = new BlockGrowEvent(b, blockState); EventFactory.callEvent(growEvent); if (!growEvent.isCancelled()) { blockState.update(true); } } else if (j < i / 16) { // look around for grass block int x = block.getX(); int y = block.getY(); int z = block.getZ(); x += random.nextInt(3) - 1; y += (random.nextInt(3)) * random.nextInt(3) / 2; z += random.nextInt(3) - 1; if (world.getBlockAt(x, y, z).getType() == Material.GRASS) { j++; continue; } } i++; break; } } while (i < 128); } @Override public void updateBlock(GlowBlock block) { if (block.getLightLevel() < 4 || block.getRelative(BlockFace.UP).getMaterialValues().getLightOpacity() > 2) { // grass block turns into dirt block final GlowBlockState state = block.getState(); state.setType(Material.DIRT); BlockFadeEvent fadeEvent = new BlockFadeEvent(block, state); EventFactory.callEvent(fadeEvent); if (!fadeEvent.isCancelled()) { state.update(true); } } else if (block.getLightLevel() >= 9) { final GlowWorld world = block.getWorld(); int sourceX = block.getX(); int sourceY = block.getY(); int sourceZ = block.getZ(); // grass spread randomly around for (int i = 0; i < 4; i++) { int x = sourceX + random.nextInt(3) - 1; int z = sourceZ + random.nextInt(3) - 1; int y = sourceY + random.nextInt(5) - 3; final GlowBlock targetBlock = world.getBlockAt(x, y, z); if (targetBlock.getType() == Material.DIRT && targetBlock.getData() == 0 && // only spread on normal dirt targetBlock.getRelative(BlockFace.UP).getMaterialValues().getLightOpacity() <= 2 && targetBlock.getRelative(BlockFace.UP).getLightLevel() >= 4) { final GlowBlockState state = targetBlock.getState(); state.setType(Material.GRASS); state.setRawData((byte) 0); BlockSpreadEvent spreadEvent = new BlockSpreadEvent(state.getBlock(), block, state); EventFactory.callEvent(spreadEvent); if (!spreadEvent.isCancelled()) { state.update(true); } } } } } }