Changed experience storage from integers to floats

This will make sure no experience is lost when the server has high
skill modifiers configured, or when low amounts of experience are being
shared.
This commit is contained in:
TfT_02 2013-04-24 19:30:46 +02:00 committed by GJ
parent eea5784527
commit 17a0382283
9 changed files with 126 additions and 64 deletions

View File

@ -208,6 +208,49 @@ public final class ExperienceAPI {
return getOfflineProfile(playerName).getSkillXpLevel(skill); return getOfflineProfile(playerName).getSkillXpLevel(skill);
} }
/**
* Get the raw amount of XP a player has in a specific skill.
* </br>
* This function is designed for API usage.
*
* @param player The player to get XP for
* @param skillType The skill to get XP for
* @return the amount of XP in a given skill
*
* @throws InvalidSkillException if the given skill is not valid
*/
public static float getXPRaw(Player player, String skillType) {
SkillType skill = SkillType.getSkill(skillType);
if (skill == null) {
throw new InvalidSkillException();
}
return UserManager.getPlayer(player).getProfile().getSkillXpLevelRaw(skill);
}
/**
* Get the raw amount of XP an offline player has in a specific skill.
* </br>
* This function is designed for API usage.
*
* @param playerName The player to get XP for
* @param skillType The skill to get XP for
* @return the amount of XP in a given skill
*
* @throws InvalidSkillException if the given skill is not valid
* @throws InvalidPlayerException if the given player does not exist in the database
*/
public static float getOfflineXPRaw(String playerName, String skillType) {
SkillType skill = SkillType.getSkill(skillType);
if (skill == null) {
throw new InvalidSkillException();
}
return getOfflineProfile(playerName).getSkillXpLevelRaw(skill);
}
/** /**
* Get the amount of XP left before leveling up. * Get the amount of XP left before leveling up.
* </br> * </br>

View File

@ -420,7 +420,7 @@ public class McMMOPlayer {
* @param skillType Skill being used * @param skillType Skill being used
* @param xp Experience amount to process * @param xp Experience amount to process
*/ */
public void beginXpGain(SkillType skillType, int xp) { public void beginXpGain(SkillType skillType, float xp) {
if (xp == 0) { if (xp == 0) {
return; return;
} }
@ -451,7 +451,7 @@ public class McMMOPlayer {
* @param skillType Skill being used * @param skillType Skill being used
* @param xp Experience amount to process * @param xp Experience amount to process
*/ */
public void beginUnsharedXpGain(SkillType skillType, int xp) { public void beginUnsharedXpGain(SkillType skillType, float xp) {
xp = modifyXpGain(skillType, xp); xp = modifyXpGain(skillType, xp);
applyXpGain(skillType, xp); applyXpGain(skillType, xp);
@ -463,7 +463,7 @@ public class McMMOPlayer {
* @param skillType Skill being used * @param skillType Skill being used
* @param xp Experience amount to add * @param xp Experience amount to add
*/ */
public void applyXpGain(SkillType skillType, int xp) { public void applyXpGain(SkillType skillType, float xp) {
if (skillType.isChildSkill()) { if (skillType.isChildSkill()) {
Set<SkillType> parentSkills = FamilyTree.getParents(skillType); Set<SkillType> parentSkills = FamilyTree.getParents(skillType);
@ -484,7 +484,7 @@ public class McMMOPlayer {
return; return;
} }
profile.setSkillXpLevel(skillType, profile.getSkillXpLevel(skillType) + event.getXpGained()); profile.setSkillXpLevel(skillType, profile.getSkillXpLevelRaw(skillType) + event.getXpGained());
McMMOHud spoutHud = profile.getSpoutHud(); McMMOHud spoutHud = profile.getSpoutHud();
@ -655,12 +655,12 @@ public class McMMOPlayer {
* @param xp Experience amount to process * @param xp Experience amount to process
* @return Modified experience * @return Modified experience
*/ */
private int modifyXpGain(SkillType skillType, int xp) { private float modifyXpGain(SkillType skillType, float xp) {
if (player.getGameMode() == GameMode.CREATIVE || (skillType.getMaxLevel() < profile.getSkillLevel(skillType) + 1) || (Config.getInstance().getPowerLevelCap() < getPowerLevel() + 1)) { if (player.getGameMode() == GameMode.CREATIVE || (skillType.getMaxLevel() < profile.getSkillLevel(skillType) + 1) || (Config.getInstance().getPowerLevelCap() < getPowerLevel() + 1)) {
return 0; return 0;
} }
xp = (int) (xp / skillType.getXpModifier() * Config.getInstance().getExperienceGainsGlobalMultiplier()); xp = (float) (xp / skillType.getXpModifier() * Config.getInstance().getExperienceGainsGlobalMultiplier());
if (Config.getInstance().getToolModsEnabled()) { if (Config.getInstance().getToolModsEnabled()) {
ItemStack item = player.getItemInHand(); ItemStack item = player.getItemInHand();

View File

@ -33,7 +33,7 @@ public class PlayerProfile {
/* Skill Data */ /* Skill Data */
private final Map<SkillType, Integer> skills = new HashMap<SkillType, Integer>(); // Skill & Level private final Map<SkillType, Integer> skills = new HashMap<SkillType, Integer>(); // Skill & Level
private final Map<SkillType, Integer> skillsXp = new HashMap<SkillType, Integer>(); // Skill & XP private final Map<SkillType, Float> skillsXp = new HashMap<SkillType, Float>(); // Skill & XP
private final Map<AbilityType, Integer> skillsDATS = new HashMap<AbilityType, Integer>(); // Ability & Cooldown private final Map<AbilityType, Integer> skillsDATS = new HashMap<AbilityType, Integer>(); // Ability & Cooldown
public PlayerProfile(String playerName, boolean addNew) { public PlayerProfile(String playerName, boolean addNew) {
@ -52,7 +52,7 @@ public class PlayerProfile {
} }
skills.put(skillType, 0); skills.put(skillType, 0);
skillsXp.put(skillType, 0); skillsXp.put(skillType, 0F);
} }
if (!loadPlayer() && addNew) { if (!loadPlayer() && addNew) {
@ -153,11 +153,15 @@ public class PlayerProfile {
return skills.get(skillType); return skills.get(skillType);
} }
public int getSkillXpLevel(SkillType skillType) { public float getSkillXpLevelRaw(SkillType skillType) {
return skillsXp.get(skillType); return skillsXp.get(skillType);
} }
public void setSkillXpLevel(SkillType skillType, int newValue) { public int getSkillXpLevel(SkillType skillType) {
return (int) Math.floor(getSkillXpLevelRaw(skillType));
}
public void setSkillXpLevel(SkillType skillType, float newValue) {
if (skillType.isChildSkill()) { if (skillType.isChildSkill()) {
return; return;
} }
@ -195,7 +199,7 @@ public class PlayerProfile {
} }
skills.put(skillType, newValue); skills.put(skillType, newValue);
skillsXp.put(skillType, 0); skillsXp.put(skillType, 0F);
} }
/** /**
@ -210,7 +214,7 @@ public class PlayerProfile {
} }
skills.put(skillType, skills.get(skillType) + levels); skills.put(skillType, skills.get(skillType) + levels);
skillsXp.put(skillType, 0); skillsXp.put(skillType, 0F);
} }
/** /**
@ -326,18 +330,18 @@ public class PlayerProfile {
mcMMO.p.getLogger().warning(playerName + "does not exist in the experience table. Their experience will be reset."); mcMMO.p.getLogger().warning(playerName + "does not exist in the experience table. Their experience will be reset.");
} }
else { else {
skillsXp.put(SkillType.TAMING, Integer.valueOf(experienceValues.get(0))); skillsXp.put(SkillType.TAMING, (float) Integer.valueOf(experienceValues.get(0)));
skillsXp.put(SkillType.MINING, Integer.valueOf(experienceValues.get(1))); skillsXp.put(SkillType.MINING, (float) Integer.valueOf(experienceValues.get(1)));
skillsXp.put(SkillType.REPAIR, Integer.valueOf(experienceValues.get(2))); skillsXp.put(SkillType.REPAIR, (float) Integer.valueOf(experienceValues.get(2)));
skillsXp.put(SkillType.WOODCUTTING, Integer.valueOf(experienceValues.get(3))); skillsXp.put(SkillType.WOODCUTTING, (float) Integer.valueOf(experienceValues.get(3)));
skillsXp.put(SkillType.UNARMED, Integer.valueOf(experienceValues.get(4))); skillsXp.put(SkillType.UNARMED, (float) Integer.valueOf(experienceValues.get(4)));
skillsXp.put(SkillType.HERBALISM, Integer.valueOf(experienceValues.get(5))); skillsXp.put(SkillType.HERBALISM, (float) Integer.valueOf(experienceValues.get(5)));
skillsXp.put(SkillType.EXCAVATION, Integer.valueOf(experienceValues.get(6))); skillsXp.put(SkillType.EXCAVATION, (float) Integer.valueOf(experienceValues.get(6)));
skillsXp.put(SkillType.ARCHERY, Integer.valueOf(experienceValues.get(7))); skillsXp.put(SkillType.ARCHERY, (float) Integer.valueOf(experienceValues.get(7)));
skillsXp.put(SkillType.SWORDS, Integer.valueOf(experienceValues.get(8))); skillsXp.put(SkillType.SWORDS, (float) Integer.valueOf(experienceValues.get(8)));
skillsXp.put(SkillType.AXES, Integer.valueOf(experienceValues.get(9))); skillsXp.put(SkillType.AXES, (float) Integer.valueOf(experienceValues.get(9)));
skillsXp.put(SkillType.ACROBATICS, Integer.valueOf(experienceValues.get(10))); skillsXp.put(SkillType.ACROBATICS, (float) Integer.valueOf(experienceValues.get(10)));
skillsXp.put(SkillType.FISHING, Integer.valueOf(experienceValues.get(11))); skillsXp.put(SkillType.FISHING, (float) Integer.valueOf(experienceValues.get(11)));
} }
loaded = true; loaded = true;
@ -512,18 +516,18 @@ public class PlayerProfile {
+ ", fishing = " + skills.get(SkillType.FISHING) + ", fishing = " + skills.get(SkillType.FISHING)
+ " WHERE user_id = " + userId); + " WHERE user_id = " + userId);
SQLDatabaseManager.write("UPDATE " + tablePrefix + "experience SET " SQLDatabaseManager.write("UPDATE " + tablePrefix + "experience SET "
+ " taming = " + skillsXp.get(SkillType.TAMING) + " taming = " + getSkillXpLevel(SkillType.TAMING)
+ ", mining = " + skillsXp.get(SkillType.MINING) + ", mining = " + getSkillXpLevel(SkillType.MINING)
+ ", repair = " + skillsXp.get(SkillType.REPAIR) + ", repair = " + getSkillXpLevel(SkillType.REPAIR)
+ ", woodcutting = " + skillsXp.get(SkillType.WOODCUTTING) + ", woodcutting = " + getSkillXpLevel(SkillType.WOODCUTTING)
+ ", unarmed = " + skillsXp.get(SkillType.UNARMED) + ", unarmed = " + getSkillXpLevel(SkillType.UNARMED)
+ ", herbalism = " + skillsXp.get(SkillType.HERBALISM) + ", herbalism = " + getSkillXpLevel(SkillType.HERBALISM)
+ ", excavation = " + skillsXp.get(SkillType.EXCAVATION) + ", excavation = " + getSkillXpLevel(SkillType.EXCAVATION)
+ ", archery = " + skillsXp.get(SkillType.ARCHERY) + ", archery = " + getSkillXpLevel(SkillType.ARCHERY)
+ ", swords = " + skillsXp.get(SkillType.SWORDS) + ", swords = " + getSkillXpLevel(SkillType.SWORDS)
+ ", axes = " + skillsXp.get(SkillType.AXES) + ", axes = " + getSkillXpLevel(SkillType.AXES)
+ ", acrobatics = " + skillsXp.get(SkillType.ACROBATICS) + ", acrobatics = " + getSkillXpLevel(SkillType.ACROBATICS)
+ ", fishing = " + skillsXp.get(SkillType.FISHING) + ", fishing = " + getSkillXpLevel(SkillType.FISHING)
+ " WHERE user_id = " + userId); + " WHERE user_id = " + userId);
} }
} }
@ -547,9 +551,9 @@ public class PlayerProfile {
writer.append(skills.get(SkillType.MINING)).append(":"); writer.append(skills.get(SkillType.MINING)).append(":");
writer.append(":"); writer.append(":");
writer.append(":"); writer.append(":");
writer.append(skillsXp.get(SkillType.MINING)).append(":"); writer.append(getSkillXpLevel(SkillType.MINING)).append(":");
writer.append(skills.get(SkillType.WOODCUTTING)).append(":"); writer.append(skills.get(SkillType.WOODCUTTING)).append(":");
writer.append(skillsXp.get(SkillType.WOODCUTTING)).append(":"); writer.append(getSkillXpLevel(SkillType.WOODCUTTING)).append(":");
writer.append(skills.get(SkillType.REPAIR)).append(":"); writer.append(skills.get(SkillType.REPAIR)).append(":");
writer.append(skills.get(SkillType.UNARMED)).append(":"); writer.append(skills.get(SkillType.UNARMED)).append(":");
writer.append(skills.get(SkillType.HERBALISM)).append(":"); writer.append(skills.get(SkillType.HERBALISM)).append(":");
@ -558,17 +562,17 @@ public class PlayerProfile {
writer.append(skills.get(SkillType.SWORDS)).append(":"); writer.append(skills.get(SkillType.SWORDS)).append(":");
writer.append(skills.get(SkillType.AXES)).append(":"); writer.append(skills.get(SkillType.AXES)).append(":");
writer.append(skills.get(SkillType.ACROBATICS)).append(":"); writer.append(skills.get(SkillType.ACROBATICS)).append(":");
writer.append(skillsXp.get(SkillType.REPAIR)).append(":"); writer.append(getSkillXpLevel(SkillType.REPAIR)).append(":");
writer.append(skillsXp.get(SkillType.UNARMED)).append(":"); writer.append(getSkillXpLevel(SkillType.UNARMED)).append(":");
writer.append(skillsXp.get(SkillType.HERBALISM)).append(":"); writer.append(getSkillXpLevel(SkillType.HERBALISM)).append(":");
writer.append(skillsXp.get(SkillType.EXCAVATION)).append(":"); writer.append(getSkillXpLevel(SkillType.EXCAVATION)).append(":");
writer.append(skillsXp.get(SkillType.ARCHERY)).append(":"); writer.append(getSkillXpLevel(SkillType.ARCHERY)).append(":");
writer.append(skillsXp.get(SkillType.SWORDS)).append(":"); writer.append(getSkillXpLevel(SkillType.SWORDS)).append(":");
writer.append(skillsXp.get(SkillType.AXES)).append(":"); writer.append(getSkillXpLevel(SkillType.AXES)).append(":");
writer.append(skillsXp.get(SkillType.ACROBATICS)).append(":"); writer.append(getSkillXpLevel(SkillType.ACROBATICS)).append(":");
writer.append(":"); writer.append(":");
writer.append(skills.get(SkillType.TAMING)).append(":"); writer.append(skills.get(SkillType.TAMING)).append(":");
writer.append(skillsXp.get(SkillType.TAMING)).append(":"); writer.append(getSkillXpLevel(SkillType.TAMING)).append(":");
writer.append(skillsDATS.get(AbilityType.BERSERK)).append(":"); writer.append(skillsDATS.get(AbilityType.BERSERK)).append(":");
writer.append(skillsDATS.get(AbilityType.GIGA_DRILL_BREAKER)).append(":"); writer.append(skillsDATS.get(AbilityType.GIGA_DRILL_BREAKER)).append(":");
writer.append(skillsDATS.get(AbilityType.TREE_FELLER)).append(":"); writer.append(skillsDATS.get(AbilityType.TREE_FELLER)).append(":");
@ -578,7 +582,7 @@ public class PlayerProfile {
writer.append(skillsDATS.get(AbilityType.SUPER_BREAKER)).append(":"); writer.append(skillsDATS.get(AbilityType.SUPER_BREAKER)).append(":");
writer.append(hudType.toString()).append(":"); writer.append(hudType.toString()).append(":");
writer.append(skills.get(SkillType.FISHING)).append(":"); writer.append(skills.get(SkillType.FISHING)).append(":");
writer.append(skillsXp.get(SkillType.FISHING)).append(":"); writer.append(getSkillXpLevel(SkillType.FISHING)).append(":");
writer.append(skillsDATS.get(AbilityType.BLAST_MINING)).append(":"); writer.append(skillsDATS.get(AbilityType.BLAST_MINING)).append(":");
writer.append(System.currentTimeMillis() / Misc.TIME_CONVERSION_FACTOR).append(":"); writer.append(System.currentTimeMillis() / Misc.TIME_CONVERSION_FACTOR).append(":");
writer.append(mobHealthbarType.toString()).append(":"); writer.append(mobHealthbarType.toString()).append(":");
@ -601,7 +605,7 @@ public class PlayerProfile {
private void loadSkillXpData(SkillType skill, String[] data, int dataIndex) { private void loadSkillXpData(SkillType skill, String[] data, int dataIndex) {
if (data.length > dataIndex) { if (data.length > dataIndex) {
skillsXp.put(skill, Integer.valueOf(data[dataIndex])); skillsXp.put(skill, (float) Integer.valueOf(data[dataIndex]));
} }
} }

View File

@ -8,9 +8,9 @@ import com.gmail.nossr50.datatypes.skills.SkillType;
* Called when a player gains XP in a skill * Called when a player gains XP in a skill
*/ */
public class McMMOPlayerXpGainEvent extends McMMOPlayerExperienceEvent { public class McMMOPlayerXpGainEvent extends McMMOPlayerExperienceEvent {
private int xpGained; private float xpGained;
public McMMOPlayerXpGainEvent(Player player, SkillType skill, int xpGained) { public McMMOPlayerXpGainEvent(Player player, SkillType skill, float xpGained) {
super(player, skill); super(player, skill);
this.xpGained = xpGained; this.xpGained = xpGained;
} }
@ -18,13 +18,29 @@ public class McMMOPlayerXpGainEvent extends McMMOPlayerExperienceEvent {
/** /**
* @return The amount of experience gained in this event * @return The amount of experience gained in this event
*/ */
public int getXpGained() { public float getRawXpGained() {
return xpGained; return xpGained;
} }
/** /**
* @param xpGained int amount of experience gained in this event * @param xpGained int amount of experience gained in this event
*/ */
@Deprecated
public int getXpGained() {
return (int) xpGained;
}
/**
* @param xpGained int amount of experience gained in this event
*/
public void setRawXpGained(float xpGained) {
this.xpGained = xpGained;
}
/**
* @param xpGained int amount of experience gained in this event
*/
@Deprecated
public void setXpGained(int xpGained) { public void setXpGained(int xpGained) {
this.xpGained = xpGained; this.xpGained = xpGained;
} }

View File

@ -52,7 +52,7 @@ public final class ShareHandler {
* @param skillType Skill being used * @param skillType Skill being used
* @return True is the xp has been shared * @return True is the xp has been shared
*/ */
public static boolean handleXpShare(int xp, McMMOPlayer mcMMOPlayer, SkillType skillType) { public static boolean handleXpShare(float xp, McMMOPlayer mcMMOPlayer, SkillType skillType) {
Party party = mcMMOPlayer.getParty(); Party party = mcMMOPlayer.getParty();
switch (party.getXpShareMode()) { switch (party.getXpShareMode()) {
@ -71,14 +71,13 @@ public final class ShareHandler {
shareBonus = Config.getInstance().getPartyShareBonusCap(); shareBonus = Config.getInstance().getPartyShareBonusCap();
} }
double splitXp = xp / partySize * shareBonus; float splitXp = (float) (xp / partySize * shareBonus);
int roundedXp = (int) Math.ceil(splitXp);
for (Player member : nearMembers) { for (Player member : nearMembers) {
UserManager.getPlayer(member).beginUnsharedXpGain(skillType, roundedXp); UserManager.getPlayer(member).beginUnsharedXpGain(skillType, splitXp);
} }
mcMMOPlayer.beginUnsharedXpGain(skillType, roundedXp); mcMMOPlayer.beginUnsharedXpGain(skillType, splitXp);
return true; return true;

View File

@ -38,7 +38,7 @@ public abstract class SkillManager {
return activationChance; return activationChance;
} }
public void applyXpGain(int xp) { public void applyXpGain(float xp) {
mcMMOPlayer.beginXpGain(skill, xp); mcMMOPlayer.beginXpGain(skill, xp);
} }
} }

View File

@ -62,7 +62,7 @@ public final class Motd {
* @param player Target player * @param player Target player
*/ */
public static void displayXpPerks(Player player) { public static void displayXpPerks(Player player) {
int perkAmount = PerksUtils.handleXpPerks(player, 1); float perkAmount = PerksUtils.handleXpPerks(player, 1);
if (perkAmount > 1) { if (perkAmount > 1) {
player.sendMessage(perkPrefix + LocaleLoader.getString("Effects.Template", LocaleLoader.getString("Perks.xp.name"), LocaleLoader.getString("Perks.xp.desc", perkAmount))); player.sendMessage(perkPrefix + LocaleLoader.getString("Effects.Template", LocaleLoader.getString("Perks.xp.name"), LocaleLoader.getString("Perks.xp.desc", perkAmount)));

View File

@ -43,7 +43,7 @@ public final class PerksUtils {
return ticks; return ticks;
} }
public static int handleXpPerks(Player player, int xp) { public static float handleXpPerks(Player player, float xp) {
if (Permissions.quadrupleXp(player)) { if (Permissions.quadrupleXp(player)) {
xp *= 4; xp *= 4;
} }

View File

@ -211,12 +211,12 @@ public class SkillUtils {
*/ */
public static void xpCheckSkill(SkillType skillType, Player player, PlayerProfile profile) { public static void xpCheckSkill(SkillType skillType, Player player, PlayerProfile profile) {
int skillups = 0; int skillups = 0;
int xpRemoved = 0; float xpRemoved = 0;
if (profile.getSkillXpLevel(skillType) >= profile.getXpToLevel(skillType)) { if (profile.getSkillXpLevelRaw(skillType) >= profile.getXpToLevel(skillType)) {
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player); McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
while (profile.getSkillXpLevel(skillType) >= profile.getXpToLevel(skillType)) { while (profile.getSkillXpLevelRaw(skillType) >= profile.getXpToLevel(skillType)) {
if ((skillType.getMaxLevel() >= profile.getSkillLevel(skillType) + 1) && (Config.getInstance().getPowerLevelCap() >= mcMMOPlayer.getPowerLevel() + 1)) { if ((skillType.getMaxLevel() >= profile.getSkillLevel(skillType) + 1) && (Config.getInstance().getPowerLevelCap() >= mcMMOPlayer.getPowerLevel() + 1)) {
int xp = profile.getXpToLevel(skillType); int xp = profile.getXpToLevel(skillType);
xpRemoved += xp; xpRemoved += xp;
@ -235,7 +235,7 @@ public class SkillUtils {
if (eventToFire.isCancelled()) { if (eventToFire.isCancelled()) {
profile.modifySkill(skillType, profile.getSkillLevel(skillType) - skillups); profile.modifySkill(skillType, profile.getSkillLevel(skillType) - skillups);
profile.setSkillXpLevel(skillType, profile.getSkillXpLevel(skillType) + xpRemoved); profile.setSkillXpLevel(skillType, profile.getSkillXpLevelRaw(skillType) + xpRemoved);
return; return;
} }