package net.glowstone.block.blocktype;
import net.glowstone.EventFactory;
import net.glowstone.block.GlowBlock;
import net.glowstone.block.GlowBlockState;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.event.block.BlockGrowEvent;
public class BlockCactus extends BlockType {
private static final BlockFace[] NEAR_BLOCKS = new BlockFace[]{BlockFace.NORTH, BlockFace.SOUTH, BlockFace.WEST, BlockFace.EAST};
@Override
public boolean canPlaceAt(GlowBlock block, BlockFace against) {
Material below = block.getRelative(BlockFace.DOWN).getType();
return (below == Material.CACTUS || below == Material.SAND) && !hasNearBlocks(block);
}
@Override
public void onNearBlockChanged(GlowBlock block, BlockFace face, GlowBlock changedBlock, Material oldType, byte oldData, Material newType, byte newData) {
updatePhysics(block);
}
@Override
public void updatePhysics(GlowBlock me) {
if (!canPlaceAt(me, BlockFace.DOWN)) {
me.breakNaturally();
}
}
@Override
public boolean canTickRandomly() {
return true;
}
@Override
public void updateBlock(GlowBlock block) {
final GlowBlock blockAbove = block.getRelative(BlockFace.UP);
// check it's the highest block of cactus
if (blockAbove.isEmpty()) {
// check the current cactus height
Block blockBelow = block.getRelative(BlockFace.DOWN);
int height = 1;
while (blockBelow.getType() == Material.CACTUS) {
height++;
blockBelow = blockBelow.getRelative(BlockFace.DOWN);
}
if (height < 3) {
GlowBlockState state = block.getState();
if (state.getRawData() < 15) {
// increase age
state.setRawData((byte) (state.getRawData() + 1));
state.update(true);
} else {
// grow the cactus on the above block
state.setRawData((byte) 0);
state.update(true);
state = blockAbove.getState();
state.setType(Material.CACTUS);
state.setRawData((byte) 0);
BlockGrowEvent growEvent = new BlockGrowEvent(blockAbove, state);
EventFactory.callEvent(growEvent);
if (!growEvent.isCancelled()) {
state.update(true);
}
updatePhysics(blockAbove);
}
}
}
}
private boolean hasNearBlocks(GlowBlock block) {
for (BlockFace face : NEAR_BLOCKS) {
if (!canPlaceNear(block.getRelative(face).getType())) {
return true;
}
}
return false;
}
private boolean canPlaceNear(Material type) {
// TODO: return true for non-buildable blocks
switch (type) {
case AIR:
case WATER:
case STATIONARY_WATER:
case LAVA:
case STATIONARY_LAVA:
case PORTAL:
case ENDER_PORTAL:
case RED_ROSE:
case YELLOW_FLOWER:
return true;
default:
return false;
}
}
}