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);
}
/**
* 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.
* </br>

View File

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

View File

@ -33,7 +33,7 @@ public class PlayerProfile {
/* Skill Data */
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
public PlayerProfile(String playerName, boolean addNew) {
@ -52,7 +52,7 @@ public class PlayerProfile {
}
skills.put(skillType, 0);
skillsXp.put(skillType, 0);
skillsXp.put(skillType, 0F);
}
if (!loadPlayer() && addNew) {
@ -153,11 +153,15 @@ public class PlayerProfile {
return skills.get(skillType);
}
public int getSkillXpLevel(SkillType skillType) {
public float getSkillXpLevelRaw(SkillType 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()) {
return;
}
@ -195,7 +199,7 @@ public class PlayerProfile {
}
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);
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.");
}
else {
skillsXp.put(SkillType.TAMING, Integer.valueOf(experienceValues.get(0)));
skillsXp.put(SkillType.MINING, Integer.valueOf(experienceValues.get(1)));
skillsXp.put(SkillType.REPAIR, Integer.valueOf(experienceValues.get(2)));
skillsXp.put(SkillType.WOODCUTTING, Integer.valueOf(experienceValues.get(3)));
skillsXp.put(SkillType.UNARMED, Integer.valueOf(experienceValues.get(4)));
skillsXp.put(SkillType.HERBALISM, Integer.valueOf(experienceValues.get(5)));
skillsXp.put(SkillType.EXCAVATION, Integer.valueOf(experienceValues.get(6)));
skillsXp.put(SkillType.ARCHERY, Integer.valueOf(experienceValues.get(7)));
skillsXp.put(SkillType.SWORDS, Integer.valueOf(experienceValues.get(8)));
skillsXp.put(SkillType.AXES, Integer.valueOf(experienceValues.get(9)));
skillsXp.put(SkillType.ACROBATICS, Integer.valueOf(experienceValues.get(10)));
skillsXp.put(SkillType.FISHING, Integer.valueOf(experienceValues.get(11)));
skillsXp.put(SkillType.TAMING, (float) Integer.valueOf(experienceValues.get(0)));
skillsXp.put(SkillType.MINING, (float) Integer.valueOf(experienceValues.get(1)));
skillsXp.put(SkillType.REPAIR, (float) Integer.valueOf(experienceValues.get(2)));
skillsXp.put(SkillType.WOODCUTTING, (float) Integer.valueOf(experienceValues.get(3)));
skillsXp.put(SkillType.UNARMED, (float) Integer.valueOf(experienceValues.get(4)));
skillsXp.put(SkillType.HERBALISM, (float) Integer.valueOf(experienceValues.get(5)));
skillsXp.put(SkillType.EXCAVATION, (float) Integer.valueOf(experienceValues.get(6)));
skillsXp.put(SkillType.ARCHERY, (float) Integer.valueOf(experienceValues.get(7)));
skillsXp.put(SkillType.SWORDS, (float) Integer.valueOf(experienceValues.get(8)));
skillsXp.put(SkillType.AXES, (float) Integer.valueOf(experienceValues.get(9)));
skillsXp.put(SkillType.ACROBATICS, (float) Integer.valueOf(experienceValues.get(10)));
skillsXp.put(SkillType.FISHING, (float) Integer.valueOf(experienceValues.get(11)));
}
loaded = true;
@ -512,18 +516,18 @@ public class PlayerProfile {
+ ", fishing = " + skills.get(SkillType.FISHING)
+ " WHERE user_id = " + userId);
SQLDatabaseManager.write("UPDATE " + tablePrefix + "experience SET "
+ " taming = " + skillsXp.get(SkillType.TAMING)
+ ", mining = " + skillsXp.get(SkillType.MINING)
+ ", repair = " + skillsXp.get(SkillType.REPAIR)
+ ", woodcutting = " + skillsXp.get(SkillType.WOODCUTTING)
+ ", unarmed = " + skillsXp.get(SkillType.UNARMED)
+ ", herbalism = " + skillsXp.get(SkillType.HERBALISM)
+ ", excavation = " + skillsXp.get(SkillType.EXCAVATION)
+ ", archery = " + skillsXp.get(SkillType.ARCHERY)
+ ", swords = " + skillsXp.get(SkillType.SWORDS)
+ ", axes = " + skillsXp.get(SkillType.AXES)
+ ", acrobatics = " + skillsXp.get(SkillType.ACROBATICS)
+ ", fishing = " + skillsXp.get(SkillType.FISHING)
+ " taming = " + getSkillXpLevel(SkillType.TAMING)
+ ", mining = " + getSkillXpLevel(SkillType.MINING)
+ ", repair = " + getSkillXpLevel(SkillType.REPAIR)
+ ", woodcutting = " + getSkillXpLevel(SkillType.WOODCUTTING)
+ ", unarmed = " + getSkillXpLevel(SkillType.UNARMED)
+ ", herbalism = " + getSkillXpLevel(SkillType.HERBALISM)
+ ", excavation = " + getSkillXpLevel(SkillType.EXCAVATION)
+ ", archery = " + getSkillXpLevel(SkillType.ARCHERY)
+ ", swords = " + getSkillXpLevel(SkillType.SWORDS)
+ ", axes = " + getSkillXpLevel(SkillType.AXES)
+ ", acrobatics = " + getSkillXpLevel(SkillType.ACROBATICS)
+ ", fishing = " + getSkillXpLevel(SkillType.FISHING)
+ " WHERE user_id = " + userId);
}
}
@ -547,9 +551,9 @@ public class PlayerProfile {
writer.append(skills.get(SkillType.MINING)).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(skillsXp.get(SkillType.WOODCUTTING)).append(":");
writer.append(getSkillXpLevel(SkillType.WOODCUTTING)).append(":");
writer.append(skills.get(SkillType.REPAIR)).append(":");
writer.append(skills.get(SkillType.UNARMED)).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.AXES)).append(":");
writer.append(skills.get(SkillType.ACROBATICS)).append(":");
writer.append(skillsXp.get(SkillType.REPAIR)).append(":");
writer.append(skillsXp.get(SkillType.UNARMED)).append(":");
writer.append(skillsXp.get(SkillType.HERBALISM)).append(":");
writer.append(skillsXp.get(SkillType.EXCAVATION)).append(":");
writer.append(skillsXp.get(SkillType.ARCHERY)).append(":");
writer.append(skillsXp.get(SkillType.SWORDS)).append(":");
writer.append(skillsXp.get(SkillType.AXES)).append(":");
writer.append(skillsXp.get(SkillType.ACROBATICS)).append(":");
writer.append(getSkillXpLevel(SkillType.REPAIR)).append(":");
writer.append(getSkillXpLevel(SkillType.UNARMED)).append(":");
writer.append(getSkillXpLevel(SkillType.HERBALISM)).append(":");
writer.append(getSkillXpLevel(SkillType.EXCAVATION)).append(":");
writer.append(getSkillXpLevel(SkillType.ARCHERY)).append(":");
writer.append(getSkillXpLevel(SkillType.SWORDS)).append(":");
writer.append(getSkillXpLevel(SkillType.AXES)).append(":");
writer.append(getSkillXpLevel(SkillType.ACROBATICS)).append(":");
writer.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.GIGA_DRILL_BREAKER)).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(hudType.toString()).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(System.currentTimeMillis() / Misc.TIME_CONVERSION_FACTOR).append(":");
writer.append(mobHealthbarType.toString()).append(":");
@ -601,7 +605,7 @@ public class PlayerProfile {
private void loadSkillXpData(SkillType skill, String[] data, int 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
*/
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);
this.xpGained = xpGained;
}
@ -18,13 +18,29 @@ public class McMMOPlayerXpGainEvent extends McMMOPlayerExperienceEvent {
/**
* @return The amount of experience gained in this event
*/
public int getXpGained() {
public float getRawXpGained() {
return xpGained;
}
/**
* @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) {
this.xpGained = xpGained;
}

View File

@ -52,7 +52,7 @@ public final class ShareHandler {
* @param skillType Skill being used
* @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();
switch (party.getXpShareMode()) {
@ -71,14 +71,13 @@ public final class ShareHandler {
shareBonus = Config.getInstance().getPartyShareBonusCap();
}
double splitXp = xp / partySize * shareBonus;
int roundedXp = (int) Math.ceil(splitXp);
float splitXp = (float) (xp / partySize * shareBonus);
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;

View File

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

View File

@ -62,7 +62,7 @@ public final class Motd {
* @param player Target player
*/
public static void displayXpPerks(Player player) {
int perkAmount = PerksUtils.handleXpPerks(player, 1);
float perkAmount = PerksUtils.handleXpPerks(player, 1);
if (perkAmount > 1) {
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;
}
public static int handleXpPerks(Player player, int xp) {
public static float handleXpPerks(Player player, float xp) {
if (Permissions.quadrupleXp(player)) {
xp *= 4;
}

View File

@ -211,12 +211,12 @@ public class SkillUtils {
*/
public static void xpCheckSkill(SkillType skillType, Player player, PlayerProfile profile) {
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);
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)) {
int xp = profile.getXpToLevel(skillType);
xpRemoved += xp;
@ -235,7 +235,7 @@ public class SkillUtils {
if (eventToFire.isCancelled()) {
profile.modifySkill(skillType, profile.getSkillLevel(skillType) - skillups);
profile.setSkillXpLevel(skillType, profile.getSkillXpLevel(skillType) + xpRemoved);
profile.setSkillXpLevel(skillType, profile.getSkillXpLevelRaw(skillType) + xpRemoved);
return;
}