public function onUpdate($currentTick)
{
if ($this->closed) {
return false;
}
$tickDiff = $currentTick - $this->lastUpdate;
if ($tickDiff <= 0 and !$this->justCreated) {
return true;
}
$this->lastUpdate = $currentTick;
$hasUpdate = $this->entityBaseTick($tickDiff);
if ($this->isAlive()) {
$movingObjectPosition = null;
if (!$this->isCollided) {
$this->motionY -= $this->gravity;
}
$moveVector = new Vector3($this->x + $this->motionX, $this->y + $this->motionY, $this->z + $this->motionZ);
$list = $this->getLevel()->getCollidingEntities($this->boundingBox->addCoord($this->motionX, $this->motionY, $this->motionZ)->expand(1, 1, 1), $this);
$nearDistance = PHP_INT_MAX;
$nearEntity = null;
foreach ($list as $entity) {
if ($entity === $this->shootingEntity and $this->ticksLived < 5) {
continue;
}
$axisalignedbb = $entity->boundingBox->grow(0.3, 0.3, 0.3);
$ob = $axisalignedbb->calculateIntercept($this, $moveVector);
if ($ob === null) {
continue;
}
$distance = $this->distanceSquared($ob->hitVector);
if ($distance < $nearDistance) {
$nearDistance = $distance;
$nearEntity = $entity;
}
}
if ($nearEntity !== null) {
$movingObjectPosition = MovingObjectPosition::fromEntity($nearEntity);
}
if ($movingObjectPosition !== null) {
if ($movingObjectPosition->entityHit !== null) {
$this->server->getPluginManager()->callEvent(new ProjectileHitEvent($this));
$motion = sqrt($this->motionX ** 2 + $this->motionY ** 2 + $this->motionZ ** 2);
$damage = ceil($motion * $this->damage);
if ($this instanceof Arrow and $this->isCritical) {
$damage += mt_rand(0, (int) ($damage / 2) + 1);
}
if ($this->shootingEntity === null) {
$ev = new EntityDamageByEntityEvent($this, $movingObjectPosition->entityHit, EntityDamageEvent::CAUSE_PROJECTILE, $damage);
} else {
$ev = new EntityDamageByChildEntityEvent($this->shootingEntity, $this, $movingObjectPosition->entityHit, EntityDamageEvent::CAUSE_PROJECTILE, $damage);
}
if ($movingObjectPosition->entityHit->attack($ev->getFinalDamage(), $ev) === true) {
if ($this instanceof Arrow and $this->getPotionId() != 0) {
foreach (Potion::getEffectsById($this->potionId - 1) as $effect) {
$movingObjectPosition->entityHit->addEffect($effect->setDuration($effect->getDuration() / 8));
}
}
$ev->useArmors();
}
$this->hadCollision = true;
if ($this->fireTicks > 0) {
$ev = new EntityCombustByEntityEvent($this, $movingObjectPosition->entityHit, 5);
$this->server->getPluginManager()->callEvent($ev);
if (!$ev->isCancelled()) {
$movingObjectPosition->entityHit->setOnFire($ev->getDuration());
}
}
$this->kill();
return true;
}
}
$this->move($this->motionX, $this->motionY, $this->motionZ);
if ($this->isCollided and !$this->hadCollision) {
$this->hadCollision = true;
$this->motionX = 0;
$this->motionY = 0;
$this->motionZ = 0;
$this->server->getPluginManager()->callEvent(new ProjectileHitEvent($this));
} elseif (!$this->isCollided and $this->hadCollision) {
$this->hadCollision = false;
}
if (!$this->onGround or abs($this->motionX) > 1.0E-5 or abs($this->motionY) > 1.0E-5 or abs($this->motionZ) > 1.0E-5) {
$f = sqrt($this->motionX ** 2 + $this->motionZ ** 2);
$this->yaw = atan2($this->motionX, $this->motionZ) * 180 / M_PI;
$this->pitch = atan2($this->motionY, $f) * 180 / M_PI;
$hasUpdate = true;
}
$this->updateMovement();
}
return $hasUpdate;
}