public function useItemOn(Vector3 $vector, Item &$item, int $face, float $fx = 0.0, float $fy = 0.0, float $fz = 0.0, Player $player = null) : bool
{
$target = $this->getBlock($vector);
$block = $target->getSide($face);
if ($block->y > 127 or $block->y < 0) {
return false;
}
if ($target->getId() === Item::AIR) {
return false;
}
if ($player !== null) {
$ev = new PlayerInteractEvent($player, $item, $target, $face, $target->getId() === 0 ? PlayerInteractEvent::RIGHT_CLICK_AIR : PlayerInteractEvent::RIGHT_CLICK_BLOCK);
if (!$player->isOp() and ($distance = $this->server->getSpawnRadius()) > -1) {
$t = new Vector2($target->x, $target->z);
$s = new Vector2($this->getSpawnLocation()->x, $this->getSpawnLocation()->z);
if (count($this->server->getOps()->getAll()) > 0 and $t->distance($s) <= $distance) {
//set it to cancelled so plugins can bypass this
$ev->setCancelled();
}
}
if ($player->isSpectator()) {
$ev->setCancelled();
}
$this->server->getPluginManager()->callEvent($ev);
if (!$ev->isCancelled()) {
$target->onUpdate(self::BLOCK_UPDATE_TOUCH);
if (!$player->isSneaking()) {
if ($target->canBeActivated() === true and $target->onActivate($item, $player) === true) {
if ($item->getCount() <= 0) {
$item = Item::get(Item::AIR, 0, 0);
} elseif ($item->isTool() and $item->getDamage() >= $item->getMaxDurability()) {
$item = Item::get(Item::AIR, 0, 0);
}
return true;
}
if ($item->canBeActivated() and $item->onActivate($this, $player, $block, $target, $face, $fx, $fy, $fz)) {
if ($item->getCount() <= 0) {
$item = Item::get(Item::AIR, 0, 0);
return true;
} elseif ($item->isTool() and $item->getDamage() >= $item->getMaxDurability()) {
$item = Item::get(Item::AIR, 0, 0);
return true;
}
}
}
/*if(!$player->isSneaking() and $target->canBeActivated() === true and $target->onActivate($item, $player) === true){
return true;
}
if(!$player->isSneaking() and $item->canBeActivated() and $item->onActivate($this, $player, $block, $target, $face, $fx, $fy, $fz)){
if($item->getCount() <= 0){
$item = Item::get(Item::AIR, 0, 0);
return true;
}
}*/
} else {
return false;
}
} elseif ($target->canBeActivated() === true and $target->onActivate($item, $player) === true) {
return true;
}
if ($item->canBePlaced()) {
$hand = $item->getBlock();
$hand->position($block);
} else {
return false;
}
if (!($block->canBeReplaced() === true or $hand->getId() === Item::SLAB and $block->getId() === Item::SLAB)) {
return false;
}
if ($target->canBeReplaced() === true) {
$block = $target;
$hand->position($block);
//$face = -1;
}
if ($hand->isSolid() === true and $hand->getBoundingBox() !== null) {
$entities = $this->getCollidingEntities($hand->getBoundingBox());
$realCount = 0;
foreach ($entities as $e) {
if ($e instanceof Arrow or $e instanceof DroppedItem or $e instanceof Player and $e->isSpectator()) {
continue;
}
++$realCount;
}
if ($player !== null) {
if ($diff = $player->getNextPosition()->subtract($player->getPosition()) and $diff->lengthSquared() > 1.0E-5) {
$bb = $player->getBoundingBox()->getOffsetBoundingBox($diff->x, $diff->y, $diff->z);
if ($hand->getBoundingBox()->intersectsWith($bb)) {
++$realCount;
}
}
}
if ($realCount > 0) {
return false;
//Entity in block
}
}
$tag = $item->getNamedTagEntry("CanPlaceOn");
if ($tag instanceof ListTag) {
$canPlace = false;
foreach ($tag as $v) {
if ($v instanceof StringTag) {
$entry = Item::fromString($v->getValue());
if ($entry->getId() > 0 and $entry->getBlock() !== null and $entry->getBlock()->getId() === $target->getId()) {
$canPlace = true;
break;
}
}
}
if (!$canPlace) {
return false;
}
}
if ($player !== null) {
$ev = new BlockPlaceEvent($player, $hand, $block, $target, $item);
if (!$player->isOp() and ($distance = $this->server->getSpawnRadius()) > -1) {
$t = new Vector2($target->x, $target->z);
$s = new Vector2($this->getSpawnLocation()->x, $this->getSpawnLocation()->z);
if (count($this->server->getOps()->getAll()) > 0 and $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;
}
}
if ($hand->place($item, $block, $target, $face, $fx, $fy, $fz, $player) === false) {
return false;
}
$this->addSound(new BlockPlaceSound($this->getBlock($block)));
//Get updated block, $block is still the original block and cannot be used directly
if ($hand->getId() === Item::SIGN_POST or $hand->getId() === Item::WALL_SIGN) {
$nbt = new CompoundTag("", ["id" => new StringTag("id", Tile::SIGN), "x" => new IntTag("x", $block->x), "y" => new IntTag("y", $block->y), "z" => new IntTag("z", $block->z), "Text1" => new StringTag("Text1", ""), "Text2" => new StringTag("Text2", ""), "Text3" => new StringTag("Text3", ""), "Text4" => new StringTag("Text4", "")]);
if ($player !== null) {
$nbt->Creator = new StringTag("Creator", $player->getRawUniqueId());
}
if ($item->hasCustomBlockData()) {
foreach ($item->getCustomBlockData() as $key => $v) {
$nbt->{$key} = $v;
}
}
Tile::createTile("Sign", $this->getChunk($block->x >> 4, $block->z >> 4), $nbt);
}
if ($player != null && $player->isCreative()) {
$item->setCount($item->getCount());
} else {
$item->setCount($item->getCount() - 1);
}
if ($item->getCount() <= 0) {
$item = Item::get(Item::AIR, 0, 0);
}
return true;
}