Ejemplo n.º 1
31
 /**
  * Tries to break a block using a item, including Player time checks if available
  * It'll try to lower the durability if Item is a tool, and set it to Air if broken.
  *
  * @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);
         if ($player->isSurvival() and $item instanceof Item and !$target->isBreakable($item)) {
             $ev->setCancelled();
         }
         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;
         }
         $breakTime = $player->isCreative() ? 0.15 : $target->getBreakTime($item);
         if ($player->hasEffect(Effect::SWIFTNESS)) {
             $breakTime *= pow(0.8, $player->getEffect(Effect::SWIFTNESS)->getAmplifier() + 1);
         }
         if (!$ev->getInstaBreak() and $player->lastBreak + $breakTime >= microtime(true)) {
             return false;
         }
         $player->lastBreak = PHP_INT_MAX;
     } 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
     $players = $this->getUsingChunk($target->x >> 4, $target->z >> 4);
     if ($player !== null) {
         unset($players[$player->getId()]);
         $this->addParticle(new DestroyBlockParticle($target->add(0.5, 0.5, 0.5), $target), $players);
     }
     $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 $chestItem) {
                 $this->dropItem($target, $chestItem);
             }
         }
         $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->isSurvival()) {
         foreach ($drops as $drop) {
             if ($drop[2] > 0) {
                 $this->dropItem($vector->add(0.5, 0.5, 0.5), Item::get(...$drop));
             }
         }
     }
     return true;
 }
Ejemplo n.º 2
10
 /**
  * Tries to break a block using a item, including Player time checks if available
  * It'll try to lower the durability if Item is a tool, and set it to Air if broken.
  *
  * @param Vector3 $vector
  * @param Item    &$item (if null, can break anything)
  * @param Player  $player
  * @param bool    $createParticles
  *
  * @return boolean
  */
 public function useBreakOn(Vector3 $vector, Item &$item = null, Player $player = null, $createParticles = false)
 {
     $target = $this->getBlock($vector);
     //TODO: Adventure mode checks
     if ($item === null) {
         $item = Item::get(Item::AIR, 0, 0);
     }
     if ($player !== null) {
         $ev = new BlockBreakEvent($player, $target, $item, $player->isCreative() ? true : false);
         if ($player->isSurvival() and $item instanceof Item and !$target->isBreakable($item)) {
             $ev->setCancelled();
         } elseif (!$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;
         }
         $breakTime = $target->getBreakTime($item);
         if ($player->isCreative() and $breakTime > 0.15) {
             $breakTime = 0.15;
         }
         if ($player->hasEffect(Effect::SWIFTNESS)) {
             $breakTime *= 1 - 0.2 * ($player->getEffect(Effect::SWIFTNESS)->getAmplifier() + 1);
         }
         if ($player->hasEffect(Effect::MINING_FATIGUE)) {
             $breakTime *= 1 + 0.3 * ($player->getEffect(Effect::MINING_FATIGUE)->getAmplifier() + 1);
         }
         $breakTime -= 0.05;
         //1 tick compensation
         if (!$ev->getInstaBreak() and $player->lastBreak + $breakTime > microtime(true)) {
             return false;
         }
         $player->lastBreak = microtime(true);
         $drops = $ev->getDrops();
     } elseif ($item !== null and !$target->isBreakable($item)) {
         return false;
     } else {
         $drops = $target->getDrops($item);
         //Fixes tile entities being deleted before getting drops
         foreach ($drops as $k => $i) {
             $drops[$k] = Item::get($i[0], $i[1], $i[2]);
         }
     }
     $above = $this->getBlock(new Vector3($target->x, $target->y + 1, $target->z));
     if ($above !== null) {
         if ($above->getId() === Item::FIRE) {
             $this->setBlock($above, new Air(), true);
         }
     }
     $tag = $item->getNamedTagEntry("CanDestroy");
     if ($tag instanceof Enum) {
         $canBreak = false;
         foreach ($tag as $v) {
             if ($v instanceof String) {
                 $entry = Item::fromString($v->getValue());
                 if ($entry->getId() > 0 and $entry->getBlock() !== null and $entry->getBlock()->getId() === $target->getId()) {
                     $canBreak = true;
                     break;
                 }
             }
         }
         if (!$canBreak) {
             return false;
         }
     }
     if ($createParticles) {
         $players = $this->getChunkPlayers($target->x >> 4, $target->z >> 4);
         if ($player !== null) {
             unset($players[$player->getLoaderId()]);
         }
         $this->addParticle(new DestroyBlockParticle($target->add(0.5), $target), $players);
     }
     $target->onBreak($item);
     $tile = $this->getTile($target);
     if ($tile !== null) {
         if ($tile instanceof InventoryHolder) {
             if ($tile instanceof Chest) {
                 $tile->unpair();
             }
             foreach ($tile->getInventory()->getContents() as $chestItem) {
                 $this->dropItem($target, $chestItem);
             }
         }
         $tile->close();
     }
     if ($item !== null) {
         $item->useOn($target);
         if ($item->isTool() and $item->getDamage() >= $item->getMaxDurability()) {
             $item = Item::get(Item::AIR, 0, 0);
         }
     }
     if ($player === null or $player->isSurvival()) {
         foreach ($drops as $drop) {
             if ($drop->getCount() > 0) {
                 $this->dropItem($vector->add(0.5, 0.5, 0.5), $drop);
             }
         }
     }
     return true;
 }
