public function setTotalXp(int $xp, bool $syncLevel = false) : bool
{
$xp &= 0x7fffffff;
if ($xp === $this->totalXp) {
return false;
}
if (!$syncLevel) {
$level = $this->getXpLevel();
$diff = $xp - $this->totalXp + $this->getFilledXp();
if ($diff > 0) {
//adding xp
while ($diff > ($v = self::getLevelXpRequirement($level))) {
$diff -= $v;
if (++$level >= 21863) {
$diff = $v;
//fill exp bar
break;
}
}
} else {
//taking xp
while ($diff < ($v = self::getLevelXpRequirement($level - 1))) {
$diff += $v;
if (--$level <= 0) {
$diff = 0;
break;
}
}
}
$progress = $diff / $v;
} else {
$values = self::getLevelFromXp($xp);
$level = $values[0];
$progress = $values[1];
}
$this->server->getPluginManager()->callEvent($ev = new PlayerExperienceChangeEvent($this, $level, $progress));
if (!$ev->isCancelled()) {
$this->totalXp = $xp;
$this->setXpLevel($ev->getExpLevel());
$this->setXpProgress($ev->getProgress());
return true;
}
return false;
}