diff --git a/Changelog.txt b/Changelog.txt index 0f8728c21..093b9d52a 100644 --- a/Changelog.txt +++ b/Changelog.txt @@ -150,6 +150,7 @@ Version 2.2.0 Config_Update_Overwrite, Tool_Mods_Enabled, Armor_Mods_Enabled, Block_Mods_Enabled, Entity_Mods_Enabled, ExperienceConversionMultiplier API Changes + Added PrimarySkillType::getCapitalizedName Config settings can now be found in the ConfigManager (getter for it in mcMMO.java) Collection values from the config get converted into a runtime appropriate dataset, those can be found in DynamicSettingsManager (getter for it in mcMMO.java) mcMMO metadata keys have been moved into a convenience class (MetadataConstants) diff --git a/src/main/java/com/gmail/nossr50/api/exceptions/MissingSkillPropertyDefinition.java b/src/main/java/com/gmail/nossr50/api/exceptions/MissingSkillPropertyDefinition.java new file mode 100644 index 000000000..e0aada6a4 --- /dev/null +++ b/src/main/java/com/gmail/nossr50/api/exceptions/MissingSkillPropertyDefinition.java @@ -0,0 +1,7 @@ +package com.gmail.nossr50.api.exceptions; + +public class MissingSkillPropertyDefinition extends RuntimeException { + public MissingSkillPropertyDefinition(String details) { + super("A skill property is undefined! Details: " + details); + } +} diff --git a/src/main/java/com/gmail/nossr50/config/ConfigManager.java b/src/main/java/com/gmail/nossr50/config/ConfigManager.java index 62f5d8af6..0155d29fd 100644 --- a/src/main/java/com/gmail/nossr50/config/ConfigManager.java +++ b/src/main/java/com/gmail/nossr50/config/ConfigManager.java @@ -55,6 +55,7 @@ import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.skills.repair.repairables.Repairable; import com.gmail.nossr50.skills.salvage.salvageables.Salvageable; import com.google.common.reflect.TypeToken; +import ninja.leaping.configurate.commented.CommentedConfigurationNode; import ninja.leaping.configurate.objectmapping.serialize.TypeSerializerCollection; import ninja.leaping.configurate.objectmapping.serialize.TypeSerializers; import org.bukkit.Material; @@ -494,6 +495,14 @@ public final class ConfigManager { return configRanks.getConfig(); } + /** + * Used to programmatically grab rank data for skills + * @return root node for the ranks config file + */ + public CommentedConfigurationNode getConfigRanksRootNode() { + return configRanks.getRootNode(); + } + /** * Checks if this plugin is using retro mode * Retro mode is a 0-1000 skill system diff --git a/src/main/java/com/gmail/nossr50/config/RankConfig.java b/src/main/java/com/gmail/nossr50/config/RankConfig.java index 68ec02442..f88241256 100644 --- a/src/main/java/com/gmail/nossr50/config/RankConfig.java +++ b/src/main/java/com/gmail/nossr50/config/RankConfig.java @@ -1,8 +1,10 @@ package com.gmail.nossr50.config; +import com.gmail.nossr50.config.hocon.skills.ranks.SkillRankProperty; import com.gmail.nossr50.datatypes.skills.SubSkillType; import com.gmail.nossr50.datatypes.skills.subskills.AbstractSubSkill; import com.gmail.nossr50.mcMMO; +import ninja.leaping.configurate.commented.CommentedConfigurationNode; import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable; import java.util.ArrayList; @@ -10,8 +12,7 @@ import java.util.List; @ConfigSerializable public class RankConfig extends ConfigValidated { - public static final String RETRO_MODE = "RetroMode"; - public static final String STANDARD = "Standard"; + //private static RankConfig instance; public RankConfig() { @@ -55,43 +56,7 @@ public class RankConfig extends ConfigValidated { return reason; } - /** - * Returns the unlock level for a subskill depending on the gamemode - * - * @param subSkillType target subskill - * @param rank the rank we are checking - * @return the level requirement for a subskill at this particular rank - */ - public int getSubSkillUnlockLevel(SubSkillType subSkillType, int rank) { - return findRankByRootAddress(rank, subSkillType.getRankConfigAddress()); - } - /** - * Returns the unlock level for a subskill depending on the gamemode - * - * @param abstractSubSkill target subskill - * @param rank the rank we are checking - * @return the level requirement for a subskill at this particular rank - */ - public int getSubSkillUnlockLevel(AbstractSubSkill abstractSubSkill, int rank) { - return findRankByRootAddress(rank, abstractSubSkill.getSubSkillType().getRankConfigAddress()); - } - - /** - * Returns the unlock level for a subskill depending on the gamemode - * - * @param key root address of the subskill in the rankskills.yml file - * @param rank the rank we are checking - * @return the level requirement for a subskill at this particular rank - */ - private int findRankByRootAddress(int rank, String[] key) { - String scalingKey = mcMMO.isRetroModeEnabled() ? RETRO_MODE : STANDARD; - - String targetRank = "Rank_" + rank; - - //key[0] = parent skill config node, key[1] subskill child node, scalingkey = retro/standard, targetrank = rank node - return getIntValue(key[0], key[1], scalingKey, targetRank); - } /** * Checks for valid keys for subskill ranks diff --git a/src/main/java/com/gmail/nossr50/config/hocon/playerleveling/ConfigSectionSkillLevelCap.java b/src/main/java/com/gmail/nossr50/config/hocon/playerleveling/ConfigSectionSkillLevelCap.java index 53ab7d9e9..6d587b278 100644 --- a/src/main/java/com/gmail/nossr50/config/hocon/playerleveling/ConfigSectionSkillLevelCap.java +++ b/src/main/java/com/gmail/nossr50/config/hocon/playerleveling/ConfigSectionSkillLevelCap.java @@ -32,6 +32,10 @@ public class ConfigSectionSkillLevelCap { return useLevelCap; } + /** + * Get the level cap for a skill, will return Integer.MAX_VALUE for values equal to or below 0 + * @return a levels max value + */ public int getLevelCap() { if(levelCap <= 0) return Integer.MAX_VALUE; diff --git a/src/main/java/com/gmail/nossr50/config/hocon/skills/ranks/ConfigRanks.java b/src/main/java/com/gmail/nossr50/config/hocon/skills/ranks/ConfigRanks.java index 59b1b5542..bce37ccf2 100644 --- a/src/main/java/com/gmail/nossr50/config/hocon/skills/ranks/ConfigRanks.java +++ b/src/main/java/com/gmail/nossr50/config/hocon/skills/ranks/ConfigRanks.java @@ -51,5 +51,4 @@ public class ConfigRanks { @Setting(value = "Repair", comment = "Configure when sub-skills unlock for Repair here.") private ConfigRanksRepair repair = new ConfigRanksRepair(); - } diff --git a/src/main/java/com/gmail/nossr50/config/hocon/skills/ranks/SkillRankProperty.java b/src/main/java/com/gmail/nossr50/config/hocon/skills/ranks/SkillRankProperty.java index 8220227d6..25e3afcd8 100644 --- a/src/main/java/com/gmail/nossr50/config/hocon/skills/ranks/SkillRankProperty.java +++ b/src/main/java/com/gmail/nossr50/config/hocon/skills/ranks/SkillRankProperty.java @@ -1,5 +1,6 @@ package com.gmail.nossr50.config.hocon.skills.ranks; +import com.gmail.nossr50.api.exceptions.MissingSkillPropertyDefinition; import com.gmail.nossr50.datatypes.skills.properties.SkillProperty; import java.util.HashMap; @@ -44,6 +45,26 @@ public class SkillRankProperty implements SkillProperty { retroRanks = new HashMap<>(); } + /** + * Gets the unlock level for this skill as defined by this SkillRankProperty + * @param retroMode whether or not mcMMO is using RetroMode, true for if it is + * @param targetRank the rank to get the unlock level for + * @return the unlock level for target rank + */ + public int getUnlockLevel(boolean retroMode, int targetRank) throws MissingSkillPropertyDefinition { + if(retroMode) { + if(retroRanks.get(targetRank) == null) { + throw new MissingSkillPropertyDefinition("No definition found for rank:"+targetRank+" using Retro scaling"); + } + return retroRanks.get(targetRank); + } else { + if(standardRanks.get(targetRank) == null) { + throw new MissingSkillPropertyDefinition("No definition found for rank:"+targetRank+" using Standard scaling"); + } + return standardRanks.get(targetRank); + } + } + public void setStandardRanks(HashMap standardRanks) { this.standardRanks = standardRanks; } diff --git a/src/main/java/com/gmail/nossr50/datatypes/skills/PrimarySkillType.java b/src/main/java/com/gmail/nossr50/datatypes/skills/PrimarySkillType.java index cbcf0dd4e..85ed63777 100644 --- a/src/main/java/com/gmail/nossr50/datatypes/skills/PrimarySkillType.java +++ b/src/main/java/com/gmail/nossr50/datatypes/skills/PrimarySkillType.java @@ -34,42 +34,47 @@ import java.util.List; public enum PrimarySkillType { ACROBATICS(AcrobaticsManager.class, Color.WHITE, - ImmutableList.of(SubSkillType.ACROBATICS_DODGE, SubSkillType.ACROBATICS_ROLL)), + ImmutableList.of(SubSkillType.ACROBATICS_DODGE, SubSkillType.ACROBATICS_ROLL), "Acrobatics"), ALCHEMY(AlchemyManager.class, Color.FUCHSIA, - ImmutableList.of(SubSkillType.ALCHEMY_CATALYSIS, SubSkillType.ALCHEMY_CONCOCTIONS)), + ImmutableList.of(SubSkillType.ALCHEMY_CATALYSIS, SubSkillType.ALCHEMY_CONCOCTIONS), "Alchemy"), ARCHERY(ArcheryManager.class, Color.MAROON, - ImmutableList.of(SubSkillType.ARCHERY_DAZE, SubSkillType.ARCHERY_ARCHERY_LIMIT_BREAK, SubSkillType.ARCHERY_ARROW_RETRIEVAL, SubSkillType.ARCHERY_SKILL_SHOT)), + ImmutableList.of(SubSkillType.ARCHERY_DAZE, SubSkillType.ARCHERY_ARCHERY_LIMIT_BREAK, SubSkillType.ARCHERY_ARROW_RETRIEVAL, SubSkillType.ARCHERY_SKILL_SHOT), "Archery"), AXES(AxesManager.class, Color.AQUA, SuperAbilityType.SKULL_SPLITTER, ToolType.AXE, - ImmutableList.of(SubSkillType.AXES_SKULL_SPLITTER, SubSkillType.AXES_AXES_LIMIT_BREAK, SubSkillType.AXES_ARMOR_IMPACT, SubSkillType.AXES_AXE_MASTERY, SubSkillType.AXES_CRITICAL_STRIKES, SubSkillType.AXES_GREATER_IMPACT)), + ImmutableList.of(SubSkillType.AXES_SKULL_SPLITTER, SubSkillType.AXES_AXES_LIMIT_BREAK, SubSkillType.AXES_ARMOR_IMPACT, SubSkillType.AXES_AXE_MASTERY, SubSkillType.AXES_CRITICAL_STRIKES, SubSkillType.AXES_GREATER_IMPACT), "Axes"), EXCAVATION(ExcavationManager.class, Color.fromRGB(139, 69, 19), SuperAbilityType.GIGA_DRILL_BREAKER, ToolType.SHOVEL, - ImmutableList.of(SubSkillType.EXCAVATION_GIGA_DRILL_BREAKER, SubSkillType.EXCAVATION_ARCHAEOLOGY)), + ImmutableList.of(SubSkillType.EXCAVATION_GIGA_DRILL_BREAKER, SubSkillType.EXCAVATION_ARCHAEOLOGY), "Excavation"), FISHING(FishingManager.class, Color.NAVY, - ImmutableList.of(SubSkillType.FISHING_FISHERMANS_DIET, SubSkillType.FISHING_TREASURE_HUNTER, SubSkillType.FISHING_ICE_FISHING, SubSkillType.FISHING_MAGIC_HUNTER, SubSkillType.FISHING_MASTER_ANGLER, SubSkillType.FISHING_SHAKE)), + ImmutableList.of(SubSkillType.FISHING_FISHERMANS_DIET, SubSkillType.FISHING_TREASURE_HUNTER, SubSkillType.FISHING_ICE_FISHING, SubSkillType.FISHING_MAGIC_HUNTER, SubSkillType.FISHING_MASTER_ANGLER, SubSkillType.FISHING_SHAKE), "Fishing"), HERBALISM(HerbalismManager.class, Color.GREEN, SuperAbilityType.GREEN_TERRA, ToolType.HOE, - ImmutableList.of(SubSkillType.HERBALISM_GREEN_TERRA, SubSkillType.HERBALISM_FARMERS_DIET, SubSkillType.HERBALISM_GREEN_THUMB, SubSkillType.HERBALISM_DOUBLE_DROPS, SubSkillType.HERBALISM_HYLIAN_LUCK, SubSkillType.HERBALISM_SHROOM_THUMB)), + ImmutableList.of(SubSkillType.HERBALISM_GREEN_TERRA, SubSkillType.HERBALISM_FARMERS_DIET, SubSkillType.HERBALISM_GREEN_THUMB, SubSkillType.HERBALISM_DOUBLE_DROPS, SubSkillType.HERBALISM_HYLIAN_LUCK, SubSkillType.HERBALISM_SHROOM_THUMB), "Herbalism"), MINING(MiningManager.class, Color.GRAY, SuperAbilityType.SUPER_BREAKER, ToolType.PICKAXE, - ImmutableList.of(SubSkillType.MINING_SUPER_BREAKER, SubSkillType.MINING_DEMOLITIONS_EXPERTISE, SubSkillType.MINING_BIGGER_BOMBS, SubSkillType.MINING_BLAST_MINING, SubSkillType.MINING_DOUBLE_DROPS)), + ImmutableList.of(SubSkillType.MINING_SUPER_BREAKER, SubSkillType.MINING_DEMOLITIONS_EXPERTISE, SubSkillType.MINING_BIGGER_BOMBS, SubSkillType.MINING_BLAST_MINING, SubSkillType.MINING_DOUBLE_DROPS), "Mining"), REPAIR(RepairManager.class, Color.SILVER, - ImmutableList.of(SubSkillType.REPAIR_ARCANE_FORGING, SubSkillType.REPAIR_REPAIR_MASTERY, SubSkillType.REPAIR_SUPER_REPAIR)), + ImmutableList.of(SubSkillType.REPAIR_ARCANE_FORGING, SubSkillType.REPAIR_REPAIR_MASTERY, SubSkillType.REPAIR_SUPER_REPAIR), "Repair"), SALVAGE(SalvageManager.class, Color.ORANGE, - ImmutableList.of(SubSkillType.SALVAGE_ADVANCED_SALVAGE, SubSkillType.SALVAGE_ARCANE_SALVAGE)), + ImmutableList.of(SubSkillType.SALVAGE_ADVANCED_SALVAGE, SubSkillType.SALVAGE_ARCANE_SALVAGE), "Salvage"), SMELTING(SmeltingManager.class, Color.YELLOW, - ImmutableList.of(SubSkillType.SMELTING_UNDERSTANDING_THE_ART, /*SubSkillType.SMELTING_FLUX_MINING,*/ SubSkillType.SMELTING_FUEL_EFFICIENCY, SubSkillType.SMELTING_SECOND_SMELT)), + ImmutableList.of(SubSkillType.SMELTING_UNDERSTANDING_THE_ART, /*SubSkillType.SMELTING_FLUX_MINING,*/ SubSkillType.SMELTING_FUEL_EFFICIENCY, SubSkillType.SMELTING_SECOND_SMELT), "Smelting"), SWORDS(SwordsManager.class, Color.fromRGB(178, 34, 34), SuperAbilityType.SERRATED_STRIKES, ToolType.SWORD, - ImmutableList.of(SubSkillType.SWORDS_SERRATED_STRIKES, SubSkillType.SWORDS_SWORDS_LIMIT_BREAK, SubSkillType.SWORDS_STAB, SubSkillType.SWORDS_RUPTURE, SubSkillType.SWORDS_COUNTER_ATTACK)), + ImmutableList.of(SubSkillType.SWORDS_SERRATED_STRIKES, SubSkillType.SWORDS_SWORDS_LIMIT_BREAK, SubSkillType.SWORDS_STAB, SubSkillType.SWORDS_RUPTURE, SubSkillType.SWORDS_COUNTER_ATTACK), "Swords"), TAMING(TamingManager.class, Color.PURPLE, - ImmutableList.of(SubSkillType.TAMING_BEAST_LORE, SubSkillType.TAMING_CALL_OF_THE_WILD, SubSkillType.TAMING_ENVIRONMENTALLY_AWARE, SubSkillType.TAMING_FAST_FOOD_SERVICE, SubSkillType.TAMING_GORE, SubSkillType.TAMING_HOLY_HOUND, SubSkillType.TAMING_SHARPENED_CLAWS, SubSkillType.TAMING_SHOCK_PROOF, SubSkillType.TAMING_THICK_FUR, SubSkillType.TAMING_PUMMEL)), + ImmutableList.of(SubSkillType.TAMING_BEAST_LORE, SubSkillType.TAMING_CALL_OF_THE_WILD, SubSkillType.TAMING_ENVIRONMENTALLY_AWARE, SubSkillType.TAMING_FAST_FOOD_SERVICE, SubSkillType.TAMING_GORE, SubSkillType.TAMING_HOLY_HOUND, SubSkillType.TAMING_SHARPENED_CLAWS, SubSkillType.TAMING_SHOCK_PROOF, SubSkillType.TAMING_THICK_FUR, SubSkillType.TAMING_PUMMEL), "Taming"), UNARMED(UnarmedManager.class, Color.BLACK, SuperAbilityType.BERSERK, ToolType.FISTS, - ImmutableList.of(SubSkillType.UNARMED_BERSERK, SubSkillType.UNARMED_UNARMED_LIMIT_BREAK, SubSkillType.UNARMED_BLOCK_CRACKER, SubSkillType.UNARMED_ARROW_DEFLECT, SubSkillType.UNARMED_DISARM, SubSkillType.UNARMED_IRON_ARM_STYLE, SubSkillType.UNARMED_IRON_GRIP)), + ImmutableList.of(SubSkillType.UNARMED_BERSERK, SubSkillType.UNARMED_UNARMED_LIMIT_BREAK, SubSkillType.UNARMED_BLOCK_CRACKER, SubSkillType.UNARMED_ARROW_DEFLECT, SubSkillType.UNARMED_DISARM, SubSkillType.UNARMED_IRON_ARM_STYLE, SubSkillType.UNARMED_IRON_GRIP), "Unarmed"), WOODCUTTING(WoodcuttingManager.class, Color.OLIVE, SuperAbilityType.TREE_FELLER, ToolType.AXE, - ImmutableList.of(SubSkillType.WOODCUTTING_LEAF_BLOWER, SubSkillType.WOODCUTTING_TREE_FELLER, SubSkillType.WOODCUTTING_HARVEST_LUMBER)); + ImmutableList.of(SubSkillType.WOODCUTTING_LEAF_BLOWER, SubSkillType.WOODCUTTING_TREE_FELLER, SubSkillType.WOODCUTTING_HARVEST_LUMBER), "Woodcutting"); private Class managerClass; private Color skillColor; + private String capitalizedName; private SuperAbilityType ability; private ToolType tool; private List subSkillTypes; + public String getCapitalizedName() { + return capitalizedName; + } + public static final List SKILL_NAMES; public static final List SUBSKILL_NAMES; public static final List CHILD_SKILLS; @@ -105,16 +110,17 @@ public enum PrimarySkillType { NON_CHILD_SKILLS = ImmutableList.copyOf(nonChildSkills); } - private PrimarySkillType(Class managerClass, Color skillColor, List subSkillTypes) { - this(managerClass, skillColor, null, null, subSkillTypes); + private PrimarySkillType(Class managerClass, Color skillColor, List subSkillTypes, String capitalizedName) { + this(managerClass, skillColor, null, null, subSkillTypes, capitalizedName); } - private PrimarySkillType(Class managerClass, Color skillColor, SuperAbilityType ability, ToolType tool, List subSkillTypes) { + private PrimarySkillType(Class managerClass, Color skillColor, SuperAbilityType ability, ToolType tool, List subSkillTypes, String capitalizedName) { this.managerClass = managerClass; this.skillColor = skillColor; this.ability = ability; this.tool = tool; this.subSkillTypes = subSkillTypes; + this.capitalizedName = capitalizedName; } public static PrimarySkillType getSkill(String skillName) { diff --git a/src/main/java/com/gmail/nossr50/datatypes/skills/SubSkillType.java b/src/main/java/com/gmail/nossr50/datatypes/skills/SubSkillType.java index c57b7a34d..f9373a086 100644 --- a/src/main/java/com/gmail/nossr50/datatypes/skills/SubSkillType.java +++ b/src/main/java/com/gmail/nossr50/datatypes/skills/SubSkillType.java @@ -1,5 +1,6 @@ package com.gmail.nossr50.datatypes.skills; +import com.gmail.nossr50.config.hocon.HOCONUtil; import com.gmail.nossr50.locale.LocaleLoader; import com.gmail.nossr50.util.StringUtils; @@ -168,6 +169,35 @@ public enum SubSkillType { return "mcmmo.ability." + getParentSkill().toString().toLowerCase() + "." + getConfigName(toString()).toLowerCase(); } + /** + * Returns the name of the sub-skill as it is used in our HOCON configs + * + * @return the yaml identifier for this skill + */ + public String getHoconFriendlyConfigName() { + /* + * Our ENUM constants name is something like PREFIX_SUB_SKILL_NAME + * We need to remove the prefix and then format the subskill to follow the naming conventions of our yaml configs + * + * So this method uses this kind of formatting + * "PARENTSKILL_COOL_SUBSKILL_ULTRA" -> "Cool Subskill Ultra" - > "Cool-Subskill-Ultra" + * + */ + + /* + * Find where to begin our substring (after the prefix) + */ + int subStringIndex = getSubStringIndex(toString()); + + /* + * Split the string up so we can capitalize each part + */ + String withoutPrefix = toString().substring(subStringIndex); + + //Grab the HOCON friendly version of the string and return it + return HOCONUtil.serializeENUMName(withoutPrefix); + } + /** * Returns the name of the skill as it is used in advanced.yml and other config files * @@ -193,15 +223,15 @@ public enum SubSkillType { /* * Split the string up so we can capitalize each part */ - String subskillNameWithoutPrefix = subSkillName.substring(subStringIndex); - if (subskillNameWithoutPrefix.contains("_")) { - String[] splitStrings = subskillNameWithoutPrefix.split("_"); + String withoutPrefix = subSkillName.substring(subStringIndex); + if (withoutPrefix.contains("_")) { + String[] splitStrings = withoutPrefix.split("_"); for (String string : splitStrings) { endResult.append(StringUtils.getCapitalized(string)); } } else { - endResult.append(StringUtils.getCapitalized(subskillNameWithoutPrefix)); + endResult.append(StringUtils.getCapitalized(withoutPrefix)); } return endResult.toString(); diff --git a/src/main/java/com/gmail/nossr50/util/skills/RankUtils.java b/src/main/java/com/gmail/nossr50/util/skills/RankUtils.java index 9cabbdfec..a113f2927 100644 --- a/src/main/java/com/gmail/nossr50/util/skills/RankUtils.java +++ b/src/main/java/com/gmail/nossr50/util/skills/RankUtils.java @@ -1,14 +1,20 @@ package com.gmail.nossr50.util.skills; +import com.gmail.nossr50.api.exceptions.MissingSkillPropertyDefinition; import com.gmail.nossr50.config.RankConfig; +import com.gmail.nossr50.config.hocon.skills.ranks.SkillRankProperty; import com.gmail.nossr50.datatypes.player.McMMOPlayer; import com.gmail.nossr50.datatypes.skills.PrimarySkillType; import com.gmail.nossr50.datatypes.skills.SubSkillType; import com.gmail.nossr50.datatypes.skills.SuperAbilityType; import com.gmail.nossr50.datatypes.skills.subskills.AbstractSubSkill; import com.gmail.nossr50.listeners.InteractionManager; +import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.runnables.skills.SkillUnlockNotificationTask; import com.gmail.nossr50.util.player.UserManager; +import com.google.common.reflect.TypeToken; +import ninja.leaping.configurate.commented.CommentedConfigurationNode; +import ninja.leaping.configurate.objectmapping.ObjectMappingException; import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; @@ -285,11 +291,11 @@ public class RankUtils { */ @Deprecated public static int getRankUnlockLevel(SubSkillType subSkillType, int rank) { - return RankConfig.getInstance().getSubSkillUnlockLevel(subSkillType, rank); + return getSubSkillUnlockLevel(subSkillType, rank); } public static int getRankUnlockLevel(AbstractSubSkill abstractSubSkill, int rank) { - return RankConfig.getInstance().getSubSkillUnlockLevel(abstractSubSkill, rank); + return getSubSkillUnlockLevel(abstractSubSkill, rank); } /** @@ -299,7 +305,7 @@ public class RankUtils { * @return The unlock requirements for rank 1 in this skill */ public static int getUnlockLevel(SubSkillType subSkillType) { - return RankConfig.getInstance().getSubSkillUnlockLevel(subSkillType, 1); + return getSubSkillUnlockLevel(subSkillType, 1); } /** @@ -309,7 +315,7 @@ public class RankUtils { * @return The unlock requirements for rank 1 in this skill */ public static int getUnlockLevel(AbstractSubSkill abstractSubSkill) { - return RankConfig.getInstance().getSubSkillUnlockLevel(abstractSubSkill, 1); + return getSubSkillUnlockLevel(abstractSubSkill, 1); } /** @@ -339,4 +345,55 @@ public class RankUtils { public static int getSuperAbilityUnlockRequirement(SuperAbilityType superAbilityType) { return getRankUnlockLevel(superAbilityType.getSubSkillTypeDefinition(), 1); } + + /** + * Returns the unlock level for a subskill depending on the gamemode + * + * @param subSkillType target subskill + * @param rank the rank we are checking + * @return the level requirement for a subskill at this particular rank + */ + public static int getSubSkillUnlockLevel(SubSkillType subSkillType, int rank) { + return findRankByRootAddress(rank, subSkillType); + } + + /** + * Returns the unlock level for a subskill depending on the level scaling + * + * @param abstractSubSkill target subskill + * @param rank the rank we are checking + * @return the level requirement for a subskill at this particular rank + */ + public static int getSubSkillUnlockLevel(AbstractSubSkill abstractSubSkill, int rank) { + return findRankByRootAddress(rank, abstractSubSkill.getSubSkillType()); + } + + /** + * Returns the unlock level for a subskill depending on the level scaling + * + * @param subSkillType target sub-skill + * @param rank the rank we are checking + * @return the level requirement for a subskill at this particular rank + */ + private static int findRankByRootAddress(int rank, SubSkillType subSkillType) { + + CommentedConfigurationNode rankConfigRoot = mcMMO.getConfigManager().getConfigRanksRootNode(); + + try { + SkillRankProperty skillRankProperty + = rankConfigRoot.getNode(subSkillType.getParentSkill()) + .getNode(subSkillType.getHoconFriendlyConfigName()) + .getValue(TypeToken.of(SkillRankProperty.class)); + + return skillRankProperty.getUnlockLevel(mcMMO.isRetroModeEnabled(), rank); + } catch (ObjectMappingException | MissingSkillPropertyDefinition e) { + mcMMO.p.getLogger().severe("Error traversing nodes to SkillRankProperty for "+subSkillType.toString()); + mcMMO.p.getLogger().severe("This indicates a problem with your rank config file, edit the file and correct the issue or delete it to generate a new default one with correct values."); + e.printStackTrace(); + } + + //Default to the max level for the skill if any errors were encountered incorrect + return mcMMO.getConfigManager().getConfigLeveling().getLevelCap(subSkillType.getParentSkill()); + } + } \ No newline at end of file