Ejemplo n.º 3
-1
 /**
  * Tries to break a block using a item, including Player time checks if available
  * It'll try to lower the durability if Item is a tool, and set it to Air if broken.
  *
  * @param Vector3 $vector
  * @param Item    &$item (if null, can break anything)
  * @param Player  $player
  * @param bool    $createParticles
  *
  * @return boolean
  */
 public function useBreakOn(Vector3 $vector, Item &$item = null, Player $player = null, $createParticles = false)
 {
     $target = $this->getBlock($vector);
     //TODO: Adventure mode checks
     if ($item === null) {
         $item = Item::get(Item::AIR, 0, 0);
     }
     if ($player !== null) {
         $ev = new BlockBreakEvent($player, $target, $item, $player->isCreative() ? true : false);
         if ($player->isSurvival() and $item instanceof Item and !$target->isBreakable($item)) {
             $ev->setCancelled();
         } elseif (!$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;
         }
         $breakTime = $player->isCreative() ? 0.15 : $target->getBreakTime($item);
         if ($player->hasEffect(Effect::SWIFTNESS)) {
             $breakTime *= 1 - 0.2 * ($player->getEffect(Effect::SWIFTNESS)->getAmplifier() + 1);
         }
         if ($player->hasEffect(Effect::MINING_FATIGUE)) {
             $breakTime *= 1 + 0.3 * ($player->getEffect(Effect::MINING_FATIGUE)->getAmplifier() + 1);
         }
         $breakTime -= 0.05;
         //1 tick compensation
         if (!$ev->getInstaBreak() and $player->lastBreak + $breakTime > microtime(true)) {
             return false;
         }
         $player->lastBreak = PHP_INT_MAX;
         $drops = $ev->getDrops();
     } elseif ($item !== null and !$target->isBreakable($item)) {
         return false;
     } else {
         $drops = $target->getDrops($item);
         //Fixes tile entities being deleted before getting drops
         foreach ($drops as $k => $i) {
             $drops[$k] = Item::get($i[0], $i[1], $i[2]);
         }
     }
     $above = $this->getBlock(new Vector3($target->x, $target->y + 1, $target->z));
     if ($above !== null) {
         if ($above->getId() === Item::FIRE) {
             $this->setBlock($above, new Air(), true);
         }
     }
     if ($createParticles) {
         $players = $this->getChunkPlayers($target->x >> 4, $target->z >> 4);
         if ($player !== null) {
             unset($players[$player->getLoaderId()]);
         }
         $pk = new LevelEventPacket();
         $pk->evid = 2001;
         $pk->x = $target->x + 0.5;
         $pk->y = $target->y + 0.5;
         $pk->z = $target->z + 0.5;
         $pk->data = $target->getId() + ($target->getDamage() << 12);
         Server::broadcastPacket($players, $pk->setChannel(Network::CHANNEL_WORLD_EVENTS));
     }
     $target->onBreak($item);
     $tile = $this->getTile($target);
     if ($tile !== null) {
         if ($tile instanceof InventoryHolder) {
             if ($tile instanceof Chest) {
                 $tile->unpair();
             }
             foreach ($tile->getInventory()->getContents() as $chestItem) {
                 $this->dropItem($target, $chestItem);
             }
         }
         $tile->close();
     }
     if ($item !== null) {
         $item->useOn($target);
         if ($item->isTool() and $item->getDamage() >= $item->getMaxDurability()) {
             $item = Item::get(Item::AIR, 0, 0);
         }
     }
     if ($player === null or $player->isSurvival()) {
         foreach ($drops as $drop) {
             if ($drop->getCount() > 0) {
                 $this->dropItem($vector->add(0.5, 0.5, 0.5), $drop);
             }
         }
     }
     return true;
 }