diff --git a/src/main/java/com/gmail/nossr50/datatypes/MobHealthbarType.java b/src/main/java/com/gmail/nossr50/datatypes/MobHealthBarType.java similarity index 69% rename from src/main/java/com/gmail/nossr50/datatypes/MobHealthbarType.java rename to src/main/java/com/gmail/nossr50/datatypes/MobHealthBarType.java index e46eb7af5..ece258b1c 100644 --- a/src/main/java/com/gmail/nossr50/datatypes/MobHealthbarType.java +++ b/src/main/java/com/gmail/nossr50/datatypes/MobHealthBarType.java @@ -1,6 +1,6 @@ package com.gmail.nossr50.datatypes; -public enum MobHealthbarType { +public enum MobHealthBarType { HEARTS, BAR, DISABLED diff --git a/src/main/java/com/gmail/nossr50/datatypes/player/CooldownManager.java b/src/main/java/com/gmail/nossr50/datatypes/player/CooldownManager.java new file mode 100644 index 000000000..b541f57bf --- /dev/null +++ b/src/main/java/com/gmail/nossr50/datatypes/player/CooldownManager.java @@ -0,0 +1,39 @@ +package com.gmail.nossr50.datatypes.player; + +import com.gmail.nossr50.util.Misc; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class CooldownManager { + private final @NotNull PersistentPlayerData playerDataRef; + + public CooldownManager(@NotNull PersistentPlayerData playerDataRef) { + this.playerDataRef = playerDataRef; + } + + /* + * Teleportation cooldown & warmup + */ + + public int getChimeraWingLastUse() { + return (int) playerDataRef.getUniqueData(UniqueDataType.CHIMAERA_WING_DATS); + } + + public void actualizeChimeraWingLastUse() { + playerProfile.setChimaeraWingDATS((int) (System.currentTimeMillis() / Misc.TIME_CONVERSION_FACTOR)); + } + + public @Nullable Location getTeleportCommenceLocation() { + return teleportCommence; + } + + public void setTeleportCommenceLocation(Location location) { + teleportCommence = location; + } + + public void actualizeTeleportCommenceLocation(Player player) { + teleportCommence = player.getLocation(); + } +} diff --git a/src/main/java/com/gmail/nossr50/datatypes/player/ExperienceManager.java b/src/main/java/com/gmail/nossr50/datatypes/player/ExperienceManager.java new file mode 100644 index 000000000..c1ffabe5a --- /dev/null +++ b/src/main/java/com/gmail/nossr50/datatypes/player/ExperienceManager.java @@ -0,0 +1,445 @@ +package com.gmail.nossr50.datatypes.player; + +import com.gmail.nossr50.config.Config; +import com.gmail.nossr50.config.experience.ExperienceConfig; +import com.gmail.nossr50.datatypes.experience.FormulaType; +import com.gmail.nossr50.datatypes.experience.SkillXpGain; +import com.gmail.nossr50.datatypes.experience.XPGainReason; +import com.gmail.nossr50.datatypes.experience.XPGainSource; +import com.gmail.nossr50.datatypes.skills.PrimarySkillType; +import com.gmail.nossr50.mcMMO; +import com.gmail.nossr50.party.ShareHandler; +import com.gmail.nossr50.skills.child.FamilyTree; +import com.gmail.nossr50.util.EventUtils; +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 com.google.common.collect.ImmutableMap; +import org.apache.commons.lang.Validate; +import org.bukkit.GameMode; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; + +import java.util.Set; + +public class ExperienceManager { + + private boolean isUsingUnarmed = false; + + private final PersistentPlayerData persistentPlayerDataRef; + + public ExperienceManager(PersistentPlayerData persistentPlayerData) { + this.persistentPlayerDataRef = persistentPlayerData; + } + + /** + * Gets the power level of this player. + * + * @return the power level of the player + */ + public int getPowerLevel() { + int powerLevel = 0; + + for (PrimarySkillType primarySkillType : PrimarySkillType.NON_CHILD_SKILLS) { + powerLevel += getSkillLevel(primarySkillType); + } + + return powerLevel; + } + + public float getSkillXpLevelRaw(PrimarySkillType skill) { + return skillExperienceValuesMap.get(skill); + } + + public int getSkillXpLevel(PrimarySkillType skill) { + if(skill.isChildSkill()) { + return 0; + } + + return (int) Math.floor(getSkillXpLevelRaw(skill)); + } + + public void setSkillXpLevel(PrimarySkillType skill, float xpLevel) { + if (skill.isChildSkill()) { + return; + } + + markProfileDirty(); + + skillsXp.put(skill, xpLevel); + } + + public float levelUp(PrimarySkillType skill) { + float xpRemoved = getXpToLevel(skill); + + markProfileDirty(); + + skills.put(skill, skills.get(skill) + 1); + skillsXp.put(skill, skillsXp.get(skill) - xpRemoved); + + return xpRemoved; + } + + /** + * 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 + * @return + */ + public boolean hasReachedLevelCap(PrimarySkillType primarySkillType) { + if(hasReachedPowerLevelCap()) + return true; + + return playerDataRef.getSkillLevel(primarySkillType) >= Config.getInstance().getLevelCap(primarySkillType); + } + + /** + * Whether or not a player is power level capped + * Compares their power level total to the current set limit + * @return true if they have reached the power level cap + */ + public boolean hasReachedPowerLevelCap() { + return this.getPowerLevel() >= Config.getInstance().getPowerLevelCap(); + } + + /** + * Begins an experience gain. The amount will be affected by primarySkillType modifiers, global rate, perks, and may be shared with the party + * + * @param primarySkillType Skill being used + * @param xp Experience amount to process + */ + public void beginXpGain(Player player, PrimarySkillType primarySkillType, float xp, XPGainReason xpGainReason, XPGainSource xpGainSource) { + Validate.isTrue(xp >= 0.0, "XP gained should be greater than or equal to zero."); + + if (xp <= 0.0) { + return; + } + + if (primarySkillType.isChildSkill()) { + Set parentSkills = FamilyTree.getParents(primarySkillType); + float splitXp = xp / parentSkills.size(); + + for (PrimarySkillType parentSkill : parentSkills) { + beginXpGain(player, parentSkill, splitXp, xpGainReason, xpGainSource); + } + + return; + } + + // Return if the experience has been shared + if (party != null && ShareHandler.handleXpShare(xp, this, primarySkillType, ShareHandler.getSharedXpGainReason(xpGainReason))) { + return; + } + + beginUnsharedXpGain(player, primarySkillType, xp, xpGainReason, xpGainSource); + } + + /** + * Begins an experience gain. The amount will be affected by skill modifiers, global rate and perks + * + * @param skill Skill being used + * @param xp Experience amount to process + */ + public void beginUnsharedXpGain(Player player, PrimarySkillType skill, float xp, XPGainReason xpGainReason, XPGainSource xpGainSource) { + if(player.getGameMode() == GameMode.CREATIVE) + return; + + applyXpGain(skill, modifyXpGain(player, skill, xp), xpGainReason, xpGainSource); + + if (party == null) { + return; + } + + if (!Config.getInstance().getPartyXpNearMembersNeeded() || !mcMMO.getPartyManager().getNearMembers(this).isEmpty()) { + party.applyXpGain(modifyXpGain(player, skill, xp)); + } + } + + /** + * Applies an experience gain + * + * @param primarySkillType Skill being used + * @param xp Experience amount to add + */ + public void applyXpGain(Player player, PrimarySkillType primarySkillType, float xp, XPGainReason xpGainReason, XPGainSource xpGainSource) { + if (!primarySkillType.getPermissions(player)) { + return; + } + + if (primarySkillType.isChildSkill()) { + Set parentSkills = FamilyTree.getParents(primarySkillType); + + for (PrimarySkillType parentSkill : parentSkills) { + applyXpGain(player, parentSkill, xp / parentSkills.size(), xpGainReason, xpGainSource); + } + + return; + } + + if (!EventUtils.handleXpGainEvent(player, primarySkillType, xp, xpGainReason)) { + return; + } + + isUsingUnarmed = (primarySkillType == PrimarySkillType.UNARMED); + checkXp(primarySkillType, xpGainReason, xpGainSource); + } + + /** + * Check the XP of a skill. + * + * @param primarySkillType The skill to check + */ + private void checkXp(McMMOPlayer mmoPlayer, PrimarySkillType primarySkillType, XPGainReason xpGainReason, XPGainSource xpGainSource) { + if(hasReachedLevelCap(primarySkillType)) + return; + + if (getSkillXpLevelRaw(primarySkillType) < getXpToLevel(primarySkillType)) { + processPostXpEvent(mmoPlayer.getPlayer(), primarySkillType, mcMMO.p, xpGainSource); + return; + } + + int levelsGained = 0; + float xpRemoved = 0; + + while (getSkillXpLevelRaw(primarySkillType) >= getXpToLevel(primarySkillType)) { + if (hasReachedLevelCap(primarySkillType)) { + setSkillXpLevel(primarySkillType, 0); + break; + } + + xpRemoved += levelUp(primarySkillType); + levelsGained++; + } + + if (EventUtils.tryLevelChangeEvent(mmoPlayer.getPlayer(), primarySkillType, levelsGained, xpRemoved, true, xpGainReason)) { + return; + } + + if (Config.getInstance().getLevelUpSoundsEnabled()) { + SoundManager.sendSound(mmoPlayer.getPlayer(), mmoPlayer.getPlayer().getLocation(), SoundType.LEVEL_UP); + } + + /* + * Check to see if the player unlocked any new skills + */ + + NotificationManager.sendPlayerLevelUpNotification(player, primarySkillType, levelsGained, getSkillLevel(primarySkillType)); + + //UPDATE XP BARS + processPostXpEvent(player, primarySkillType, mcMMO.p, xpGainSource); + } + + public void processPostXpEvent(McMMOPlayer mmoPlayer, PrimarySkillType primarySkillType, Plugin plugin, XPGainSource xpGainSource) + { + //Check if they've reached the power level cap just now + if(hasReachedPowerLevelCap()) { + NotificationManager.sendPlayerInformationChatOnly(mmoPlayer.getPlayer(), "LevelCap.PowerLevel", String.valueOf(Config.getInstance().getPowerLevelCap())); + } else if(hasReachedLevelCap(primarySkillType)) { + NotificationManager.sendPlayerInformationChatOnly(mmoPlayer.getPlayer(), "LevelCap.Skill", String.valueOf(Config.getInstance().getLevelCap(primarySkillType)), primarySkillType.getName()); + } + + //Updates from Party sources + if(xpGainSource == XPGainSource.PARTY_MEMBERS && !ExperienceConfig.getInstance().isPartyExperienceBarsEnabled()) + return; + + //Updates from passive sources (Alchemy, Smelting, etc...) + if(xpGainSource == XPGainSource.PASSIVE && !ExperienceConfig.getInstance().isPassiveGainsExperienceBarsEnabled()) + return; + + mmoPlayer.updateXPBar(primarySkillType, plugin); + } + + public int getSkillLevel(PrimarySkillType skill) { + return skill.isChildSkill() ? getChildSkillLevel(skill) : skills.get(skill); + } + + /** + * Get the amount of Xp remaining before the next level. + * + * @param primarySkillType Type of skill to check + * @return the total amount of Xp until next level + */ + public int getXpToLevel(PrimarySkillType primarySkillType) { + if(primarySkillType.isChildSkill()) { + return 0; + } + + int level = (ExperienceConfig.getInstance().getCumulativeCurveEnabled()) ? getPowerLevel() : playerDataRef..get(primarySkillType); + FormulaType formulaType = ExperienceConfig.getInstance().getFormulaType(); + + return mcMMO.getFormulaManager().getXPtoNextLevel(level, formulaType); + } + + private int getChildSkillLevel(PrimarySkillType primarySkillType) { + Set parents = FamilyTree.getParents(primarySkillType); + int sum = 0; + + for (PrimarySkillType parent : parents) { + sum += Math.min(getSkillLevel(parent), parent.getMaxLevel()); + } + + return sum / parents.size(); + } + + /* + * Xp Functions + */ + + /** + * Remove Xp from a skill. + * + * @param skill Type of skill to modify + * @param xp Amount of xp to remove + */ + public void removeXp(PrimarySkillType skill, int xp) { + if (skill.isChildSkill()) { + return; + } + + markProfileDirty(); + + skillsXp.put(skill, skillsXp.get(skill) - xp); + } + + public void removeXp(PrimarySkillType skill, float xp) { + if (skill.isChildSkill()) { + return; + } + + markProfileDirty(); + + skillsXp.put(skill, skillsXp.get(skill) - xp); + } + + /** + * Modify a skill level. + * + * @param skill Type of skill to modify + * @param level New level value for the skill + */ + public void modifySkill(PrimarySkillType skill, int level) { + if (skill.isChildSkill()) { + return; + } + + markProfileDirty(); + + //Don't allow levels to be negative + if(level < 0) + level = 0; + + skills.put(skill, level); + skillsXp.put(skill, 0F); + } + + /** + * Add levels to a skill. + * + * @param skill Type of skill to add levels to + * @param levels Number of levels to add + */ + public void addLevels(PrimarySkillType skill, int levels) { + modifySkill(skill, skills.get(skill) + levels); + } + + /** + * Add Experience to a skill. + * + * @param skill Type of skill to add experience to + * @param xp Number of experience to add + */ + public void addXp(PrimarySkillType skill, float xp) { + markProfileDirty(); + + if (skill.isChildSkill()) { + Set parentSkills = FamilyTree.getParents(skill); + float dividedXP = (xp / parentSkills.size()); + + for (PrimarySkillType parentSkill : parentSkills) { + skillsXp.put(parentSkill, skillsXp.get(parentSkill) + dividedXP); + } + } + else { + skillsXp.put(skill, skillsXp.get(skill) + xp); + } + } + + /** + * Get the registered amount of experience gained + * This is used for diminished XP returns + * + * @return xp Experience amount registered + */ + public float getRegisteredXpGain(PrimarySkillType primarySkillType) { + float xp = 0F; + + if (rollingSkillsXp.get(primarySkillType) != null) { + xp = rollingSkillsXp.get(primarySkillType); + } + + return xp; + } + + /** + * Register an experience gain + * This is used for diminished XP returns + * + * @param primarySkillType Skill being used + * @param xp Experience amount to add + */ + public void registerXpGain(PrimarySkillType primarySkillType, float xp) { + gainedSkillsXp.add(new SkillXpGain(primarySkillType, xp)); + rollingSkillsXp.put(primarySkillType, getRegisteredXpGain(primarySkillType) + xp); + } + + /** + * Remove experience gains older than a given time + * This is used for diminished XP returns + */ + public void purgeExpiredXpGains() { + SkillXpGain gain; + while ((gain = gainedSkillsXp.poll()) != null) { + rollingSkillsXp.put(gain.getSkill(), getRegisteredXpGain(gain.getSkill()) - gain.getXp()); + } + } + + public ImmutableMap copyPrimarySkillLevelsMap() { + return ImmutableMap.copyOf(primarySkillLevelMap); + } + + public ImmutableMap copyPrimarySkillExperienceValuesMap() { + return ImmutableMap.copyOf(primarySkillCurrentExpMap); + } + + /** + * Modifies an experience gain using skill modifiers, global rate and perks + * + * @param primarySkillType Skill being used + * @param xp Experience amount to process + * @return Modified experience + */ + private float modifyXpGain(Player player, PrimarySkillType primarySkillType, float xp) { + if ((primarySkillType.getMaxLevel() <= getSkillLevel(primarySkillType)) || (Config.getInstance().getPowerLevelCap() <= getPowerLevel())) { + return 0; + } + + xp = (float) (xp / primarySkillType.getXpModifier() * ExperienceConfig.getInstance().getExperienceGainsGlobalMultiplier()); + + return PerksUtils.handleXpPerks(player, xp, primarySkillType); + } + + public double getProgressInCurrentSkillLevel(PrimarySkillType primarySkillType) + { + if(primarySkillType.isChildSkill()) { + return 1.0D; + } + + double currentXP = getSkillXpLevel(primarySkillType); + double maxXP = getXpToLevel(primarySkillType); + + return (currentXP / maxXP); + } + + +} diff --git a/src/main/java/com/gmail/nossr50/util/MobHealthbarUtils.java b/src/main/java/com/gmail/nossr50/util/MobHealthbarUtils.java index c31e51424..5a9ded881 100644 --- a/src/main/java/com/gmail/nossr50/util/MobHealthbarUtils.java +++ b/src/main/java/com/gmail/nossr50/util/MobHealthbarUtils.java @@ -2,7 +2,7 @@ package com.gmail.nossr50.util; import com.gmail.nossr50.config.AdvancedConfig; import com.gmail.nossr50.config.Config; -import com.gmail.nossr50.datatypes.MobHealthbarType; +import com.gmail.nossr50.datatypes.MobHealthBarType; import com.gmail.nossr50.datatypes.meta.OldName; import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.runnables.MobHealthDisplayUpdaterTask; @@ -90,7 +90,7 @@ public final class MobHealthbarUtils { } } - private static String createHealthDisplay(MobHealthbarType mobHealthbarType, LivingEntity entity, double damage) { + private static String createHealthDisplay(MobHealthBarType mobHealthbarType, LivingEntity entity, double damage) { double maxHealth = entity.getMaxHealth(); double currentHealth = Math.max(entity.getHealth() - damage, 0); double healthPercentage = (currentHealth / maxHealth) * 100.0D; diff --git a/src/main/java/com/gmail/nossr50/util/experience/MMOExperienceBarManager.java b/src/main/java/com/gmail/nossr50/util/experience/MMOExperienceBarManager.java new file mode 100644 index 000000000..97dba5fcd --- /dev/null +++ b/src/main/java/com/gmail/nossr50/util/experience/MMOExperienceBarManager.java @@ -0,0 +1,202 @@ +package com.gmail.nossr50.util.experience; + +import com.gmail.nossr50.config.experience.ExperienceConfig; +import com.gmail.nossr50.datatypes.dirtydata.DirtyDataMap; +import com.gmail.nossr50.datatypes.player.McMMOPlayer; +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 org.bukkit.plugin.Plugin; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.EnumMap; +import java.util.Map; + +/** + * ExperienceBarManager handles displaying and updating mcMMO experience bars for players + * Each ExperienceBarManager only manages a single player + */ +public class MMOExperienceBarManager { + private final McMMOPlayer mmoPlayer; + + int delaySeconds = 3; + + private @NotNull final DirtyDataMap barStateMapRef; + + private @NotNull EnumMap experienceBars; + private @NotNull EnumMap experienceBarHideTaskHashMap; + + + public MMOExperienceBarManager(@NotNull McMMOPlayer mmoPlayer, @NotNull DirtyDataMap barStateMapRef) + { + this.mmoPlayer = mmoPlayer; + this.barStateMapRef = barStateMapRef; + + //Init maps + experienceBars = new EnumMap<>(PrimarySkillType.class); + experienceBarHideTaskHashMap = new EnumMap<>(PrimarySkillType.class); + + init(); + } + + private void init() { + syncBarStates(); + } + + private void syncBarStates() { + for(Map.Entry entry : barStateMapRef.entrySet()) { + PrimarySkillType key = entry.getKey(); + BarState barState = entry.getValue(); + + switch(barState) { + case NORMAL: + break; + case ALWAYS_ON: + xpBarSettingToggle(XPBarSettingTarget.SHOW, key); + case DISABLED: + xpBarSettingToggle(XPBarSettingTarget.HIDE, key); + } + } + } + + private void resetBarStateMap() { + barStateMapRef.putAll(generateDefaultBarStateMap()); + } + + public void updateExperienceBar(PrimarySkillType primarySkillType, Plugin plugin) + { + if(isBarDisabled(primarySkillType)) + return; + + //Init Bar + if(experienceBars.get(primarySkillType) == null) + experienceBars.put(primarySkillType, new ExperienceBarWrapper(primarySkillType, mmoPlayer.getPersistentPlayerData())); + + //Get Bar + ExperienceBarWrapper experienceBarWrapper = experienceBars.get(primarySkillType); + + //Update Progress + experienceBarWrapper.setProgress(mmoPlayer.getExperienceManager().getProgressInCurrentSkillLevel(primarySkillType)); + + //Show Bar + experienceBarWrapper.showExperienceBar(); + + //Setup Hide Bar Task + if(experienceBarHideTaskHashMap.get(primarySkillType) != null) + { + experienceBarHideTaskHashMap.get(primarySkillType).cancel(); + } + + scheduleHideTask(primarySkillType, plugin); + } + + private boolean isBarDisabled(PrimarySkillType primarySkillType) { + return barStateMapRef.get(primarySkillType) == BarState.DISABLED + //Config checks + || !ExperienceConfig.getInstance().isExperienceBarsEnabled() + || !ExperienceConfig.getInstance().isExperienceBarEnabled(primarySkillType); + } + + private boolean isBarAlwaysVisible(PrimarySkillType primarySkillType) { + return barStateMapRef.get(primarySkillType) == BarState.ALWAYS_ON; + } + + private void scheduleHideTask(PrimarySkillType primarySkillType, Plugin plugin) { + if(isBarAlwaysVisible(primarySkillType)) + return; + + ExperienceBarHideTask experienceBarHideTask = new ExperienceBarHideTask(this, mmoPlayer, primarySkillType); + experienceBarHideTask.runTaskLater(plugin, 20* delaySeconds); + experienceBarHideTaskHashMap.put(primarySkillType, experienceBarHideTask); + } + + public void hideExperienceBar(PrimarySkillType primarySkillType) + { + if(experienceBars.containsKey(primarySkillType)) + experienceBars.get(primarySkillType).hideExperienceBar(); + } + + public void clearTask(PrimarySkillType primarySkillType) + { + experienceBarHideTaskHashMap.remove(primarySkillType); + } + + public void disableAllBars() { + for(PrimarySkillType primarySkillType : PrimarySkillType.values()) { + xpBarSettingToggle(XPBarSettingTarget.HIDE, primarySkillType); + } + + NotificationManager.sendPlayerInformationChatOnlyPrefixed(mmoPlayer.getPlayer(), "Commands.XPBar.DisableAll"); + } + + public void xpBarSettingToggle(@NotNull XPBarSettingTarget settingTarget, @Nullable PrimarySkillType skillType) { + switch(settingTarget) { + case SHOW: + barStateMapRef.put(skillType, BarState.ALWAYS_ON); + + //Remove lingering tasks + if(experienceBarHideTaskHashMap.containsKey(skillType)) { + experienceBarHideTaskHashMap.get(skillType).cancel(); + } + + updateExperienceBar(skillType, mcMMO.p); + break; + case HIDE: + barStateMapRef.put(skillType, BarState.DISABLED); + + //Remove lingering tasks + if(experienceBarHideTaskHashMap.containsKey(skillType)) { + experienceBarHideTaskHashMap.get(skillType).cancel(); + } + + hideExperienceBar(skillType); + break; + case RESET: + resetBarSettings(); + break; + } + + informPlayer(settingTarget, skillType); + } + + private void resetBarSettings() { + barStateMapRef.putAll(generateDefaultBarStateMap()); + } + + private void informPlayer(@NotNull MMOExperienceBarManager.@NotNull XPBarSettingTarget settingTarget, @Nullable PrimarySkillType skillType) { + //Inform player of setting change + if(settingTarget != XPBarSettingTarget.RESET) { + NotificationManager.sendPlayerInformationChatOnlyPrefixed(mmoPlayer.getPlayer(), "Commands.XPBar.SettingChanged", skillType.getName(), settingTarget.toString()); + } else { + NotificationManager.sendPlayerInformationChatOnlyPrefixed(mmoPlayer.getPlayer(), "Commands.XPBar.Reset"); + } + } + + public enum XPBarSettingTarget { SHOW, HIDE, RESET, DISABLE } + + public enum BarState { NORMAL, ALWAYS_ON, DISABLED } + + /* + * Utility Methods + */ + + public static EnumMap generateDefaultBarStateMap() { + EnumMap barStateMap = new EnumMap<>(PrimarySkillType.class); + + setBarStateDefaults(barStateMap); + + return barStateMap; + } + + public static void setBarStateDefaults(EnumMap barStateHashMap) { + for(PrimarySkillType skillType : PrimarySkillType.values()) { + if(skillType.isChildSkill()) { + barStateHashMap.put(skillType, MMOExperienceBarManager.BarState.DISABLED); + } else { + barStateHashMap.put(skillType, MMOExperienceBarManager.BarState.NORMAL); + } + } + } +}