Explorar o código

SuperAbilityManager will handle super ability stuff

nossr50 %!s(int64=5) %!d(string=hai) anos
pai
achega
df7c9e0b1c
Modificáronse 21 ficheiros con 392 adicións e 335 borrados
  1. 8 8
      src/main/java/com/gmail/nossr50/api/AbilityAPI.java
  2. 2 2
      src/main/java/com/gmail/nossr50/commands/McabilityCommand.java
  3. 2 2
      src/main/java/com/gmail/nossr50/commands/McrefreshCommand.java
  4. 13 258
      src/main/java/com/gmail/nossr50/datatypes/player/McMMOPlayer.java
  5. 3 3
      src/main/java/com/gmail/nossr50/datatypes/player/PlayerProfile.java
  6. 18 18
      src/main/java/com/gmail/nossr50/listeners/BlockListener.java
  7. 14 14
      src/main/java/com/gmail/nossr50/listeners/PlayerListener.java
  8. 2 2
      src/main/java/com/gmail/nossr50/runnables/skills/AbilityCooldownTask.java
  9. 3 3
      src/main/java/com/gmail/nossr50/runnables/skills/AbilityDisableTask.java
  10. 2 2
      src/main/java/com/gmail/nossr50/runnables/skills/ToolLowerTask.java
  11. 2 2
      src/main/java/com/gmail/nossr50/skills/axes/AxesManager.java
  12. 4 4
      src/main/java/com/gmail/nossr50/skills/herbalism/HerbalismManager.java
  13. 3 3
      src/main/java/com/gmail/nossr50/skills/mining/MiningManager.java
  14. 2 2
      src/main/java/com/gmail/nossr50/skills/swords/SwordsManager.java
  15. 2 2
      src/main/java/com/gmail/nossr50/skills/unarmed/UnarmedManager.java
  16. 1 1
      src/main/java/com/gmail/nossr50/skills/woodcutting/WoodcuttingManager.java
  17. 7 5
      src/main/java/com/gmail/nossr50/util/ItemUtils.java
  18. 296 0
      src/main/java/com/gmail/nossr50/util/input/SuperAbilityManager.java
  19. 4 0
      src/main/java/com/gmail/nossr50/util/input/SuperAbilityState.java
  20. 3 3
      src/main/java/com/gmail/nossr50/util/skills/CombatUtils.java
  21. 1 1
      src/main/java/com/gmail/nossr50/util/skills/SkillUtils.java

+ 8 - 8
src/main/java/com/gmail/nossr50/api/AbilityAPI.java

