-
-
Save Programie/4af446f372aa9310018c4238f9bd7ccc to your computer and use it in GitHub Desktop.
A utility for managing experience with Bukkit.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.github.jikoo.experience; | |
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. | |
* @see http://minecraft.gamepedia.com/Experience#Leveling_up | |
* | |
* @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. | |
* | |
* @see http://minecraft.gamepedia.com/Experience#Leveling_up | |
* | |
* "One can determine how much experience has been collected to reach a level using the equations: | |
* | |
* 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; | |
} | |
/** | |
* @see http://minecraft.gamepedia.com/Experience#Leveling_up | |
* | |
* "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; | |
} | |
int level = (int) getLevelFromExp(exp); | |
int xpAtLevel = getExpFromLevel(level); | |
player.setLevel(level); | |
player.setExp(0); | |
player.giveExp(exp - xpAtLevel); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment