package net.glowstone.block.blocktype;
import net.glowstone.block.GlowBlock;
import net.glowstone.block.GlowBlockState;
import net.glowstone.block.entity.BlockEntity;
import net.glowstone.block.entity.DispenserEntity;
import net.glowstone.block.state.GlowDispenser;
import net.glowstone.chunk.GlowChunk;
import net.glowstone.entity.GlowPlayer;
import net.glowstone.inventory.MaterialMatcher;
import net.glowstone.inventory.ToolType;
import org.bukkit.Material;
import org.bukkit.block.BlockFace;
import org.bukkit.inventory.ItemStack;
import org.bukkit.material.Dispenser;
import org.bukkit.material.MaterialData;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.Vector;
public class BlockDispenser extends BlockContainer {
public static Vector getDispensePosition(GlowBlock block) {
BlockFace facing = getFacing(block);
double x = block.getX() + 0.7 * facing.getModX();
double y = block.getY() + 0.7 * facing.getModY();
double z = block.getZ() + 0.7 * facing.getModZ();
return new Vector(x, y, z);
}
public static BlockFace getFacing(GlowBlock block) {
GlowBlockState state = block.getState();
MaterialData data = state.getData();
if (!(data instanceof Dispenser)) {
return BlockFace.SELF;
}
Dispenser dispenserData = (Dispenser) data;
return dispenserData.getFacing();
}
@Override
public BlockEntity createBlockEntity(GlowChunk chunk, int cx, int cy, int cz) {
return new DispenserEntity(chunk.getBlock(cx, cy, cz));
}
@Override
public void placeBlock(GlowPlayer player, GlowBlockState state, BlockFace face, ItemStack holding, Vector clickedLoc) {
super.placeBlock(player, state, face, holding, clickedLoc);
MaterialData data = state.getData();
if (data instanceof Dispenser) {
((Dispenser) data).setFacingDirection(getOppositeBlockFace(player.getLocation(), true));
state.setData(data);
} else {
warnMaterialData(Dispenser.class, data);
}
}
@Override
protected MaterialMatcher getNeededMiningTool(GlowBlock block) {
return ToolType.PICKAXE;
}
@Override
public void afterPlace(GlowPlayer player, GlowBlock block, ItemStack holding, GlowBlockState oldState) {
updatePhysics(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 block) {
GlowBlock up = block.getRelative(BlockFace.UP);
boolean powered = block.isBlockPowered() | block.isBlockIndirectlyPowered() |
up.isBlockPowered() | up.isBlockIndirectlyPowered();
GlowBlockState state = block.getState();
MaterialData data = state.getData();
if (!(data instanceof Dispenser)) {
return;
}
boolean isTriggered = (data.getData() >> 3 & 1) != 0;
if (powered && !isTriggered) {
new BukkitRunnable() {
@Override
public void run() {
trigger(block);
}
}.runTaskLater(null, 4);
// TODO replace this with dispenser materialdata class (as soon as it provides access to this property)
data.setData((byte) (data.getData() | 0x8));
state.update();
} else if (!powered && isTriggered) {
data.setData((byte) (data.getData() & ~0x8));
state.update();
}
}
public void trigger(GlowBlock block) {
BlockEntity te = block.getBlockEntity();
if (!(te instanceof DispenserEntity)) {
return;
}
DispenserEntity teDispenser = (DispenserEntity) te;
GlowDispenser dispenser = (GlowDispenser) teDispenser.getState();
dispenser.dispense();
}
}