isSurvival() and !$player->getInventory()->contains(ItemFactory::get(Item::ARROW, 0, 1))){ $player->getInventory()->sendContents($player); return false; } $directionVector = $player->getDirectionVector(); $nbt = new CompoundTag("", [ new ListTag("Pos", [ new DoubleTag("", $player->x), new DoubleTag("", $player->y + $player->getEyeHeight()), new DoubleTag("", $player->z) ]), new ListTag("Motion", [ new DoubleTag("", $directionVector->x), new DoubleTag("", $directionVector->y), new DoubleTag("", $directionVector->z) ]), new ListTag("Rotation", [ //yaw/pitch for arrows taken crosswise, not along the arrow shaft. new FloatTag("", ($player->yaw > 180 ? 360 : 0) - $player->yaw), //arrow yaw must range from -180 to +180 new FloatTag("", -$player->pitch) ]), new ShortTag("Fire", $player->isOnFire() ? 45 * 60 : 0) ]); $diff = $player->getItemUseDuration(); $p = $diff / 20; $force = min((($p ** 2) + $p * 2) / 3, 1) * 2; $entity = Entity::createEntity("Arrow", $player->getLevel(), $nbt, $player, $force == 2); if($entity instanceof Projectile){ $ev = new EntityShootBowEvent($player, $this, $entity, $force); if($force < 0.1 or $diff < 5){ $ev->setCancelled(); } $player->getServer()->getPluginManager()->callEvent($ev); $entity = $ev->getProjectile(); //This might have been changed by plugins if($ev->isCancelled()){ $entity->kill(); $player->getInventory()->sendContents($player); }else{ $entity->setMotion($entity->getMotion()->multiply($ev->getForce())); if($player->isSurvival()){ $player->getInventory()->removeItem(ItemFactory::get(Item::ARROW, 0, 1)); $this->applyDamage(1); } if($entity instanceof Projectile){ $player->getServer()->getPluginManager()->callEvent($projectileEv = new ProjectileLaunchEvent($entity)); if($projectileEv->isCancelled()){ $ev->getProjectile()->kill(); }else{ $ev->getProjectile()->spawnToAll(); $player->level->addSound(new LaunchSound($player), $player->getViewers()); } }else{ $entity->spawnToAll(); } } }else{ $entity->spawnToAll(); } return true; } }