From 17a038228344159647de6a650e7b3efe4e995744 Mon Sep 17 00:00:00 2001 From: TfT_02 Date: Wed, 24 Apr 2013 19:30:46 +0200 Subject: [PATCH] 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. --- .../com/gmail/nossr50/api/ExperienceAPI.java | 43 +++++++++ .../nossr50/datatypes/player/McMMOPlayer.java | 12 +-- .../datatypes/player/PlayerProfile.java | 90 ++++++++++--------- .../experience/McMMOPlayerXpGainEvent.java | 22 ++++- .../com/gmail/nossr50/party/ShareHandler.java | 9 +- .../gmail/nossr50/skills/SkillManager.java | 2 +- .../java/com/gmail/nossr50/util/Motd.java | 2 +- .../gmail/nossr50/util/skills/PerksUtils.java | 2 +- .../gmail/nossr50/util/skills/SkillUtils.java | 8 +- 9 files changed, 126 insertions(+), 64 deletions(-) diff --git a/src/main/java/com/gmail/nossr50/api/ExperienceAPI.java b/src/main/java/com/gmail/nossr50/api/ExperienceAPI.java index 65e338ebf..e9e508cd1 100644 --- a/src/main/java/com/gmail/nossr50/api/ExperienceAPI.java +++ b/src/main/java/com/gmail/nossr50/api/ExperienceAPI.java @@ -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. + *
+ * 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. + *
+ * 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. *
diff --git a/src/main/java/com/gmail/nossr50/datatypes/player/McMMOPlayer.java b/src/main/java/com/gmail/nossr50/datatypes/player/McMMOPlayer.java index c82f25a2e..1b3a8092a 100644 --- a/src/main/java/com/gmail/nossr50/datatypes/player/McMMOPlayer.java +++ b/src/main/java/com/gmail/nossr50/datatypes/player/McMMOPlayer.java @@ -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 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(); diff --git a/src/main/java/com/gmail/nossr50/datatypes/player/PlayerProfile.java b/src/main/java/com/gmail/nossr50/datatypes/player/PlayerProfile.java index d2b2a9c0c..fb4e4aa1f 100644 --- a/src/main/java/com/gmail/nossr50/datatypes/player/PlayerProfile.java +++ b/src/main/java/com/gmail/nossr50/datatypes/player/PlayerProfile.java @@ -33,7 +33,7 @@ public class PlayerProfile { /* Skill Data */ private final Map skills = new HashMap(); // Skill & Level - private final Map skillsXp = new HashMap(); // Skill & XP + private final Map skillsXp = new HashMap(); // Skill & XP private final Map skillsDATS = new HashMap(); // 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])); } } diff --git a/src/main/java/com/gmail/nossr50/events/experience/McMMOPlayerXpGainEvent.java b/src/main/java/com/gmail/nossr50/events/experience/McMMOPlayerXpGainEvent.java index 31d982b8a..bf8a74ad4 100644 --- a/src/main/java/com/gmail/nossr50/events/experience/McMMOPlayerXpGainEvent.java +++ b/src/main/java/com/gmail/nossr50/events/experience/McMMOPlayerXpGainEvent.java @@ -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; } diff --git a/src/main/java/com/gmail/nossr50/party/ShareHandler.java b/src/main/java/com/gmail/nossr50/party/ShareHandler.java index aa391ae97..5d4899875 100644 --- a/src/main/java/com/gmail/nossr50/party/ShareHandler.java +++ b/src/main/java/com/gmail/nossr50/party/ShareHandler.java @@ -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; diff --git a/src/main/java/com/gmail/nossr50/skills/SkillManager.java b/src/main/java/com/gmail/nossr50/skills/SkillManager.java index 8595b0929..38e4c79a4 100644 --- a/src/main/java/com/gmail/nossr50/skills/SkillManager.java +++ b/src/main/java/com/gmail/nossr50/skills/SkillManager.java @@ -38,7 +38,7 @@ public abstract class SkillManager { return activationChance; } - public void applyXpGain(int xp) { + public void applyXpGain(float xp) { mcMMOPlayer.beginXpGain(skill, xp); } } diff --git a/src/main/java/com/gmail/nossr50/util/Motd.java b/src/main/java/com/gmail/nossr50/util/Motd.java index 55474f2d7..c09205c39 100644 --- a/src/main/java/com/gmail/nossr50/util/Motd.java +++ b/src/main/java/com/gmail/nossr50/util/Motd.java @@ -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))); diff --git a/src/main/java/com/gmail/nossr50/util/skills/PerksUtils.java b/src/main/java/com/gmail/nossr50/util/skills/PerksUtils.java index 22d3ad6e8..74202181f 100644 --- a/src/main/java/com/gmail/nossr50/util/skills/PerksUtils.java +++ b/src/main/java/com/gmail/nossr50/util/skills/PerksUtils.java @@ -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; } diff --git a/src/main/java/com/gmail/nossr50/util/skills/SkillUtils.java b/src/main/java/com/gmail/nossr50/util/skills/SkillUtils.java index 26d92e8e2..54fd46d5f 100644 --- a/src/main/java/com/gmail/nossr50/util/skills/SkillUtils.java +++ b/src/main/java/com/gmail/nossr50/util/skills/SkillUtils.java @@ -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; }