浏览代码

More work on Skill API migration

nossr50 4 年之前
父节点
当前提交
573d9d014e

+ 6 - 6
src/main/java/com/gmail/nossr50/api/ExperienceAPI.java

@@ -492,7 +492,7 @@ public final class ExperienceAPI {
      * @throws UnsupportedOperationException if the given skill is a child skill
      */
     public static int getXPToNextLevel(Player player, String skillType) {
-        return getPlayer(player).getExperienceManager().getXpToLevel(getNonChildSkillType(skillType));
+        return getPlayer(player).getExperienceManager().getExperienceToNextLevel(getNonChildSkillType(skillType));
     }
 
     /**
@@ -510,7 +510,7 @@ public final class ExperienceAPI {
      */
     @Deprecated
     public static int getOfflineXPToNextLevel(String playerName, String skillType) {
-        return getOfflineProfile(playerName).getExperienceManager().getXpToLevel(getNonChildSkillType(skillType));
+        return getOfflineProfile(playerName).getExperienceManager().getExperienceToNextLevel(getNonChildSkillType(skillType));
     }
 
     /**
@@ -527,7 +527,7 @@ public final class ExperienceAPI {
      * @throws UnsupportedOperationException if the given skill is a child skill
      */
     public static int getOfflineXPToNextLevel(UUID uuid, String skillType) {
-        return getOfflineProfile(uuid).getExperienceManager().getXpToLevel(getNonChildSkillType(skillType));
+        return getOfflineProfile(uuid).getExperienceManager().getExperienceToNextLevel(getNonChildSkillType(skillType));
     }
 
     /**
@@ -547,7 +547,7 @@ public final class ExperienceAPI {
 
         PlayerProfile profile = getPlayer(player);
 
-        return profile.getExperienceManager().getXpToLevel(skill) - profile.getExperienceManager().getSkillXpValue(skill);
+        return profile.getExperienceManager().getExperienceToNextLevel(skill) - profile.getExperienceManager().getSkillXpValue(skill);
     }
 
     /**
@@ -568,7 +568,7 @@ public final class ExperienceAPI {
         PrimarySkillType skill = getNonChildSkillType(skillType);
         PlayerProfile profile = getOfflineProfile(playerName);
 
-        return profile.getExperienceManager().getXpToLevel(skill) - profile.getExperienceManager().getSkillXpValue(skill);
+        return profile.getExperienceManager().getExperienceToNextLevel(skill) - profile.getExperienceManager().getSkillXpValue(skill);
     }
 
     /**
@@ -588,7 +588,7 @@ public final class ExperienceAPI {
         PrimarySkillType skill = getNonChildSkillType(skillType);
         PlayerProfile profile = getOfflineProfile(uuid);
 
-        return profile.getExperienceManager().getXpToLevel(skill) - profile.getExperienceManager().getSkillXpLevelRaw(skill);
+        return profile.getExperienceManager().getExperienceToNextLevel(skill) - profile.getExperienceManager().getSkillXpLevelRaw(skill);
     }
 
     /**

+ 1 - 1
src/main/java/com/gmail/nossr50/commands/skills/SkillCommand.java

@@ -153,7 +153,7 @@ public abstract class SkillCommand implements TabExecutor {
             mmoPlayer.getPlayer().sendMessage(LocaleLoader.getString("Commands.XPGain.Overhaul", LocaleLoader.getString("Commands.XPGain." + StringUtils.getCapitalized(skill.toString()))));
 
             //LEVEL
-            mmoPlayer.getPlayer().sendMessage(LocaleLoader.getString("Effects.Level.Overhaul", skillValue, mmoPlayer.getExperienceManager().getSkillXpValue(skill), mmoPlayer.getExperienceManager().getXpToLevel(skill)));
+            mmoPlayer.getPlayer().sendMessage(LocaleLoader.getString("Effects.Level.Overhaul", skillValue, mmoPlayer.getExperienceManager().getSkillXpValue(skill), mmoPlayer.getExperienceManager().getExperienceToNextLevel(skill)));
 
         } else {
             /*

+ 4 - 2
src/main/java/com/gmail/nossr50/config/Config.java

@@ -6,9 +6,11 @@ import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 import com.gmail.nossr50.datatypes.skills.SuperAbilityType;
 import com.gmail.nossr50.util.text.StringUtils;
 import com.neetgames.mcmmo.MobHealthBarType;
+import com.neetgames.mcmmo.skill.SkillIdentity;
 import org.bukkit.Material;
 import org.bukkit.block.data.BlockData;
 import org.bukkit.configuration.ConfigurationSection;
+import org.jetbrains.annotations.NotNull;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -549,8 +551,8 @@ public class Config extends AutoUpdateConfigLoader {
         return (cap <= 0) ? Integer.MAX_VALUE : cap;
     }
 
-    public int getLevelCap(PrimarySkillType skill) {
-        int cap = config.getInt("Skills." + StringUtils.getCapitalized(skill.toString()) + ".Level_Cap", 0);
+    public int getLevelCap(@NotNull SkillIdentity skillIdentity) {
+        int cap = config.getInt("Skills." + StringUtils.getCapitalized(skillIdentity.getSkillName()) + ".Level_Cap", 0);
         return (cap <= 0) ? Integer.MAX_VALUE : cap;
     }
 

+ 51 - 49
src/main/java/com/gmail/nossr50/datatypes/experience/ExperienceManager.java

@@ -5,6 +5,7 @@ import com.gmail.nossr50.config.experience.ExperienceConfig;
 import com.gmail.nossr50.datatypes.party.Party;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.player.PersistentPlayerData;
+import com.gmail.nossr50.datatypes.skills.CoreSkillConstants;
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.party.ShareHandler;
@@ -15,7 +16,8 @@ import com.gmail.nossr50.util.player.NotificationManager;
 import com.gmail.nossr50.util.skills.PerksUtils;
 import com.gmail.nossr50.util.sounds.SoundManager;
 import com.gmail.nossr50.util.sounds.SoundType;
-import org.apache.commons.lang.Validate;
+import com.neetgames.mcmmo.exceptions.UnknownSkillException;
+import com.neetgames.mcmmo.skill.SkillIdentity;
 import org.bukkit.GameMode;
 import org.bukkit.plugin.Plugin;
 import org.jetbrains.annotations.NotNull;
@@ -67,30 +69,30 @@ public class ExperienceManager {
     /**
      * Get the value of XP a player has accumulated in target skill
      * Child Skills will return 0 (Child Skills will be removed in a future update)
-     * @param primarySkillType target skill
+     * @param skillIdentity target skill
      * @return the value for XP the player has accumulated in target skill
      */
-    public int getSkillXpValue(@NotNull PrimarySkillType primarySkillType) {
-        if(primarySkillType.isChildSkill()) {
+    public int getSkillXpValue(@NotNull SkillIdentity skillIdentity) {
+        if(CoreSkillConstants.isChildSkill(skillIdentity)) {
             return 0;
         }
 
-        return (int) Math.floor(getSkillXpLevelRaw(primarySkillType));
+        return (int) Math.floor(getSkillXpLevelRaw(skillIdentity));
     }
 
-    public void setSkillXpValue(@NotNull PrimarySkillType primarySkillType, float xpLevel) {
-        if (primarySkillType.isChildSkill()) {
+    public void setSkillXpValue(@NotNull SkillIdentity skillIdentity, float xpLevel) {
+        if (CoreSkillConstants.isChildSkill(skillIdentity)) {
             return;
         }
 
-        persistentPlayerDataRef.getSkillsExperienceMap().put(primarySkillType, xpLevel);
+        persistentPlayerDataRef.getSkillsExperienceMap().put(skillIdentity, xpLevel);
     }
 
-    public float levelUp(@NotNull PrimarySkillType primarySkillType) {
-        float xpRemoved = getXpToLevel(primarySkillType);
+    public float levelUp(@NotNull SkillIdentity skillIdentity) {
+        float xpRemoved = getExperienceToNextLevel(skillIdentity);
 
-        setSkillLevel(primarySkillType, getSkillLevel(primarySkillType) + 1);
-        setSkillXpValue(primarySkillType, getSkillXpValue(primarySkillType) - xpRemoved);
+        setSkillLevel(skillIdentity, getSkillLevel(skillIdentity) + 1);
+        setSkillXpValue(skillIdentity, getSkillXpValue(skillIdentity) - xpRemoved);
 
         return xpRemoved;
     }
@@ -99,14 +101,14 @@ public class ExperienceManager {
      * Whether or not a player is level capped
      * If they are at the power level cap, this will return true, otherwise it checks their skill level
      *
-     * @param primarySkillType
+     * @param skillIdentity
      * @return
      */
-    public boolean hasReachedLevelCap(@NotNull PrimarySkillType primarySkillType) {
+    public boolean hasReachedLevelCap(@NotNull SkillIdentity skillIdentity) {
         if(hasReachedPowerLevelCap())
             return true;
 
-        return getSkillLevel(primarySkillType) >= Config.getInstance().getLevelCap(primarySkillType);
+        return getSkillLevel(skillIdentity) >= Config.getInstance().getLevelCap(skillIdentity);
     }
 
     /**
@@ -119,21 +121,21 @@ public class ExperienceManager {
     }
 
     /**
-     * Begins an experience gain. The amount will be affected by primarySkillType modifiers, global rate, perks, and may be shared with the party
+     * Begins an experience gain. The amount will be affected by skill modifiers, global rate, perks, and may be shared with the party
      *
-     * @param primarySkillType Skill being used
+     * @param skillIdentity Skill being used
      * @param xp Experience amount to process
      */
-    public void beginXpGain(@NotNull PrimarySkillType primarySkillType, float xp, @NotNull XPGainReason xpGainReason, @NotNull XPGainSource xpGainSource) {
+    public void beginXpGain(@NotNull SkillIdentity skillIdentity, float xp, @NotNull XPGainReason xpGainReason, @NotNull XPGainSource xpGainSource) {
         if (xp <= 0.0) {
             return;
         }
 
-        if (primarySkillType.isChildSkill()) {
-            Set<PrimarySkillType> parentSkills = FamilyTree.getParents(primarySkillType);
+        if (CoreSkillConstants.isChildSkill(skillIdentity)) {
+            Set<SkillIdentity> parentSkills = FamilyTree.getParentSkills(skillIdentity);
             float splitXp = xp / parentSkills.size();
 
-            for (PrimarySkillType parentSkill : parentSkills) {
+            for (SkillIdentity parentSkill : parentSkills) {
                 beginXpGain(parentSkill, splitXp, xpGainReason, xpGainSource);
             }
 
@@ -143,61 +145,61 @@ public class ExperienceManager {
         //TODO: The logic here is so stupid... rewrite later
 
         // Return if the experience has been shared
-        if (mmoPlayer.getParty() != null && ShareHandler.handleXpShare(xp, mmoPlayer, mmoPlayer.getParty(), primarySkillType, ShareHandler.getSharedXpGainReason(xpGainReason))) {
+        if (mmoPlayer.getParty() != null && ShareHandler.handleXpShare(xp, mmoPlayer, mmoPlayer.getParty(), skillIdentity, ShareHandler.getSharedXpGainReason(xpGainReason))) {
             return;
         }
 
-        beginUnsharedXpGain(primarySkillType, xp, xpGainReason, xpGainSource);
+        beginUnsharedXpGain(skillIdentity, xp, xpGainReason, xpGainSource);
     }
 
     /**
-     * Begins an experience gain. The amount will be affected by primarySkillType modifiers, global rate and perks
+     * Begins an experience gain. The amount will be affected by skill modifiers, global rate and perks
      *
-     * @param primarySkillType Skill being used
+     * @param skillIdentity Skill being used
      * @param xp Experience amount to process
      */
-    public void beginUnsharedXpGain(@NotNull PrimarySkillType primarySkillType, float xp, @NotNull XPGainReason xpGainReason, @NotNull XPGainSource xpGainSource) {
+    public void beginUnsharedXpGain(@NotNull SkillIdentity skillIdentity, float xp, @NotNull XPGainReason xpGainReason, @NotNull XPGainSource xpGainSource) {
         if(mmoPlayer.getPlayer().getGameMode() == GameMode.CREATIVE)
             return;
 
-        ExperienceUtils.applyXpGain(mmoPlayer, primarySkillType, modifyXpGain(primarySkillType, xp), xpGainReason, xpGainSource);
+        ExperienceUtils.applyXpGain(mmoPlayer, skillIdentity, modifyXpGain(skillIdentity, xp), xpGainReason, xpGainSource);
 
         Party party = mmoPlayer.getParty();
 
         if (party != null) {
             if (!Config.getInstance().getPartyXpNearMembersNeeded() || !mcMMO.getPartyManager().getNearMembers(mmoPlayer).isEmpty()) {
-                party.getPartyExperienceManager().applyXpGain(modifyXpGain(primarySkillType, xp));
+                party.getPartyExperienceManager().applyXpGain(modifyXpGain(skillIdentity, xp));
             }
         }
     }
 
-    public int getSkillLevel(@NotNull PrimarySkillType skill) {
-        return skill.isChildSkill() ? getChildSkillLevel(skill) : getSkillLevel(skill);
+    public int getSkillLevel(@NotNull SkillIdentity skillIdentity) {
+        return CoreSkillConstants.isChildSkill(skillIdentity) ? getChildSkillLevel(skillIdentity) : getSkillLevel(skillIdentity);
     }
 
     /**
      * Get the amount of Xp remaining before the next level.
      *
-     * @param primarySkillType Type of skill to check
+     * @param skillIdentity Type of skill to check
      * @return the total amount of Xp until next level
      */
-    public int getXpToLevel(@NotNull PrimarySkillType primarySkillType) {
-        if(primarySkillType.isChildSkill()) {
+    public int getExperienceToNextLevel(@NotNull SkillIdentity skillIdentity) {
+        if(CoreSkillConstants.isChildSkill(skillIdentity)) {
             return 0;
         }
 
-        int level = (ExperienceConfig.getInstance().getCumulativeCurveEnabled()) ? getPowerLevel() : getSkillLevel(primarySkillType);
+        int level = (ExperienceConfig.getInstance().getCumulativeCurveEnabled()) ? getPowerLevel() : getSkillLevel(skillIdentity);
         FormulaType formulaType = ExperienceConfig.getInstance().getFormulaType();
 
         return mcMMO.getFormulaManager().getXPtoNextLevel(level, formulaType);
     }
 
-    private int getChildSkillLevel(@NotNull PrimarySkillType primarySkillType) {
-        Set<PrimarySkillType> parents = FamilyTree.getParents(primarySkillType);
+    private int getChildSkillLevel(@NotNull SkillIdentity skillIdentity) {
+        Set<SkillIdentity> parents = FamilyTree.getParentSkills(skillIdentity);
         int sum = 0;
 
-        for (PrimarySkillType parent : parents) {
-            sum += Math.min(getSkillLevel(parent), parent.getMaxLevel());
+        for (SkillIdentity parentIdentity : parents) {
+            sum += getSkillLevel(parentIdentity);
         }
 
         return sum / parents.size();
@@ -320,28 +322,28 @@ public class ExperienceManager {
     /**
      * Modifies an experience gain using skill modifiers, global rate and perks
      *
-     * @param primarySkillType Skill being used
+     * @param skillIdentity Skill being used
      * @param xp Experience amount to process
      * @return Modified experience
      */
-    private float modifyXpGain(PrimarySkillType primarySkillType, float xp) {
-        if ((primarySkillType.getMaxLevel() <= getSkillLevel(primarySkillType)) || (Config.getInstance().getPowerLevelCap() <= getPowerLevel())) {
+    private float modifyXpGain(@NotNull SkillIdentity skillIdentity, float xp) {
+        if ((skillIdentity.getMaxLevel() <= getSkillLevel(skillIdentity)) || (Config.getInstance().getPowerLevelCap() <= getPowerLevel())) {
             return 0;
         }
 
-        xp = (float) (xp / primarySkillType.getXpModifier() * ExperienceConfig.getInstance().getExperienceGainsGlobalMultiplier());
+        xp = (float) (xp / skillIdentity.getXpModifier() * ExperienceConfig.getInstance().getExperienceGainsGlobalMultiplier());
 
-        return PerksUtils.handleXpPerks(mmoPlayer.getPlayer(), xp, primarySkillType);
+        return PerksUtils.handleXpPerks(mmoPlayer.getPlayer(), xp, skillIdentity);
     }
 
-    public double getProgressInCurrentSkillLevel(PrimarySkillType primarySkillType)
+    public double getProgressInCurrentSkillLevel(@NotNull SkillIdentity skillIdentity) throws UnknownSkillException
     {
-        if(primarySkillType.isChildSkill()) {
+        if(CoreSkillConstants.isChildSkill(skillIdentity)) {
             return 1.0D;
         }
 
-        double currentXP = getSkillXpValue(primarySkillType);
-        double maxXP = getXpToLevel(primarySkillType);
+        double currentXP = getSkillXpValue(skillIdentity);
+        double maxXP = getExperienceToNextLevel(skillIdentity);
 
         return (currentXP / maxXP);
     }
@@ -417,7 +419,7 @@ public class ExperienceManager {
         if(hasReachedLevelCap(primarySkillType))
             return;
 
-        if (getSkillXpLevelRaw(primarySkillType) < getXpToLevel(primarySkillType)) {
+        if (getSkillXpLevelRaw(primarySkillType) < getExperienceToNextLevel(primarySkillType)) {
             processPostXpEvent(primarySkillType, mcMMO.p, xpGainSource);
             return;
         }
@@ -425,7 +427,7 @@ public class ExperienceManager {
         int levelsGained = 0;
         float xpRemoved = 0;
 
-        while (getSkillXpLevelRaw(primarySkillType) >= getXpToLevel(primarySkillType)) {
+        while (getSkillXpLevelRaw(primarySkillType) >= getExperienceToNextLevel(primarySkillType)) {
             if (hasReachedLevelCap(primarySkillType)) {
                 setSkillXpValue(primarySkillType, 0);
                 break;

+ 25 - 5
src/main/java/com/gmail/nossr50/datatypes/player/McMMOPlayer.java

@@ -33,9 +33,9 @@ import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.experience.MMOExperienceBarManager;
 import com.gmail.nossr50.util.input.AbilityActivationProcessor;
 import com.gmail.nossr50.util.input.SuperAbilityManager;
-import com.neetgames.jmal.core.player.OnlinePlayer;
-import com.neetgames.mcmmo.player.MMOPlayer;
+import com.neetgames.mcmmo.exceptions.UnknownSkillException;
 import com.neetgames.mcmmo.player.OnlineMMOPlayer;
+import com.neetgames.mcmmo.skill.SkillIdentity;
 import net.kyori.adventure.identity.Identified;
 import net.kyori.adventure.identity.Identity;
 import org.bukkit.Location;
@@ -478,12 +478,12 @@ public class McMMOPlayer extends PlayerProfile implements OnlineMMOPlayer, Ident
 
     /**
      * Update the experience bars for this player
-     * @param primarySkillType target skill
+     * @param skillIdentity target skill
      * @param plugin your {@link Plugin}
      */
-    public void updateXPBar(PrimarySkillType primarySkillType, Plugin plugin) {
+    public void updateXPBar(@NotNull SkillIdentity skillIdentity, Plugin plugin) {
         //XP BAR UPDATES
-        experienceBarManager.updateExperienceBar(primarySkillType, plugin);
+        experienceBarManager.updateExperienceBar(skillIdentity, plugin);
     }
 
     /**
@@ -618,4 +618,24 @@ public class McMMOPlayer extends PlayerProfile implements OnlineMMOPlayer, Ident
     public boolean isChatSpying() {
         return false;
     }
+
+    @Override
+    public double getProgressInCurrentSkillLevel(@NotNull SkillIdentity skillIdentity) throws UnknownSkillException {
+        return experienceManager.getProgressInCurrentSkillLevel(skillIdentity);
+    }
+
+    @Override
+    public int getSkillLevel(@NotNull SkillIdentity skillIdentity) throws UnknownSkillException {
+        return experienceManager.getSkillLevel(skillIdentity);
+    }
+
+    @Override
+    public int getSkillExperience(@NotNull SkillIdentity skillIdentity) throws UnknownSkillException {
+        return experienceManager.getSkillXpValue(skillIdentity);
+    }
+
+    @Override
+    public int getExperienceToNextLevel(@NotNull SkillIdentity skillIdentity) throws UnknownSkillException {
+        return experienceManager.getExperienceToNextLevel(skillIdentity);
+    }
 }

+ 12 - 11
src/main/java/com/gmail/nossr50/datatypes/player/PersistentPlayerData.java

@@ -1,6 +1,7 @@
 package com.gmail.nossr50.datatypes.player;
 
 import com.gmail.nossr50.config.AdvancedConfig;
+import com.gmail.nossr50.datatypes.skills.CoreSkillConstants;
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 import com.gmail.nossr50.datatypes.skills.SuperAbilityType;
 import com.gmail.nossr50.datatypes.validation.NonNullRule;
@@ -68,9 +69,9 @@ public class PersistentPlayerData implements MMOPlayerData {
         this.playerUUID = playerUUID;
         this.playerName = new DirtyData<>(new MutableString(playerName), dirtyFlag);
 
-        this.skillLevelValues = new DirtyMap<>(new HashMap<>(SkillIdentity.class), dirtyFlag);
-        this.skillExperienceValues = new DirtyMap<>(new HashMap<>(SkillIdentity.class), dirtyFlag);
-        this.abilityDeactivationTimestamps = new DirtyMap<>(new EnumMap<>(SkillIdentity.class), dirtyFlag);
+        this.skillLevelValues = new DirtyMap<>(new HashMap<>(), dirtyFlag);
+        this.skillExperienceValues = new DirtyMap<>(new HashMap<>(), dirtyFlag);
+        this.abilityDeactivationTimestamps = new DirtyMap<>(new HashMap<>(), dirtyFlag);
         this.uniquePlayerData = new DirtyMap<>(new EnumMap<>(UniqueDataType.class), dirtyFlag);
 
         this.scoreboardTipsShown = new DirtyData<>(new MutableInteger(0), dirtyFlag);
@@ -79,9 +80,11 @@ public class PersistentPlayerData implements MMOPlayerData {
             abilityDeactivationTimestamps.put(rootSkill.getSkillIdentity(), 0);
         }
 
-        for(PrimarySkillType primarySkillType : PrimarySkillType.values()) {
-            skillLevelValues.put(primarySkillType, AdvancedConfig.getInstance().getStartingLevel());
-            skillExperienceValues.put(primarySkillType, 0F);
+        //Core skills
+        //TODO: Don't store values for disabled skills
+        for(RootSkill rootSkill : CoreSkillConstants.getImmutableCoreRootSkillSet()) {
+            skillLevelValues.put(rootSkill.getSkillIdentity(), AdvancedConfig.getInstance().getStartingLevel());
+            skillExperienceValues.put(rootSkill.getSkillIdentity(), 0F);
         }
 
         //Unique Player Data
@@ -106,7 +109,6 @@ public class PersistentPlayerData implements MMOPlayerData {
      * @param uniquePlayerData target player's misc unique data
      * @param barStateMap target player's XP bar state settings
      * @param scoreboardTipsShown target player's scoreboard tip view count
-     * @param mobHealthBarType target player's mob health bar type
      * @param lastLogin target player's last login
      * @param leaderBoardExclusion target player's leaderboard exemption status
      */
@@ -119,7 +121,6 @@ public class PersistentPlayerData implements MMOPlayerData {
                                 @NotNull EnumMap<UniqueDataType, Integer> uniquePlayerData,
                                 @NotNull EnumMap<PrimarySkillType, SkillBossBarState> barStateMap,
                                 int scoreboardTipsShown,
-                                @NotNull MobHealthBarType mobHealthBarType,
                                 long lastLogin,
                                 boolean leaderBoardExclusion) throws Exception {
 
@@ -140,7 +141,6 @@ public class PersistentPlayerData implements MMOPlayerData {
         this.uniquePlayerData = new DirtyMap<>(uniquePlayerData, dirtyFlag);
 
         this.scoreboardTipsShown = new DirtyData<>(new MutableInteger(scoreboardTipsShown), dirtyFlag);
-        this.mobHealthBarType = new DirtyData<>(mobHealthBarType, dirtyFlag);
 
         this.playerUUID = playerUUID;
         this.playerName = new DirtyData<>(new MutableString(playerName), dirtyFlag);
@@ -174,8 +174,9 @@ public class PersistentPlayerData implements MMOPlayerData {
      * @param primarySkillType target Primary Skill
      * @param newSkillLevel the new value of the skill
      */
-    public void setSkillLevel(PrimarySkillType primarySkillType, int newSkillLevel) {
-        skillLevelValues.put(primarySkillType, newSkillLevel);
+    @Override
+    public void setSkillLevel(@NotNull SkillIdentity skillIdentity, int newSkillLevel) {
+        skillLevelValues.put(skillIdentity, newSkillLevel);
     }
 
     /**

+ 87 - 5
src/main/java/com/gmail/nossr50/datatypes/skills/CoreSkillConstants.java

@@ -1,6 +1,8 @@
 package com.gmail.nossr50.datatypes.skills;
 
 import com.google.common.collect.ImmutableSet;
+import com.neetgames.mcmmo.skill.RootSkill;
+import com.neetgames.mcmmo.skill.Skill;
 import com.neetgames.mcmmo.skill.SkillIdentity;
 import org.jetbrains.annotations.NotNull;
 
@@ -9,32 +11,75 @@ import java.util.Set;
 
 public class CoreSkillConstants {
 
-    private static final @NotNull ImmutableSet<CoreRootSkill> immutableCoreRootSkillSet;
+    private static final @NotNull ImmutableSet<RootSkill> CORE_ROOT_SKILLS_IMMUTABLE_SET;
+    private static final @NotNull ImmutableSet<RootSkill> CORE_CHILD_SKILLS;
 
-    public static @NotNull CoreRootSkill ACROBATICS, ALCHEMY, ARCHERY, AXES, EXCAVATION,
+    public static final @NotNull CoreRootSkill ACROBATICS, ALCHEMY, ARCHERY, AXES, EXCAVATION,
             FISHING, HERBALISM, MINING, REPAIR, SALVAGE, SMELTING, SWORDS, TAMING, UNARMED,
             WOODCUTTING, TRIDENTS, CROSSBOWS;
 
+    public static final @NotNull SkillIdentity ACROBATICS_ID, ALCHEMY_ID, ARCHERY_ID, AXES_ID, EXCAVATION_ID,
+            FISHING_ID, HERBALISM_ID, MINING_ID, REPAIR_ID, SALVAGE_ID, SMELTING_ID, SWORDS_ID, TAMING_ID, UNARMED_ID,
+            WOODCUTTING_ID, TRIDENTS_ID, CROSSBOWS_ID;
+
     static {
         HashSet<CoreRootSkill> rootSkillSet = new HashSet<>();
+        HashSet<CoreRootSkill> childSkillSet = new HashSet<>();
 
         ACROBATICS = new CoreRootSkill("acrobatics");
+        ACROBATICS_ID = ACROBATICS.getSkillIdentity();
+
         ALCHEMY = new CoreRootSkill("alchemy");
+        ALCHEMY_ID = ALCHEMY.getSkillIdentity();
+
         ARCHERY = new CoreRootSkill("archery");
+        ARCHERY_ID = ARCHERY.getSkillIdentity();
+
         AXES = new CoreRootSkill("axes");
+        AXES_ID = AXES.getSkillIdentity();
+
         EXCAVATION = new CoreRootSkill("excavation");
+        EXCAVATION_ID = EXCAVATION.getSkillIdentity();
+
         FISHING = new CoreRootSkill("fishing");
+        FISHING_ID = FISHING.getSkillIdentity();
+
         HERBALISM = new CoreRootSkill("herbalism");
+        HERBALISM_ID = HERBALISM.getSkillIdentity();
+
         MINING = new CoreRootSkill("mining");
+        MINING_ID = MINING.getSkillIdentity();
+
         REPAIR = new CoreRootSkill("repair");
+        REPAIR_ID = REPAIR.getSkillIdentity();
+
         SALVAGE = new CoreRootSkill("salvage");
+        SALVAGE_ID = SALVAGE.getSkillIdentity();
+
         SMELTING = new CoreRootSkill("smelting");
+        SMELTING_ID = SMELTING.getSkillIdentity();
+
         SWORDS = new CoreRootSkill("swords");
+        SWORDS_ID = SWORDS.getSkillIdentity();
+
         TAMING = new CoreRootSkill("taming");
+        TAMING_ID = TAMING.getSkillIdentity();
+
         UNARMED = new CoreRootSkill("unarmed");
+        UNARMED_ID = UNARMED.getSkillIdentity();
+
         WOODCUTTING = new CoreRootSkill("woodcutting");
+        WOODCUTTING_ID = WOODCUTTING.getSkillIdentity();
+
         TRIDENTS = new CoreRootSkill("tridents");
+        TRIDENTS_ID = TRIDENTS.getSkillIdentity();
+
         CROSSBOWS = new CoreRootSkill("crossbows");
+        CROSSBOWS_ID = CROSSBOWS.getSkillIdentity();
+        
+        //Child skills (soon to be removed)
+        childSkillSet.add(SMELTING);
+        childSkillSet.add(SALVAGE);
 
         rootSkillSet.add(ACROBATICS);
         rootSkillSet.add(ALCHEMY);
@@ -54,7 +99,8 @@ public class CoreSkillConstants {
         rootSkillSet.add(TRIDENTS);
         rootSkillSet.add(CROSSBOWS);
 
-        immutableCoreRootSkillSet = ImmutableSet.copyOf(rootSkillSet);
+        CORE_ROOT_SKILLS_IMMUTABLE_SET = ImmutableSet.copyOf(rootSkillSet);
+        CORE_CHILD_SKILLS = ImmutableSet.copyOf(childSkillSet);
     }
 
     /**
@@ -63,7 +109,43 @@ public class CoreSkillConstants {
      *
      * @return a set of all root skills built into mcMMO
      */
-    public static @NotNull Set<CoreRootSkill> getImmutableCoreRootSkillSet() {
-        return immutableCoreRootSkillSet;
+    public static @NotNull Set<RootSkill> getImmutableCoreRootSkillSet() {
+        return CORE_ROOT_SKILLS_IMMUTABLE_SET;
+    }
+
+    /**
+     * Returns a set of built in skills for mcMMO which are child skills
+     * No guarantees for whether or not the skills are registered or active or inactive
+     *
+     * @return a set of all "child" root skills for mcMMO
+     * @deprecated child skills will be removed in an upcoming update
+     */
+    @Deprecated
+    public static @NotNull Set<RootSkill> getChildSkills() {
+        return CORE_CHILD_SKILLS;
+    }
+
+    /**
+     * Whether or not a skill is considered a child skill
+     * @param skillIdentity target skill identity
+     * @return true if the skill identity belongs to a core "child" root skill
+     */
+    public static boolean isChildSkill(@NotNull SkillIdentity skillIdentity) {
+        for(RootSkill rootSkill : CORE_CHILD_SKILLS) {
+            if(rootSkill.getSkillIdentity().equals(skillIdentity)) {
+                return true;
+            }
+        }
+        
+        return false;
+    }
+
+    /**
+     * Whether or not a skill is considered a child skill
+     * @param skill target skill
+     * @return true if the skill identity belongs to a core "child" root skill
+     */
+    public static boolean isChildSkill(@NotNull Skill skill) {
+        return isChildSkill(skill.getSkillIdentity());
     }
 }

+ 3 - 3
src/main/java/com/gmail/nossr50/datatypes/skills/SkillRegisterImpl.java

@@ -143,9 +143,9 @@ public class SkillRegisterImpl implements SkillRegister {
     }
 
     private void registerCoreSkills() {
-        for(CoreRootSkill coreRootSkill : CoreSkillConstants.getImmutableCoreRootSkillSet()) {
-            mcMMO.p.getLogger().info("Registering core skill: "+coreRootSkill.getSkillName());
-            registerSkill(coreRootSkill);
+        for(RootSkill rootSkill : CoreSkillConstants.getImmutableCoreRootSkillSet()) {
+            mcMMO.p.getLogger().info("Registering core skill: "+rootSkill.getSkillName());
+            registerSkill(rootSkill);
         }
     }
 

+ 1 - 1
src/main/java/com/gmail/nossr50/listeners/SelfListener.java

@@ -122,7 +122,7 @@ public class SelfListener implements Listener {
             //Give some bonus XP for low levels
             if(PlayerLevelUtils.qualifiesForEarlyGameBoost(mmoPlayer, primarySkillType))
             {
-                earlyGameBonusXP += (mmoPlayer.getExperienceManager().getXpToLevel(primarySkillType) * 0.05);
+                earlyGameBonusXP += (mmoPlayer.getExperienceManager().getExperienceToNextLevel(primarySkillType) * 0.05);
                 event.setRawXpGained(event.getRawXpGained() + earlyGameBonusXP);
             }
         }

+ 28 - 37
src/main/java/com/gmail/nossr50/skills/child/FamilyTree.java

@@ -1,53 +1,44 @@
 package com.gmail.nossr50.skills.child;
 
-import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
+import com.gmail.nossr50.datatypes.skills.CoreSkillConstants;
+import com.neetgames.mcmmo.exceptions.UnknownSkillException;
+import com.neetgames.mcmmo.skill.SkillIdentity;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Set;
 
 public class FamilyTree {
-    private static final HashMap<PrimarySkillType, Set<PrimarySkillType>> tree = new HashMap<>();
 
-    public static Set<PrimarySkillType> getParents(PrimarySkillType childSkill) {
-        enforceChildSkill(childSkill);
+    /*
+     * Hacky crap, will remove later
+     */
 
-        // We do not check if we have the child skill in question, as not having it would mean we did something wrong, and an NPE is desired.
-        return tree.get(childSkill);
-    }
-
-    protected static void registerParent(PrimarySkillType childSkill, PrimarySkillType parentSkill) {
-        enforceChildSkill(childSkill);
-        enforceNotChildSkill(parentSkill);
+    private static @Nullable Set<SkillIdentity> smeltingParents;
+    private static @Nullable Set<SkillIdentity> salvageParents;
 
-        if (!tree.containsKey(childSkill)) {
-            tree.put(childSkill, EnumSet.noneOf(PrimarySkillType.class));
-        }
-
-        tree.get(childSkill).add(parentSkill);
-    }
+    public static @NotNull Set<SkillIdentity> getParentSkills(@NotNull SkillIdentity skillIdentity) throws UnknownSkillException {
+        if(CoreSkillConstants.isChildSkill(skillIdentity)) {
+            if(smeltingParents == null || salvageParents == null) {
+                smeltingParents = new HashSet<>();
+                salvageParents = new HashSet<>();
 
-    protected static void closeRegistration() {
-        for (PrimarySkillType childSkill : tree.keySet()) {
-            Set<PrimarySkillType> immutableSet = Collections.unmodifiableSet(tree.get(childSkill));
-            tree.put(childSkill, immutableSet);
-        }
-    }
+                smeltingParents.add(CoreSkillConstants.MINING_ID);
+                smeltingParents.add(CoreSkillConstants.REPAIR_ID);
 
-    protected static void clearRegistrations() {
-        tree.clear();
-    }
+                salvageParents.add(CoreSkillConstants.FISHING_ID);
+                salvageParents.add(CoreSkillConstants.REPAIR_ID);
+            }
 
-    protected static void enforceChildSkill(PrimarySkillType skill) {
-        if (!skill.isChildSkill()) {
-            throw new IllegalArgumentException(skill.name() + " is not a child skill!");
-        }
-    }
+            if(skillIdentity.equals(CoreSkillConstants.SALVAGE_ID)) {
+                return salvageParents;
+            } else {
+                return smeltingParents;
+            }
 
-    protected static void enforceNotChildSkill(PrimarySkillType skill) {
-        if (skill.isChildSkill()) {
-            throw new IllegalArgumentException(skill.name() + " is a child skill!");
+        } else {
+            throw new UnknownSkillException();
         }
     }
 }

+ 16 - 18
src/main/java/com/gmail/nossr50/util/experience/ExperienceBarWrapper.java

@@ -1,13 +1,11 @@
 package com.gmail.nossr50.util.experience;
 
 import com.gmail.nossr50.config.experience.ExperienceConfig;
-import com.gmail.nossr50.datatypes.player.PersistentPlayerData;
-import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.util.player.PlayerLevelUtils;
 import com.gmail.nossr50.util.text.StringUtils;
-import com.neetgames.mcmmo.player.MMOPlayerData;
 import com.neetgames.mcmmo.player.OnlineMMOPlayer;
+import com.neetgames.mcmmo.skill.SkillIdentity;
 import org.bukkit.boss.BarColor;
 import org.bukkit.boss.BarStyle;
 import org.bukkit.boss.BossBar;
@@ -21,9 +19,9 @@ import java.util.List;
  */
 public class ExperienceBarWrapper {
 
-    private final @NotNull PrimarySkillType primarySkillType; //Primary Skill
+    private final @NotNull SkillIdentity skillIdentity; //Primary Skill
     private @NotNull BossBar bossBar;
-    protected final @NotNull MMOPlayerData mmoPlayerData;
+    protected final @NotNull OnlineMMOPlayer onlineMMOPlayer;
     private int lastLevelUpdated;
 
     /*
@@ -32,14 +30,14 @@ public class ExperienceBarWrapper {
     protected String niceSkillName;
     protected String title;
 
-    public ExperienceBarWrapper(@NotNull PrimarySkillType primarySkillType, @NotNull OnlineMMOPlayer mmoPlayer) {
-        this.mmoPlayerData = mmoPlayer.getMMOPlayerData();
-        this.primarySkillType = primarySkillType;
+    public ExperienceBarWrapper(@NotNull SkillIdentity skillIdentity, @NotNull OnlineMMOPlayer onlineMMOPlayer) {
+        this.onlineMMOPlayer = onlineMMOPlayer;
+        this.skillIdentity = skillIdentity;
         title = "";
         lastLevelUpdated = 0;
 
         //These vars are stored to help reduce operations involving strings
-        niceSkillName = StringUtils.getCapitalized(primarySkillType.toString());
+        niceSkillName = StringUtils.getCapitalized(skillIdentity.toString());
 
         //Create the bar
         initBar();
@@ -58,7 +56,7 @@ public class ExperienceBarWrapper {
     private String getTitleTemplate() {
         //If they are using extra details
 
-        if(ExperienceConfig.getInstance().isEarlyGameBoostEnabled() && PlayerLevelUtils.qualifiesForEarlyGameBoost(persistentPlayerData, primarySkillType)) {
+        if(ExperienceConfig.getInstance().isEarlyGameBoostEnabled() && PlayerLevelUtils.qualifiesForEarlyGameBoost(onlineMMOPlayer, skillIdentity)) {
                 return LocaleLoader.getString("XPBar.Template.EarlyGameBoost");
         } else if(ExperienceConfig.getInstance().getAddExtraDetails())
             return LocaleLoader.getString("XPBar.Complex.Template", LocaleLoader.getString("XPBar."+niceSkillName, getLevel()), getCurrentXP(), getMaxXP(), getPowerLevel(), getPercentageOfLevel());
@@ -67,16 +65,16 @@ public class ExperienceBarWrapper {
     }
 
     private int getLevel() {
-        return persistentPlayerData.getSkillLevel(primarySkillType);
+        return onlineMMOPlayer.getSkillLevel(skillIdentity);
     }
     private int getCurrentXP() {
-        return mmoPlayer.getSkillXpLevel(primarySkillType);
+        return onlineMMOPlayer.getSkillExperience(skillIdentity);
     }
     private int getMaxXP() {
-        return mmoPlayer.getXpToLevel(primarySkillType);
+        return onlineMMOPlayer.getExperienceToNextLevel(skillIdentity);
     }
-    private int getPowerLevel() { return mmoPlayer.getPowerLevel(); }
-    private int getPercentageOfLevel() { return (int) (mmoPlayer.getProgressInCurrentSkillLevel(primarySkillType) * 100); }
+    private int getPowerLevel() { return onlineMMOPlayer.getPowerLevel(); }
+    private int getPercentageOfLevel() { return (int) (onlineMMOPlayer.getProgressInCurrentSkillLevel(skillIdentity) * 100); }
 
     public String getTitle() {
         return bossBar.getTitle();
@@ -113,10 +111,10 @@ public class ExperienceBarWrapper {
             bossBar.setProgress(v);
 
         //Check player level
-        if(ExperienceConfig.getInstance().isEarlyGameBoostEnabled() && PlayerLevelUtils.qualifiesForEarlyGameBoost(mmoPlayer, primarySkillType)) {
+        if(ExperienceConfig.getInstance().isEarlyGameBoostEnabled() && PlayerLevelUtils.qualifiesForEarlyGameBoost(mmoPlayer, skillIdentity)) {
            setColor(BarColor.YELLOW);
         } else {
-            setColor(ExperienceConfig.getInstance().getExperienceBarColor(primarySkillType));
+            setColor(ExperienceConfig.getInstance().getExperienceBarColor(skillIdentity));
         }
 
         //Every time progress updates we need to check for a title update
@@ -156,7 +154,7 @@ public class ExperienceBarWrapper {
 
     private void createBossBar()
     {
-        bossBar = mmoPlayer.getPlayer().getServer().createBossBar(title, ExperienceConfig.getInstance().getExperienceBarColor(primarySkillType), ExperienceConfig.getInstance().getExperienceBarStyle(primarySkillType));
+        bossBar = mmoPlayer.getPlayer().getServer().createBossBar(title, ExperienceConfig.getInstance().getExperienceBarColor(skillIdentity), ExperienceConfig.getInstance().getExperienceBarStyle(skillIdentity));
         bossBar.addPlayer(mmoPlayer.getPlayer());
     }
 }

+ 38 - 40
src/main/java/com/gmail/nossr50/util/experience/MMOExperienceBarManager.java

@@ -2,17 +2,18 @@ package com.gmail.nossr50.util.experience;
 
 import com.gmail.nossr50.config.experience.ExperienceConfig;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
+import com.gmail.nossr50.datatypes.skills.CoreSkillConstants;
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.runnables.skills.ExperienceBarHideTask;
 import com.gmail.nossr50.util.player.NotificationManager;
-import com.neetgames.mcmmo.skill.SkillBossBarSetting;
-import com.neetgames.mcmmo.skill.SkillBossBarState;
+import com.neetgames.mcmmo.skill.*;
 import org.bukkit.plugin.Plugin;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import java.util.EnumMap;
+import java.util.HashMap;
 import java.util.Map;
 
 /**
@@ -24,20 +25,20 @@ public class MMOExperienceBarManager {
 
     int delaySeconds = 3;
 
-    private @NotNull final Map<PrimarySkillType, SkillBossBarState> barStateMapRef;
+    private @NotNull final Map<SkillIdentity, SkillBossBarState> barStateMapRef;
 
-    private @NotNull final EnumMap<PrimarySkillType, ExperienceBarWrapper> experienceBars;
-    private @NotNull final EnumMap<PrimarySkillType, ExperienceBarHideTask> experienceBarHideTaskHashMap;
+    private @NotNull final HashMap<SkillIdentity, ExperienceBarWrapper> experienceBars;
+    private @NotNull final HashMap<SkillIdentity, ExperienceBarHideTask> experienceBarHideTaskHashMap;
 
 
-    public MMOExperienceBarManager(@NotNull McMMOPlayer mmoPlayer, @NotNull Map<PrimarySkillType, SkillBossBarState> barStateMapRef)
+    public MMOExperienceBarManager(@NotNull McMMOPlayer mmoPlayer, @NotNull Map<SkillIdentity, SkillBossBarState> barStateMapRef)
     {
         this.mmoPlayer = mmoPlayer;
         this.barStateMapRef = barStateMapRef;
 
         //Init maps
-        experienceBars = new EnumMap<>(PrimarySkillType.class);
-        experienceBarHideTaskHashMap = new EnumMap<>(PrimarySkillType.class);
+        experienceBars = new HashMap<>();
+        experienceBarHideTaskHashMap = new HashMap<>();
 
         init();
     }
@@ -47,8 +48,8 @@ public class MMOExperienceBarManager {
     }
 
     private void syncBarStates() {
-        for(Map.Entry<PrimarySkillType, SkillBossBarState> entry : barStateMapRef.entrySet()) {
-            PrimarySkillType key = entry.getKey();
+        for(Map.Entry<SkillIdentity, SkillBossBarState> entry : barStateMapRef.entrySet()) {
+            SkillIdentity key = entry.getKey();
             SkillBossBarState barState = entry.getValue();
 
             switch(barState) {
@@ -66,31 +67,31 @@ public class MMOExperienceBarManager {
         barStateMapRef.putAll(generateDefaultBarStateMap());
     }
 
-    public void updateExperienceBar(@NotNull PrimarySkillType primarySkillType, @NotNull Plugin plugin)
+    public void updateExperienceBar(@NotNull SkillIdentity skillIdentity, @NotNull Plugin plugin)
     {
-        if(isBarDisabled(primarySkillType))
+        if(isBarDisabled(skillIdentity))
             return;
 
         //Init Bar
-        if(experienceBars.get(primarySkillType) == null)
-            experienceBars.put(primarySkillType, new ExperienceBarWrapper(primarySkillType, mmoPlayer.getPersistentPlayerData()));
+        if(experienceBars.get(skillIdentity) == null)
+            experienceBars.put(skillIdentity, new ExperienceBarWrapper(skillIdentity, mmoPlayer.getPersistentPlayerData()));
 
         //Get Bar
-        ExperienceBarWrapper experienceBarWrapper = experienceBars.get(primarySkillType);
+        ExperienceBarWrapper experienceBarWrapper = experienceBars.get(skillIdentity);
 
         //Update Progress
-        experienceBarWrapper.setProgress(mmoPlayer.getExperienceManager().getProgressInCurrentSkillLevel(primarySkillType));
+        experienceBarWrapper.setProgress(mmoPlayer.getExperienceManager().getProgressInCurrentSkillLevel(skillIdentity));
 
         //Show Bar
         experienceBarWrapper.showExperienceBar();
 
         //Setup Hide Bar Task
-        if(experienceBarHideTaskHashMap.get(primarySkillType) != null)
+        if(experienceBarHideTaskHashMap.get(skillIdentity) != null)
         {
-            experienceBarHideTaskHashMap.get(primarySkillType).cancel();
+            experienceBarHideTaskHashMap.get(skillIdentity).cancel();
         }
 
-        scheduleHideTask(primarySkillType, plugin);
+        scheduleHideTask(skillIdentity, plugin);
     }
 
     private boolean isBarDisabled(PrimarySkillType primarySkillType) {
@@ -132,34 +133,34 @@ public class MMOExperienceBarManager {
         NotificationManager.sendPlayerInformationChatOnlyPrefixed(mmoPlayer.getPlayer(), "Commands.XPBar.DisableAll");
     }
 
-    public void xpBarSettingToggle(@NotNull SkillBossBarSetting skillBossBarSetting, @Nullable PrimarySkillType skillType) {
+    public void xpBarSettingToggle(@NotNull SkillBossBarSetting skillBossBarSetting, @Nullable SkillIdentity skillIdentity) {
         switch(skillBossBarSetting) {
             case SHOW:
-                barStateMapRef.put(skillType, SkillBossBarState.ALWAYS_ON);
+                barStateMapRef.put(skillIdentity, SkillBossBarState.ALWAYS_ON);
 
                 //Remove lingering tasks
-                if(experienceBarHideTaskHashMap.containsKey(skillType)) {
-                    experienceBarHideTaskHashMap.get(skillType).cancel();
+                if(experienceBarHideTaskHashMap.containsKey(skillIdentity)) {
+                    experienceBarHideTaskHashMap.get(skillIdentity).cancel();
                 }
 
-                updateExperienceBar(skillType, mcMMO.p);
+                updateExperienceBar(skillIdentity, mcMMO.p);
                 break;
             case HIDE:
-                barStateMapRef.put(skillType, SkillBossBarState.DISABLED);
+                barStateMapRef.put(skillIdentity, SkillBossBarState.DISABLED);
 
                 //Remove lingering tasks
-                if(experienceBarHideTaskHashMap.containsKey(skillType)) {
-                    experienceBarHideTaskHashMap.get(skillType).cancel();
+                if(experienceBarHideTaskHashMap.containsKey(skillIdentity)) {
+                    experienceBarHideTaskHashMap.get(skillIdentity).cancel();
                 }
 
-                hideExperienceBar(skillType);
+                hideExperienceBar(skillIdentity);
                 break;
             case RESET:
                 resetBarSettings();
                 break;
         }
 
-        informPlayer(skillBossBarSetting, skillType);
+        informPlayer(skillBossBarSetting, skillIdentity);
     }
 
     private void resetBarSettings() {
@@ -175,24 +176,21 @@ public class MMOExperienceBarManager {
         }
     }
 
-    /*
-     * Utility Methods
-     */
-
-    public static @NotNull EnumMap<PrimarySkillType, SkillBossBarState> generateDefaultBarStateMap() {
-        EnumMap<PrimarySkillType, SkillBossBarState> barStateMap = new EnumMap<>(PrimarySkillType.class);
+    public static @NotNull HashMap<SkillIdentity, SkillBossBarState> generateDefaultBarStateMap() {
+        HashMap<SkillIdentity, SkillBossBarState> barStateMap = new HashMap<>();
 
         setBarStateDefaults(barStateMap);
 
         return barStateMap;
     }
 
-    public static void setBarStateDefaults(EnumMap<PrimarySkillType, SkillBossBarState> barStateHashMap) {
-        for(PrimarySkillType skillType : PrimarySkillType.values()) {
-            if(skillType.isChildSkill()) {
-                barStateHashMap.put(skillType, SkillBossBarState.DISABLED);
+    public static void setBarStateDefaults(HashMap<SkillIdentity, SkillBossBarState> barStateHashMap) {
+        for(RootSkill rootSkill : CoreSkillConstants.getImmutableCoreRootSkillSet()) {
+
+            if(CoreSkillConstants.isChildSkill(rootSkill.getSkillIdentity())) {
+                barStateHashMap.put(rootSkill.getSkillIdentity(), SkillBossBarState.DISABLED);
             } else {
-                barStateHashMap.put(skillType, SkillBossBarState.NORMAL);
+                barStateHashMap.put(rootSkill.getSkillIdentity(), SkillBossBarState.NORMAL);
             }
         }
     }

+ 1 - 1
src/main/java/com/gmail/nossr50/util/scoreboards/ScoreboardWrapper.java

@@ -449,7 +449,7 @@ public class ScoreboardWrapper {
                     int currentXP = mmoPlayer.getExperienceManager().getSkillXpValue(targetSkill);
 
                     sidebarObjective.getScore(ScoreboardManager.LABEL_CURRENT_XP).setScore(currentXP);
-                    sidebarObjective.getScore(ScoreboardManager.LABEL_REMAINING_XP).setScore(mmoPlayer.getExperienceManager().getXpToLevel(targetSkill) - currentXP);
+                    sidebarObjective.getScore(ScoreboardManager.LABEL_REMAINING_XP).setScore(mmoPlayer.getExperienceManager().getExperienceToNextLevel(targetSkill) - currentXP);
                 }
                 else {
                     for (PrimarySkillType parentSkill : FamilyTree.getParents(targetSkill)) {