package net.glowstone.dispenser; import net.glowstone.EventFactory; import net.glowstone.block.GlowBlock; import net.glowstone.block.blocktype.BlockDispenser; import net.glowstone.entity.objects.GlowItem; import org.bukkit.Effect; import org.bukkit.Location; import org.bukkit.block.BlockFace; import org.bukkit.event.block.BlockDispenseEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.util.Vector; import java.util.Random; public class DefaultDispenseBehavior implements DispenseBehavior { private final Random random = new Random(); @Override public ItemStack dispense(GlowBlock block, ItemStack stack) { ItemStack result = dispenseStack(block, stack); playDispenseSound(block); spawnDispenseParticles(block, BlockDispenser.getFacing(block)); return result; } protected ItemStack dispenseStack(GlowBlock block, ItemStack stack) { BlockFace facing = BlockDispenser.getFacing(block); Vector dispensePosition = BlockDispenser.getDispensePosition(block); ItemStack items = new ItemStack(stack.getType(), 1); stack.setAmount(stack.getAmount() - 1); doDispense(block, items, 6, facing, dispensePosition); return stack.getAmount() > 0 ? stack : null; } private void doDispense(GlowBlock block, ItemStack items, int power, BlockFace facing, Vector target) { double x = target.getX(); double y = target.getY(); double z = target.getZ(); if (facing.getModY() != 0) { y -= 0.125; } else { y -= 0.15625; } double velocity = random.nextDouble() * 0.1 + 0.2; double velocityX = facing.getModX() * velocity; double velocityY = 0.2; double velocityZ = facing.getModZ() * velocity; velocityX += random.nextGaussian() * 0.0075 * power; velocityY += random.nextGaussian() * 0.0075 * power; velocityZ += random.nextGaussian() * 0.0075 * power; BlockDispenseEvent dispenseEvent = new BlockDispenseEvent(block, items, new Vector(velocityX, velocityY, velocityZ)); EventFactory.callEvent(dispenseEvent); if (!dispenseEvent.isCancelled()) { GlowItem item = new GlowItem(new Location(block.getWorld(), x, y, z), dispenseEvent.getItem()); item.setVelocity(dispenseEvent.getVelocity()); } } private int getParticleMetadataForFace(BlockFace face) { return face.getModX() + 1 + (face.getModZ() + 1) * 3; } protected void playDispenseSound(GlowBlock block) { block.getWorld().playEffect(block.getLocation(), Effect.CLICK2, 0); } protected void spawnDispenseParticles(GlowBlock block, BlockFace facing) { block.getWorld().playEffect(block.getLocation(), Effect.SMOKE, getParticleMetadataForFace(facing)); } }