/**
* Tries to break a block using a item, including Player time checks if available
*
* @param Vector3 $vector
* @param Item &$item (if null, can break anything)
* @param Player $player
*
* @return boolean
*/
public function useBreakOn(Vector3 $vector, Item &$item = null, Player $player = null)
{
$target = $this->getBlock($vector);
//TODO: Adventure mode checks
if ($item === null) {
$item = Item::get(Item::AIR, 0, 0);
}
if ($player instanceof Player) {
$ev = new BlockBreakEvent($player, $target, $item, ($player->getGamemode() & 0x1) === 1 ? true : false);
$lastTime = $player->lastBreak - 0.1;
//TODO: replace with true lag
if (($player->getGamemode() & 0x1) > 0) {
$ev->setInstaBreak(true);
} elseif ($lastTime + $target->getBreakTime($item) >= microtime(true)) {
$ev->setCancelled();
}
if ($item instanceof Item and !$target->isBreakable($item) and $ev->getInstaBreak() === false) {
$ev->setCancelled();
}
if (!$player->isOp() and ($distance = $this->server->getConfigInt("spawn-protection", 16)) > -1) {
$t = new Vector2($target->x, $target->z);
$s = new Vector2($this->getSpawn()->x, $this->getSpawn()->z);
if ($t->distance($s) <= $distance) {
//set it to cancelled so plugins can bypass this
$ev->setCancelled();
}
}
$this->server->getPluginManager()->callEvent($ev);
if ($ev->isCancelled()) {
return false;
}
$player->lastBreak = microtime(true);
} elseif ($item instanceof Item and !$target->isBreakable($item)) {
return false;
}
$level = $target->getLevel();
if ($level instanceof Level) {
$above = $level->getBlock(new Vector3($target->x, $target->y + 1, $target->z));
if ($above instanceof Block) {
if ($above->getID() === Item::FIRE) {
$level->setBlock($above, new Air(), true);
}
}
}
$drops = $target->getDrops($item);
//Fixes tile entities being deleted before getting drops
$target->onBreak($item);
$tile = $this->getTile($target);
if ($tile instanceof Tile) {
if ($tile instanceof InventoryHolder) {
if ($tile instanceof Chest) {
$tile->unpair();
}
foreach ($tile->getInventory()->getContents() as $item) {
$this->dropItem($target, $item);
}
}
$tile->close();
}
if ($item instanceof Item) {
$item->useOn($target);
if ($item->isTool() and $item->getDamage() >= $item->getMaxDurability()) {
$item = Item::get(Item::AIR, 0, 0);
}
}
if (!$player instanceof Player or ($player->getGamemode() & 0x1) === 0) {
foreach ($drops as $drop) {
if ($drop[2] > 0) {
$this->dropItem($vector->add(0.5, 0.5, 0.5), Item::get($drop[0], $drop[1], $drop[2]));
}
}
}
return true;
}