106 lines
3.0 KiB
Java
106 lines
3.0 KiB
Java
package com.songoda.epicenchants.utils.single;
|
|
|
|
import org.bukkit.entity.Player;
|
|
|
|
/**
|
|
* A utility for managing Player experience properly.
|
|
*
|
|
* @author Jikoo
|
|
*/
|
|
public class Experience {
|
|
|
|
/**
|
|
* Calculates a player's total exp based on level and progress to next.
|
|
*
|
|
* @param player the Player
|
|
*
|
|
* @return the amount of exp the Player has
|
|
*/
|
|
public static int getExp(Player player) {
|
|
return getExpFromLevel(player.getLevel())
|
|
+ Math.round(getExpToNext(player.getLevel()) * player.getExp());
|
|
}
|
|
|
|
/**
|
|
* Calculates total experience based on level.
|
|
* <p>
|
|
* "One can determine how much experience has been collected to reach a level using the equations:
|
|
* <p>
|
|
* Total Experience = [Level]2 + 6[Level] (at levels 0-15)
|
|
* 2.5[Level]2 - 40.5[Level] + 360 (at levels 16-30)
|
|
* 4.5[Level]2 - 162.5[Level] + 2220 (at level 31+)"
|
|
*
|
|
* @param level the level
|
|
*
|
|
* @return the total experience calculated
|
|
*/
|
|
public static int getExpFromLevel(int level) {
|
|
if (level > 30) {
|
|
return (int) (4.5 * level * level - 162.5 * level + 2220);
|
|
}
|
|
if (level > 15) {
|
|
return (int) (2.5 * level * level - 40.5 * level + 360);
|
|
}
|
|
return level * level + 6 * level;
|
|
}
|
|
|
|
/**
|
|
* Calculates level based on total experience.
|
|
*
|
|
* @param exp the total experience
|
|
*
|
|
* @return the level calculated
|
|
*/
|
|
public static double getLevelFromExp(long exp) {
|
|
if (exp > 1395) {
|
|
return (Math.sqrt(72 * exp - 54215) + 325) / 18;
|
|
}
|
|
if (exp > 315) {
|
|
return Math.sqrt(40 * exp - 7839) / 10 + 8.1;
|
|
}
|
|
if (exp > 0) {
|
|
return Math.sqrt(exp + 9) - 3;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* "The formulas for figuring out how many experience orbs you need to get to the next level are as follows:
|
|
* Experience Required = 2[Current Level] + 7 (at levels 0-15)
|
|
* 5[Current Level] - 38 (at levels 16-30)
|
|
* 9[Current Level] - 158 (at level 31+)"
|
|
*/
|
|
private static int getExpToNext(int level) {
|
|
if (level > 30) {
|
|
return 9 * level - 158;
|
|
}
|
|
if (level > 15) {
|
|
return 5 * level - 38;
|
|
}
|
|
return 2 * level + 7;
|
|
}
|
|
|
|
/**
|
|
* Change a Player's exp.
|
|
* <p>
|
|
* This method should be used in place of {@link Player#giveExp(int)}, which does not properly
|
|
* account for different levels requiring different amounts of experience.
|
|
*
|
|
* @param player the Player affected
|
|
* @param exp the amount of experience to add or remove
|
|
*/
|
|
public static void changeExp(Player player, int exp) {
|
|
exp += getExp(player);
|
|
|
|
if (exp < 0) {
|
|
exp = 0;
|
|
}
|
|
|
|
double levelAndExp = getLevelFromExp(exp);
|
|
|
|
int level = (int) levelAndExp;
|
|
player.setLevel(level);
|
|
player.setExp((float) (levelAndExp - level));
|
|
}
|
|
}
|