# 1.16.5 How to Calculate Exp and Levels

Discussion in 'Spigot Plugin Development' started by filtastisch, Jun 10, 2021.

1. ### filtastisch

Hey,
im coding a plugin rn, where if you wanna teleport to some warps, it costs Exp.
But now im struggeling how to calculate this. I want the further you are the more xp is consumed and when you teleport from another dimension at least 10 lvl plus the levels are consumed for the distance, but that doesn't work.

Whatever i try, i always get either the message not enough xp, although I have given myself 1000 lvl, or only 0.001 lvl are used

Code (Java):
public boolean teleport(Player p) {
double xp = p.getExp();
float newXP = (float) (p.getExp() - this.getCost(p));
if (xp > this.getCost(p)) {
p.teleport(this.location);
p.setExp(newXP);
return true;
}

//for debug reason
p.sendMessage(String.valueOf(newXP));
return false;
}

public String costBetweenWorld(Player p){
return String.valueOf(getCostBetweenWorlds(p));
}

public void remove(){
all.remove(this);
}

/*Getter / Setter*/

public double getCost(Player p) {
ExperienceManager expM = new ExperienceManager(p);
if (Objects.equals(this.location.getWorld(), p.getLocation().getWorld())) {
return (p.getLocation().distance(this.location) / 2000);
}
return (getCostBetweenWorlds(p) / 5000);
}

public double getCostBetweenWorlds(Player p){
double x1, x2, y1, y2, z1, z2;
x1 = p.getLocation().getX();
y1 = p.getLocation().getY();
z1 = p.getLocation().getZ();
x2 = location.getX();
y2 = location.getY();
z2 = location.getZ();

return Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2) + Math.pow(z1 - z2, 2));
}

#1
Last edited: Jun 10, 2021
2. ### SteelPhoenix Moderator

Use the correct method. I doubt you want #getExp() here.

wich then?

5. ### mfnalex

Which method should they use instead? If getExp isn‘t the correct one to get Exp, which one do you think it is?

6. ### SteelPhoenix Moderator

Look at all exp related methods, read their documentation and pick the one that suits your needs. I do not know which one OP needs because I do not know what he is trying to do. I know that #getExp() returns the progress towards the next level as a fraction (i.e. range [0, 1)) which generally isn't that useful except for some niche applications.

• Agree x 1
7. ### mfnalex

There unfortunately is no method to get the total XP, i think the API is very bad regarding this. The total amount of XP can only be calculated :/

8. ### Lifeonblack

Code (Java):
public int getTotalExperience() {
int experience = 0;
int level = player.getLevel();
if(level >= 0 && level <= 15) {
experience = (int) Math.ceil(Math.pow(level, 2) + (6 * level));
int requiredExperience = 2 * level + 7;
double currentExp = Double.parseDouble(Float.toString(player.getExp()));
experience += Math.ceil(currentExp * requiredExperience);
return experience;
} else if(level > 15 && level <= 30) {
experience = (int) Math.ceil((2.5 * Math.pow(level, 2) - (40.5 * level) + 360));
int requiredExperience = 5 * level - 38;
double currentExp = Double.parseDouble(Float.toString(player.getExp()));
experience += Math.ceil(currentExp * requiredExperience);
return experience;
} else {
experience = (int) Math.ceil(((4.5 * Math.pow(level, 2) - (162.5 * level) + 2220)));
int requiredExperience = 9 * level - 158;
double currentExp = Double.parseDouble(Float.toString(player.getExp()));
experience += Math.ceil(currentExp * requiredExperience);
return experience;
}
}

public void setTotalExperience(int xp) {
//Levels 0 through 15
if(xp >= 0 && xp < 351) {
//Calculate Everything
int a = 1; int b = 6; int c = -xp;
int level = (int) (-b + Math.sqrt(Math.pow(b, 2) - (4 * a * c))) / (2 * a);
int xpForLevel = (int) (Math.pow(level, 2) + (6 * level));
int remainder = xp - xpForLevel;
int experienceNeeded = (2 * level) + 7;
float experience = (float) remainder / (float) experienceNeeded;
experience = round(experience, 2);

//Set Everything
player.setLevel(level);
player.setExp(experience);
//Levels 16 through 30
} else if(xp >= 352 && xp < 1507) {
//Calculate Everything
double a = 2.5; double b = -40.5; int c = -xp + 360;
double dLevel = (-b + Math.sqrt(Math.pow(b, 2) - (4 * a * c))) / (2 * a);
int level = (int) Math.floor(dLevel);
int xpForLevel = (int) (2.5 * Math.pow(level, 2) - (40.5 * level) + 360);
int remainder = xp - xpForLevel;
int experienceNeeded = (5 * level) - 38;
float experience = (float) remainder / (float) experienceNeeded;
experience = round(experience, 2);

//Set Everything
player.setLevel(level);
player.setExp(experience);
//Level 31 and greater
} else {
//Calculate Everything
double a = 4.5; double b = -162.5; int c = -xp + 2220;
double dLevel = (-b + Math.sqrt(Math.pow(b, 2) - (4 * a * c))) / (2 * a);
int level = (int) Math.floor(dLevel);
int xpForLevel = (int) (4.5 * Math.pow(level, 2) - (162.5 * level) + 2220);
int remainder = xp - xpForLevel;
int experienceNeeded = (9 * level) - 158;
float experience = (float) remainder / (float) experienceNeeded;
experience = round(experience, 2);

//Set Everything
player.setLevel(level);
player.setExp(experience);
}
}

private float round(float d, int decimalPlace) {
BigDecimal bd = new BigDecimal(Float.toString(d));
bd = bd.setScale(decimalPlace, BigDecimal.ROUND_HALF_DOWN);
return bd.floatValue();
}