blob: 2b03aee305a7018960c2305dd472cd23fb538012 [file] [log] [blame] [raw]
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.concurrent.ThreadLocalRandom;
public class DefaultDispenseBehavior implements DispenseBehavior {
public static final DefaultDispenseBehavior INSTANCE = new DefaultDispenseBehavior();
protected DefaultDispenseBehavior() {}
@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 = ThreadLocalRandom.current().nextDouble() * 0.1 + 0.2;
double velocityX = facing.getModX() * velocity;
double velocityY = 0.2;
double velocityZ = facing.getModZ() * velocity;
velocityX += ThreadLocalRandom.current().nextGaussian() * 0.0075 * power;
velocityY += ThreadLocalRandom.current().nextGaussian() * 0.0075 * power;
velocityZ += ThreadLocalRandom.current().nextGaussian() * 0.0075 * power;
BlockDispenseEvent dispenseEvent = new BlockDispenseEvent(block, items,
new Vector(velocityX, velocityY, velocityZ));
EventFactory.getInstance().callEvent(dispenseEvent);
if (!dispenseEvent.isCancelled()) {
GlowItem item = block.getWorld().dropItem(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));
}
}