/** * Changes the total exp of a player * * @param int $xp * @param bool $syncLevel This will reset the level to be in sync with the total. Usually you don't want to do this, * because it'll mess up use of xp in anvils and enchanting tables. * * @return bool */ 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; }