/** * 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; }