@@ -11,38 +11,38 @@ public final class AbilityAPI {
     private AbilityAPI() {}
 
     public static boolean berserkEnabled(Player player) {
-        return UserManager.getPlayer(player).getAbilityMode(SuperAbilityType.BERSERK);
+        return UserManager.getPlayer(player).getSuperAbilityManager().getAbilityMode(SuperAbilityType.BERSERK);
     }
 
     public static boolean gigaDrillBreakerEnabled(Player player) {
-        return UserManager.getPlayer(player).getAbilityMode(SuperAbilityType.GIGA_DRILL_BREAKER);
+        return UserManager.getPlayer(player).getSuperAbilityManager().getAbilityMode(SuperAbilityType.GIGA_DRILL_BREAKER);
     }
 
     public static boolean greenTerraEnabled(Player player) {
-        return UserManager.getPlayer(player).getAbilityMode(SuperAbilityType.GREEN_TERRA);
+        return UserManager.getPlayer(player).getSuperAbilityManager().getAbilityMode(SuperAbilityType.GREEN_TERRA);
     }
 
     public static boolean serratedStrikesEnabled(Player player) {
-        return UserManager.getPlayer(player).getAbilityMode(SuperAbilityType.SERRATED_STRIKES);
+        return UserManager.getPlayer(player).getSuperAbilityManager().getAbilityMode(SuperAbilityType.SERRATED_STRIKES);
     }
 
     public static boolean skullSplitterEnabled(Player player) {
-        return UserManager.getPlayer(player).getAbilityMode(SuperAbilityType.SKULL_SPLITTER);
+        return UserManager.getPlayer(player).getSuperAbilityManager().getAbilityMode(SuperAbilityType.SKULL_SPLITTER);
     }
 
     public static boolean superBreakerEnabled(Player player) {
-        return UserManager.getPlayer(player).getAbilityMode(SuperAbilityType.SUPER_BREAKER);
+        return UserManager.getPlayer(player).getSuperAbilityManager().getAbilityMode(SuperAbilityType.SUPER_BREAKER);
     }
 
     public static boolean treeFellerEnabled(Player player) {
-        return UserManager.getPlayer(player).getAbilityMode(SuperAbilityType.TREE_FELLER);
+        return UserManager.getPlayer(player).getSuperAbilityManager().getAbilityMode(SuperAbilityType.TREE_FELLER);
     }
 
     public static boolean isAnyAbilityEnabled(Player player) {
         McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
 
         for (SuperAbilityType ability : SuperAbilityType.values()) {
-            if (mcMMOPlayer.getAbilityMode(ability)) {
+            if (mcMMOPlayer.getSuperAbilityManager().getAbilityMode(ability)) {
                 return true;
             }
         }

+ 2 - 2
src/main/java/com/gmail/nossr50/commands/McabilityCommand.java

@@ -18,8 +18,8 @@ public class McabilityCommand extends ToggleCommand {
 
     @Override
     protected void applyCommandAction(McMMOPlayer mcMMOPlayer) {
-        mcMMOPlayer.getPlayer().sendMessage(LocaleLoader.getString("Commands.Ability." + (mcMMOPlayer.getAbilityUse() ? "Off" : "On")));
-        mcMMOPlayer.toggleAbilityUse();
+        mcMMOPlayer.getPlayer().sendMessage(LocaleLoader.getString("Commands.Ability." + (mcMMOPlayer.getSuperAbilityManager().getAbilityActivationPermission() ? "Off" : "On")));
+        mcMMOPlayer.getSuperAbilityManager().toggleAbilityActivationPermission();
     }
 
     @Override

+ 2 - 2
src/main/java/com/gmail/nossr50/commands/McrefreshCommand.java

@@ -20,8 +20,8 @@ public class McrefreshCommand extends ToggleCommand {
     protected void applyCommandAction(McMMOPlayer mcMMOPlayer) {
         mcMMOPlayer.setRecentlyHurt(0);
         mcMMOPlayer.resetCooldowns();
-        mcMMOPlayer.resetToolPrepMode();
-        mcMMOPlayer.resetAbilityMode();
+        mcMMOPlayer.getSuperAbilityManager().resetToolPrepMode();
+        mcMMOPlayer.getSuperAbilityManager().resetSuperAbilities();
 
         mcMMOPlayer.getPlayer().sendMessage(LocaleLoader.getString("Ability.Generic.Refresh"));
     }

+ 13 - 258
src/main/java/com/gmail/nossr50/datatypes/player/McMMOPlayer.java

@@ -1,26 +1,21 @@
 package com.gmail.nossr50.datatypes.player;
 
-import com.gmail.nossr50.config.AdvancedConfig;
 import com.gmail.nossr50.config.Config;
 import com.gmail.nossr50.config.WorldBlacklist;
 import com.gmail.nossr50.config.experience.ExperienceConfig;
 import com.gmail.nossr50.datatypes.chat.ChatMode;
 import com.gmail.nossr50.datatypes.experience.XPGainReason;
 import com.gmail.nossr50.datatypes.experience.XPGainSource;
-import com.gmail.nossr50.datatypes.interactions.NotificationType;
 import com.gmail.nossr50.datatypes.mods.CustomTool;
 import com.gmail.nossr50.datatypes.party.Party;
 import com.gmail.nossr50.datatypes.party.PartyTeleportRecord;
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 import com.gmail.nossr50.datatypes.skills.SuperAbilityType;
-import com.gmail.nossr50.datatypes.skills.ToolType;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.party.PartyManager;
 import com.gmail.nossr50.party.ShareHandler;
-import com.gmail.nossr50.runnables.skills.AbilityDisableTask;
 import com.gmail.nossr50.runnables.skills.BleedTimerTask;
-import com.gmail.nossr50.runnables.skills.ToolLowerTask;
 import com.gmail.nossr50.skills.SkillManager;
 import com.gmail.nossr50.skills.acrobatics.AcrobaticsManager;
 import com.gmail.nossr50.skills.alchemy.AlchemyManager;
@@ -44,19 +39,18 @@ import com.gmail.nossr50.util.EventUtils;
 import com.gmail.nossr50.util.Misc;
 import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.experience.ExperienceBarManager;
+import com.gmail.nossr50.util.input.SuperAbilityManager;
 import com.gmail.nossr50.util.player.NotificationManager;
 import com.gmail.nossr50.util.player.UserManager;
 import com.gmail.nossr50.util.scoreboards.ScoreboardManager;
 import com.gmail.nossr50.util.skills.PerksUtils;
 import com.gmail.nossr50.util.skills.RankUtils;
-import com.gmail.nossr50.util.skills.SkillUtils;
 import com.gmail.nossr50.util.sounds.SoundManager;
 import com.gmail.nossr50.util.sounds.SoundType;
 import org.apache.commons.lang.Validate;
 import org.bukkit.GameMode;
 import org.bukkit.Location;
 import org.bukkit.entity.Player;
-import org.bukkit.inventory.ItemStack;
 import org.bukkit.metadata.FixedMetadataValue;
 import org.bukkit.plugin.Plugin;
 
@@ -84,15 +78,9 @@ public class McMMOPlayer {
     private boolean displaySkillNotifications = true;
     private boolean debugMode;
 
-    private boolean abilityUse = true;
     private boolean godMode;
     private boolean chatSpy = false; //Off by default
 
-    private final Map<SuperAbilityType, Boolean> abilityMode     = new HashMap<>();
-    private final Map<SuperAbilityType, Boolean> abilityInformed = new HashMap<>();
-
-    private final Map<ToolType, Boolean> toolMode = new HashMap<>();
-
     private int recentlyHurt;
     private int respawnATS;
     private int teleportATS;
@@ -104,6 +92,7 @@ public class McMMOPlayer {
     private boolean isUsingUnarmed;
     private final FixedMetadataValue playerMetadata;
     private final String playerName;
+    private final SuperAbilityManager superAbilityManager;
 
     public McMMOPlayer(Player player, PlayerProfile profile) {
         this.playerName = player.getName();
@@ -132,14 +121,7 @@ public class McMMOPlayer {
             mcMMO.p.getPluginLoader().disablePlugin(mcMMO.p);
         }
 
-        for (SuperAbilityType superAbilityType : SuperAbilityType.values()) {
-            abilityMode.put(superAbilityType, false);
-            abilityInformed.put(superAbilityType, true); // This is intended
-        }
-
-        for (ToolType toolType : ToolType.values()) {
-            toolMode.put(toolType, false);
-        }
+        superAbilityManager = new SuperAbilityManager(this);
 
         experienceBarManager = new ExperienceBarManager(this, profile.getXpBarStateMap());
 
@@ -159,11 +141,6 @@ public class McMMOPlayer {
         this.attackStrength = attackStrength;
     }
 
-    /*public void hideXpBar(PrimarySkillType primarySkillType)
-    {
-        experienceBarManager.hideExperienceBar(primarySkillType);
-    }*/
-
     public void processPostXpEvent(PrimarySkillType primarySkillType, Plugin plugin, XPGainSource xpGainSource)
     {
         //Check if they've reached the power level cap just now
@@ -279,100 +256,6 @@ public class McMMOPlayer {
         return (WoodcuttingManager) skillManagers.get(PrimarySkillType.WOODCUTTING);
     }
 
-    /*
-     * Abilities
-     */
-
-    /**
-     * Reset the mode of all abilities.
-     */
-    public void resetAbilityMode() {
-        for (SuperAbilityType ability : SuperAbilityType.values()) {
-            // Correctly disable and handle any special deactivate code
-            new AbilityDisableTask(this, ability).run();
-        }
-    }
-
-    /**
-     * Get the mode of an ability.
-     *
-     * @param ability The ability to check
-     * @return true if the ability is enabled, false otherwise
-     */
-    public boolean getAbilityMode(SuperAbilityType ability) {
-        return abilityMode.get(ability);
-    }
-
-    /**
-     * Set the mode of an ability.
-     *
-     * @param ability The ability to check
-     * @param isActive True if the ability is active, false otherwise
-     */
-    public void setAbilityMode(SuperAbilityType ability, boolean isActive) {
-        abilityMode.put(ability, isActive);
-    }
-
-    /**
-     * Get the informed state of an ability
-     *
-     * @param ability The ability to check
-     * @return true if the ability is informed, false otherwise
-     */
-    public boolean getAbilityInformed(SuperAbilityType ability) {
-        return abilityInformed.get(ability);
-    }
-
-    /**
-     * Set the informed state of an ability.
-     *
-     * @param ability The ability to check
-     * @param isInformed True if the ability is informed, false otherwise
-     */
-    public void setAbilityInformed(SuperAbilityType ability, boolean isInformed) {
-        abilityInformed.put(ability, isInformed);
-    }
-
-    /**
-     * Get the current prep mode of a tool.
-     *
-     * @param tool Tool to get the mode for
-     * @return true if the tool is prepped, false otherwise
-     */
-    public boolean getToolPreparationMode(ToolType tool) {
-        return toolMode.get(tool);
-    }
-
-    public boolean getAbilityUse() {
-        return abilityUse;
-    }
-
-    public void toggleAbilityUse() {
-        abilityUse = !abilityUse;
-    }
-
-    /*
-     * Tools
-     */
-
-    /**
-     * Reset the prep modes of all tools.
-     */
-    public void resetToolPrepMode() {
-        for (ToolType tool : ToolType.values()) {
-            setToolPreparationMode(tool, false);
-        }
-    }
-
-    /**
-     * Set the current prep mode of a tool.
-     *
-     * @param tool Tool to set the mode for
-     * @param isPrepared true if the tool should be prepped, false otherwise
-     */
-    public void setToolPreparationMode(ToolType tool, boolean isPrepared) {
-        toolMode.put(tool, isPrepared);
-    }
 
     /*
      * Recently Hurt
@@ -855,149 +738,16 @@ public class McMMOPlayer {
         }
     }
 
-    /**
-     * Check to see if an ability can be activated.
-     *
-     * @param skill The skill the ability is based on
-     */
-    public void checkAbilityActivation(PrimarySkillType skill) {
-        ToolType tool = skill.getTool();
-        SuperAbilityType ability = skill.getAbility();
-
-        if (getAbilityMode(ability) || !ability.getPermissions(player)) {
-            return;
-        }
-
-        //TODO: This is hacky and temporary solution until skills are move to the new system
-        //Potential problems with this include skills with two super abilities (ie mining)
-        if(!skill.isSuperAbilityUnlocked(getPlayer()))
-        {
-            int diff = RankUtils.getSuperAbilityUnlockRequirement(skill.getAbility()) - getSkillLevel(skill);
-
-            //Inform the player they are not yet skilled enough
-            NotificationManager.sendPlayerInformation(player, NotificationType.ABILITY_COOLDOWN, "Skills.AbilityGateRequirementFail", String.valueOf(diff), skill.getName());
-            return;
-        }
-
-        int timeRemaining = calculateTimeRemaining(ability);
-
-        if (timeRemaining > 0) {
-            /*
-             * Axes and Woodcutting are odd because they share the same tool.
-             * We show them the too tired message when they take action.
-             */
-            if (skill == PrimarySkillType.WOODCUTTING || skill == PrimarySkillType.AXES) {
-                NotificationManager.sendPlayerInformation(player, NotificationType.ABILITY_COOLDOWN, "Skills.TooTired", String.valueOf(timeRemaining));
-                //SoundManager.sendSound(player, player.getLocation(), SoundType.TIRED);
-            }
-
-            return;
-        }
-
-        if (EventUtils.callPlayerAbilityActivateEvent(player, skill).isCancelled()) {
-            return;
-        }
-
-        //These values change depending on whether or not the server is in retro mode
-        int abilityLengthVar = AdvancedConfig.getInstance().getAbilityLength();
-        int abilityLengthCap = AdvancedConfig.getInstance().getAbilityLengthCap();
-
-        int ticks;
-
-        //Ability cap of 0 or below means no cap
-        if(abilityLengthCap > 0)
-        {
-            ticks = PerksUtils.handleActivationPerks(player, 2 + (Math.min(abilityLengthCap, getSkillLevel(skill)) / abilityLengthVar), ability.getMaxLength());
-        } else {
-            ticks = PerksUtils.handleActivationPerks(player, 2 + (getSkillLevel(skill) / abilityLengthVar), ability.getMaxLength());
-        }
-
-        if (useChatNotifications()) {
-            NotificationManager.sendPlayerInformation(player, NotificationType.SUPER_ABILITY, ability.getAbilityOn());
-            //player.sendMessage(ability.getAbilityOn());
-        }
-
-        if (AdvancedConfig.getInstance().sendAbilityNotificationToOtherPlayers()) {
-            SkillUtils.sendSkillMessage(player, NotificationType.SUPER_ABILITY_ALERT_OTHERS, ability.getAbilityPlayer());
-        }
-
-        //Sounds
-        SoundManager.worldSendSound(player.getWorld(), player.getLocation(), SoundType.ABILITY_ACTIVATED_GENERIC);
-
-        // Enable the ability
-        profile.setAbilityDATS(ability, System.currentTimeMillis() + (ticks * Misc.TIME_CONVERSION_FACTOR));
-        setAbilityMode(ability, true);
-
-        if (ability == SuperAbilityType.SUPER_BREAKER || ability == SuperAbilityType.GIGA_DRILL_BREAKER) {
-            SkillUtils.handleAbilitySpeedIncrease(player);
-        }
-
-        setToolPreparationMode(tool, false);
-        new AbilityDisableTask(this, ability).runTaskLater(mcMMO.p, ticks * Misc.TICK_CONVERSION_FACTOR);
-    }
-
-    public void processAbilityActivation(PrimarySkillType skill) {
-        if (!skill.getPermissions(getPlayer())) {
-            return;
-        }
-
-        if (Config.getInstance().getAbilitiesOnlyActivateWhenSneaking() && !player.isSneaking()) {
-            return;
-        }
-
-        ItemStack inHand = player.getInventory().getItemInMainHand();
-
-        if (mcMMO.getModManager().isCustomTool(inHand) && !mcMMO.getModManager().getTool(inHand).isAbilityEnabled()) {
-            return;
-        }
-
-        if (!getAbilityUse()) {
-            return;
-        }
-
-        for (SuperAbilityType superAbilityType : SuperAbilityType.values()) {
-            if (getAbilityMode(superAbilityType)) {
-                return;
-            }
-        }
-
-        SuperAbilityType ability = skill.getAbility();
-        ToolType tool = skill.getTool();
-
-        /*
-         * Woodcutting & Axes need to be treated differently.
-         * Basically the tool always needs to ready and we check to see if the cooldown is over when the user takes action
-         */
-        if (tool.inHand(inHand) && !getToolPreparationMode(tool)) {
-            if (skill != PrimarySkillType.WOODCUTTING && skill != PrimarySkillType.AXES) {
-                int timeRemaining = calculateTimeRemaining(ability);
-
-                if (!getAbilityMode(ability) && timeRemaining > 0) {
-                    NotificationManager.sendPlayerInformation(player, NotificationType.ABILITY_COOLDOWN, "Skills.TooTired", String.valueOf(timeRemaining));
-                    return;
-                }
-            }
-
-            if (Config.getInstance().getAbilityMessagesEnabled()) {
-                NotificationManager.sendPlayerInformation(player, NotificationType.TOOL, tool.getRaiseTool());
-                SoundManager.sendSound(player, player.getLocation(), SoundType.TOOL_READY);
-            }
-
-            setToolPreparationMode(tool, true);
-            new ToolLowerTask(this, tool).runTaskLater(mcMMO.p, 4 * Misc.TICK_CONVERSION_FACTOR);
-        }
-    }
 
     /**
-     * Calculate the time remaining until the ability's cooldown expires.
+     * Calculate the time remaining until the superAbilityType's cooldown expires.
      *
-     * @param ability SuperAbilityType whose cooldown to check
+     * @param superAbilityType SuperAbilityType whose cooldown to check
      *
      * @return the number of seconds remaining before the cooldown expires
      */
-    public int calculateTimeRemaining(SuperAbilityType ability) {
-        long deactivatedTimestamp = profile.getAbilityDATS(ability) * Misc.TIME_CONVERSION_FACTOR;
-        return (int) (((deactivatedTimestamp + (PerksUtils.handleCooldownPerks(player, ability.getCooldown()) * Misc.TIME_CONVERSION_FACTOR)) - System.currentTimeMillis()) / Misc.TIME_CONVERSION_FACTOR);
+    public int calculateTimeRemaining(SuperAbilityType superAbilityType) {
+        return superAbilityManager.calculateTimeRemaining(superAbilityType);
     }
 
     /*
@@ -1080,6 +830,11 @@ public class McMMOPlayer {
         mcMMO.getDatabaseManager().cleanupUser(thisPlayer.getUniqueId());
     }
 
+    public SuperAbilityManager getSuperAbilityManager() {
+        return superAbilityManager;
+    }
+
+
     /**
      * Cleanup various things related to this player
      * Such as temporary summons..
@@ -1087,7 +842,7 @@ public class McMMOPlayer {
      * Etc...
      */
     public void cleanup() {
-        resetAbilityMode();
+        superAbilityManager.resetSuperAbilities();
         getTamingManager().cleanupAllSummons();
     }
 }

+ 3 - 3
src/main/java/com/gmail/nossr50/datatypes/player/PlayerProfile.java

@@ -241,7 +241,7 @@ public class PlayerProfile {
      * @param ability The {@link SuperAbilityType} to set the DATS for
      * @param DATS the DATS of the ability
      */
-    protected void setAbilityDATS(SuperAbilityType ability, long DATS) {
+    public void setAbilityDATS(SuperAbilityType ability, long DATS) {
         markProfileDirty();
 
         abilityDATS.put(ability, (int) (DATS * .001D));
@@ -250,7 +250,7 @@ public class PlayerProfile {
     /**
      * Reset all ability cooldowns.
      */
-    protected void resetCooldowns() {
+    public void resetCooldowns() {
         markProfileDirty();
 
         abilityDATS.replaceAll((a, v) -> 0);
@@ -286,7 +286,7 @@ public class PlayerProfile {
         skillsXp.put(skill, xpLevel);
     }
 
-    protected float levelUp(PrimarySkillType skill) {
+    public float levelUp(PrimarySkillType skill) {
         float xpRemoved = getXpToLevel(skill);
 
         markProfileDirty();

+ 18 - 18
src/main/java/com/gmail/nossr50/listeners/BlockListener.java

@@ -335,7 +335,7 @@ public class BlockListener implements Listener {
 
             /* Green Terra */
             if (herbalismManager.canActivateAbility()) {
-                mcMMOPlayer.checkAbilityActivation(PrimarySkillType.HERBALISM);
+                mcMMOPlayer.getSuperAbilityManager().checkAbilityActivation(PrimarySkillType.HERBALISM);
             }
 
             /*
@@ -374,7 +374,7 @@ public class BlockListener implements Listener {
             ExcavationManager excavationManager = mcMMOPlayer.getExcavationManager();
             excavationManager.excavationBlockCheck(blockState);
 
-            if (mcMMOPlayer.getAbilityMode(SuperAbilityType.GIGA_DRILL_BREAKER)) {
+            if (mcMMOPlayer.getSuperAbilityManager().getAbilityMode(SuperAbilityType.GIGA_DRILL_BREAKER)) {
                 excavationManager.gigaDrillBreaker(blockState);
             }
         }
@@ -491,25 +491,25 @@ public class BlockListener implements Listener {
         if (BlockUtils.canActivateAbilities(blockState)) {
             ItemStack heldItem = player.getInventory().getItemInMainHand();
 
-            if (mcMMOPlayer.getToolPreparationMode(ToolType.HOE) && ItemUtils.isHoe(heldItem) && (BlockUtils.affectedByGreenTerra(blockState) || BlockUtils.canMakeMossy(blockState)) && Permissions.greenTerra(player)) {
-                mcMMOPlayer.checkAbilityActivation(PrimarySkillType.HERBALISM);
+            if (mcMMOPlayer.getSuperAbilityManager().getToolPreparationMode(ToolType.HOE) && ItemUtils.isHoe(heldItem) && (BlockUtils.affectedByGreenTerra(blockState) || BlockUtils.canMakeMossy(blockState)) && Permissions.greenTerra(player)) {
+                mcMMOPlayer.getSuperAbilityManager().checkAbilityActivation(PrimarySkillType.HERBALISM);
             }
-            else if (mcMMOPlayer.getToolPreparationMode(ToolType.AXE) && ItemUtils.isAxe(heldItem) && BlockUtils.isLog(blockState) && Permissions.treeFeller(player)) {
-                mcMMOPlayer.checkAbilityActivation(PrimarySkillType.WOODCUTTING);
+            else if (mcMMOPlayer.getSuperAbilityManager().getToolPreparationMode(ToolType.AXE) && ItemUtils.isAxe(heldItem) && BlockUtils.isLog(blockState) && Permissions.treeFeller(player)) {
+                mcMMOPlayer.getSuperAbilityManager().checkAbilityActivation(PrimarySkillType.WOODCUTTING);
             }
-            else if (mcMMOPlayer.getToolPreparationMode(ToolType.PICKAXE) && ItemUtils.isPickaxe(heldItem) && BlockUtils.affectedBySuperBreaker(blockState) && Permissions.superBreaker(player)) {
-                mcMMOPlayer.checkAbilityActivation(PrimarySkillType.MINING);
+            else if (mcMMOPlayer.getSuperAbilityManager().getToolPreparationMode(ToolType.PICKAXE) && ItemUtils.isPickaxe(heldItem) && BlockUtils.affectedBySuperBreaker(blockState) && Permissions.superBreaker(player)) {
+                mcMMOPlayer.getSuperAbilityManager().checkAbilityActivation(PrimarySkillType.MINING);
             }
-            else if (mcMMOPlayer.getToolPreparationMode(ToolType.SHOVEL) && ItemUtils.isShovel(heldItem) && BlockUtils.affectedByGigaDrillBreaker(blockState) && Permissions.gigaDrillBreaker(player)) {
-                mcMMOPlayer.checkAbilityActivation(PrimarySkillType.EXCAVATION);
+            else if (mcMMOPlayer.getSuperAbilityManager().getToolPreparationMode(ToolType.SHOVEL) && ItemUtils.isShovel(heldItem) && BlockUtils.affectedByGigaDrillBreaker(blockState) && Permissions.gigaDrillBreaker(player)) {
+                mcMMOPlayer.getSuperAbilityManager().checkAbilityActivation(PrimarySkillType.EXCAVATION);
             }
-            else if (mcMMOPlayer.getToolPreparationMode(ToolType.FISTS) && heldItem.getType() == Material.AIR && (BlockUtils.affectedByGigaDrillBreaker(blockState)
+            else if (mcMMOPlayer.getSuperAbilityManager().getToolPreparationMode(ToolType.FISTS) && heldItem.getType() == Material.AIR && (BlockUtils.affectedByGigaDrillBreaker(blockState)
                     || mcMMO.getMaterialMapStore().isGlass(blockState.getType())
                     || blockState.getType() == Material.SNOW
                     || BlockUtils.affectedByBlockCracker(blockState) && Permissions.berserk(player))) {
-                mcMMOPlayer.checkAbilityActivation(PrimarySkillType.UNARMED);
+                mcMMOPlayer.getSuperAbilityManager().checkAbilityActivation(PrimarySkillType.UNARMED);
 
-                if(mcMMOPlayer.getAbilityMode(SuperAbilityType.BERSERK)) {
+                if(mcMMOPlayer.getSuperAbilityManager().getAbilityMode(SuperAbilityType.BERSERK)) {
                     if (SuperAbilityType.BERSERK.blockCheck(blockState) && EventUtils.simulateBlockBreak(blockState.getBlock(), player, true)) {
                         event.setInstaBreak(true);
 
@@ -528,7 +528,7 @@ public class BlockListener implements Listener {
          *
          * We don't need to check permissions here because they've already been checked for the ability to even activate.
          */
-        if (mcMMOPlayer.getAbilityMode(SuperAbilityType.TREE_FELLER) && BlockUtils.isLog(blockState) && Config.getInstance().getTreeFellerSoundsEnabled()) {
+        if (mcMMOPlayer.getSuperAbilityManager().getAbilityMode(SuperAbilityType.TREE_FELLER) && BlockUtils.isLog(blockState) && Config.getInstance().getTreeFellerSoundsEnabled()) {
             SoundManager.sendSound(player, blockState.getLocation(), SoundType.FIZZ);
         }
     }
@@ -578,12 +578,12 @@ public class BlockListener implements Listener {
          *
          * We don't need to check permissions here because they've already been checked for the ability to even activate.
          */
-        if (mcMMOPlayer.getAbilityMode(SuperAbilityType.GREEN_TERRA) && BlockUtils.canMakeMossy(blockState)) {
+        if (mcMMOPlayer.getSuperAbilityManager().getAbilityMode(SuperAbilityType.GREEN_TERRA) && BlockUtils.canMakeMossy(blockState)) {
             if (mcMMOPlayer.getHerbalismManager().processGreenTerraBlockConversion(blockState)) {
                 blockState.update(true);
             }
         }
-        else if (mcMMOPlayer.getAbilityMode(SuperAbilityType.BERSERK) && (heldItem.getType() == Material.AIR || Config.getInstance().getUnarmedItemsAsUnarmed())) {
+        else if (mcMMOPlayer.getSuperAbilityManager().getAbilityMode(SuperAbilityType.BERSERK) && (heldItem.getType() == Material.AIR || Config.getInstance().getUnarmedItemsAsUnarmed())) {
             if (mcMMOPlayer.getUnarmedManager().canUseBlockCracker() && BlockUtils.affectedByBlockCracker(blockState)) {
                 if (EventUtils.simulateBlockBreak(block, player, true) && mcMMOPlayer.getUnarmedManager().blockCrackerCheck(blockState)) {
                     blockState.update();
@@ -682,11 +682,11 @@ public class BlockListener implements Listener {
 
     private void cleanupAbilityTools(Player player, McMMOPlayer mcMMOPlayer, BlockState blockState, ItemStack heldItem) {
         if (HiddenConfig.getInstance().useEnchantmentBuffs()) {
-            if ((ItemUtils.isPickaxe(heldItem) && !mcMMOPlayer.getAbilityMode(SuperAbilityType.SUPER_BREAKER)) || (ItemUtils.isShovel(heldItem) && !mcMMOPlayer.getAbilityMode(SuperAbilityType.GIGA_DRILL_BREAKER))) {
+            if ((ItemUtils.isPickaxe(heldItem) && !mcMMOPlayer.getSuperAbilityManager().getAbilityMode(SuperAbilityType.SUPER_BREAKER)) || (ItemUtils.isShovel(heldItem) && !mcMMOPlayer.getSuperAbilityManager().getAbilityMode(SuperAbilityType.GIGA_DRILL_BREAKER))) {
                 SkillUtils.removeAbilityBuff(heldItem);
             }
         } else {
-            if ((mcMMOPlayer.getAbilityMode(SuperAbilityType.SUPER_BREAKER) && !BlockUtils.affectedBySuperBreaker(blockState)) || (mcMMOPlayer.getAbilityMode(SuperAbilityType.GIGA_DRILL_BREAKER) && !BlockUtils.affectedByGigaDrillBreaker(blockState))) {
+            if ((mcMMOPlayer.getSuperAbilityManager().getAbilityMode(SuperAbilityType.SUPER_BREAKER) && !BlockUtils.affectedBySuperBreaker(blockState)) || (mcMMOPlayer.getSuperAbilityManager().getAbilityMode(SuperAbilityType.GIGA_DRILL_BREAKER) && !BlockUtils.affectedByGigaDrillBreaker(blockState))) {
                 SkillUtils.handleAbilitySpeedDecrease(player);
             }
         }

+ 14 - 14
src/main/java/com/gmail/nossr50/listeners/PlayerListener.java

@@ -772,15 +772,15 @@ public class PlayerListener implements Listener {
                 if (BlockUtils.canActivateTools(blockState)) {
                     if (Config.getInstance().getAbilitiesEnabled()) {
                         if (BlockUtils.canActivateHerbalism(blockState)) {
-                            mcMMOPlayer.processAbilityActivation(PrimarySkillType.HERBALISM);
+                            mcMMOPlayer.getSuperAbilityManager().processAbilityActivation(PrimarySkillType.HERBALISM);
                         }
 
-                        mcMMOPlayer.processAbilityActivation(PrimarySkillType.AXES);
-                        mcMMOPlayer.processAbilityActivation(PrimarySkillType.EXCAVATION);
-                        mcMMOPlayer.processAbilityActivation(PrimarySkillType.MINING);
-                        mcMMOPlayer.processAbilityActivation(PrimarySkillType.SWORDS);
-                        mcMMOPlayer.processAbilityActivation(PrimarySkillType.UNARMED);
-                        mcMMOPlayer.processAbilityActivation(PrimarySkillType.WOODCUTTING);
+                        mcMMOPlayer.getSuperAbilityManager().processAbilityActivation(PrimarySkillType.AXES);
+                        mcMMOPlayer.getSuperAbilityManager().processAbilityActivation(PrimarySkillType.EXCAVATION);
+                        mcMMOPlayer.getSuperAbilityManager().processAbilityActivation(PrimarySkillType.MINING);
+                        mcMMOPlayer.getSuperAbilityManager().processAbilityActivation(PrimarySkillType.SWORDS);
+                        mcMMOPlayer.getSuperAbilityManager().processAbilityActivation(PrimarySkillType.UNARMED);
+                        mcMMOPlayer.getSuperAbilityManager().processAbilityActivation(PrimarySkillType.WOODCUTTING);
                     }
 
                     ChimaeraWing.activationCheck(player);
@@ -826,13 +826,13 @@ public class PlayerListener implements Listener {
                 
                 /* ACTIVATION CHECKS */
                 if (Config.getInstance().getAbilitiesEnabled()) {
-                    mcMMOPlayer.processAbilityActivation(PrimarySkillType.AXES);
-                    mcMMOPlayer.processAbilityActivation(PrimarySkillType.EXCAVATION);
-                    mcMMOPlayer.processAbilityActivation(PrimarySkillType.HERBALISM);
-                    mcMMOPlayer.processAbilityActivation(PrimarySkillType.MINING);
-                    mcMMOPlayer.processAbilityActivation(PrimarySkillType.SWORDS);
-                    mcMMOPlayer.processAbilityActivation(PrimarySkillType.UNARMED);
-                    mcMMOPlayer.processAbilityActivation(PrimarySkillType.WOODCUTTING);
+                    mcMMOPlayer.getSuperAbilityManager().processAbilityActivation(PrimarySkillType.AXES);
+                    mcMMOPlayer.getSuperAbilityManager().processAbilityActivation(PrimarySkillType.EXCAVATION);
+                    mcMMOPlayer.getSuperAbilityManager().processAbilityActivation(PrimarySkillType.HERBALISM);
+                    mcMMOPlayer.getSuperAbilityManager().processAbilityActivation(PrimarySkillType.MINING);
+                    mcMMOPlayer.getSuperAbilityManager().processAbilityActivation(PrimarySkillType.SWORDS);
+                    mcMMOPlayer.getSuperAbilityManager().processAbilityActivation(PrimarySkillType.UNARMED);
+                    mcMMOPlayer.getSuperAbilityManager().processAbilityActivation(PrimarySkillType.WOODCUTTING);
                 }
 
                 /* ITEM CHECKS */

+ 2 - 2
src/main/java/com/gmail/nossr50/runnables/skills/AbilityCooldownTask.java

@@ -17,11 +17,11 @@ public class AbilityCooldownTask extends BukkitRunnable {
 
     @Override
     public void run() {
-        if (!mcMMOPlayer.getPlayer().isOnline() || mcMMOPlayer.getAbilityInformed(ability)) {
+        if (!mcMMOPlayer.getPlayer().isOnline() || mcMMOPlayer.getSuperAbilityManager().getAbilityInformed(ability)) {
             return;
         }
 
-        mcMMOPlayer.setAbilityInformed(ability, true);
+        mcMMOPlayer.getSuperAbilityManager().setAbilityInformed(ability, true);
 
         NotificationManager.sendPlayerInformation(mcMMOPlayer.getPlayer(), NotificationType.ABILITY_REFRESHED, ability.getAbilityRefresh());
         //mcMMOPlayer.getPlayer().sendMessage(ability.getAbilityRefresh());

+ 3 - 3
src/main/java/com/gmail/nossr50/runnables/skills/AbilityDisableTask.java

@@ -28,7 +28,7 @@ public class AbilityDisableTask extends BukkitRunnable {
 
     @Override
     public void run() {
-        if (!mcMMOPlayer.getAbilityMode(ability)) {
+        if (!mcMMOPlayer.getSuperAbilityManager().getAbilityMode(ability)) {
             return;
         }
 
@@ -52,8 +52,8 @@ public class AbilityDisableTask extends BukkitRunnable {
 
         EventUtils.callAbilityDeactivateEvent(player, ability);
 
-        mcMMOPlayer.setAbilityMode(ability, false);
-        mcMMOPlayer.setAbilityInformed(ability, false);
+        mcMMOPlayer.getSuperAbilityManager().setAbilityMode(ability, false);
+        mcMMOPlayer.getSuperAbilityManager().setAbilityInformed(ability, false);
 
         ParticleEffectUtils.playAbilityDisabledEffect(player);
 

+ 2 - 2
src/main/java/com/gmail/nossr50/runnables/skills/ToolLowerTask.java

@@ -18,11 +18,11 @@ public class ToolLowerTask extends BukkitRunnable {
 
     @Override
     public void run() {
-        if (!mcMMOPlayer.getToolPreparationMode(tool)) {
+        if (!mcMMOPlayer.getSuperAbilityManager().getToolPreparationMode(tool)) {
             return;
         }
 
-        mcMMOPlayer.setToolPreparationMode(tool, false);
+        mcMMOPlayer.getSuperAbilityManager().setToolPreparationMode(tool, false);
 
         if (Config.getInstance().getAbilityMessagesEnabled()) {
             NotificationManager.sendPlayerInformation(mcMMOPlayer.getPlayer(), NotificationType.TOOL, tool.getLowerTool());

+ 2 - 2
src/main/java/com/gmail/nossr50/skills/axes/AxesManager.java

@@ -57,11 +57,11 @@ public class AxesManager extends SkillManager {
         if(!RankUtils.hasUnlockedSubskill(getPlayer(), SubSkillType.AXES_SKULL_SPLITTER))
             return false;
 
-        return target.isValid() && mcMMOPlayer.getAbilityMode(SuperAbilityType.SKULL_SPLITTER) && Permissions.skullSplitter(getPlayer());
+        return target.isValid() && mcMMOPlayer.getSuperAbilityManager().getAbilityMode(SuperAbilityType.SKULL_SPLITTER) && Permissions.skullSplitter(getPlayer());
     }
 
     public boolean canActivateAbility() {
-        return mcMMOPlayer.getToolPreparationMode(ToolType.AXE) && Permissions.skullSplitter(getPlayer());
+        return mcMMOPlayer.getSuperAbilityManager().getToolPreparationMode(ToolType.AXE) && Permissions.skullSplitter(getPlayer());
     }
 
     /**

+ 4 - 4
src/main/java/com/gmail/nossr50/skills/herbalism/HerbalismManager.java

@@ -78,15 +78,15 @@ public class HerbalismManager extends SkillManager {
     }
 
     public boolean canGreenTerraBlock(BlockState blockState) {
-        return mcMMOPlayer.getAbilityMode(SuperAbilityType.GREEN_TERRA) && BlockUtils.canMakeMossy(blockState);
+        return mcMMOPlayer.getSuperAbilityManager().getAbilityMode(SuperAbilityType.GREEN_TERRA) && BlockUtils.canMakeMossy(blockState);
     }
 
     public boolean canActivateAbility() {
-        return mcMMOPlayer.getToolPreparationMode(ToolType.HOE) && Permissions.greenTerra(getPlayer());
+        return mcMMOPlayer.getSuperAbilityManager().getToolPreparationMode(ToolType.HOE) && Permissions.greenTerra(getPlayer());
     }
 
     public boolean isGreenTerraActive() {
-        return mcMMOPlayer.getAbilityMode(SuperAbilityType.GREEN_TERRA);
+        return mcMMOPlayer.getSuperAbilityManager().getAbilityMode(SuperAbilityType.GREEN_TERRA);
     }
 
     /**
@@ -328,7 +328,7 @@ public class HerbalismManager extends SkillManager {
 
     public void markForBonusDrops(BlockState brokenPlantState) {
         //Add metadata to mark this block for double or triple drops
-        boolean awardTriple = mcMMOPlayer.getAbilityMode(SuperAbilityType.GREEN_TERRA);
+        boolean awardTriple = mcMMOPlayer.getSuperAbilityManager().getAbilityMode(SuperAbilityType.GREEN_TERRA);
         BlockUtils.markDropsAsBonus(brokenPlantState, awardTriple);
     }
 

+ 3 - 3
src/main/java/com/gmail/nossr50/skills/mining/MiningManager.java

@@ -81,7 +81,7 @@ public class MiningManager extends SkillManager {
             return;
         }
 
-        if (mcMMOPlayer.getAbilityMode(skill.getAbility())) {
+        if (mcMMOPlayer.getSuperAbilityManager().getAbilityMode(skill.getAbility())) {
             SkillUtils.handleDurabilityChange(getPlayer().getInventory().getItemInMainHand(), Config.getInstance().getAbilityToolDamage());
         }
 
@@ -95,7 +95,7 @@ public class MiningManager extends SkillManager {
 
         //TODO: Make this readable
         if (RandomChanceUtil.checkRandomChanceExecutionSuccess(getPlayer(), SubSkillType.MINING_DOUBLE_DROPS, true)) {
-            BlockUtils.markDropsAsBonus(blockState, mcMMOPlayer.getAbilityMode(skill.getAbility()));
+            BlockUtils.markDropsAsBonus(blockState, mcMMOPlayer.getSuperAbilityManager().getAbilityMode(skill.getAbility()));
         }
     }
 
@@ -122,7 +122,7 @@ public class MiningManager extends SkillManager {
         targetBlock.setType(Material.AIR);
 
         mcMMOPlayer.setAbilityDATS(SuperAbilityType.BLAST_MINING, System.currentTimeMillis());
-        mcMMOPlayer.setAbilityInformed(SuperAbilityType.BLAST_MINING, false);
+        mcMMOPlayer.getSuperAbilityManager().setAbilityInformed(SuperAbilityType.BLAST_MINING, false);
         new AbilityCooldownTask(mcMMOPlayer, SuperAbilityType.BLAST_MINING).runTaskLater(mcMMO.p, SuperAbilityType.BLAST_MINING.getCooldown() * Misc.TICK_CONVERSION_FACTOR);
     }
 

+ 2 - 2
src/main/java/com/gmail/nossr50/skills/swords/SwordsManager.java

@@ -29,7 +29,7 @@ public class SwordsManager extends SkillManager {
     }
 
     public boolean canActivateAbility() {
-        return mcMMOPlayer.getToolPreparationMode(ToolType.SWORD) && Permissions.serratedStrikes(getPlayer());
+        return mcMMOPlayer.getSuperAbilityManager().getToolPreparationMode(ToolType.SWORD) && Permissions.serratedStrikes(getPlayer());
     }
 
     public boolean canUseStab() {
@@ -51,7 +51,7 @@ public class SwordsManager extends SkillManager {
         if(!RankUtils.hasUnlockedSubskill(getPlayer(), SubSkillType.SWORDS_SERRATED_STRIKES))
             return false;
 
-        return mcMMOPlayer.getAbilityMode(SuperAbilityType.SERRATED_STRIKES);
+        return mcMMOPlayer.getSuperAbilityManager().getAbilityMode(SuperAbilityType.SERRATED_STRIKES);
     }
 
     /**

+ 2 - 2
src/main/java/com/gmail/nossr50/skills/unarmed/UnarmedManager.java

@@ -32,7 +32,7 @@ public class UnarmedManager extends SkillManager {
     }
 
     public boolean canActivateAbility() {
-        return mcMMOPlayer.getToolPreparationMode(ToolType.FISTS) && Permissions.berserk(getPlayer());
+        return mcMMOPlayer.getSuperAbilityManager().getToolPreparationMode(ToolType.FISTS) && Permissions.berserk(getPlayer());
     }
 
     public boolean canUseIronArm() {
@@ -43,7 +43,7 @@ public class UnarmedManager extends SkillManager {
     }
 
     public boolean canUseBerserk() {
-        return mcMMOPlayer.getAbilityMode(SuperAbilityType.BERSERK);
+        return mcMMOPlayer.getSuperAbilityManager().getAbilityMode(SuperAbilityType.BERSERK);
     }
 
     public boolean canDisarm(LivingEntity target) {

+ 1 - 1
src/main/java/com/gmail/nossr50/skills/woodcutting/WoodcuttingManager.java

@@ -60,7 +60,7 @@ public class WoodcuttingManager extends SkillManager {
     }
 
     public boolean canUseTreeFeller(ItemStack heldItem) {
-        return mcMMOPlayer.getAbilityMode(SuperAbilityType.TREE_FELLER)
+        return mcMMOPlayer.getSuperAbilityManager().getAbilityMode(SuperAbilityType.TREE_FELLER)
                 && ItemUtils.isAxe(heldItem);
     }
 

+ 7 - 5
src/main/java/com/gmail/nossr50/util/ItemUtils.java

@@ -4,14 +4,16 @@ import com.gmail.nossr50.config.Config;
 import com.gmail.nossr50.config.party.ItemWeightConfig;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.mcMMO;
-import org.bukkit.Bukkit;
 import org.bukkit.ChatColor;
 import org.bukkit.Material;
-import org.bukkit.NamespacedKey;
 import org.bukkit.entity.Player;
-import org.bukkit.inventory.*;
+import org.bukkit.inventory.FurnaceRecipe;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.Recipe;
 import org.bukkit.inventory.meta.ItemMeta;
 
+import static org.bukkit.Material.AIR;
+
 public final class ItemUtils {
     private ItemUtils() {}
 
@@ -132,7 +134,7 @@ public final class ItemUtils {
             return !isMinecraftTool(item);
         }
 
-        return item.getType() == Material.AIR;
+        return item.getType() == AIR;
     }
 
     /**
@@ -310,7 +312,7 @@ public final class ItemUtils {
      * @return True if the item can be shared.
      */
     public static boolean isSharable(ItemStack item) {
-        if (item == null || item.getType() == Material.AIR) {
+        if (item == null || item.getType() == AIR) {
             return false;
         }
 

+ 296 - 0
src/main/java/com/gmail/nossr50/util/input/SuperAbilityManager.java

@@ -0,0 +1,296 @@
+package com.gmail.nossr50.util.input;
+
+import com.gmail.nossr50.config.AdvancedConfig;
+import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.datatypes.interactions.NotificationType;
+import com.gmail.nossr50.datatypes.player.McMMOPlayer;
+import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
+import com.gmail.nossr50.datatypes.skills.SuperAbilityType;
+import com.gmail.nossr50.datatypes.skills.ToolType;
+import com.gmail.nossr50.mcMMO;
+import com.gmail.nossr50.runnables.skills.AbilityDisableTask;
+import com.gmail.nossr50.runnables.skills.ToolLowerTask;
+import com.gmail.nossr50.util.EventUtils;
+import com.gmail.nossr50.util.Misc;
+import com.gmail.nossr50.util.player.NotificationManager;
+import com.gmail.nossr50.util.skills.PerksUtils;
+import com.gmail.nossr50.util.skills.RankUtils;
+import com.gmail.nossr50.util.skills.SkillUtils;
+import com.gmail.nossr50.util.sounds.SoundManager;
+import com.gmail.nossr50.util.sounds.SoundType;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.ItemStack;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class SuperAbilityManager {
+
+    private final McMMOPlayer mmoPlayer;
+    private final Player player;
+
+    private final Map<SuperAbilityType, Boolean> abilityMode     = new HashMap<>();
+    private final Map<SuperAbilityType, Boolean> abilityInformed = new HashMap<>();
+
+    private boolean abilityActivationPermission = true;
+
+    private final Map<ToolType, Boolean> toolMode = new HashMap<>();
+
+    public SuperAbilityManager(McMMOPlayer mmoPlayer) {
+        this.mmoPlayer = mmoPlayer;
+        this.player = mmoPlayer.getPlayer();
+
+        for (SuperAbilityType superAbilityType : SuperAbilityType.values()) {
+            abilityMode.put(superAbilityType, false);
+            abilityInformed.put(superAbilityType, true); // This is intended
+        }
+
+        for (ToolType toolType : ToolType.values()) {
+            toolMode.put(toolType, false);
+        }
+    }
+
+    public void processAbilityActivation(PrimarySkillType skill) {
+        Player player = mmoPlayer.getPlayer();
+
+        if (!skill.getPermissions(player)) {
+            return;
+        }
+
+        if (Config.getInstance().getAbilitiesOnlyActivateWhenSneaking() && !player.isSneaking()) {
+            return;
+        }
+
+        ItemStack inHand = player.getInventory().getItemInMainHand();
+
+        if (mcMMO.getModManager().isCustomTool(inHand) && !mcMMO.getModManager().getTool(inHand).isAbilityEnabled()) {
+            return;
+        }
+
+        if (!getAbilityActivationPermission()) {
+            return;
+        }
+
+        //Don't activate 2 abilities at once
+        for (SuperAbilityType superAbilityType : SuperAbilityType.values()) {
+            if (getAbilityMode(superAbilityType)) {
+                return;
+            }
+        }
+
+        SuperAbilityType ability = skill.getAbility();
+        ToolType tool = skill.getTool();
+
+        /*
+         * Woodcutting & Axes need to be treated differently.
+         * Basically the tool always needs to ready and we check to see if the cooldown is over when the user takes action
+         */
+        if (tool.inHand(inHand) && !getToolPreparationMode(tool)) {
+            if (skill != PrimarySkillType.WOODCUTTING && skill != PrimarySkillType.AXES) {
+                int timeRemaining = calculateTimeRemaining(ability);
+
+                if (!getAbilityMode(ability) && timeRemaining > 0) {
+                    NotificationManager.sendPlayerInformation(player, NotificationType.ABILITY_COOLDOWN, "Skills.TooTired", String.valueOf(timeRemaining));
+                    return;
+                }
+            }
+
+            if (Config.getInstance().getAbilityMessagesEnabled()) {
+                NotificationManager.sendPlayerInformation(player, NotificationType.TOOL, tool.getRaiseTool());
+                SoundManager.sendSound(player, player.getLocation(), SoundType.TOOL_READY);
+            }
+
+            setToolPreparationMode(tool, true);
+            new ToolLowerTask(mmoPlayer, tool).runTaskLater(mcMMO.p, 4 * Misc.TICK_CONVERSION_FACTOR);
+        }
+    }
+
+    /**
+     * Check to see if an ability can be activated.
+     *
+     * @param primarySkillType The primarySkillType the ability is based on
+     */
+    public void checkAbilityActivation(PrimarySkillType primarySkillType) {
+        ToolType tool = primarySkillType.getTool();
+        SuperAbilityType ability = primarySkillType.getAbility();
+
+        if (getAbilityMode(ability) || !ability.getPermissions(player)) {
+            return;
+        }
+
+        //TODO: This is hacky and temporary solution until skills are move to the new system
+        //Potential problems with this include skills with two super abilities (ie mining)
+        if(!primarySkillType.isSuperAbilityUnlocked(player))
+        {
+            int diff = RankUtils.getSuperAbilityUnlockRequirement(primarySkillType.getAbility()) - mmoPlayer.getSkillLevel(primarySkillType);
+
+            //Inform the player they are not yet skilled enough
+            NotificationManager.sendPlayerInformation(player, NotificationType.ABILITY_COOLDOWN, "Skills.AbilityGateRequirementFail", String.valueOf(diff), primarySkillType.getName());
+            return;
+        }
+
+        int timeRemaining = calculateTimeRemaining(ability);
+
+        if (timeRemaining > 0) {
+            /*
+             * Axes and Woodcutting are odd because they share the same tool.
+             * We show them the too tired message when they take action.
+             */
+            if (primarySkillType == PrimarySkillType.WOODCUTTING || primarySkillType == PrimarySkillType.AXES) {
+                NotificationManager.sendPlayerInformation(player, NotificationType.ABILITY_COOLDOWN, "Skills.TooTired", String.valueOf(timeRemaining));
+                //SoundManager.sendSound(player, player.getLocation(), SoundType.TIRED);
+            }
+
+            return;
+        }
+
+        if (EventUtils.callPlayerAbilityActivateEvent(player, primarySkillType).isCancelled()) {
+            return;
+        }
+
+        //These values change depending on whether or not the server is in retro mode
+        int abilityLengthVar = AdvancedConfig.getInstance().getAbilityLength();
+        int abilityLengthCap = AdvancedConfig.getInstance().getAbilityLengthCap();
+
+        int ticks;
+
+        //Ability cap of 0 or below means no cap
+        if(abilityLengthCap > 0)
+        {
+            ticks = PerksUtils.handleActivationPerks(player, 2 + (Math.min(abilityLengthCap, mmoPlayer.getSkillLevel(primarySkillType)) / abilityLengthVar), ability.getMaxLength());
+        } else {
+            ticks = PerksUtils.handleActivationPerks(player, 2 + (mmoPlayer.getSkillLevel(primarySkillType) / abilityLengthVar), ability.getMaxLength());
+        }
+
+        if (mmoPlayer.useChatNotifications()) {
+            NotificationManager.sendPlayerInformation(player, NotificationType.SUPER_ABILITY, ability.getAbilityOn());
+            //player.sendMessage(ability.getAbilityOn());
+        }
+
+        if (AdvancedConfig.getInstance().sendAbilityNotificationToOtherPlayers()) {
+            SkillUtils.sendSkillMessage(player, NotificationType.SUPER_ABILITY_ALERT_OTHERS, ability.getAbilityPlayer());
+        }
+
+        //Sounds
+        SoundManager.worldSendSound(player.getWorld(), player.getLocation(), SoundType.ABILITY_ACTIVATED_GENERIC);
+
+        // Enable the ability
+        mmoPlayer.getProfile().setAbilityDATS(ability, System.currentTimeMillis() + (ticks * Misc.TIME_CONVERSION_FACTOR));
+        setAbilityMode(ability, true);
+
+        if (ability == SuperAbilityType.SUPER_BREAKER || ability == SuperAbilityType.GIGA_DRILL_BREAKER) {
+            SkillUtils.handleAbilitySpeedIncrease(player);
+        }
+
+        setToolPreparationMode(tool, false);
+        new AbilityDisableTask(mmoPlayer, ability).runTaskLater(mcMMO.p, ticks * Misc.TICK_CONVERSION_FACTOR);
+    }
+
+    /*
+     * Abilities
+     */
+
+    /**
+     * Reset the mode of all abilities.
+     */
+    public void resetSuperAbilities() {
+        for (SuperAbilityType ability : SuperAbilityType.values()) {
+            // Correctly disable and handle any special deactivate code
+            new AbilityDisableTask(mmoPlayer, ability).run();
+        }
+    }
+
+    /**
+     * Get the mode of an ability.
+     *
+     * @param ability The ability to check
+     * @return true if the ability is enabled, false otherwise
+     */
+    public boolean getAbilityMode(SuperAbilityType ability) {
+        return abilityMode.get(ability);
+    }
+
+    /**
+     * Set the mode of an ability.
+     *
+     * @param ability The ability to check
+     * @param isActive True if the ability is active, false otherwise
+     */
+    public void setAbilityMode(SuperAbilityType ability, boolean isActive) {
+        abilityMode.put(ability, isActive);
+    }
+
+    /**
+     * Get the informed state of an ability
+     *
+     * @param ability The ability to check
+     * @return true if the ability is informed, false otherwise
+     */
+    public boolean getAbilityInformed(SuperAbilityType ability) {
+        return abilityInformed.get(ability);
+    }
+
+    /**
+     * Set the informed state of an ability.
+     *
+     * @param ability The ability to check
+     * @param isInformed True if the ability is informed, false otherwise
+     */
+    public void setAbilityInformed(SuperAbilityType ability, boolean isInformed) {
+        abilityInformed.put(ability, isInformed);
+    }
+
+    /**
+     * Get the current prep mode of a tool.
+     *
+     * @param tool Tool to get the mode for
+     * @return true if the tool is prepped, false otherwise
+     */
+    public boolean getToolPreparationMode(ToolType tool) {
+        return toolMode.get(tool);
+    }
+
+    public boolean getAbilityActivationPermission() {
+        return abilityActivationPermission;
+    }
+
+    public void toggleAbilityActivationPermission() {
+        abilityActivationPermission = !abilityActivationPermission;
+    }
+
+    /*
+     * Tools
+     */
+
+    /**
+     * Reset the prep modes of all tools.
+     */
+    public void resetToolPrepMode() {
+        for (ToolType tool : ToolType.values()) {
+            setToolPreparationMode(tool, false);
+        }
+    }
+
+    /**
+     * Set the current prep mode of a tool.
+     *
+     * @param tool Tool to set the mode for
+     * @param isPrepared true if the tool should be prepped, false otherwise
+     */
+    public void setToolPreparationMode(ToolType tool, boolean isPrepared) {
+        toolMode.put(tool, isPrepared);
+    }
+
+    /**
+     * Calculate the time remaining until the superAbilityType's cooldown expires.
+     *
+     * @param superAbilityType SuperAbilityType whose cooldown to check
+     *
+     * @return the number of seconds remaining before the cooldown expires
+     */
+    public int calculateTimeRemaining(SuperAbilityType superAbilityType) {
+        long deactivatedTimestamp = mmoPlayer.getProfile().getAbilityDATS(superAbilityType) * Misc.TIME_CONVERSION_FACTOR;
+        return (int) (((deactivatedTimestamp + (PerksUtils.handleCooldownPerks(mmoPlayer.getPlayer(), superAbilityType.getCooldown()) * Misc.TIME_CONVERSION_FACTOR)) - System.currentTimeMillis()) / Misc.TIME_CONVERSION_FACTOR);
+    }
+
+}

+ 4 - 0
src/main/java/com/gmail/nossr50/util/input/SuperAbilityState.java

@@ -0,0 +1,4 @@
+package com.gmail.nossr50.util.input;
+
+public enum SuperAbilityState {
+}

+ 3 - 3
src/main/java/com/gmail/nossr50/util/skills/CombatUtils.java

@@ -63,7 +63,7 @@ public final class CombatUtils {
         Map<DamageModifier, Double> modifiers = getModifiers(event);
 
         if (swordsManager.canActivateAbility()) {
-            mcMMOPlayer.checkAbilityActivation(PrimarySkillType.SWORDS);
+            mcMMOPlayer.getSuperAbilityManager().checkAbilityActivation(PrimarySkillType.SWORDS);
         }
 
         if(target.getHealth() - event.getFinalDamage() >= 1)
@@ -156,7 +156,7 @@ public final class CombatUtils {
         AxesManager axesManager = mcMMOPlayer.getAxesManager();
 
         if (axesManager.canActivateAbility()) {
-            mcMMOPlayer.checkAbilityActivation(PrimarySkillType.AXES);
+            mcMMOPlayer.getSuperAbilityManager().checkAbilityActivation(PrimarySkillType.AXES);
         }
 
         if (axesManager.canUseAxeMastery()) {
@@ -205,7 +205,7 @@ public final class CombatUtils {
         UnarmedManager unarmedManager = mcMMOPlayer.getUnarmedManager();
 
         if (unarmedManager.canActivateAbility()) {
-            mcMMOPlayer.checkAbilityActivation(PrimarySkillType.UNARMED);
+            mcMMOPlayer.getSuperAbilityManager().checkAbilityActivation(PrimarySkillType.UNARMED);
         }
 
         //Only execute bonuses if the player is not spamming

+ 1 - 1
src/main/java/com/gmail/nossr50/util/skills/SkillUtils.java

@@ -204,7 +204,7 @@ public class SkillUtils {
             if(mcMMOPlayer == null)
                 return;
 
-            PrimarySkillType skill = mcMMOPlayer.getAbilityMode(SuperAbilityType.SUPER_BREAKER) ? PrimarySkillType.MINING : PrimarySkillType.EXCAVATION;
+            PrimarySkillType skill = mcMMOPlayer.getSuperAbilityManager().getAbilityMode(SuperAbilityType.SUPER_BREAKER) ? PrimarySkillType.MINING : PrimarySkillType.EXCAVATION;
 
             int abilityLengthVar = AdvancedConfig.getInstance().getAbilityLength();
             int abilityLengthCap = AdvancedConfig.getInstance().getAbilityLengthCap();