hasFiniteResources() and !$player->getInventory()->contains($arrow)){ return ItemUseResult::FAIL(); } $location = $player->getLocation(); $nbt = EntityFactory::createBaseNBT( $player->getEyePos(), $player->getDirectionVector(), ($location->yaw > 180 ? 360 : 0) - $location->yaw, -$location->pitch ); $nbt->setShort("Fire", $player->isOnFire() ? 45 * 60 : 0); $diff = $player->getItemUseDuration(); $p = $diff / 20; $baseForce = min((($p ** 2) + $p * 2) / 3, 1); /** @var ArrowEntity $entity */ $entity = EntityFactory::create(ArrowEntity::class, $location->getWorld(), $nbt, $player, $baseForce >= 1); $infinity = $this->hasEnchantment(Enchantment::INFINITY()); if($infinity){ $entity->setPickupMode(ArrowEntity::PICKUP_CREATIVE); } if(($punchLevel = $this->getEnchantmentLevel(Enchantment::PUNCH())) > 0){ $entity->setPunchKnockback($punchLevel); } if(($powerLevel = $this->getEnchantmentLevel(Enchantment::POWER())) > 0){ $entity->setBaseDamage($entity->getBaseDamage() + (($powerLevel + 1) / 2)); } if($this->hasEnchantment(Enchantment::FLAME())){ $entity->setOnFire(intdiv($entity->getFireTicks(), 20) + 100); } $ev = new EntityShootBowEvent($player, $this, $entity, $baseForce * 3); if($baseForce < 0.1 or $diff < 5){ $ev->setCancelled(); } $ev->call(); $entity = $ev->getProjectile(); //This might have been changed by plugins if($ev->isCancelled()){ $entity->flagForDespawn(); return ItemUseResult::FAIL(); } $entity->setMotion($entity->getMotion()->multiply($ev->getForce())); if($entity instanceof Projectile){ $projectileEv = new ProjectileLaunchEvent($entity); $projectileEv->call(); if($projectileEv->isCancelled()){ $ev->getProjectile()->flagForDespawn(); return ItemUseResult::FAIL(); } $ev->getProjectile()->spawnToAll(); $location->getWorld()->addSound($location, new BowShootSound()); }else{ $entity->spawnToAll(); } if($player->hasFiniteResources()){ if(!$infinity){ //TODO: tipped arrows are still consumed when Infinity is applied $player->getInventory()->removeItem($arrow); } $this->applyDamage(1); } return ItemUseResult::SUCCESS(); } }