-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathXpUtils.java
More file actions
116 lines (104 loc) · 3.31 KB
/
Copy pathXpUtils.java
File metadata and controls
116 lines (104 loc) · 3.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package ru.cwcode.cwutils.xp;
import org.bukkit.Location;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.ExperienceOrb;
import org.bukkit.entity.Player;
import java.util.Objects;
/**
* A utility for managing Player experience properly.
*
* @author Jikoo
*/
public class XpUtils {
public static void dropExp(final Location location, final int xp) {
final ExperienceOrb orb = (ExperienceOrb) Objects.requireNonNull(location.getWorld()).spawnEntity(location, EntityType.EXPERIENCE_ORB);
orb.setExperience(xp);
}
/**
* 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
* @see <a href="http://minecraft.gamepedia.com/Experience#Leveling_up">ref</a>
*/
public static int getExp(Player player) {
return getExpFromLevel(player.getLevel())
+ Math.round(getExpToNext(player.getLevel()) * player.getExp());
}
/**
* Calculates total experience based on level.
*
* @param level the level
* @return the total experience calculated
* @see <a href="http://minecraft.gamepedia.com/Experience#Leveling_up">ref</a>
* <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+)"
*/
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;
}
/**
* 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));
}
/**
* @see <a href="http://minecraft.gamepedia.com/Experience#Leveling_up">ref</a>
* <p>
* "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;
}
}