diff --git a/src/main/java/com/gmail/nossr50/commands/skills/WoodcuttingCommand.java b/src/main/java/com/gmail/nossr50/commands/skills/WoodcuttingCommand.java index 4a3dbd0a7..06ed32840 100644 --- a/src/main/java/com/gmail/nossr50/commands/skills/WoodcuttingCommand.java +++ b/src/main/java/com/gmail/nossr50/commands/skills/WoodcuttingCommand.java @@ -36,7 +36,7 @@ public class WoodcuttingCommand extends SkillCommand { // DOUBLE DROPS if (canDoubleDrop) { - String[] doubleDropStrings = calculateAbilityDisplayValues(skillValue, SecondaryAbility.WOODCUTTING_DOUBLE_DROPS, isLucky); + String[] doubleDropStrings = calculateAbilityDisplayValues(skillValue, SecondaryAbility.WOODCUTTING_HARVEST, isLucky); doubleDropChance = doubleDropStrings[0]; doubleDropChanceLucky = doubleDropStrings[1]; } @@ -45,8 +45,8 @@ public class WoodcuttingCommand extends SkillCommand { @Override protected void permissionsCheck(Player player) { canTreeFell = Permissions.treeFeller(player); - canDoubleDrop = Permissions.secondaryAbilityEnabled(player, SecondaryAbility.WOODCUTTING_DOUBLE_DROPS) && !skill.getDoubleDropsDisabled(); - canLeafBlow = Permissions.secondaryAbilityEnabled(player, SecondaryAbility.LEAF_BLOWER); + canDoubleDrop = Permissions.secondaryAbilityEnabled(player, SecondaryAbility.WOODCUTTING_HARVEST) && !skill.getDoubleDropsDisabled(); + canLeafBlow = Permissions.secondaryAbilityEnabled(player, SecondaryAbility.WOODCUTTING_LEAF_BLOWER); } @Override diff --git a/src/main/java/com/gmail/nossr50/config/AdvancedConfig.java b/src/main/java/com/gmail/nossr50/config/AdvancedConfig.java index 0469583ef..23da636d7 100644 --- a/src/main/java/com/gmail/nossr50/config/AdvancedConfig.java +++ b/src/main/java/com/gmail/nossr50/config/AdvancedConfig.java @@ -654,11 +654,11 @@ public class AdvancedConfig extends AutoUpdateConfigLoader { reason.add("Skills.Woodcutting.LeafBlower.UnlockLevel should be at least 0!"); } - if (getMaxChance(SecondaryAbility.WOODCUTTING_DOUBLE_DROPS) < 1) { + if (getMaxChance(SecondaryAbility.WOODCUTTING_HARVEST) < 1) { reason.add("Skills.Woodcutting.DoubleDrops.ChanceMax should be at least 1!"); } - if (getMaxBonusLevel(SecondaryAbility.WOODCUTTING_DOUBLE_DROPS) < 1) { + if (getMaxBonusLevel(SecondaryAbility.WOODCUTTING_HARVEST) < 1) { reason.add("Skills.Woodcutting.DoubleDrops.MaxBonusLevel should be at least 1!"); } diff --git a/src/main/java/com/gmail/nossr50/datatypes/skills/SecondaryAbility.java b/src/main/java/com/gmail/nossr50/datatypes/skills/SecondaryAbility.java index 9ce073739..e974580a8 100644 --- a/src/main/java/com/gmail/nossr50/datatypes/skills/SecondaryAbility.java +++ b/src/main/java/com/gmail/nossr50/datatypes/skills/SecondaryAbility.java @@ -1,86 +1,102 @@ package com.gmail.nossr50.datatypes.skills; +import static com.gmail.nossr50.datatypes.skills.SkillType.*; public enum SecondaryAbility { + /* !! Warning -- Do not let subskills share a name with any existing SkillType as it will clash with the static import !! */ + /* ACROBATICS */ - DODGE, - GRACEFUL_ROLL, - ROLL, + DODGE(ACROBATICS), + GRACEFUL_ROLL(ACROBATICS), + ROLL(ACROBATICS), /* ALCHEMY */ - CATALYSIS, - CONCOCTIONS, + CATALYSIS(ALCHEMY), + CONCOCTIONS(ALCHEMY), /* ARCHERY */ - DAZE, - RETRIEVE, - SKILL_SHOT, + DAZE(ARCHERY), + RETRIEVE(ARCHERY), + SKILL_SHOT(ARCHERY), /* Axes */ - ARMOR_IMPACT, - AXE_MASTERY, - CRITICAL_HIT, - GREATER_IMPACT, + ARMOR_IMPACT(AXES), + AXE_MASTERY(AXES), + CRITICAL_HIT(AXES), + GREATER_IMPACT(AXES), /* Excavation */ - EXCAVATION_TREASURE_HUNTER, + EXCAVATION_TREASURE_HUNTER(EXCAVATION), /* Fishing */ - FISHERMANS_DIET, - FISHING_TREASURE_HUNTER, - ICE_FISHING, - MAGIC_HUNTER, - MASTER_ANGLER, - SHAKE, + FISHERMANS_DIET(FISHING), + FISHING_TREASURE_HUNTER(FISHING), + ICE_FISHING(FISHING), + MAGIC_HUNTER(FISHING), + MASTER_ANGLER(FISHING), + SHAKE(FISHING), /* Herbalism */ - FARMERS_DIET, - GREEN_THUMB_PLANT, - GREEN_THUMB_BLOCK, - HERBALISM_DOUBLE_DROPS, - HYLIAN_LUCK, - SHROOM_THUMB, + FARMERS_DIET(HERBALISM), + GREEN_THUMB_PLANT(HERBALISM), + GREEN_THUMB_BLOCK(HERBALISM), + HERBALISM_DOUBLE_DROPS(HERBALISM), + HYLIAN_LUCK(HERBALISM), + SHROOM_THUMB(HERBALISM), /* Mining */ - MINING_DOUBLE_DROPS, + MINING_DOUBLE_DROPS(MINING), /* Repair */ - ARCANE_FORGING, - REPAIR_MASTERY, - SUPER_REPAIR, + ARCANE_FORGING(REPAIR), + REPAIR_MASTERY(REPAIR), + SUPER_REPAIR(REPAIR), /* Salvage */ - ADVANCED_SALVAGE, - ARCANE_SALVAGE, + ADVANCED_SALVAGE(SALVAGE), + ARCANE_SALVAGE(SALVAGE), /* Smelting */ - FLUX_MINING, - FUEL_EFFICIENCY, - SECOND_SMELT, + FLUX_MINING(SMELTING), + FUEL_EFFICIENCY(SMELTING), + SECOND_SMELT(SMELTING), /* Swords */ - BLEED, - COUNTER, + BLEED(SWORDS), + COUNTER(SWORDS), /* Taming */ - BEAST_LORE, - CALL_OF_THE_WILD, - ENVIRONMENTALLY_AWARE, - FAST_FOOD, - GORE, - HOLY_HOUND, - SHARPENED_CLAWS, - SHOCK_PROOF, - THICK_FUR, - PUMMEL, + BEAST_LORE(TAMING), + CALL_OF_THE_WILD(TAMING), + ENVIRONMENTALLY_AWARE(TAMING), + FAST_FOOD(TAMING), + GORE(TAMING), + HOLY_HOUND(TAMING), + SHARPENED_CLAWS(TAMING), + SHOCK_PROOF(TAMING), + THICK_FUR(TAMING), + PUMMEL(TAMING), /* Unarmed */ - BLOCK_CRACKER, - DEFLECT, - DISARM, - IRON_ARM, - IRON_GRIP, + BLOCK_CRACKER(UNARMED), + DEFLECT(UNARMED), + DISARM(UNARMED), + IRON_ARM(UNARMED), + IRON_GRIP(UNARMED), /* Woodcutting */ - LEAF_BLOWER, - WOODCUTTING_DOUBLE_DROPS; + WOODCUTTING_TREE_FELLER(WOODCUTTING), + WOODCUTTING_LEAF_BLOWER(WOODCUTTING), + WOODCUTTING_SURGEON(WOODCUTTING), + WOODCUTTING_NATURES_BOUNTY(WOODCUTTING), + WOODCUTTING_SPLINTER(WOODCUTTING), + WOODCUTTING_HARVEST(WOODCUTTING); + + private final SkillType parentSkill; + + SecondaryAbility(SkillType parentSkill) + { + this.parentSkill = parentSkill; + } + + public SkillType getParentSkill() { return parentSkill; } } diff --git a/src/main/java/com/gmail/nossr50/datatypes/skills/SkillMilestone.java b/src/main/java/com/gmail/nossr50/datatypes/skills/SkillMilestone.java new file mode 100644 index 000000000..ffb5caf79 --- /dev/null +++ b/src/main/java/com/gmail/nossr50/datatypes/skills/SkillMilestone.java @@ -0,0 +1,39 @@ +package com.gmail.nossr50.datatypes.skills; + +/** + * This class represents a gated subskill + * A gated subskill is a subskill that requires a certain level to unlock + * This class is mostly to make it easier to grab information about subskills for a player + */ +public class SkillMilestone { + private int unlockLevel; //Level that grants access to this skill + private SecondaryAbility subskill; //Subskill that this milestone belongs to + private SkillMilestone childMilestone; //Next rank in the milestone + + public SkillMilestone(SecondaryAbility subskill, int unlockLevel, SkillMilestone childMilestone) + { + this.subskill = subskill; + this.unlockLevel = unlockLevel; + + //Assign a child subskill if it exists + if(childMilestone != null) + this.childMilestone = childMilestone; + } + + public SkillMilestone(SecondaryAbility subskill, int unlockLevel) + { + this(subskill, unlockLevel, null); + } + + public int getUnlockLevel() { + return unlockLevel; + } + + public SecondaryAbility getSubskill() { + return subskill; + } + + public SkillMilestone getChildMilestone() { + return childMilestone; + } +} diff --git a/src/main/java/com/gmail/nossr50/datatypes/skills/SkillType.java b/src/main/java/com/gmail/nossr50/datatypes/skills/SkillType.java index ec31c3bb7..8193d7123 100644 --- a/src/main/java/com/gmail/nossr50/datatypes/skills/SkillType.java +++ b/src/main/java/com/gmail/nossr50/datatypes/skills/SkillType.java @@ -50,7 +50,7 @@ public enum SkillType { SWORDS(SwordsManager.class, Color.fromRGB(178, 34, 34), AbilityType.SERRATED_STRIKES, ToolType.SWORD, ImmutableList.of(SecondaryAbility.BLEED, SecondaryAbility.COUNTER)), TAMING(TamingManager.class, Color.PURPLE, ImmutableList.of(SecondaryAbility.BEAST_LORE, SecondaryAbility.CALL_OF_THE_WILD, SecondaryAbility.ENVIRONMENTALLY_AWARE, SecondaryAbility.FAST_FOOD, SecondaryAbility.GORE, SecondaryAbility.HOLY_HOUND, SecondaryAbility.SHARPENED_CLAWS, SecondaryAbility.SHOCK_PROOF, SecondaryAbility.THICK_FUR, SecondaryAbility.PUMMEL)), UNARMED(UnarmedManager.class, Color.BLACK, AbilityType.BERSERK, ToolType.FISTS, ImmutableList.of(SecondaryAbility.BLOCK_CRACKER, SecondaryAbility.DEFLECT, SecondaryAbility.DISARM, SecondaryAbility.IRON_ARM, SecondaryAbility.IRON_GRIP)), - WOODCUTTING(WoodcuttingManager.class, Color.OLIVE, AbilityType.TREE_FELLER, ToolType.AXE, ImmutableList.of(SecondaryAbility.LEAF_BLOWER, SecondaryAbility.WOODCUTTING_DOUBLE_DROPS)); + WOODCUTTING(WoodcuttingManager.class, Color.OLIVE, AbilityType.TREE_FELLER, ToolType.AXE, ImmutableList.of(SecondaryAbility.WOODCUTTING_LEAF_BLOWER, SecondaryAbility.WOODCUTTING_HARVEST)); private Class managerClass; private Color runescapeColor; diff --git a/src/main/java/com/gmail/nossr50/skills/woodcutting/WoodcuttingManager.java b/src/main/java/com/gmail/nossr50/skills/woodcutting/WoodcuttingManager.java index 3e3f79efc..87a374a39 100644 --- a/src/main/java/com/gmail/nossr50/skills/woodcutting/WoodcuttingManager.java +++ b/src/main/java/com/gmail/nossr50/skills/woodcutting/WoodcuttingManager.java @@ -31,7 +31,7 @@ public class WoodcuttingManager extends SkillManager { } public boolean canUseLeafBlower(ItemStack heldItem) { - return Permissions.secondaryAbilityEnabled(getPlayer(), SecondaryAbility.LEAF_BLOWER) && getSkillLevel() >= Woodcutting.leafBlowerUnlockLevel && ItemUtils.isAxe(heldItem); + return Permissions.secondaryAbilityEnabled(getPlayer(), SecondaryAbility.WOODCUTTING_LEAF_BLOWER) && getSkillLevel() >= Woodcutting.leafBlowerUnlockLevel && ItemUtils.isAxe(heldItem); } public boolean canUseTreeFeller(ItemStack heldItem) { @@ -39,7 +39,7 @@ public class WoodcuttingManager extends SkillManager { } protected boolean canGetDoubleDrops() { - return Permissions.secondaryAbilityEnabled(getPlayer(), SecondaryAbility.WOODCUTTING_DOUBLE_DROPS) && SkillUtils.isActivationSuccessful(SecondarySkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, SecondaryAbility.WOODCUTTING_DOUBLE_DROPS, getPlayer(), this.skill, getSkillLevel(), activationChance); + return Permissions.secondaryAbilityEnabled(getPlayer(), SecondaryAbility.WOODCUTTING_HARVEST) && SkillUtils.isActivationSuccessful(SecondarySkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, SecondaryAbility.WOODCUTTING_HARVEST, getPlayer(), this.skill, getSkillLevel(), activationChance); } /** diff --git a/src/main/java/com/gmail/nossr50/util/StringUtils.java b/src/main/java/com/gmail/nossr50/util/StringUtils.java index 0b66049d2..08c5face1 100644 --- a/src/main/java/com/gmail/nossr50/util/StringUtils.java +++ b/src/main/java/com/gmail/nossr50/util/StringUtils.java @@ -83,7 +83,7 @@ public class StringUtils { switch (secondaryAbility) { case HERBALISM_DOUBLE_DROPS : case MINING_DOUBLE_DROPS : - case WOODCUTTING_DOUBLE_DROPS : + case WOODCUTTING_HARVEST: return "Double Drops"; case FISHING_TREASURE_HUNTER : case EXCAVATION_TREASURE_HUNTER : diff --git a/src/main/java/com/gmail/nossr50/util/player/FeedbackManager.java b/src/main/java/com/gmail/nossr50/util/player/FeedbackManager.java new file mode 100644 index 000000000..b8fc771fb --- /dev/null +++ b/src/main/java/com/gmail/nossr50/util/player/FeedbackManager.java @@ -0,0 +1,30 @@ +package com.gmail.nossr50.util.player; + +import org.bukkit.entity.Player; + +/** + * This class will manage all types of feedback for a player done through mcMMO + * Including + * 1) Audio Feedback + * 2) Visual Feedback (Anything on the screen that we use to convey information) + */ +public class FeedbackManager { + + /** + * Used for sending specific sound cues to a player + * @param player The player who will be receiving the sound cues + */ + public void sendAudioFeedback(Player player) + { + + } + + /** + * Used for sending specific visual aides to a player + * @param player The player who will be receiving the visual feedback + */ + public void sendVisualFeedback(Player player) + { + + } +} diff --git a/src/main/java/com/gmail/nossr50/util/player/VisualFeedbackType.java b/src/main/java/com/gmail/nossr50/util/player/VisualFeedbackType.java new file mode 100644 index 000000000..5c425acef --- /dev/null +++ b/src/main/java/com/gmail/nossr50/util/player/VisualFeedbackType.java @@ -0,0 +1,7 @@ +package com.gmail.nossr50.util.player; + +public enum VisualFeedbackType { + ADVANCEMENT, + CHAT_MESSAGE, + CUSTOM_SCOREBOARD +} diff --git a/src/main/java/com/gmail/nossr50/util/scoreboards/ScoreboardManager.java b/src/main/java/com/gmail/nossr50/util/scoreboards/ScoreboardManager.java index 8c69e3614..d2d0b582f 100644 --- a/src/main/java/com/gmail/nossr50/util/scoreboards/ScoreboardManager.java +++ b/src/main/java/com/gmail/nossr50/util/scoreboards/ScoreboardManager.java @@ -26,6 +26,9 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; +/** + * Manages the Scoreboards used to display a variety of mcMMO related information to the player + */ public class ScoreboardManager { static final Map PLAYER_SCOREBOARDS = new HashMap(); @@ -51,11 +54,22 @@ public class ScoreboardManager { static final Map abilityLabelsColored; static final Map abilityLabelsSkill; + /* + * Initializes the static properties of this class + */ static { + /* + * We need immutable objects for our Scoreboard's labels + */ ImmutableMap.Builder skillLabelBuilder = ImmutableMap.builder(); ImmutableMap.Builder abilityLabelBuilder = ImmutableMap.builder(); ImmutableMap.Builder abilityLabelSkillBuilder = ImmutableMap.builder(); + /* + * Builds the labels for our ScoreBoards + * Stylizes the scoreboard in a Rainbow Pattern + * This is off by default + */ if (Config.getInstance().getScoreboardRainbows()) { // Everything but black, gray, gold List colors = Lists.newArrayList( @@ -93,6 +107,10 @@ public class ScoreboardManager { } } } + /* + * Builds the labels for our ScoreBoards + * Stylizes the scoreboard using our normal color scheme + */ else { for (SkillType type : SkillType.values()) { // Include child skills diff --git a/src/main/java/com/gmail/nossr50/util/scoreboards/ScoreboardWrapper.java b/src/main/java/com/gmail/nossr50/util/scoreboards/ScoreboardWrapper.java index a5f0b19b5..5179b4e0e 100644 --- a/src/main/java/com/gmail/nossr50/util/scoreboards/ScoreboardWrapper.java +++ b/src/main/java/com/gmail/nossr50/util/scoreboards/ScoreboardWrapper.java @@ -3,6 +3,7 @@ package com.gmail.nossr50.util.scoreboards; import java.util.List; import java.util.Map; +import jdk.internal.jline.internal.Nullable; import org.bukkit.ChatColor; import org.bukkit.entity.Player; import org.bukkit.scheduler.BukkitRunnable; @@ -40,9 +41,13 @@ public class ScoreboardWrapper { private Objective powerObjective; // Parameter variables (May be null / invalid) + @Nullable private Scoreboard oldBoard = null; + @Nullable public String targetPlayer = null; + @Nullable public SkillType targetSkill = null; + @Nullable private PlayerProfile targetProfile = null; public int leaderboardPage = -1; diff --git a/src/main/java/com/gmail/nossr50/util/skills/SkillMilestoneManager.java b/src/main/java/com/gmail/nossr50/util/skills/SkillMilestoneManager.java new file mode 100644 index 000000000..58bd43585 --- /dev/null +++ b/src/main/java/com/gmail/nossr50/util/skills/SkillMilestoneManager.java @@ -0,0 +1,33 @@ +package com.gmail.nossr50.util.skills; + +import com.gmail.nossr50.datatypes.skills.SecondaryAbility; +import com.gmail.nossr50.datatypes.skills.SkillType; + +import java.util.HashMap; + +/** + * This class will handle the following things + * 1) Informing the player of important milestones in a skill (Every 5 levels) + * 2) Getting lists of milestones (skill unlocks) a player has + * 3) Propagating events for milestones (API) + * + * By setting up a skill milestone system it will make managing the audio/visual feedback for progression a lot easier + * + */ +//TODO: Inform players of milestones +//TODO: Helper methods for getting milestones +//TODO: Propagate events when milestones are achieved +//TODO: Update existing parts of the codebase to use this where appropriate +public class SkillMilestoneManager { + public static final HashMap subskillMilestones; + + static { + //Init our maps + subskillMilestones = new HashMap<>(); + + for(SkillType skillType : SkillType.values()) + { + //TODO: Setup these values + } + } +}