fix XP being lost or duplicated
The current calculation did not work for larger amounts of levels
and either removed or added levels unintentionally.
(cherry picked from commit d83bad5a33)
This commit is contained in:
parent
fe86792731
commit
0bcdc86d32
|
|
@ -184,10 +184,8 @@ public class VanillaSync {
|
|||
// Restore basic attributes
|
||||
serverPlayer.setHealth(rs2.getInt("health"));
|
||||
serverPlayer.getFoodData().setFoodLevel(rs2.getInt("food_level"));
|
||||
serverPlayer.totalExperience = 0;
|
||||
serverPlayer.experienceLevel = 0;
|
||||
serverPlayer.experienceProgress = 0;
|
||||
serverPlayer.giveExperiencePoints(rs2.getInt("xp"));
|
||||
|
||||
setXpForPlayer(serverPlayer, rs2.getInt("xp"));
|
||||
serverPlayer.setScore(rs2.getInt("score"));
|
||||
|
||||
// Restore left-hand item
|
||||
|
|
@ -472,7 +470,7 @@ public class VanillaSync {
|
|||
PlayerSync.LOGGER.info("Storing data for player " + player_uuid + " (init=" + init + ")");
|
||||
|
||||
// Basic Attributes
|
||||
int XP = player.totalExperience;
|
||||
int XP = getTotalExperience(player);
|
||||
int score = player.getScore();
|
||||
int food_level = player.getFoodData().getFoodLevel();
|
||||
int health = (int) player.getHealth();
|
||||
|
|
@ -635,4 +633,52 @@ public class VanillaSync {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void setXpForPlayer(ServerPlayer serverPlayer, int databaseXp) {
|
||||
// Don't use giveExperience() as it has several side-effects:
|
||||
// triggers an event, sends network packets, increases the score, ...
|
||||
serverPlayer.totalExperience = databaseXp;
|
||||
serverPlayer.experienceLevel = 0;
|
||||
serverPlayer.experienceProgress = 0;
|
||||
|
||||
int xpForLevel;
|
||||
|
||||
while (databaseXp >= (xpForLevel = serverPlayer.getXpNeededForNextLevel())) {
|
||||
databaseXp -= xpForLevel;
|
||||
serverPlayer.experienceLevel++;
|
||||
}
|
||||
|
||||
serverPlayer.experienceProgress = serverPlayer.experienceLevel > 0
|
||||
? (float) databaseXp / serverPlayer.getXpNeededForNextLevel()
|
||||
: 0f;
|
||||
|
||||
PlayerSync.LOGGER.debug("Giving player "
|
||||
+ serverPlayer.experienceLevel + " levels and "
|
||||
+ serverPlayer.experienceProgress * 100 + "% experience progress, calculated from "
|
||||
+ serverPlayer.totalExperience + " XP.");
|
||||
}
|
||||
|
||||
private static int getTotalExperience(final Player player) {
|
||||
int level = player.experienceLevel;
|
||||
int totalXp = 0;
|
||||
|
||||
// Calculate total XP for completed levels
|
||||
if (level > 30) {
|
||||
totalXp = (int) (4.5 * Math.pow(level, 2) - 162.5 * level + 2220);
|
||||
} else if (level > 15) {
|
||||
totalXp = (int) (2.5 * Math.pow(level, 2) - 40.5 * level + 360);
|
||||
} else {
|
||||
totalXp = level * level + 6 * level;
|
||||
}
|
||||
|
||||
// Add partial level progress
|
||||
totalXp += Math.round(player.getXpNeededForNextLevel() * player.experienceProgress);
|
||||
|
||||
PlayerSync.LOGGER.debug("Experience calcuation for "
|
||||
+ player.experienceLevel + " levels and "
|
||||
+ player.experienceProgress * 100 + "% experience progress yields "
|
||||
+ totalXp + " XP.");
|
||||
|
||||
return totalXp;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user