*/ abstract public function getProjectileEntityClass() : string; abstract public function getThrowForce() : float; /** * Helper function to apply extra NBT tags to pass to the created projectile. */ protected function addExtraTags(CompoundTag $tag) : void{ } public function onClickAir(Player $player, Vector3 $directionVector) : ItemUseResult{ $location = $player->getLocation(); $nbt = EntityFactory::createBaseNBT($player->getEyePos(), $directionVector, $location->yaw, $location->pitch); $this->addExtraTags($nbt); $class = $this->getProjectileEntityClass(); Utils::testValidInstance($class, Throwable::class); /** @var Throwable $projectile */ $projectile = EntityFactory::getInstance()->create($class, $location->getWorldNonNull(), $nbt, $player); $projectile->setMotion($projectile->getMotion()->multiply($this->getThrowForce())); $projectileEv = new ProjectileLaunchEvent($projectile); $projectileEv->call(); if($projectileEv->isCancelled()){ $projectile->flagForDespawn(); return ItemUseResult::FAIL(); } $projectile->spawnToAll(); $location->getWorldNonNull()->addSound($location, new ThrowSound()); $this->pop(); return ItemUseResult::SUCCESS(); } }