소스 검색

MASSIVE Permissions overhaul. Added a handful of new permissions,
renamed a few more. Changed Green Terra to handle blocks based on
perms rather than the config file.

For more details, read the diff.

GJ 12 년 전
부모
커밋
701822c69f
73개의 변경된 파일478개의 추가작업 그리고 963개의 파일을 삭제
  1. 1 0
      Changelog.txt
  2. 13 12
      src/main/java/com/gmail/nossr50/commands/CommandHelper.java
  3. 1 1
      src/main/java/com/gmail/nossr50/commands/CommandRegistrationHelper.java
  4. 3 2
      src/main/java/com/gmail/nossr50/commands/admin/AddlevelsCommand.java
  5. 3 2
      src/main/java/com/gmail/nossr50/commands/admin/AddxpCommand.java
  6. 5 4
      src/main/java/com/gmail/nossr50/commands/admin/HardcoreCommand.java
  7. 3 2
      src/main/java/com/gmail/nossr50/commands/admin/McgodCommand.java
  8. 3 2
      src/main/java/com/gmail/nossr50/commands/admin/McrefreshCommand.java
  9. 3 2
      src/main/java/com/gmail/nossr50/commands/admin/MmoeditCommand.java
  10. 8 7
      src/main/java/com/gmail/nossr50/commands/admin/SkillresetCommand.java
  11. 5 4
      src/main/java/com/gmail/nossr50/commands/admin/VampirismCommand.java
  12. 3 2
      src/main/java/com/gmail/nossr50/commands/admin/XprateCommand.java
  13. 4 7
      src/main/java/com/gmail/nossr50/commands/player/InspectCommand.java
  14. 3 2
      src/main/java/com/gmail/nossr50/commands/player/McabilityCommand.java
  15. 17 10
      src/main/java/com/gmail/nossr50/commands/player/McmmoCommand.java
  16. 5 4
      src/main/java/com/gmail/nossr50/commands/player/McrankCommand.java
  17. 2 1
      src/main/java/com/gmail/nossr50/commands/player/MctopCommand.java
  18. 0 5
      src/main/java/com/gmail/nossr50/config/Config.java
  19. 2 1
      src/main/java/com/gmail/nossr50/datatypes/McMMOPlayer.java
  20. 16 16
      src/main/java/com/gmail/nossr50/listeners/BlockListener.java
  21. 8 8
      src/main/java/com/gmail/nossr50/listeners/PlayerListener.java
  22. 0 5
      src/main/java/com/gmail/nossr50/party/commands/PartyAcceptCommand.java
  23. 0 5
      src/main/java/com/gmail/nossr50/party/commands/PartyChangeOwnerCommand.java
  24. 1 5
      src/main/java/com/gmail/nossr50/party/commands/PartyChangePasswordCommand.java
  25. 8 1
      src/main/java/com/gmail/nossr50/party/commands/PartyCommand.java
  26. 0 5
      src/main/java/com/gmail/nossr50/party/commands/PartyCreateCommand.java
  27. 0 5
      src/main/java/com/gmail/nossr50/party/commands/PartyDisbandCommand.java
  28. 0 5
      src/main/java/com/gmail/nossr50/party/commands/PartyExpShareCommand.java
  29. 0 5
      src/main/java/com/gmail/nossr50/party/commands/PartyInviteCommand.java
  30. 0 5
      src/main/java/com/gmail/nossr50/party/commands/PartyItemShareCommand.java
  31. 0 5
      src/main/java/com/gmail/nossr50/party/commands/PartyJoinCommand.java
  32. 0 5
      src/main/java/com/gmail/nossr50/party/commands/PartyKickCommand.java
  33. 3 2
      src/main/java/com/gmail/nossr50/party/commands/PartyLockCommand.java
  34. 0 5
      src/main/java/com/gmail/nossr50/party/commands/PartyQuitCommand.java
  35. 0 5
      src/main/java/com/gmail/nossr50/party/commands/PartyRenameCommand.java
  36. 3 3
      src/main/java/com/gmail/nossr50/party/commands/PtpCommand.java
  37. 3 1
      src/main/java/com/gmail/nossr50/runnables/McTopAsync.java
  38. 4 3
      src/main/java/com/gmail/nossr50/skills/SkillCommand.java
  39. 7 2
      src/main/java/com/gmail/nossr50/skills/SkillManager.java
  40. 2 2
      src/main/java/com/gmail/nossr50/skills/archery/ArcheryCommand.java
  41. 1 1
      src/main/java/com/gmail/nossr50/skills/archery/ArcheryManager.java
  42. 3 3
      src/main/java/com/gmail/nossr50/skills/axes/AxesCommand.java
  43. 2 2
      src/main/java/com/gmail/nossr50/skills/excavation/Excavation.java
  44. 1 1
      src/main/java/com/gmail/nossr50/skills/excavation/ExcavationCommand.java
  45. 7 5
      src/main/java/com/gmail/nossr50/skills/fishing/Fishing.java
  46. 3 3
      src/main/java/com/gmail/nossr50/skills/fishing/FishingCommand.java
  47. 2 2
      src/main/java/com/gmail/nossr50/skills/fishing/ShakeMob.java
  48. 13 18
      src/main/java/com/gmail/nossr50/skills/herbalism/Herbalism.java
  49. 1 14
      src/main/java/com/gmail/nossr50/skills/herbalism/HerbalismBlock.java
  50. 5 3
      src/main/java/com/gmail/nossr50/skills/herbalism/HerbalismCommand.java
  51. 2 2
      src/main/java/com/gmail/nossr50/skills/mining/MiningCommand.java
  52. 1 1
      src/main/java/com/gmail/nossr50/skills/mining/MiningManager.java
  53. 3 3
      src/main/java/com/gmail/nossr50/skills/repair/Repair.java
  54. 8 8
      src/main/java/com/gmail/nossr50/skills/repair/RepairCommand.java
  55. 3 3
      src/main/java/com/gmail/nossr50/skills/repair/RepairItemType.java
  56. 8 8
      src/main/java/com/gmail/nossr50/skills/repair/RepairMaterialType.java
  57. 1 1
      src/main/java/com/gmail/nossr50/skills/smelting/FluxMiningEventHandler.java
  58. 2 2
      src/main/java/com/gmail/nossr50/skills/smelting/SmeltResourceEventHandler.java
  59. 2 2
      src/main/java/com/gmail/nossr50/skills/smelting/SmeltingCommand.java
  60. 3 3
      src/main/java/com/gmail/nossr50/skills/smelting/SmeltingManager.java
  61. 1 1
      src/main/java/com/gmail/nossr50/skills/swords/SwordsCommand.java
  62. 2 2
      src/main/java/com/gmail/nossr50/skills/unarmed/UnarmedCommand.java
  63. 1 1
      src/main/java/com/gmail/nossr50/skills/unarmed/UnarmedManager.java
  64. 1 1
      src/main/java/com/gmail/nossr50/skills/utilities/AbilityType.java
  65. 12 12
      src/main/java/com/gmail/nossr50/skills/utilities/CombatTools.java
  66. 13 13
      src/main/java/com/gmail/nossr50/skills/utilities/PerksUtils.java
  67. 13 11
      src/main/java/com/gmail/nossr50/skills/utilities/SkillTools.java
  68. 2 2
      src/main/java/com/gmail/nossr50/skills/woodcutting/Woodcutting.java
  69. 1 1
      src/main/java/com/gmail/nossr50/skills/woodcutting/WoodcuttingCommand.java
  70. 2 1
      src/main/java/com/gmail/nossr50/spout/commands/XplockCommand.java
  71. 170 643
      src/main/java/com/gmail/nossr50/util/Permissions.java
  72. 0 5
      src/main/resources/config.yml
  73. 50 17
      src/main/resources/plugin.yml

+ 1 - 0
Changelog.txt

@@ -68,6 +68,7 @@ Version 1.4.00-dev
  = Fixed a bug where a new party leader wasn't appointed, after the previous party leader left
  = Fixed a bug where Disarm and Deflect had wrong values
  = Fixed Magic Hunter (Fishing ability) favoring certain enchants
+ ! Changed Green Terra blocks to be determined via permissions instead of the config file
  ! Config files are now backed up even when running in SQL mode
  ! Changed /p and /a to use /partychat and /adminchat as the default command name. The use of /p, /pc, /a, and /ac is still supported.
  ! We're now using Bukkit sounds instead of Spout sounds.

+ 13 - 12
src/main/java/com/gmail/nossr50/commands/CommandHelper.java

@@ -7,6 +7,7 @@ import com.gmail.nossr50.datatypes.PlayerProfile;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.skills.utilities.SkillTools;
 import com.gmail.nossr50.skills.utilities.SkillType;
+import com.gmail.nossr50.util.Permissions;
 
 public final class CommandHelper {
     private CommandHelper() {}
@@ -31,23 +32,23 @@ public final class CommandHelper {
         if (SkillTools.hasGatheringSkills(inspect)) {
             display.sendMessage(LocaleLoader.getString("Stats.Header.Gathering"));
 
-            if (inspect.hasPermission("mcmmo.skills.excavation")) {
+            if (Permissions.skillEnabled(inspect, SkillType.EXCAVATION)) {
                 display.sendMessage(LocaleLoader.getString("Skills.Stats", LocaleLoader.getString("Excavation.Listener"), profile.getSkillLevel(SkillType.EXCAVATION), profile.getSkillXpLevel(SkillType.EXCAVATION), profile.getXpToLevel(SkillType.EXCAVATION)));
             }
 
-            if (inspect.hasPermission("mcmmo.skills.fishing")) {
+            if (Permissions.skillEnabled(inspect, SkillType.FISHING)) {
                 display.sendMessage(LocaleLoader.getString("Skills.Stats", LocaleLoader.getString("Fishing.Listener"), profile.getSkillLevel(SkillType.FISHING), profile.getSkillXpLevel(SkillType.FISHING), profile.getXpToLevel(SkillType.FISHING)));
             }
 
-            if (inspect.hasPermission("mcmmo.skills.fishing")) {
+            if (Permissions.skillEnabled(inspect, SkillType.HERBALISM)) {
                 display.sendMessage(LocaleLoader.getString("Skills.Stats", LocaleLoader.getString("Herbalism.Listener"), profile.getSkillLevel(SkillType.HERBALISM), profile.getSkillXpLevel(SkillType.HERBALISM), profile.getXpToLevel(SkillType.HERBALISM)));
             }
 
-            if (inspect.hasPermission("mcmmo.skills.mining")) {
+            if (Permissions.skillEnabled(inspect, SkillType.MINING)) {
                 display.sendMessage(LocaleLoader.getString("Skills.Stats", LocaleLoader.getString("Mining.Listener"), profile.getSkillLevel(SkillType.MINING), profile.getSkillXpLevel(SkillType.MINING), profile.getXpToLevel(SkillType.MINING)));
             }
 
-            if (inspect.hasPermission("mcmmo.skills.woodcutting")) {
+            if (Permissions.skillEnabled(inspect, SkillType.WOODCUTTING)) {
                 display.sendMessage(LocaleLoader.getString("Skills.Stats", LocaleLoader.getString("Woodcutting.Listener"), profile.getSkillLevel(SkillType.WOODCUTTING), profile.getSkillXpLevel(SkillType.WOODCUTTING), profile.getXpToLevel(SkillType.WOODCUTTING)));
             }
         }
@@ -68,23 +69,23 @@ public final class CommandHelper {
         if (SkillTools.hasCombatSkills(inspect)) {
             display.sendMessage(LocaleLoader.getString("Stats.Header.Combat"));
 
-            if (inspect.hasPermission("mcmmo.skills.axes")) {
+            if (Permissions.skillEnabled(inspect, SkillType.AXES)) {
                 display.sendMessage(LocaleLoader.getString("Skills.Stats", LocaleLoader.getString("Axes.Listener"), profile.getSkillLevel(SkillType.AXES), profile.getSkillXpLevel(SkillType.AXES), profile.getXpToLevel(SkillType.AXES)));
             }
 
-            if (inspect.hasPermission("mcmmo.skills.archery")) {
+            if (Permissions.skillEnabled(inspect, SkillType.ARCHERY)) {
                 display.sendMessage(LocaleLoader.getString("Skills.Stats", LocaleLoader.getString("Archery.Listener"), profile.getSkillLevel(SkillType.ARCHERY), profile.getSkillXpLevel(SkillType.ARCHERY), profile.getXpToLevel(SkillType.ARCHERY)));
             }
 
-            if (inspect.hasPermission("mcmmo.skills.swords")) {
+            if (Permissions.skillEnabled(inspect, SkillType.SWORDS)) {
                 display.sendMessage(LocaleLoader.getString("Skills.Stats", LocaleLoader.getString("Swords.Listener"), profile.getSkillLevel(SkillType.SWORDS), profile.getSkillXpLevel(SkillType.SWORDS), profile.getXpToLevel(SkillType.SWORDS)));
             }
 
-            if (inspect.hasPermission("mcmmo.skills.taming")) {
+            if (Permissions.skillEnabled(inspect, SkillType.TAMING)) {
                 display.sendMessage(LocaleLoader.getString("Skills.Stats", LocaleLoader.getString("Taming.Listener"), profile.getSkillLevel(SkillType.TAMING), profile.getSkillXpLevel(SkillType.TAMING), profile.getXpToLevel(SkillType.TAMING)));
             }
 
-            if (inspect.hasPermission("mcmmo.skills.unarmed")) {
+            if (Permissions.skillEnabled(inspect, SkillType.UNARMED)) {
                 display.sendMessage(LocaleLoader.getString("Skills.Stats", LocaleLoader.getString("Unarmed.Listener"), profile.getSkillLevel(SkillType.UNARMED), profile.getSkillXpLevel(SkillType.UNARMED), profile.getXpToLevel(SkillType.UNARMED)));
             }
         }
@@ -105,11 +106,11 @@ public final class CommandHelper {
         if (SkillTools.hasMiscSkills(inspect)) {
             display.sendMessage(LocaleLoader.getString("Stats.Header.Misc"));
 
-            if (inspect.hasPermission("mcmmo.skills.acrobatics")) {
+            if (Permissions.skillEnabled(inspect, SkillType.ACROBATICS)) {
                 display.sendMessage(LocaleLoader.getString("Skills.Stats", LocaleLoader.getString("Acrobatics.Listener"), profile.getSkillLevel(SkillType.ACROBATICS), profile.getSkillXpLevel(SkillType.ACROBATICS), profile.getXpToLevel(SkillType.ACROBATICS)));
             }
 
-            if (inspect.hasPermission("mcmmo.skills.repair")) {
+            if (Permissions.skillEnabled(inspect, SkillType.REPAIR)) {
                 display.sendMessage(LocaleLoader.getString("Skills.Stats", LocaleLoader.getString("Repair.Listener"), profile.getSkillLevel(SkillType.REPAIR), profile.getSkillXpLevel(SkillType.REPAIR), profile.getXpToLevel(SkillType.REPAIR)));
             }
         }

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

@@ -215,7 +215,7 @@ public final class CommandRegistrationHelper {
     public static void registerMcmmoCommand() {
         PluginCommand command = mcMMO.p.getCommand("mcmmo");
         command.setDescription(LocaleLoader.getString("Commands.Description.mcmmo"));
-        command.setPermission("mcmmo.commands.mcmmo;mcmmo.commands.mcmmo.help");
+        command.setPermission("mcmmo.commands.mcmmo.description;mcmmo.commands.mcmmo.help");
         command.setPermissionMessage(permissionsMessage);
         command.setUsage(LocaleLoader.getString("Commands.Usage.0", "mcmmo"));
         command.setUsage(command.getUsage() + "\n" + LocaleLoader.getString("Commands.Usage.1", "mcmmo", "help"));

+ 3 - 2
src/main/java/com/gmail/nossr50/commands/admin/AddlevelsCommand.java

@@ -10,6 +10,7 @@ import com.gmail.nossr50.datatypes.PlayerProfile;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.skills.utilities.SkillTools;
 import com.gmail.nossr50.skills.utilities.SkillType;
+import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.StringUtils;
 import com.gmail.nossr50.util.Users;
 
@@ -23,7 +24,7 @@ public class AddlevelsCommand implements CommandExecutor{
 
         switch (args.length) {
         case 2:
-            if (!sender.hasPermission("mcmmo.commands.addlevels")) {
+            if (!Permissions.addlevels(sender)) {
                 sender.sendMessage(command.getPermissionMessage());
                 return true;
             }
@@ -71,7 +72,7 @@ public class AddlevelsCommand implements CommandExecutor{
             return true;
 
         case 3:
-            if (!sender.hasPermission("mcmmo.commands.addlevels.others")) {
+            if (!Permissions.addlevelsOthers(sender)) {
                 sender.sendMessage(command.getPermissionMessage());
                 return true;
             }

+ 3 - 2
src/main/java/com/gmail/nossr50/commands/admin/AddxpCommand.java

@@ -9,6 +9,7 @@ import com.gmail.nossr50.datatypes.PlayerProfile;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.skills.utilities.SkillTools;
 import com.gmail.nossr50.skills.utilities.SkillType;
+import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.StringUtils;
 import com.gmail.nossr50.util.Users;
 
@@ -23,7 +24,7 @@ public class AddxpCommand implements CommandExecutor {
 
         switch (args.length) {
         case 2:
-            if (!sender.hasPermission("mcmmo.commands.addxp")) {
+            if (!Permissions.addxp(sender)) {
                 sender.sendMessage(command.getPermissionMessage());
                 return true;
             }
@@ -69,7 +70,7 @@ public class AddxpCommand implements CommandExecutor {
             return true;
 
         case 3:
-            if (!sender.hasPermission("mcmmo.commands.addxp.others")) {
+            if (!Permissions.addxpOthers(sender)) {
                 sender.sendMessage(command.getPermissionMessage());
                 return true;
             }

+ 5 - 4
src/main/java/com/gmail/nossr50/commands/admin/HardcoreCommand.java

@@ -9,6 +9,7 @@ import org.bukkit.command.CommandSender;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.config.Config;
 import com.gmail.nossr50.locale.LocaleLoader;
+import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.StringUtils;
 
 public class HardcoreCommand implements CommandExecutor{
@@ -17,7 +18,7 @@ public class HardcoreCommand implements CommandExecutor{
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
         switch (args.length) {
         case 0:
-            if (!sender.hasPermission("mcmmo.commands.hardcore.toggle")) {
+            if (!Permissions.hardcoreToggle(sender)) {
                 sender.sendMessage(command.getPermissionMessage());
                 return true;
             }
@@ -33,7 +34,7 @@ public class HardcoreCommand implements CommandExecutor{
 
         case 1:
             if (args[0].equalsIgnoreCase("on") || args[0].equalsIgnoreCase("true") || args[0].equalsIgnoreCase("enabled")) {
-                if (!sender.hasPermission("mcmmo.commands.hardcore.toggle")) {
+                if (!Permissions.hardcoreToggle(sender)) {
                     sender.sendMessage(command.getPermissionMessage());
                     return true;
                 }
@@ -43,7 +44,7 @@ public class HardcoreCommand implements CommandExecutor{
             }
 
             if (args[0].equalsIgnoreCase("off") || args[0].equalsIgnoreCase("false") || args[0].equalsIgnoreCase("disabled")) {
-                if (!sender.hasPermission("mcmmo.commands.hardcore.toggle")) {
+                if (!Permissions.hardcoreToggle(sender)) {
                     sender.sendMessage(command.getPermissionMessage());
                     return true;
                 }
@@ -56,7 +57,7 @@ public class HardcoreCommand implements CommandExecutor{
                 return false;
             }
 
-            if (!sender.hasPermission("mcmmo.commands.hardcore.modify")) {
+            if (!Permissions.hardcoreModify(sender)) {
                 sender.sendMessage(command.getPermissionMessage());
                 return true;
             }

+ 3 - 2
src/main/java/com/gmail/nossr50/commands/admin/McgodCommand.java

@@ -8,6 +8,7 @@ import org.bukkit.entity.Player;
 import com.gmail.nossr50.datatypes.McMMOPlayer;
 import com.gmail.nossr50.datatypes.PlayerProfile;
 import com.gmail.nossr50.locale.LocaleLoader;
+import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.Users;
 
 public class McgodCommand implements CommandExecutor {
@@ -17,7 +18,7 @@ public class McgodCommand implements CommandExecutor {
 
         switch (args.length) {
         case 0:
-            if (!sender.hasPermission("mcmmo.commands.mcgod")) {
+            if (!Permissions.mcgod(sender)) {
                 sender.sendMessage(command.getPermissionMessage());
                 return true;
             }
@@ -44,7 +45,7 @@ public class McgodCommand implements CommandExecutor {
             return true;
 
         case 1:
-            if (!sender.hasPermission("mcmmo.commands.mcgod.others")) {
+            if (!Permissions.mcgodOthers(sender)) {
                 sender.sendMessage(command.getPermissionMessage());
                 return true;
             }

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

@@ -8,6 +8,7 @@ import org.bukkit.entity.Player;
 import com.gmail.nossr50.datatypes.McMMOPlayer;
 import com.gmail.nossr50.datatypes.PlayerProfile;
 import com.gmail.nossr50.locale.LocaleLoader;
+import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.Users;
 
 public class McrefreshCommand implements CommandExecutor {
@@ -17,7 +18,7 @@ public class McrefreshCommand implements CommandExecutor {
 
         switch (args.length) {
         case 0:
-            if (!sender.hasPermission("mcmmo.commands.mcrefresh")) {
+            if (!Permissions.mcrefresh(sender)) {
                 sender.sendMessage(command.getPermissionMessage());
                 return true;
             }
@@ -37,7 +38,7 @@ public class McrefreshCommand implements CommandExecutor {
             return true;
 
         case 1:
-            if (!sender.hasPermission("mcmmo.commands.mcrefresh.others")) {
+            if (!Permissions.mcrefreshOthers(sender)) {
                 sender.sendMessage(command.getPermissionMessage());
                 return true;
             }

+ 3 - 2
src/main/java/com/gmail/nossr50/commands/admin/MmoeditCommand.java

@@ -10,6 +10,7 @@ import com.gmail.nossr50.datatypes.PlayerProfile;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.skills.utilities.SkillTools;
 import com.gmail.nossr50.skills.utilities.SkillType;
+import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.StringUtils;
 import com.gmail.nossr50.util.Users;
 
@@ -23,7 +24,7 @@ public class MmoeditCommand implements CommandExecutor {
 
         switch (args.length) {
         case 2:
-            if (!sender.hasPermission("mcmmo.commands.mmoedit")) {
+            if (!Permissions.mmoedit(sender)) {
                 sender.sendMessage(command.getPermissionMessage());
                 return true;
             }
@@ -67,7 +68,7 @@ public class MmoeditCommand implements CommandExecutor {
             return true;
 
         case 3:
-            if (!sender.hasPermission("mcmmo.commands.mmoedit.others")) {
+            if (!Permissions.mmoeditOthers(sender)) {
                 sender.sendMessage(command.getPermissionMessage());
                 return true;
             }

+ 8 - 7
src/main/java/com/gmail/nossr50/commands/admin/SkillresetCommand.java

@@ -10,6 +10,7 @@ import com.gmail.nossr50.datatypes.PlayerProfile;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.skills.utilities.SkillTools;
 import com.gmail.nossr50.skills.utilities.SkillType;
+import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.Users;
 
 public class SkillresetCommand implements CommandExecutor {
@@ -22,7 +23,7 @@ public class SkillresetCommand implements CommandExecutor {
 
         switch (args.length) {
         case 1:
-            if (!sender.hasPermission("mcmmo.commands.skillreset")) {
+            if (!Permissions.skillreset(sender)) {
                 sender.sendMessage(command.getPermissionMessage());
                 return true;
             }
@@ -47,7 +48,7 @@ public class SkillresetCommand implements CommandExecutor {
                         continue;
                     }
 
-                    if (!sender.hasPermission("mcmmo.commands.skillreset." + skillType.toString().toLowerCase())) {
+                    if (!Permissions.skillreset(sender, skillType)) {
                         sender.sendMessage(command.getPermissionMessage());
                         continue;
                     }
@@ -61,7 +62,7 @@ public class SkillresetCommand implements CommandExecutor {
                 skill = SkillType.getSkill(args[0]);
                 skillName = SkillTools.getSkillName(skill);
 
-                if (!sender.hasPermission("mcmmo.commands.skillreset." + skill.toString().toLowerCase())) {
+                if (!Permissions.skillreset(sender, skill)) {
                     sender.sendMessage(command.getPermissionMessage());
                     return true;
                 }
@@ -73,7 +74,7 @@ public class SkillresetCommand implements CommandExecutor {
             return true;
 
         case 2:
-            if (!sender.hasPermission("mcmmo.commands.skillreset.others")) {
+            if (!Permissions.skillresetOthers(sender)) {
                 sender.sendMessage(command.getPermissionMessage());
                 return true;
             }
@@ -90,7 +91,7 @@ public class SkillresetCommand implements CommandExecutor {
                 skill = SkillType.getSkill(args[1]);
                 skillName = SkillTools.getSkillName(skill);
 
-                if (!sender.hasPermission("mcmmo.commands.skillreset.others." + skill.toString().toLowerCase())) {
+                if (!Permissions.skillresetOthers(sender, skill)) {
                     sender.sendMessage(command.getPermissionMessage());
                     return true;
                 }
@@ -113,7 +114,7 @@ public class SkillresetCommand implements CommandExecutor {
                             continue;
                         }
 
-                        if (!sender.hasPermission("mcmmo.commands.skillreset.others." + skillType.toString().toLowerCase())) {
+                        if (!Permissions.skillresetOthers(sender, skill)) {
                             sender.sendMessage(command.getPermissionMessage());
                             continue;
                         }
@@ -136,7 +137,7 @@ public class SkillresetCommand implements CommandExecutor {
                             continue;
                         }
 
-                        if (!sender.hasPermission("mcmmo.commands.skillreset.others." + skillType.toString().toLowerCase())) {
+                        if (!Permissions.skillresetOthers(sender, skill)) {
                             sender.sendMessage(command.getPermissionMessage());
                             continue;
                         }

+ 5 - 4
src/main/java/com/gmail/nossr50/commands/admin/VampirismCommand.java

@@ -9,6 +9,7 @@ import org.bukkit.command.CommandSender;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.config.Config;
 import com.gmail.nossr50.locale.LocaleLoader;
+import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.StringUtils;
 
 public class VampirismCommand implements CommandExecutor {
@@ -22,7 +23,7 @@ public class VampirismCommand implements CommandExecutor {
 
         switch (args.length) {
         case 0:
-            if (!sender.hasPermission("mcmmo.commands.vampirism.toggle")) {
+            if (!Permissions.vampirismToggle(sender)) {
                 sender.sendMessage(command.getPermissionMessage());
                 return true;
             }
@@ -38,7 +39,7 @@ public class VampirismCommand implements CommandExecutor {
 
         case 1:
             if (args[0].equalsIgnoreCase("on") || args[0].equalsIgnoreCase("true") || args[0].equalsIgnoreCase("enabled")) {
-                if (!sender.hasPermission("mcmmo.commands.vampirism.toggle")) {
+                if (!Permissions.vampirismToggle(sender)) {
                     sender.sendMessage(command.getPermissionMessage());
                     return true;
                 }
@@ -48,7 +49,7 @@ public class VampirismCommand implements CommandExecutor {
             }
 
             if (args[0].equalsIgnoreCase("off") || args[0].equalsIgnoreCase("false") || args[0].equalsIgnoreCase("disabled")) {
-                if (!sender.hasPermission("mcmmo.commands.vampirism.toggle")) {
+                if (!Permissions.vampirismToggle(sender)) {
                     sender.sendMessage(command.getPermissionMessage());
                     return true;
                 }
@@ -61,7 +62,7 @@ public class VampirismCommand implements CommandExecutor {
                 return false;
             }
 
-            if (!sender.hasPermission("mcmmo.commands.vampirism.modify")) {
+            if (!Permissions.vampirismModify(sender)) {
                 sender.sendMessage(command.getPermissionMessage());
                 return true;
             }

+ 3 - 2
src/main/java/com/gmail/nossr50/commands/admin/XprateCommand.java

@@ -7,6 +7,7 @@ import org.bukkit.command.CommandSender;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.config.Config;
 import com.gmail.nossr50.locale.LocaleLoader;
+import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.StringUtils;
 
 public class XprateCommand implements CommandExecutor {
@@ -20,7 +21,7 @@ public class XprateCommand implements CommandExecutor {
                 return false;
             }
 
-            if (!sender.hasPermission("mcmmo.commands.xprate.reset")) {
+            if (!Permissions.xprateReset(sender)) {
                 sender.sendMessage(command.getPermissionMessage());
                 return true;
             }
@@ -38,7 +39,7 @@ public class XprateCommand implements CommandExecutor {
                 return false;
             }
 
-            if (!sender.hasPermission("mcmmo.commands.xprate.set")) {
+            if (!Permissions.xprateSet(sender)) {
                 sender.sendMessage(command.getPermissionMessage());
                 return true;
             }

+ 4 - 7
src/main/java/com/gmail/nossr50/commands/player/InspectCommand.java

@@ -11,6 +11,7 @@ import com.gmail.nossr50.datatypes.PlayerProfile;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.skills.utilities.SkillType;
 import com.gmail.nossr50.util.Misc;
+import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.Users;
 
 public class InspectCommand implements CommandExecutor {
@@ -20,11 +21,6 @@ public class InspectCommand implements CommandExecutor {
 
         switch (args.length) {
         case 1:
-            if (!sender.hasPermission("mcmmo.commands.inspect")) {
-                sender.sendMessage(command.getPermissionMessage());
-                return true;
-            }
-
             McMMOPlayer mcMMOPlayer = Users.getPlayer(args[0]);
 
             // If the mcMMOPlayer doesn't exist, create a temporary profile and check if it's present in the database. If it's not, abort the process.
@@ -36,7 +32,8 @@ public class InspectCommand implements CommandExecutor {
                     return true;
                 }
 
-                if (sender instanceof Player && !sender.hasPermission("mcmmo.commands.inspect.offline")) {
+                // TODO: Why do we care if this is a player?
+                if (sender instanceof Player && !Permissions.inspectOffline(sender)) {
                     sender.sendMessage(LocaleLoader.getString("Inspect.Offline"));
                     return true;
                 }
@@ -67,7 +64,7 @@ public class InspectCommand implements CommandExecutor {
                 if (sender instanceof Player) {
                     Player inspector = (Player) sender;
 
-                    if (!Misc.isNear(inspector.getLocation(), target.getLocation(), 5.0) && !inspector.hasPermission("mcmmo.commands.inspect.far")) {
+                    if (!Misc.isNear(inspector.getLocation(), target.getLocation(), 5.0) && !Permissions.inspectFar(inspector)) {
                         sender.sendMessage(LocaleLoader.getString("Inspect.TooFar"));
                         return true;
                     }

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

@@ -8,6 +8,7 @@ import org.bukkit.entity.Player;
 import com.gmail.nossr50.datatypes.McMMOPlayer;
 import com.gmail.nossr50.datatypes.PlayerProfile;
 import com.gmail.nossr50.locale.LocaleLoader;
+import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.Users;
 
 public class McabilityCommand implements CommandExecutor {
@@ -17,7 +18,7 @@ public class McabilityCommand implements CommandExecutor {
 
         switch (args.length) {
         case 0:
-            if (!sender.hasPermission("mcmmo.commands.mcability")) {
+            if (!Permissions.mcability(sender)) {
                 sender.sendMessage(command.getPermissionMessage());
                 return true;
             }
@@ -35,7 +36,7 @@ public class McabilityCommand implements CommandExecutor {
             return true;
 
         case 1:
-            if (!sender.hasPermission("mcmmo.commands.mcability.others")) {
+            if (!Permissions.mcabilityOthers(sender)) {
                 sender.sendMessage(command.getPermissionMessage());
                 return true;
             }

+ 17 - 10
src/main/java/com/gmail/nossr50/commands/player/McmmoCommand.java

@@ -10,6 +10,8 @@ import org.getspout.spoutapi.player.SpoutPlayer;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.config.Config;
 import com.gmail.nossr50.locale.LocaleLoader;
+import com.gmail.nossr50.party.commands.PartySubcommandType;
+import com.gmail.nossr50.util.Permissions;
 
 public class McmmoCommand implements CommandExecutor {
     @Override
@@ -17,6 +19,11 @@ public class McmmoCommand implements CommandExecutor {
 
         switch (args.length) {
         case 0:
+            if (!Permissions.mcmmoDescription(sender)) {
+                sender.sendMessage(command.getPermissionMessage());
+                return true;
+            }
+
             String description = LocaleLoader.getString("mcMMO.Description");
             String[] mcSplit = description.split(",");
             sender.sendMessage(mcSplit);
@@ -36,7 +43,7 @@ public class McmmoCommand implements CommandExecutor {
 
         case 1:
             if (args[0].equalsIgnoreCase("?") || args[0].equalsIgnoreCase("help") || args[0].equalsIgnoreCase("commands")) {
-                if (!sender.hasPermission("mcmmo.commands.mcmmo.help")) {
+                if (!Permissions.mcmmoHelp(sender)) {
                     sender.sendMessage(command.getPermissionMessage());
                     return true;
                 }
@@ -54,20 +61,20 @@ public class McmmoCommand implements CommandExecutor {
     }
 
     private void displayPartyCommands(CommandSender sender) {
-        if (sender.hasPermission("mcmmo.commands.party")) {
+        if (Permissions.party(sender)) {
             sender.sendMessage(LocaleLoader.getString("Commands.Party.Commands"));
             sender.sendMessage("/party create <" + LocaleLoader.getString("Commands.Usage.PartyName") + "> " + LocaleLoader.getString("Commands.Party1"));
             sender.sendMessage("/party join <" + LocaleLoader.getString("Commands.Usage.Player") + "> " + LocaleLoader.getString("Commands.Party2"));
             sender.sendMessage("/party quit " + LocaleLoader.getString("Commands.Party.Quit"));
 
-            if (sender.hasPermission("mcmmo.chat.party")) {
+            if (Permissions.partyChat(sender)) {
                 sender.sendMessage("/party chat " + LocaleLoader.getString("Commands.Party.Toggle"));
             }
 
             sender.sendMessage("/party invite <" + LocaleLoader.getString("Commands.Usage.Player") + "> " + LocaleLoader.getString("Commands.Party.Invite"));
             sender.sendMessage("/party accept " + LocaleLoader.getString("Commands.Party.Accept"));
 
-            if (sender.hasPermission("mcmmo.commands.ptp")) {
+            if (Permissions.partySubcommand(sender, PartySubcommandType.TELEPORT)) {
                 sender.sendMessage("/party teleport " + LocaleLoader.getString("Commands.Party.Teleport"));
             }
         }
@@ -78,27 +85,27 @@ public class McmmoCommand implements CommandExecutor {
         sender.sendMessage("/mcstats " + LocaleLoader.getString("Commands.Stats"));
         sender.sendMessage("/mctop " + LocaleLoader.getString("Commands.Leaderboards"));
 
-        if (sender.hasPermission("mcmmo.commands.skillreset")) {
+        if (Permissions.skillreset(sender)) {
             sender.sendMessage("/skillreset <skill|all> " + LocaleLoader.getString("Commands.Reset"));
         }
 
-        if (sender.hasPermission("mcmmo.commands.mcability")) {
+        if (Permissions.mcability(sender)) {
             sender.sendMessage("/mcability " + LocaleLoader.getString("Commands.ToggleAbility"));
         }
 
-        if (sender.hasPermission("mcmmo.chat.admin")) {
+        if (Permissions.adminChat(sender)) {
             sender.sendMessage("/adminchat " + LocaleLoader.getString("Commands.AdminToggle"));
         }
 
-        if (sender.hasPermission("mcmmo.commands.inspect")) {
+        if (Permissions.inspect(sender)) {
             sender.sendMessage("/inspect " + LocaleLoader.getString("Commands.Inspect"));
         }
 
-        if (sender.hasPermission("mcmmo.commands.mmoedit")) {
+        if (Permissions.mmoedit(sender)) {
             sender.sendMessage("/mmoedit " + LocaleLoader.getString("Commands.mmoedit"));
         }
 
-        if (sender.hasPermission("mcmmo.commands.mcgod")) {
+        if (Permissions.mcgod(sender)) {
             sender.sendMessage("/mcgod " + LocaleLoader.getString("Commands.mcgod"));
         }
 

+ 5 - 4
src/main/java/com/gmail/nossr50/commands/player/McrankCommand.java

@@ -16,6 +16,7 @@ import com.gmail.nossr50.runnables.McRankAsync;
 import com.gmail.nossr50.skills.utilities.SkillTools;
 import com.gmail.nossr50.skills.utilities.SkillType;
 import com.gmail.nossr50.util.Misc;
+import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.Users;
 
 public class McrankCommand implements CommandExecutor {
@@ -23,7 +24,7 @@ public class McrankCommand implements CommandExecutor {
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
         switch (args.length) {
         case 0:
-            if (!sender.hasPermission("mcmmo.commands.mcrank")) {
+            if (!Permissions.mcrank(sender)) {
                 sender.sendMessage(command.getPermissionMessage());
                 return true;
             }
@@ -43,7 +44,7 @@ public class McrankCommand implements CommandExecutor {
             return true;
 
         case 1:
-            if (!sender.hasPermission("mcmmo.commands.mcrank.others")) {
+            if (!Permissions.mcrankOthers(sender)) {
                 sender.sendMessage(command.getPermissionMessage());
                 return true;
             }
@@ -58,7 +59,7 @@ public class McrankCommand implements CommandExecutor {
                     return true;
                 }
 
-                if (sender instanceof Player && !!sender.hasPermission("mcmmo.commands.mcrank.others.offline")) {
+                if (sender instanceof Player && !Permissions.mcrankOffline(sender)) {
                     sender.sendMessage(LocaleLoader.getString("Inspect.Offline"));
                     return true;
                 }
@@ -66,7 +67,7 @@ public class McrankCommand implements CommandExecutor {
             else {
                 Player target = mcMMOPlayer.getPlayer();
 
-                if (sender instanceof Player && !Misc.isNear(((Player) sender).getLocation(), target.getLocation(), 5.0) && !sender.hasPermission("mcmmo.commands.mcrank.others.far")) {
+                if (sender instanceof Player && !Misc.isNear(((Player) sender).getLocation(), target.getLocation(), 5.0) && !Permissions.mcrankFar(sender)) {
                     sender.sendMessage(LocaleLoader.getString("Inspect.TooFar"));
                     return true;
                 }

+ 2 - 1
src/main/java/com/gmail/nossr50/commands/player/MctopCommand.java

@@ -13,6 +13,7 @@ import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.runnables.McTopAsync;
 import com.gmail.nossr50.skills.utilities.SkillTools;
 import com.gmail.nossr50.skills.utilities.SkillType;
+import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.StringUtils;
 
 public class MctopCommand implements CommandExecutor {
@@ -72,7 +73,7 @@ public class MctopCommand implements CommandExecutor {
     }
 
     private void flatfileDisplay(int page, String skill, CommandSender sender, Command command) {
-        if (!skill.equalsIgnoreCase("all") && !sender.hasPermission("mcmmo.commands.mctop." + skill.toLowerCase())) {
+        if (!skill.equalsIgnoreCase("all") && !Permissions.mctop(sender, SkillType.getSkill(skill))) {
             sender.sendMessage(command.getPermissionMessage());
             return;
         }

+ 0 - 5
src/main/java/com/gmail/nossr50/config/Config.java

@@ -182,11 +182,6 @@ public class Config extends ConfigLoader {
     public int getHerbalismXPCarrot() { return config.getInt("Experience.Herbalism.Carrot", 50); }
     public int getHerbalismXPPotato() { return config.getInt("Experience.Herbalism.Potato", 50); }
 
-    public boolean getHerbalismGreenThumbCobbleToMossy() { return config.getBoolean("Skills.Herbalism.Green_Thumb.Cobble_To_Mossy", true); }
-    public boolean getHerbalismGreenThumbCobbleWallToMossyWall() { return config.getBoolean("Skills.Herbalism.Green_Thumb.CobbleWall_To_MossyWall", true); }
-    public boolean getHerbalismGreenThumbSmoothbrickToMossy() { return config.getBoolean("Skills.Herbalism.Green_Thumb.SmoothBrick_To_MossyBrick", true); }
-    public boolean getHerbalismGreenThumbDirtToGrass() { return config.getBoolean("Skills.Herbalism.Green_Thumb.Dirt_To_Grass", true); }
-
     public boolean getBrownMushroomsDoubleDropsEnabled() { return config.getBoolean("Double_Drops.Herbalism.Brown_Mushrooms", true); }
     public boolean getCactiDoubleDropsEnabled() { return config.getBoolean("Double_Drops.Herbalism.Cacti", true); }
     public boolean getWheatDoubleDropsEnabled() { return config.getBoolean("Double_Drops.Herbalism.Wheat", true); }

+ 2 - 1
src/main/java/com/gmail/nossr50/datatypes/McMMOPlayer.java

@@ -17,6 +17,7 @@ import com.gmail.nossr50.skills.utilities.SkillTools;
 import com.gmail.nossr50.skills.utilities.SkillType;
 import com.gmail.nossr50.spout.huds.SpoutHud;
 import com.gmail.nossr50.util.Misc;
+import com.gmail.nossr50.util.Permissions;
 
 public class McMMOPlayer {
     private Player player;
@@ -50,7 +51,7 @@ public class McMMOPlayer {
                 continue;
             }
 
-            if (player.hasPermission("mcmmo.skills." + type.toString().toLowerCase())) {
+            if (Permissions.skillEnabled(player, type)) {
                 powerLevel += profile.getSkillLevel(type);
             }
         }

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

@@ -44,6 +44,7 @@ import com.gmail.nossr50.skills.woodcutting.Woodcutting;
 import com.gmail.nossr50.util.BlockChecks;
 import com.gmail.nossr50.util.ItemChecks;
 import com.gmail.nossr50.util.Misc;
+import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.Users;
 
 public class BlockListener implements Listener {
@@ -151,7 +152,7 @@ public class BlockListener implements Listener {
         /* HERBALISM */
         if (BlockChecks.canBeGreenTerra(block)) {
             /* Green Terra */
-            if (profile.getToolPreparationMode(ToolType.HOE) && player.hasPermission("mcmmo.ability.herbalism.greenterra")) {
+            if (profile.getToolPreparationMode(ToolType.HOE) && Permissions.greenTerra(player)) {
                 SkillTools.abilityCheck(player, SkillType.HERBALISM);
             }
 
@@ -159,7 +160,7 @@ public class BlockListener implements Listener {
              * We don't check the block store here because herbalism has too many unusual edge cases.
              * Instead, we check it inside the drops handler.
              */
-            if (player.hasPermission("mcmmo.skills.herbalism")) {
+            if (Permissions.skillEnabled(player, SkillType.HERBALISM)) {
                 Herbalism.herbalismProcCheck(block, mcMMOPlayer, plugin); //Double drops
 
                 if (profile.getAbilityMode(AbilityType.GREEN_TERRA)) {
@@ -169,7 +170,7 @@ public class BlockListener implements Listener {
         }
 
         /* MINING */
-        else if (BlockChecks.canBeSuperBroken(block) && ItemChecks.isPickaxe(heldItem) && player.hasPermission("mcmmo.skills.mining") && !mcMMO.placeStore.isTrue(block)) {
+        else if (BlockChecks.canBeSuperBroken(block) && ItemChecks.isPickaxe(heldItem) && Permissions.skillEnabled(player, SkillType.MINING) && !mcMMO.placeStore.isTrue(block)) {
             MiningManager miningManager = new MiningManager(mcMMOPlayer);
             miningManager.miningBlockCheck(block);
 
@@ -179,8 +180,8 @@ public class BlockListener implements Listener {
         }
 
         /* WOOD CUTTING */
-        else if (BlockChecks.isLog(block) && player.hasPermission("mcmmo.skills.woodcutting") && !mcMMO.placeStore.isTrue(block)) {
-            if (profile.getAbilityMode(AbilityType.TREE_FELLER) && player.hasPermission("mcmmo.ability.woodcutting.treefeller") && ItemChecks.isAxe(heldItem)) {
+        else if (BlockChecks.isLog(block) && Permissions.skillEnabled(player, SkillType.WOODCUTTING) && !mcMMO.placeStore.isTrue(block)) {
+            if (profile.getAbilityMode(AbilityType.TREE_FELLER) && Permissions.treeFeller(player) && ItemChecks.isAxe(heldItem)) {
                 Woodcutting.beginTreeFeller(mcMMOPlayer, block);
             }
             else {
@@ -196,7 +197,7 @@ public class BlockListener implements Listener {
         }
 
         /* EXCAVATION */
-        else if (BlockChecks.canBeGigaDrillBroken(block) && ItemChecks.isShovel(heldItem) && player.hasPermission("mcmmo.skills.excavation") && !mcMMO.placeStore.isTrue(block)) {
+        else if (BlockChecks.canBeGigaDrillBroken(block) && ItemChecks.isShovel(heldItem) && Permissions.skillEnabled(player, SkillType.EXCAVATION) && !mcMMO.placeStore.isTrue(block)) {
             Excavation.excavationProcCheck(block, mcMMOPlayer);
 
             if (profile.getAbilityMode(AbilityType.GIGA_DRILL_BREAKER)) {
@@ -230,10 +231,10 @@ public class BlockListener implements Listener {
         Block block = event.getBlock();
         ItemStack heldItem = player.getItemInHand();
 
-        if (player.hasPermission("mcmmo.ability.herbalism.hylianluck") && ItemChecks.isSword(heldItem)) {
+        if (Permissions.hylianLuck(player) && ItemChecks.isSword(heldItem)) {
             Herbalism.hylianLuck(block, player, event);
         }
-        else if (BlockChecks.canBeFluxMined(block) && ItemChecks.isPickaxe(heldItem) && !heldItem.containsEnchantment(Enchantment.SILK_TOUCH) && player.hasPermission("mcmmo.ability.smelting.fluxmining") && !mcMMO.placeStore.isTrue(block)) {
+        else if (BlockChecks.canBeFluxMined(block) && ItemChecks.isPickaxe(heldItem) && !heldItem.containsEnchantment(Enchantment.SILK_TOUCH) && Permissions.fluxMining(player) && !mcMMO.placeStore.isTrue(block)) {
             SmeltingManager smeltingManager = new SmeltingManager(Users.getPlayer(player));
             smeltingManager.fluxMining(event);
         }
@@ -278,19 +279,19 @@ public class BlockListener implements Listener {
                 }
             }
 
-            if (profile.getToolPreparationMode(ToolType.HOE) && ItemChecks.isHoe(heldItem) && (BlockChecks.canBeGreenTerra(block) || BlockChecks.canMakeMossy(block)) && player.hasPermission("mcmmo.ability.herbalism.greenterra")) {
+            if (profile.getToolPreparationMode(ToolType.HOE) && ItemChecks.isHoe(heldItem) && (BlockChecks.canBeGreenTerra(block) || BlockChecks.canMakeMossy(block)) && Permissions.greenTerra(player)) {
                 SkillTools.abilityCheck(player, SkillType.HERBALISM);
             }
-            else if (profile.getToolPreparationMode(ToolType.AXE) && ItemChecks.isAxe(heldItem) && BlockChecks.isLog(block) && player.hasPermission("mcmmo.ability.woodcutting.treefeller")) {
+            else if (profile.getToolPreparationMode(ToolType.AXE) && ItemChecks.isAxe(heldItem) && BlockChecks.isLog(block) && Permissions.treeFeller(player)) {
                 SkillTools.abilityCheck(player, SkillType.WOODCUTTING);
             }
-            else if (profile.getToolPreparationMode(ToolType.PICKAXE) && ItemChecks.isPickaxe(heldItem) && BlockChecks.canBeSuperBroken(block) && player.hasPermission("mcmmo.ability.mining.superbreaker")) {
+            else if (profile.getToolPreparationMode(ToolType.PICKAXE) && ItemChecks.isPickaxe(heldItem) && BlockChecks.canBeSuperBroken(block) && Permissions.superBreaker(player)) {
                 SkillTools.abilityCheck(player, SkillType.MINING);
             }
-            else if (profile.getToolPreparationMode(ToolType.SHOVEL) && ItemChecks.isShovel(heldItem) && BlockChecks.canBeGigaDrillBroken(block) && player.hasPermission("mcmmo.ability.excavation.gigadrillbreaker")) {
+            else if (profile.getToolPreparationMode(ToolType.SHOVEL) && ItemChecks.isShovel(heldItem) && BlockChecks.canBeGigaDrillBroken(block) && Permissions.gigaDrillBreaker(player)) {
                 SkillTools.abilityCheck(player, SkillType.EXCAVATION);
             }
-            else if (profile.getToolPreparationMode(ToolType.FISTS) && heldItem.getType() == Material.AIR && (BlockChecks.canBeGigaDrillBroken(block) || block.getType() == Material.SNOW || (block.getType() == Material.SMOOTH_BRICK && block.getData() == 0x0)) && player.hasPermission("mcmmo.ability.unarmed.berserk")) {
+            else if (profile.getToolPreparationMode(ToolType.FISTS) && heldItem.getType() == Material.AIR && (BlockChecks.canBeGigaDrillBroken(block) || block.getType() == Material.SNOW || (block.getType() == Material.SMOOTH_BRICK && block.getData() == 0x0)) && Permissions.berserk(player)) {
                 SkillTools.abilityCheck(player, SkillType.UNARMED);
             }
         }
@@ -332,8 +333,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.
          */
-        // Except right here, which is for the Green Thumb activation, not the normal effect of Green Terra
-        if (profile.getAbilityMode(AbilityType.GREEN_TERRA) && BlockChecks.canMakeMossy(block) && player.hasPermission("mcmmo.ability.herbalism.greenthumbblocks")) {
+        if (profile.getAbilityMode(AbilityType.GREEN_TERRA) && BlockChecks.canMakeMossy(block)) {
             Herbalism.greenTerra(player, block);
         }
         else if (profile.getAbilityMode(AbilityType.BERSERK)) {
@@ -347,7 +347,7 @@ public class BlockListener implements Listener {
                 }
             }
             // Another perm check for the cracked blocks activation
-            else if (BlockChecks.canBeCracked(block) && player.hasPermission("mcmmo.ability.unarmed.blockcracker")) {
+            else if (BlockChecks.canBeCracked(block) && Permissions.blockCracker(player)) {
                 Unarmed.blockCracker(player, block);
             }
         }

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

@@ -77,7 +77,7 @@ public class PlayerListener implements Listener {
             return;
         }
 
-        if (!Permissions.hardcoremodeBypass(player)) {
+        if (!Permissions.hardcoreBypass(player)) {
             Player killer = player.getKiller();
 
             if (killer != null && Config.getInstance().getHardcoreVampirismEnabled()) {
@@ -157,7 +157,7 @@ public class PlayerListener implements Listener {
     public void onPlayerFish(PlayerFishEvent event) {
         Player player = event.getPlayer();
 
-        if (Misc.isNPCEntity(player) || !Permissions.fishing(player)) {
+        if (Misc.isNPCEntity(player) || !Permissions.skillEnabled(player, SkillType.FISHING)) {
             return;
         }
 
@@ -172,7 +172,7 @@ public class PlayerListener implements Listener {
         case CAUGHT_ENTITY:
             Entity entity = event.getCaught();
 
-            if (entity instanceof LivingEntity && skillLevel >= AdvancedConfig.getInstance().getShakeUnlockLevel() && Permissions.shakeMob(player)) {
+            if (entity instanceof LivingEntity && skillLevel >= AdvancedConfig.getInstance().getShakeUnlockLevel() && Permissions.shake(player)) {
                 Fishing.beginShakeMob(player, (LivingEntity) entity, skillLevel);
             }
 
@@ -237,7 +237,7 @@ public class PlayerListener implements Listener {
             player.sendMessage(LocaleLoader.getString("XPRate.Event", Config.getInstance().getExperienceGainsGlobalMultiplier()));
         }
 
-        if (player.hasPermission("mcmmo.tools.updatecheck") && mcMMO.p.updateAvailable) {
+        if (Permissions.updateNotifications(player) && mcMMO.p.updateAvailable) {
             player.sendMessage(LocaleLoader.getString("UpdateChecker.outdated"));
             player.sendMessage(LocaleLoader.getString("UpdateChecker.newavailable"));
         }
@@ -279,7 +279,7 @@ public class PlayerListener implements Listener {
             int blockID = block.getTypeId();
 
             /* REPAIR CHECKS */
-            if (blockID == Repair.anvilID && Permissions.repair(player) && mcMMO.repairManager.isRepairable(heldItem)) {
+            if (blockID == Repair.anvilID && Permissions.skillEnabled(player, SkillType.REPAIR) && mcMMO.repairManager.isRepairable(heldItem)) {
                 mcMMO.repairManager.handleRepair(Users.getPlayer(player), heldItem);
                 event.setCancelled(true);
                 player.updateInventory();
@@ -291,7 +291,7 @@ public class PlayerListener implements Listener {
                 player.updateInventory();
             }
             /* BLAST MINING CHECK */
-            else if (player.isSneaking() && Permissions.blastMining(player) && heldItem.getTypeId() == BlastMining.detonatorID) {
+            else if (player.isSneaking() && Permissions.remoteDetonation(player) && heldItem.getTypeId() == BlastMining.detonatorID) {
                 MiningManager miningManager = new MiningManager(Users.getPlayer(player));
                 miningManager.detonate(event);
             }
@@ -300,7 +300,7 @@ public class PlayerListener implements Listener {
 
         case RIGHT_CLICK_AIR:
             /* BLAST MINING CHECK */
-            if (player.isSneaking() && Permissions.blastMining(player) && heldItem.getTypeId() == BlastMining.detonatorID) {
+            if (player.isSneaking() && Permissions.remoteDetonation(player) && heldItem.getTypeId() == BlastMining.detonatorID) {
                 MiningManager miningManager = new MiningManager(Users.getPlayer(player));
                 miningManager.detonate(event);
             }
@@ -350,7 +350,7 @@ public class PlayerListener implements Listener {
             }
 
             /* GREEN THUMB CHECK */
-            if (heldItem.getType() == Material.SEEDS && BlockChecks.canMakeMossy(block) && Permissions.greenThumbBlocks(player)) {
+            if (heldItem.getType() == Material.SEEDS && BlockChecks.canMakeMossy(block)) {
                 Herbalism.greenThumbBlocks(heldItem, player, block);
             }
 

+ 0 - 5
src/main/java/com/gmail/nossr50/party/commands/PartyAcceptCommand.java

@@ -16,11 +16,6 @@ public class PartyAcceptCommand implements CommandExecutor {
 
     @Override
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
-        if (!sender.hasPermission("mcmmo.commands.party.accept")) {
-            sender.sendMessage(command.getPermissionMessage());
-            return true;
-        }
-
         switch (args.length) {
         case 1:
             player = (Player) sender;

+ 0 - 5
src/main/java/com/gmail/nossr50/party/commands/PartyChangeOwnerCommand.java

@@ -14,11 +14,6 @@ import com.gmail.nossr50.util.Users;
 public class PartyChangeOwnerCommand implements CommandExecutor {
     @Override
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
-        if (!sender.hasPermission("mcmmo.commands.party.owner")) {
-            sender.sendMessage(command.getPermissionMessage());
-            return true;
-        }
-
         switch (args.length) {
         case 2:
             Party playerParty = Users.getPlayer((Player) sender).getParty();

+ 1 - 5
src/main/java/com/gmail/nossr50/party/commands/PartyChangePasswordCommand.java

@@ -13,12 +13,8 @@ public class PartyChangePasswordCommand implements CommandExecutor {
 
     @Override
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
-        if (!sender.hasPermission("mcmmo.commands.party.password")) {
-            sender.sendMessage(command.getPermissionMessage());
-            return true;
-        }
-
         Party playerParty = Users.getPlayer((Player) sender).getParty();
+
         switch (args.length) {
         case 1:
             unprotectParty(sender, playerParty);

+ 8 - 1
src/main/java/com/gmail/nossr50/party/commands/PartyCommand.java

@@ -9,6 +9,7 @@ import com.gmail.nossr50.chat.commands.PartyChatCommand;
 import com.gmail.nossr50.commands.CommandHelper;
 import com.gmail.nossr50.datatypes.McMMOPlayer;
 import com.gmail.nossr50.locale.LocaleLoader;
+import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.Users;
 
 public class PartyCommand implements CommandExecutor {
@@ -39,7 +40,7 @@ public class PartyCommand implements CommandExecutor {
             return true;
         }
 
-        if (!sender.hasPermission("mcmmo.commands.party")) {
+        if (!Permissions.party(sender)) {
             sender.sendMessage(command.getPermissionMessage());
             return true;
         }
@@ -62,6 +63,12 @@ public class PartyCommand implements CommandExecutor {
             return printUsage();
         }
 
+        // Can't use this for lock/unlock since they're handled by the same command
+        if (subcommand != PartySubcommandType.LOCK && subcommand != PartySubcommandType.UNLOCK && !Permissions.partySubcommand(sender, subcommand)) {
+            sender.sendMessage(command.getPermissionMessage());
+            return true;
+        }
+
         switch (subcommand) {
         case JOIN:
             return partyJoinCommand.onCommand(sender, command, label, args);

+ 0 - 5
src/main/java/com/gmail/nossr50/party/commands/PartyCreateCommand.java

@@ -17,11 +17,6 @@ public class PartyCreateCommand implements CommandExecutor {
 
     @Override
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
-        if (!sender.hasPermission("mcmmo.commands.party.create")) {
-            sender.sendMessage(command.getPermissionMessage());
-            return true;
-        }
-
         switch (args.length) {
         case 2:
         case 3:

+ 0 - 5
src/main/java/com/gmail/nossr50/party/commands/PartyDisbandCommand.java

@@ -14,11 +14,6 @@ import com.gmail.nossr50.util.Users;
 public class PartyDisbandCommand implements CommandExecutor {
     @Override
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
-        if (!sender.hasPermission("mcmmo.commands.party.disband")) {
-            sender.sendMessage(command.getPermissionMessage());
-            return true;
-        }
-
         switch (args.length) {
         case 1:
             Party playerParty = Users.getPlayer((Player) sender).getParty();

+ 0 - 5
src/main/java/com/gmail/nossr50/party/commands/PartyExpShareCommand.java

@@ -23,11 +23,6 @@ public class PartyExpShareCommand implements CommandExecutor {
             return true;
         }
 
-        if (!sender.hasPermission("mcmmo.commands.party.expshare")) {
-            sender.sendMessage(command.getPermissionMessage());
-            return true;
-        }
-
         switch (args.length) {
         case 2:
             playerParty = Users.getPlayer((Player) sender).getParty();

+ 0 - 5
src/main/java/com/gmail/nossr50/party/commands/PartyInviteCommand.java

@@ -21,11 +21,6 @@ public class PartyInviteCommand implements CommandExecutor {
 
     @Override
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
-        if (!sender.hasPermission("mcmmo.commands.party.invite")) {
-            sender.sendMessage(command.getPermissionMessage());
-            return true;
-        }
-
         switch (args.length) {
         case 2:
             if (!mcMMO.p.getServer().getOfflinePlayer(args[1]).isOnline()) {

+ 0 - 5
src/main/java/com/gmail/nossr50/party/commands/PartyItemShareCommand.java

@@ -23,11 +23,6 @@ public class PartyItemShareCommand implements CommandExecutor {
             return true;
         }
 
-        if (!sender.hasPermission("mcmmo.commands.party.itemshare")) {
-            sender.sendMessage(command.getPermissionMessage());
-            return true;
-        }
-
         switch (args.length) {
         case 2:
             playerParty = Users.getPlayer((Player) sender).getParty();

+ 0 - 5
src/main/java/com/gmail/nossr50/party/commands/PartyJoinCommand.java

@@ -23,11 +23,6 @@ public class PartyJoinCommand implements CommandExecutor {
 
     @Override
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
-        if (!sender.hasPermission("mcmmo.commands.party.join")) {
-            sender.sendMessage(command.getPermissionMessage());
-            return true;
-        }
-
         switch (args.length) {
         case 2:
         case 3:

+ 0 - 5
src/main/java/com/gmail/nossr50/party/commands/PartyKickCommand.java

@@ -16,11 +16,6 @@ import com.gmail.nossr50.util.Users;
 public class PartyKickCommand implements CommandExecutor {
     @Override
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
-        if (!sender.hasPermission("mcmmo.commands.party.kick")) {
-            sender.sendMessage(command.getPermissionMessage());
-            return true;
-        }
-
         switch (args.length) {
         case 2:
             Party playerParty = Users.getPlayer((Player) sender).getParty();

+ 3 - 2
src/main/java/com/gmail/nossr50/party/commands/PartyLockCommand.java

@@ -7,6 +7,7 @@ import org.bukkit.entity.Player;
 
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.party.Party;
+import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.Users;
 
 public class PartyLockCommand implements CommandExecutor {
@@ -55,7 +56,7 @@ public class PartyLockCommand implements CommandExecutor {
      * Handle locking a party.
      */
     private void lockParty(CommandSender sender, Command command) {
-        if (!sender.hasPermission("mcmmo.commands.party.lock")) {
+        if (!Permissions.partySubcommand(sender, PartySubcommandType.LOCK)) {
             sender.sendMessage(command.getPermissionMessage());
             return;
         }
@@ -75,7 +76,7 @@ public class PartyLockCommand implements CommandExecutor {
      * @return true if party is successfully unlocked, false otherwise.
      */
     private void unlockParty(CommandSender sender, Command command) {
-        if (!sender.hasPermission("mcmmo.commands.party.unlock")) {
+        if (!Permissions.partySubcommand(sender, PartySubcommandType.UNLOCK)) {
             sender.sendMessage(command.getPermissionMessage());
             return;
         }

+ 0 - 5
src/main/java/com/gmail/nossr50/party/commands/PartyQuitCommand.java

@@ -17,11 +17,6 @@ public class PartyQuitCommand implements CommandExecutor {
 
     @Override
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
-        if (!sender.hasPermission("mcmmo.commands.party.quit")) {
-            sender.sendMessage(command.getPermissionMessage());
-            return true;
-        }
-
         switch (args.length) {
         case 1:
             player = (Player) sender;

+ 0 - 5
src/main/java/com/gmail/nossr50/party/commands/PartyRenameCommand.java

@@ -15,11 +15,6 @@ public class PartyRenameCommand implements CommandExecutor {
 
     @Override
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
-        if (!sender.hasPermission("mcmmo.commands.party.rename")) {
-            sender.sendMessage(command.getPermissionMessage());
-            return true;
-        }
-
         Party playerParty = Users.getPlayer((Player) sender).getParty();
         String leaderName = playerParty.getLeader();
 

+ 3 - 3
src/main/java/com/gmail/nossr50/party/commands/PtpCommand.java

@@ -38,7 +38,7 @@ public class PtpCommand implements CommandExecutor {
             playerProfile = mcMMOPlayer.getProfile();
 
             if (args[0].equalsIgnoreCase("toggle")) {
-                if (!sender.hasPermission("mcmmo.commands.ptp.toggle")) {
+                if (!Permissions.partyTeleportToggle(sender)) {
                     sender.sendMessage(command.getPermissionMessage());
                     return true;
                 }
@@ -47,7 +47,7 @@ public class PtpCommand implements CommandExecutor {
             }
 
             if (args[0].equalsIgnoreCase("acceptany") || args[0].equalsIgnoreCase("acceptall")) {
-                if (!sender.hasPermission("mcmmo.commands.ptp.acceptall")) {
+                if (!Permissions.partyTeleportAcceptAll(sender)) {
                     sender.sendMessage(command.getPermissionMessage());
                     return true;
                 }
@@ -63,7 +63,7 @@ public class PtpCommand implements CommandExecutor {
             }
 
             if (args[0].equalsIgnoreCase("accept")) {
-                if (!sender.hasPermission("mcmmo.commands.ptp.accept")) {
+                if (!Permissions.partyTeleportAccept(sender)) {
                     sender.sendMessage(command.getPermissionMessage());
                     return true;
                 }

+ 3 - 1
src/main/java/com/gmail/nossr50/runnables/McTopAsync.java

@@ -12,6 +12,8 @@ import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.config.Config;
 import com.gmail.nossr50.database.Database;
 import com.gmail.nossr50.locale.LocaleLoader;
+import com.gmail.nossr50.skills.utilities.SkillType;
+import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.StringUtils;
 
 public class McTopAsync implements Runnable {
@@ -31,7 +33,7 @@ public class McTopAsync implements Runnable {
     @Override
     public void run() {
         if (!query.equalsIgnoreCase("taming+mining+woodcutting+repair+unarmed+herbalism+excavation+archery+swords+axes+acrobatics+fishing")) {
-            if (!sender.hasPermission("mcmmo.commands.mctop." + query.toLowerCase())) {
+            if (!Permissions.mctop(sender, SkillType.getSkill(query))) {
                 sender.sendMessage(command.getPermissionMessage());
                 return;
             }

+ 4 - 3
src/main/java/com/gmail/nossr50/skills/SkillCommand.java

@@ -13,11 +13,12 @@ import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.skills.utilities.PerksUtils;
 import com.gmail.nossr50.skills.utilities.SkillTools;
 import com.gmail.nossr50.skills.utilities.SkillType;
+import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.StringUtils;
 import com.gmail.nossr50.util.Users;
 
 public abstract class SkillCommand implements CommandExecutor {
-    private SkillType skill;
+    protected SkillType skill;
     private String skillString;
 
     protected Player player;
@@ -49,8 +50,8 @@ public abstract class SkillCommand implements CommandExecutor {
         }
 
         skillValue = profile.getSkillLevel(skill);
-        isLucky = player.hasPermission("mcmmo.perks.lucky." + skill.toString().toLowerCase());
-        hasEndurance = (player.hasPermission("mcmmo.perks.activationtime.twelveseconds") || player.hasPermission("mcmmo.perks.activationtime.eightseconds") || player.hasPermission("mcmmo.perks.activationtime.fourseconds"));
+        isLucky = Permissions.lucky(sender, skill);
+        hasEndurance = (Permissions.twelveSecondActivationBoost(sender) || Permissions.eightSecondActivationBoost(sender) || Permissions.fourSecondActivationBoost(sender));
 
         dataCalculations();
         permissionsCheck();

+ 7 - 2
src/main/java/com/gmail/nossr50/skills/SkillManager.java

@@ -3,17 +3,18 @@ package com.gmail.nossr50.skills;
 import com.gmail.nossr50.datatypes.McMMOPlayer;
 import com.gmail.nossr50.skills.utilities.PerksUtils;
 import com.gmail.nossr50.skills.utilities.SkillType;
-import com.gmail.nossr50.util.Permissions;
 
 public abstract class SkillManager {
     protected McMMOPlayer mcMMOPlayer;
     protected int skillLevel;
     protected int activationChance;
+    protected SkillType skill;
 
     public SkillManager(McMMOPlayer mcMMOPlayer, SkillType skill) {
         this.mcMMOPlayer = mcMMOPlayer;
         this.skillLevel = mcMMOPlayer.getProfile().getSkillLevel(skill);
-        this.activationChance = PerksUtils.handleLuckyPerks(Permissions.lucky(mcMMOPlayer.getPlayer(), skill));
+        this.activationChance = PerksUtils.handleLuckyPerks(mcMMOPlayer.getPlayer(), skill);
+        this.skill = skill;
     }
 
     public McMMOPlayer getMcMMOPlayer() {
@@ -27,4 +28,8 @@ public abstract class SkillManager {
     public int getActivationChance() {
         return activationChance;
     }
+
+    public SkillType getSkill() {
+        return skill;
+    }
 }

+ 2 - 2
src/main/java/com/gmail/nossr50/skills/archery/ArcheryCommand.java

@@ -45,9 +45,9 @@ public class ArcheryCommand extends SkillCommand {
 
     @Override
     protected void permissionsCheck() {
-        canSkillShot = Permissions.archeryBonus(player);
+        canSkillShot = Permissions.bonusDamage(player, skill);
         canDaze = Permissions.daze(player);
-        canRetrieve = Permissions.trackArrows(player);
+        canRetrieve = Permissions.arrowRetrieval(player);
     }
 
     @Override

+ 1 - 1
src/main/java/com/gmail/nossr50/skills/archery/ArcheryManager.java

@@ -75,7 +75,7 @@ public class ArcheryManager extends SkillManager {
      * @param event The event to modify.
      */
     public void skillShot(EntityDamageEvent event) {
-        if (skillLevel >= Archery.skillShotIncreaseLevel && Permissions.archeryBonus(mcMMOPlayer.getPlayer())) {
+        if (skillLevel >= Archery.skillShotIncreaseLevel && Permissions.bonusDamage(mcMMOPlayer.getPlayer(), skill)) {
             SkillShotEventHandler eventHandler = new SkillShotEventHandler(this, event);
 
             eventHandler.calculateDamageBonus();

+ 3 - 3
src/main/java/com/gmail/nossr50/skills/axes/AxesCommand.java

@@ -52,9 +52,9 @@ public class AxesCommand extends SkillCommand {
     @Override
     protected void permissionsCheck() {
         canSkullSplitter = Permissions.skullSplitter(player);
-        canCritical = Permissions.criticalHit(player);
-        canBonusDamage = Permissions.axeBonus(player);
-        canImpact = Permissions.impact(player);
+        canCritical = Permissions.criticalStrikes(player);
+        canBonusDamage = Permissions.bonusDamage(player, skill);
+        canImpact = Permissions.armorImpact(player);
         canGreaterImpact = Permissions.greaterImpact(player);
     }
 

+ 2 - 2
src/main/java/com/gmail/nossr50/skills/excavation/Excavation.java

@@ -67,7 +67,7 @@ public class Excavation {
         Player player = mcMMOPlayer.getPlayer();
         List<ExcavationTreasure> treasures = new ArrayList<ExcavationTreasure>();
 
-        if (Permissions.excavationTreasures(player)) {
+        if (Permissions.excavationTreasureHunter(player)) {
             switch (material) {
             case DIRT:
                 treasures = TreasuresConfig.getInstance().excavationFromDirt;
@@ -105,7 +105,7 @@ public class Excavation {
 
             for (ExcavationTreasure treasure : treasures) {
                 if (mcMMOPlayer.getProfile().getSkillLevel(SkillType.EXCAVATION) >= treasure.getDropLevel()) {
-                    int activationChance = PerksUtils.handleLuckyPerks(Permissions.luckyExcavation(player));
+                    int activationChance = PerksUtils.handleLuckyPerks(player, SkillType.EXCAVATION);
 
                     if (Misc.getRandom().nextDouble() * activationChance <= treasure.getDropChance()) {
                         xp += treasure.getXp();

+ 1 - 1
src/main/java/com/gmail/nossr50/skills/excavation/ExcavationCommand.java

@@ -27,7 +27,7 @@ public class ExcavationCommand extends SkillCommand {
     @Override
     protected void permissionsCheck() {
         canGigaDrill = Permissions.gigaDrillBreaker(player);
-        canTreasureHunt = Permissions.excavationTreasures(player);
+        canTreasureHunt = Permissions.excavationTreasureHunter(player);
     }
 
     @Override

+ 7 - 5
src/main/java/com/gmail/nossr50/skills/fishing/Fishing.java

@@ -119,7 +119,7 @@ public final class Fishing {
             treasureXp = treasure.getXp();
             ItemStack treasureDrop = treasure.getDrop();
 
-            if (Permissions.fishingMagic(player) && beginMagicHunter(player, skillLevel, treasureDrop, player.getWorld().hasStorm())) {
+            if (Permissions.magicHunter(player) && beginMagicHunter(player, skillLevel, treasureDrop, player.getWorld().hasStorm())) {
                 player.sendMessage(LocaleLoader.getString("Fishing.MagicFound"));
             }
 
@@ -130,7 +130,9 @@ public final class Fishing {
         }
 
         mcMMOPlayer.beginXpGain(SkillType.FISHING, Config.getInstance().getFishingBaseXP() + treasureXp);
-        event.setExpToDrop(event.getExpToDrop() * getVanillaXpMultiplier(skillLevel));
+        if (Permissions.vanillaXpBoost(player, SkillType.FISHING)) {
+            event.setExpToDrop(event.getExpToDrop() * getVanillaXpMultiplier(skillLevel));
+        }
     }
 
     /**
@@ -141,7 +143,7 @@ public final class Fishing {
      * @return Chosen treasure
      */
     private static FishingTreasure checkForTreasure(Player player, int skillLevel) {
-        if (!Config.getInstance().getFishingDropsEnabled() || !Permissions.fishingTreasures(player)) {
+        if (!Config.getInstance().getFishingDropsEnabled() || !Permissions.fishingTreasureHunter(player)) {
             return null;
         }
 
@@ -161,7 +163,7 @@ public final class Fishing {
 
         FishingTreasure treasure = rewards.get(Misc.getRandom().nextInt(rewards.size()));
         ItemStack treasureDrop = treasure.getDrop();
-        int activationChance = PerksUtils.handleLuckyPerks(Permissions.luckyFishing(player));
+        int activationChance = PerksUtils.handleLuckyPerks(player, SkillType.FISHING);
 
         if (Misc.getRandom().nextDouble() * activationChance > treasure.getDropChance()) {
             return null;
@@ -190,7 +192,7 @@ public final class Fishing {
             return false;
         }
 
-        int activationChance = PerksUtils.handleLuckyPerks(Permissions.luckyFishing(player));
+        int activationChance = PerksUtils.handleLuckyPerks(player, SkillType.FISHING);
 
         if (storm) {
             activationChance = (int) (activationChance * 0.909);

+ 3 - 3
src/main/java/com/gmail/nossr50/skills/fishing/FishingCommand.java

@@ -51,9 +51,9 @@ public class FishingCommand extends SkillCommand {
 
     @Override
     protected void permissionsCheck() {
-        canTreasureHunt = Permissions.fishingTreasures(player);
-        canMagicHunt = Permissions.fishingMagic(player);
-        canShake = Permissions.shakeMob(player);
+        canTreasureHunt = Permissions.fishingTreasureHunter(player);
+        canMagicHunt = Permissions.magicHunter(player);
+        canShake = Permissions.shake(player);
         canFishermansDiet = Permissions.fishermansDiet(player);
     }
 

+ 2 - 2
src/main/java/com/gmail/nossr50/skills/fishing/ShakeMob.java

@@ -19,8 +19,8 @@ import org.bukkit.potion.PotionType;
 import com.gmail.nossr50.skills.fishing.Fishing.Tier;
 import com.gmail.nossr50.skills.utilities.CombatTools;
 import com.gmail.nossr50.skills.utilities.PerksUtils;
+import com.gmail.nossr50.skills.utilities.SkillType;
 import com.gmail.nossr50.util.Misc;
-import com.gmail.nossr50.util.Permissions;
 
 public final class ShakeMob {
     private ShakeMob() {}
@@ -33,7 +33,7 @@ public final class ShakeMob {
      * @param skillLevel Fishing level of the player
      */
     public static void process(Player player, LivingEntity mob, int skillLevel) {
-        int activationChance = PerksUtils.handleLuckyPerks(Permissions.luckyFishing(player));
+        int activationChance = PerksUtils.handleLuckyPerks(player, SkillType.FISHING);
 
         if (getShakeProbability(skillLevel) <= Misc.getRandom().nextInt(activationChance)) {
             return;

+ 13 - 18
src/main/java/com/gmail/nossr50/skills/herbalism/Herbalism.java

@@ -50,11 +50,6 @@ public class Herbalism {
     public static double hylianLuckMaxChance = AdvancedConfig.getInstance().getHylianLuckChanceMax();
     public static int hylianLuckMaxLevel = AdvancedConfig.getInstance().getHylianLucksMaxLevel();
 
-    public static boolean greenTerraWalls = Config.getInstance().getHerbalismGreenThumbCobbleWallToMossyWall();
-    public static boolean greenTerraSmoothBrick = Config.getInstance().getHerbalismGreenThumbSmoothbrickToMossy();
-    public static boolean greenTerraDirt = Config.getInstance().getHerbalismGreenThumbDirtToGrass();
-    public static boolean greenTerraCobble = Config.getInstance().getHerbalismGreenThumbCobbleToMossy();
-
     /**
      * Handle the farmers diet skill.
      *
@@ -94,27 +89,27 @@ public class Herbalism {
         if (SkillTools.blockBreakSimulate(block, player, false)) {
             Material type = block.getType();
 
+            if (!Permissions.greenThumbBlock(player, type)) {
+                return;
+            }
+
             switch (type) {
             case SMOOTH_BRICK:
-                if (greenTerraSmoothBrick && block.getData() == 0x0) {
+                if (block.getData() == 0x0) {
                     block.setData((byte) 0x1);
                 }
                 return;
 
             case DIRT:
-                if (greenTerraDirt) {
-                    block.setType(Material.GRASS);
-                }
+                block.setType(Material.GRASS);
                 return;
 
             case COBBLESTONE:
-                if (greenTerraCobble) {
-                    block.setType(Material.MOSSY_COBBLESTONE);
-                }
+                block.setType(Material.MOSSY_COBBLESTONE);
                 return;
 
             case COBBLE_WALL:
-                if (greenTerraWalls && block.getData() == 0x0) {
+                if (block.getData() == 0x0) {
                     block.setData((byte) 0x1);
                 }
                 return;
@@ -190,8 +185,8 @@ public class Herbalism {
             xp = customBlock.getXpGain();
         }
 
-        if (Permissions.herbalismDoubleDrops(player)) {
-            int activationChance = PerksUtils.handleLuckyPerks(Permissions.luckyHerbalism(player));
+        if (Permissions.doubleDrops(player, SkillType.HERBALISM)) {
+            int activationChance = PerksUtils.handleLuckyPerks(player, SkillType.HERBALISM);
             double chance = (doubleDropsMaxChance / doubleDropsMaxLevel) * SkillTools.skillCheck(herbLevel, doubleDropsMaxLevel);
 
             if (chance > Misc.getRandom().nextInt(activationChance)) {
@@ -255,7 +250,7 @@ public class Herbalism {
             return;
         }
 
-        int activationChance = PerksUtils.handleLuckyPerks(Permissions.luckyHerbalism(player));
+        int activationChance = PerksUtils.handleLuckyPerks(player, SkillType.HERBALISM);
         float chance = (float) (greenThumbMaxChance / greenThumbMaxLevel * herbLevel);
 
         if (chance > greenThumbMaxChance) {
@@ -302,7 +297,7 @@ public class Herbalism {
 
         player.setItemInHand(new ItemStack(Material.SEEDS, seeds - 1));
 
-        int activationChance = PerksUtils.handleLuckyPerks(Permissions.luckyHerbalism(player));
+        int activationChance = PerksUtils.handleLuckyPerks(player, SkillType.HERBALISM);
 
         float chance = (float) ((greenThumbMaxChance / greenThumbMaxLevel) * skillLevel);
         if (chance > greenThumbMaxChance) chance = (float) greenThumbMaxChance;
@@ -319,7 +314,7 @@ public class Herbalism {
         int skillLevel = Users.getPlayer(player).getProfile().getSkillLevel(SkillType.HERBALISM);
 
         double chance = (hylianLuckMaxChance / hylianLuckMaxLevel) * SkillTools.skillCheck(skillLevel, hylianLuckMaxLevel);
-        int activationChance = PerksUtils.handleLuckyPerks(Permissions.luckyHerbalism(player));
+        int activationChance = PerksUtils.handleLuckyPerks(player, SkillType.HERBALISM);
 
         if (chance > Misc.getRandom().nextInt(activationChance)) {
             List<HylianTreasure> treasures = new ArrayList<HylianTreasure>();

+ 1 - 14
src/main/java/com/gmail/nossr50/skills/herbalism/HerbalismBlock.java

@@ -69,20 +69,7 @@ public enum HerbalismBlock {
     }
 
     public boolean hasGreenThumbPermission(Player player) {
-        switch (this) {
-        case CARROT:
-            return Permissions.greenThumbCarrots(player);
-        case COCOA:
-            return Permissions.greenThumbCocoa(player);
-        case CROPS:
-            return Permissions.greenThumbWheat(player);
-        case POTATO:
-            return Permissions.greenThumbPotatoes(player);
-        case NETHER_WARTS:
-            return Permissions.greenThumbNetherwart(player);
-        default:
-            return false;
-        }
+        return Permissions.greenThumbPlant(player, blockType);
     }
 
     public static HerbalismBlock getHerbalismBlock(Material blockType) {

+ 5 - 3
src/main/java/com/gmail/nossr50/skills/herbalism/HerbalismCommand.java

@@ -1,5 +1,7 @@
 package com.gmail.nossr50.skills.herbalism;
 
+import org.bukkit.Material;
+
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.skills.SkillCommand;
 import com.gmail.nossr50.skills.utilities.SkillType;
@@ -61,10 +63,10 @@ public class HerbalismCommand extends SkillCommand {
     protected void permissionsCheck() {
         hasHylianLuck = Permissions.hylianLuck(player);
         canGreenTerra = Permissions.greenTerra(player);
-        canGreenThumbWheat = Permissions.greenThumbWheat(player);
-        canGreenThumbBlocks = Permissions.greenThumbBlocks(player);
+        canGreenThumbWheat = Permissions.greenThumbPlant(player, Material.CROPS); //TODO: This isn't really accurate - they could have perms for other crops but not wheat.
+        canGreenThumbBlocks = (Permissions.greenThumbBlock(player, Material.DIRT) || Permissions.greenThumbBlock(player, Material.COBBLESTONE) || Permissions.greenThumbBlock(player, Material.COBBLE_WALL) || Permissions.greenThumbBlock(player, Material.SMOOTH_BRICK));
         canFarmersDiet = Permissions.farmersDiet(player);
-        canDoubleDrop = Permissions.herbalismDoubleDrops(player);
+        canDoubleDrop = Permissions.doubleDrops(player, skill);
         doubleDropsDisabled = Herbalism.doubleDropsDisabled;
     }
 

+ 2 - 2
src/main/java/com/gmail/nossr50/skills/mining/MiningCommand.java

@@ -88,9 +88,9 @@ public class MiningCommand extends SkillCommand {
     @Override
     protected void permissionsCheck() {
         canBiggerBombs = Permissions.biggerBombs(player);
-        canBlast = Permissions.blastMining(player);
+        canBlast = Permissions.remoteDetonation(player);
         canDemoExpert = Permissions.demolitionsExpertise(player);
-        canDoubleDrop = Permissions.miningDoubleDrops(player);
+        canDoubleDrop = Permissions.doubleDrops(player, skill);
         canSuperBreaker = Permissions.superBreaker(player);
         doubleDropsDisabled = Mining.doubleDropsDisabled;
     }

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

@@ -112,7 +112,7 @@ public class MiningManager extends SkillManager{
         MiningBlockEventHandler eventHandler = new MiningBlockEventHandler(this, block);
         eventHandler.processXPGain();
 
-        if (!Permissions.miningDoubleDrops(mcMMOPlayer.getPlayer())) {
+        if (!Permissions.doubleDrops(mcMMOPlayer.getPlayer(), skill)) {
             return;
         }
 

+ 3 - 3
src/main/java/com/gmail/nossr50/skills/repair/Repair.java

@@ -110,7 +110,7 @@ public class Repair {
         for (Entry<Enchantment, Integer> enchant : enchants.entrySet()) {
             Enchantment enchantment = enchant.getKey();
 
-            int activationChance = PerksUtils.handleLuckyPerks(Permissions.luckyRepair(player));
+            int activationChance = PerksUtils.handleLuckyPerks(player, SkillType.REPAIR);
 
             if (Misc.getRandom().nextInt(activationChance) <= getEnchantChance(rank)) {
                 int enchantLevel = enchant.getValue();
@@ -237,9 +237,9 @@ public class Repair {
         int chance = (int) ((SUPER_REPAIR_CHANCE_MAX / SUPER_REPAIR_MAX_BONUS_LEVEL) * skillLevel);
         if (skillLevel >= SUPER_REPAIR_MAX_BONUS_LEVEL) chance = (int) SUPER_REPAIR_CHANCE_MAX;
 
-        int activationChance = PerksUtils.handleLuckyPerks(Permissions.luckyRepair(player));
+        int activationChance = PerksUtils.handleLuckyPerks(player, SkillType.REPAIR);
 
-        if (chance > Misc.getRandom().nextInt(activationChance) && Permissions.repairBonus(player)) {
+        if (chance > Misc.getRandom().nextInt(activationChance) && Permissions.superRepair(player)) {
             player.sendMessage(LocaleLoader.getString("Repair.Skills.FeltEasy"));
             return true;
         }

+ 8 - 8
src/main/java/com/gmail/nossr50/skills/repair/RepairCommand.java

@@ -69,17 +69,17 @@ public class RepairCommand extends SkillCommand {
 
     @Override
     protected void permissionsCheck() {
-        canSuperRepair = Permissions.repairBonus(player);
+        canSuperRepair = Permissions.superRepair(player);
         canMasterRepair = Permissions.repairMastery(player);
         canArcaneForge = Permissions.arcaneForging(player);
         canSalvage = Permissions.salvage(player);
-        canRepairDiamond = Permissions.diamondRepair(player);
-        canRepairGold = Permissions.goldRepair(player);
-        canRepairIron = Permissions.ironRepair(player);
-        canRepairStone = Permissions.stoneRepair(player);
-        canRepairString = Permissions.stringRepair(player);
-        canRepairLeather = Permissions.leatherRepair(player);
-        canRepairWood = Permissions.woodRepair(player);
+        canRepairDiamond = Permissions.repairDiamond(player);
+        canRepairGold = Permissions.repairGold(player);
+        canRepairIron = Permissions.repairIron(player);
+        canRepairStone = Permissions.repairStone(player);
+        canRepairString = Permissions.repairString(player);
+        canRepairLeather = Permissions.repairLeather(player);
+        canRepairWood = Permissions.repairWood(player);
         arcaneBypass = Permissions.arcaneBypass(player);
     }
 

+ 3 - 3
src/main/java/com/gmail/nossr50/skills/repair/RepairItemType.java

@@ -18,13 +18,13 @@ public enum RepairItemType {
     public boolean getPermissions(Player player) {
         switch (this) {
         case ARMOR:
-            return Permissions.armorRepair(player);
+            return Permissions.repairArmor(player);
 
         case TOOL:
-            return Permissions.toolRepair(player);
+            return Permissions.repairTools(player);
 
         case OTHER:
-            return Permissions.otherRepair(player);
+            return Permissions.repairOtherItems(player);
 
         default:
             return false;

+ 8 - 8
src/main/java/com/gmail/nossr50/skills/repair/RepairMaterialType.java

@@ -23,28 +23,28 @@ public enum RepairMaterialType {
     public boolean getPermissions(Player player) {
         switch (this) {
         case STRING:
-            return Permissions.stringRepair(player);
+            return Permissions.repairString(player);
 
         case LEATHER:
-            return Permissions.leatherRepair(player);
+            return Permissions.repairLeather(player);
 
         case WOOD:
-            return Permissions.woodRepair(player);
+            return Permissions.repairWood(player);
 
         case STONE:
-            return Permissions.stoneRepair(player);
+            return Permissions.repairStone(player);
 
         case IRON:
-            return Permissions.ironRepair(player);
+            return Permissions.repairIron(player);
 
         case GOLD:
-            return Permissions.goldRepair(player);
+            return Permissions.repairGold(player);
 
         case DIAMOND:
-            return Permissions.diamondRepair(player);
+            return Permissions.repairDiamond(player);
 
         case OTHER:
-            return Permissions.otherMaterialRepair(player);
+            return Permissions.repairOtherMaterials(player);
 
         default:
             return false;

+ 1 - 1
src/main/java/com/gmail/nossr50/skills/smelting/FluxMiningEventHandler.java

@@ -51,7 +51,7 @@ public class FluxMiningEventHandler {
 
         McMMOPlayer mcMMOPlayer = manager.getMcMMOPlayer();
 
-        if (Permissions.secondSmelt(mcMMOPlayer.getPlayer())) {
+        if (Permissions.doubleDrops(mcMMOPlayer.getPlayer(), manager.getSkill())) {
             int chance = (int) ((Mining.doubleDropsMaxChance / Mining.doubleDropsMaxLevel) * (SkillTools.skillCheck(mcMMOPlayer.getProfile().getSkillLevel(SkillType.MINING), Mining.doubleDropsMaxLevel)));
             Misc.randomDropItem(location, item, chance);
         }

+ 2 - 2
src/main/java/com/gmail/nossr50/skills/smelting/SmeltResourceEventHandler.java

@@ -67,11 +67,11 @@ public class SmeltResourceEventHandler {
         McMMOPlayer mcMMOPlayer = manager.getMcMMOPlayer();
         Player player = mcMMOPlayer.getPlayer();
 
-        if (Permissions.mining(player)) {
+        if (Permissions.skillEnabled(player, SkillType.MINING)) {
             mcMMOPlayer.beginXpGain(SkillType.MINING, xp / 2);
         }
 
-        if (Permissions.repair(player)) {
+        if (Permissions.skillEnabled(player, SkillType.REPAIR)) {
             mcMMOPlayer.beginXpGain(SkillType.REPAIR, xp / 2);
         }
     }

+ 2 - 2
src/main/java/com/gmail/nossr50/skills/smelting/SmeltingCommand.java

@@ -58,9 +58,9 @@ public class SmeltingCommand extends SkillCommand {
     @Override
     protected void permissionsCheck() {
         canFuelEfficiency = Permissions.fuelEfficiency(player);
-        canSecondSmelt = Permissions.secondSmelt(player);
+        canSecondSmelt = Permissions.doubleDrops(player, skill);
         canFluxMine = Permissions.fluxMining(player);
-        canVanillaXPBoost = Permissions.smeltingVanillaXPBoost(player);
+        canVanillaXPBoost = Permissions.vanillaXpBoost(player, skill);
     }
 
     @Override

+ 3 - 3
src/main/java/com/gmail/nossr50/skills/smelting/SmeltingManager.java

@@ -44,11 +44,11 @@ public class SmeltingManager extends SkillManager {
 
         SmeltResourceEventHandler eventHandler = new SmeltResourceEventHandler(this, event);
 
-        if (Permissions.smelting(player)) {
+        if (Permissions.skillEnabled(player, skill)) {
             eventHandler.handleXPGain();
         }
 
-        if (!Permissions.secondSmelt(player)) {
+        if (!Permissions.doubleDrops(player, skill)) {
             return;
         }
 
@@ -74,7 +74,7 @@ public class SmeltingManager extends SkillManager {
     }
 
     public void vanillaXPBoost(FurnaceExtractEvent event) {
-        if (skillLevel < Smelting.vanillaXPBoostRank1Level || !Permissions.smeltingVanillaXPBoost(mcMMOPlayer.getPlayer())) {
+        if (skillLevel < Smelting.vanillaXPBoostRank1Level || !Permissions.vanillaXpBoost(mcMMOPlayer.getPlayer(), skill)) {
             return;
         }
 

+ 1 - 1
src/main/java/com/gmail/nossr50/skills/swords/SwordsCommand.java

@@ -49,7 +49,7 @@ public class SwordsCommand extends SkillCommand {
 
     @Override
     protected void permissionsCheck() {
-        canBleed = Permissions.swordsBleed(player);
+        canBleed = Permissions.bleed(player);
         canCounter = Permissions.counterAttack(player);
         canSerratedStrike = Permissions.serratedStrikes(player);
     }

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

@@ -60,8 +60,8 @@ public class UnarmedCommand extends SkillCommand {
     @Override
     protected void permissionsCheck() {
         canBerserk = Permissions.berserk(player);
-        canBonusDamage = Permissions.unarmedBonus(player);
-        canDeflect = Permissions.deflect(player);
+        canBonusDamage = Permissions.bonusDamage(player, skill);
+        canDeflect = Permissions.arrowDeflect(player);
         canDisarm = Permissions.disarm(player);
         canIronGrip = Permissions.ironGrip(player);
     }

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

@@ -87,7 +87,7 @@ public class UnarmedManager extends SkillManager {
 
         double chance = (Unarmed.ironGripMaxChance / Unarmed.ironGripMaxBonusLevel) * eventHandler.skillModifier;
 
-        if (chance > Misc.getRandom().nextInt(PerksUtils.handleLuckyPerks(Permissions.luckyUnarmed(defender)))) {
+        if (chance > Misc.getRandom().nextInt(PerksUtils.handleLuckyPerks(defender, skill))) {
             eventHandler.sendAbilityMessages();
             return true;
         }

+ 1 - 1
src/main/java/com/gmail/nossr50/skills/utilities/AbilityType.java

@@ -150,7 +150,7 @@ public enum AbilityType {
             return Permissions.berserk(player);
 
         case BLAST_MINING:
-            return Permissions.blastMining(player);
+            return Permissions.remoteDetonation(player);
 
         case GIGA_DRILL_BREAKER:
             return Permissions.gigaDrillBreaker(player);

+ 12 - 12
src/main/java/com/gmail/nossr50/skills/utilities/CombatTools.java

@@ -87,7 +87,7 @@ public final class CombatTools {
                     return;
                 }
 
-                if (Permissions.swords(player)) {
+                if (Permissions.skillEnabled(player, SkillType.SWORDS)) {
                     McMMOPlayer mcMMOPlayer = Users.getPlayer(player);
                     PlayerProfile profile = mcMMOPlayer.getProfile();
                     SwordsManager swordsManager = new SwordsManager(mcMMOPlayer);
@@ -97,7 +97,7 @@ public final class CombatTools {
                         SkillTools.abilityCheck(player, SkillType.SWORDS);
                     }
 
-                    if (Permissions.swordsBleed(player)) {
+                    if (Permissions.bleed(player)) {
                         swordsManager.bleedCheck(target);
                     }
 
@@ -118,7 +118,7 @@ public final class CombatTools {
                     return;
                 }
 
-                if (Permissions.axes(player)) {
+                if (Permissions.skillEnabled(player, SkillType.AXES)) {
                     McMMOPlayer mcMMOPlayer = Users.getPlayer(player);
                     PlayerProfile profile = mcMMOPlayer.getProfile();
                     AxeManager axeManager = new AxeManager(mcMMOPlayer);
@@ -127,15 +127,15 @@ public final class CombatTools {
                         SkillTools.abilityCheck(player, SkillType.AXES);
                     }
 
-                    if (Permissions.axeBonus(player)) {
+                    if (Permissions.bonusDamage(player, axeManager.getSkill())) {
                         axeManager.bonusDamage(event);
                     }
 
-                    if (!target.isDead() && Permissions.criticalHit(player)) {
+                    if (!target.isDead() && Permissions.criticalStrikes(player)) {
                         axeManager.criticalHitCheck(event, target);
                     }
 
-                    if (!target.isDead() && Permissions.impact(player)) {
+                    if (!target.isDead() && Permissions.armorImpact(player)) {
                         axeManager.impact(event, target);
                     }
 
@@ -156,7 +156,7 @@ public final class CombatTools {
                     return;
                 }
 
-                if (Permissions.unarmed(player)) {
+                if (Permissions.skillEnabled(player, SkillType.UNARMED)) {
                     McMMOPlayer mcMMOPlayer = Users.getPlayer(player);
                     PlayerProfile profile = mcMMOPlayer.getProfile();
                     UnarmedManager unarmedManager = new UnarmedManager(mcMMOPlayer);
@@ -166,7 +166,7 @@ public final class CombatTools {
                         SkillTools.abilityCheck(player, SkillType.UNARMED);
                     }
 
-                    if (Permissions.unarmedBonus(player)) {
+                    if (Permissions.bonusDamage(player, unarmedManager.getSkill())) {
                         unarmedManager.bonusDamage(event);
                     }
 
@@ -210,7 +210,7 @@ public final class CombatTools {
                     return;
                 }
 
-                if (Permissions.taming(master)) {
+                if (Permissions.skillEnabled(master, SkillType.TAMING)) {
                     McMMOPlayer mcMMOPlayer = Users.getPlayer(master);
                     TamingManager tamingManager = new TamingManager(mcMMOPlayer);
                     int skillLevel = tamingManager.getSkillLevel();
@@ -303,13 +303,13 @@ public final class CombatTools {
             return;
         }
 
-        if (Permissions.archery(shooter)) {
+        if (Permissions.skillEnabled(shooter, SkillType.ARCHERY)) {
             McMMOPlayer mcMMOPlayer = Users.getPlayer(shooter);
             ArcheryManager archeryManager = new ArcheryManager(mcMMOPlayer);
             archeryManager.skillShot(event);
 
             if (target instanceof Player) {
-                if (Unarmed.pvpEnabled && ((Player) target).getItemInHand().getType() == Material.AIR && Permissions.deflect((Player) target)) {
+                if (Unarmed.pvpEnabled && ((Player) target).getItemInHand().getType() == Material.AIR && Permissions.arrowDeflect((Player) target)) {
                     UnarmedManager unarmedManager = new UnarmedManager(Users.getPlayer((Player) target));
                     unarmedManager.deflectCheck(event);
                 }
@@ -320,7 +320,7 @@ public final class CombatTools {
                 }
             }
 
-            if (!(shooter.getItemInHand().containsEnchantment(Enchantment.ARROW_INFINITE)) && Permissions.trackArrows(shooter)) {
+            if (!(shooter.getItemInHand().containsEnchantment(Enchantment.ARROW_INFINITE)) && Permissions.arrowRetrieval(shooter)) {
                 archeryManager.trackArrows(target);
             }
 

+ 13 - 13
src/main/java/com/gmail/nossr50/skills/utilities/PerksUtils.java

@@ -11,13 +11,13 @@ public final class PerksUtils {
     private PerksUtils() {};
 
     public static int handleCooldownPerks(Player player, int cooldown) {
-        if (Permissions.cooldownsHalved(player)) {
+        if (Permissions.halvedCooldowns(player)) {
             cooldown *= 0.5;
         }
-        else if (Permissions.cooldownsThirded(player)) {
+        else if (Permissions.thirdedCooldowns(player)) {
             cooldown *= (1.0 / 3.0);
         }
-        else if (Permissions.cooldownsQuartered(player)) {
+        else if (Permissions.quarteredCooldowns(player)) {
             cooldown *= 0.75;
         }
 
@@ -25,13 +25,13 @@ public final class PerksUtils {
     }
 
     public static int handleActivationPerks(Player player, int ticks, int maxTicks) {
-        if (Permissions.activationTwelve(player)) {
+        if (Permissions.twelveSecondActivationBoost(player)) {
             ticks += 12;
         }
-        else if (Permissions.activationEight(player)) {
+        else if (Permissions.eightSecondActivationBoost(player)) {
             ticks += 8;
         }
-        else if (Permissions.activationFour(player)) {
+        else if (Permissions.fourSecondActivationBoost(player)) {
             ticks += 4;
         }
 
@@ -43,19 +43,19 @@ public final class PerksUtils {
     }
 
     public static int handleXpPerks(Player player, int xp) {
-        if (player.hasPermission("mcmmo.perks.xp.quadruple")) {
+        if (Permissions.quadrupleXp(player)) {
             xp *= 4;
         }
-        else if (player.hasPermission("mcmmo.perks.xp.triple")) {
+        else if (Permissions.tripleXp(player)) {
             xp *= 3;
         }
-        else if (player.hasPermission("mcmmo.perks.xp.150percentboost")) {
+        else if (Permissions.doubleAndOneHalfXp(player)) {
             xp *= 2.5;
         }
-        else if (player.hasPermission("mcmmo.perks.xp.150percentboost")) {
+        else if (Permissions.doubleXp(player)) {
             xp *= 2;
         }
-        else if (player.hasPermission("mcmmo.perks.xp.50percentboost")) {
+        else if (Permissions.oneAndOneHalfXp(player)) {
             xp *= 1.5;
         }
 
@@ -68,8 +68,8 @@ public final class PerksUtils {
      * @param isLucky true if the player has the appropriate "lucky" perk, false otherwise
      * @return the activation chance
      */
-    public static int handleLuckyPerks(boolean isLucky) {
-        if (isLucky) {
+    public static int handleLuckyPerks(Player player, SkillType skill) {
+        if (Permissions.lucky(player, skill)) {
             return LUCKY_SKILL_ACTIVATION_CHANCE;
         }
     

+ 13 - 11
src/main/java/com/gmail/nossr50/skills/utilities/SkillTools.java

@@ -316,11 +316,11 @@ public class SkillTools {
      * @return true if the player has combat skills, false otherwise
      */
     public static boolean hasCombatSkills(Player player) {
-        if (Permissions.axes(player)
-                || Permissions.archery(player)
-                || Permissions.swords(player)
-                || Permissions.taming(player)
-                || Permissions.unarmed(player)) {
+        if (Permissions.skillEnabled(player, SkillType.AXES)
+                || Permissions.skillEnabled(player, SkillType.ARCHERY)
+                || Permissions.skillEnabled(player, SkillType.SWORDS)
+                || Permissions.skillEnabled(player, SkillType.TAMING)
+                || Permissions.skillEnabled(player, SkillType.UNARMED)) {
             return true;
         }
 
@@ -334,11 +334,11 @@ public class SkillTools {
      * @return true if the player has gathering skills, false otherwise
      */
     public static boolean hasGatheringSkills(Player player) {
-        if (Permissions.excavation(player)
-                || Permissions.fishing(player)
-                || Permissions.herbalism(player)
-                || Permissions.mining(player)
-                || Permissions.woodcutting(player)) {
+        if (Permissions.skillEnabled(player, SkillType.EXCAVATION)
+                || Permissions.skillEnabled(player, SkillType.FISHING)
+                || Permissions.skillEnabled(player, SkillType.HERBALISM)
+                || Permissions.skillEnabled(player, SkillType.MINING)
+                || Permissions.skillEnabled(player, SkillType.WOODCUTTING)) {
             return true;
         }
 
@@ -352,7 +352,9 @@ public class SkillTools {
      * @return true if the player has misc skills, false otherwise
      */
     public static boolean hasMiscSkills(Player player) {
-        if (Permissions.acrobatics(player) || Permissions.repair(player)) {
+        if (Permissions.skillEnabled(player, SkillType.ACROBATICS)
+                || Permissions.skillEnabled(player, SkillType.SMELTING)
+                || Permissions.skillEnabled(player, SkillType.REPAIR)) {
             return true;
         }
 

+ 2 - 2
src/main/java/com/gmail/nossr50/skills/woodcutting/Woodcutting.java

@@ -77,7 +77,7 @@ public final class Woodcutting {
 
         Player player = mcMMOPlayer.getPlayer();
 
-        if (Permissions.woodcuttingDoubleDrops(player)) {
+        if (Permissions.doubleDrops(player, SkillType.WOODCUTTING)) {
             checkForDoubleDrop(mcMMOPlayer, block);
         }
 
@@ -143,7 +143,7 @@ public final class Woodcutting {
         double configDoubleDropChance = ADVANCED_CONFIG.getWoodcuttingDoubleDropChance();
         int configDoubleDropMaxLevel = ADVANCED_CONFIG.getWoodcuttingDoubleDropMaxLevel();
         int probability = (int) ((configDoubleDropChance / configDoubleDropMaxLevel) * Users.getPlayer(player).getProfile().getSkillLevel(SkillType.WOODCUTTING));
-        int activationChance = PerksUtils.handleLuckyPerks(Permissions.luckyWoodcutting(player));
+        int activationChance = PerksUtils.handleLuckyPerks(player, SkillType.WOODCUTTING);
 
         if (probability > configDoubleDropChance) {
             probability = (int) configDoubleDropChance;

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

@@ -38,7 +38,7 @@ public class WoodcuttingCommand extends SkillCommand {
     @Override
     protected void permissionsCheck() {
         canTreeFell = Permissions.treeFeller(player);
-        canDoubleDrop = Permissions.woodcuttingDoubleDrops(player);
+        canDoubleDrop = Permissions.doubleDrops(player, skill);
         canLeafBlow = Permissions.leafBlower(player);
     }
 

+ 2 - 1
src/main/java/com/gmail/nossr50/spout/commands/XplockCommand.java

@@ -6,6 +6,7 @@ import org.bukkit.command.CommandSender;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.skills.utilities.SkillTools;
 import com.gmail.nossr50.skills.utilities.SkillType;
+import com.gmail.nossr50.util.Permissions;
 
 public class XplockCommand extends SpoutCommand {
     @Override
@@ -38,7 +39,7 @@ public class XplockCommand extends SpoutCommand {
 
         SkillType skill = SkillType.getSkill(args[0]);
 
-        if (!sender.hasPermission("mcmmo.commands.xplock." + skill.toString().toLowerCase())) {
+        if (!Permissions.xplock(sender, skill)) {
             sender.sendMessage(command.getPermissionMessage());
             return true;
         }

+ 170 - 643
src/main/java/com/gmail/nossr50/util/Permissions.java

@@ -4,705 +4,232 @@ import java.util.HashMap;
 import java.util.Map;
 
 import org.bukkit.Bukkit;
+import org.bukkit.Material;
 import org.bukkit.command.CommandSender;
-import org.bukkit.entity.Player;
+import org.bukkit.permissions.Permissible;
 import org.bukkit.permissions.Permission;
 import org.bukkit.plugin.PluginManager;
 
+import com.gmail.nossr50.party.commands.PartySubcommandType;
 import com.gmail.nossr50.skills.utilities.SkillType;
 
 public final class Permissions {
     private Permissions() {}
 
-    public static boolean hasPermission(CommandSender sender, String perm) {
-        return (sender.hasPermission(perm));
-    }
-
-    public static boolean hasDynamicPermission(CommandSender sender, String perm, String defaultType) {
-        Map<String, Object> m = new HashMap<String, Object>();
-
-        if(defaultType != null) {
-            m.put("default", defaultType);
-        }
-
-        PluginManager manager = Bukkit.getPluginManager();
-
-        if (manager.getPermission(perm) == null) {
-            Permission.loadPermission(perm, m);
-        }
-
-        return hasPermission(sender, perm);
-    }
-
-    /*
-     * GENERIC PERMISSIONS
-     */
-
-    public static boolean motd(Player player) {
-        return player.hasPermission("mcmmo.motd");
-    }
-
-    /**
-     * @deprecated Use the permission "mcmmo.all" instead.
-     */
-    @Deprecated
-    public static boolean admin(Player player) {
-        return player.hasPermission("mcmmo.admin");
-    }
-
-    /*
-     * MCMMO.BYPASS.*
-     */
-    public static boolean hardcoremodeBypass(Player player) {
-        return player.hasPermission("mcmmo.bypass.hardcoremode");
-    }
-
-    public static boolean arcaneBypass(Player player) {
-        return player.hasPermission("mcmmo.bypass.arcanebypass");
-    }
-
-    /**
-     * @deprecated Use {@link #inspectFar(player)} instead.
-     */
-    @Deprecated
-    public static boolean inspectDistanceBypass(Player player) {
-        return player.hasPermission("mcmmo.bypass.inspect.distance");
-    }
-
-    public static boolean inspectFar(Player player) {
-        return (player.hasPermission("mcmmo.commands.inspect.far"));
-    }
-
-    /**
-     * @deprecated Use {@link #inspectOffline(player)} instead.
-     */
-    @Deprecated
-    public static boolean inspectOfflineBypass(Player player) {
-        return player.hasPermission("mcmmo.bypass.inspect.offline");
-    }
-
-    public static boolean inspectOffline(Player player) {
-        return (player.hasPermission("mcmmo.commands.inspect.offline"));
-    }
-
-    /*
-     * MCMMO.TOOLS.*
-     */
-
-    public static boolean mcrefresh(Player player) {
-        return player.hasPermission("mcmmo.tools.mcrefresh");
-    }
-
-    public static boolean mcremove(Player player) {
-        return player.hasPermission("mcmmo.tools.mcremove");
-    }
-
-    /**
-     * @deprecated Use {@link #mmoeditCommand(player)} instead.
-     */
-    @Deprecated
-    public static boolean mmoedit(CommandSender sender) {
-        return sender.hasPermission("mcmmo.tools.mmoedit");
-    }
-
-    /**
-     * @deprecated Use {@link #mcgodCommand(player)} instead.
-     */
-    @Deprecated
-    public static boolean mcgod(CommandSender sender) {
-        return sender.hasPermission("mcmmo.tools.mcgod");
-    }
-
-    /*
-     * MCMMO.PERKS.LUCKY*
-     */
-
-    public static boolean lucky(Player player, SkillType skill) {
-        return player.hasPermission("mcmmo.perks.lucky." + skill.toString().toLowerCase());
-    }
-
-    public static boolean luckyAcrobatics(Player player) {
-        return player.hasPermission("mcmmo.perks.lucky.acrobatics");
-    }
-
-    public static boolean luckyArchery(Player player) {
-        return player.hasPermission("mcmmo.perks.lucky.archery");
-    }
-
-    public static boolean luckyAxes(Player player) {
-        return player.hasPermission("mcmmo.perks.lucky.axes");
-    }
-
-    public static boolean luckyExcavation(Player player) {
-        return player.hasPermission("mcmmo.perks.lucky.excavation");
-    }
-
-    public static boolean luckyFishing(Player player) {
-        return player.hasPermission("mcmmo.perks.lucky.fishing");
-    }
-
-    public static boolean luckyHerbalism(Player player) {
-        return player.hasPermission("mcmmo.perks.lucky.herbalism");
-    }
-
-    public static boolean luckyMining(Player player) {
-        return player.hasPermission("mcmmo.perks.lucky.mining");
-    }
-
-    public static boolean luckyRepair(Player player) {
-        return player.hasPermission("mcmmo.perks.lucky.repair");
-    }
-
-    public static boolean luckySmelting(Player player) {
-        return player.hasPermission("mcmmo.perks.lucky.smelting");
-    }
-
-    public static boolean luckySwords(Player player) {
-        return player.hasPermission("mcmmo.perks.lucky.swords");
-    }
-
-    public static boolean luckyTaming(Player player) {
-        return player.hasPermission("mcmmo.perks.lucky.taming");
-    }
-
-    public static boolean luckyUnarmed(Player player) {
-        return player.hasPermission("mcmmo.perks.lucky.unarmed");
-    }
-
-    public static boolean luckyWoodcutting(Player player) {
-        return player.hasPermission("mcmmo.perks.lucky.woodcutting");
-    }
-
     /*
-     * MCMMO.PERKS.XP*
+     * GENERAL
      */
 
-    public static boolean xpQuadruple(Player player) {
-        return player.hasPermission("mcmmo.perks.xp.quadruple");
-    }
+    public static boolean motd(Permissible permissible) { return permissible.hasPermission("mcmmo.motd"); }
+    public static boolean updateNotifications(Permissible permissible) {return permissible.hasPermission("mcmmo.tools.updatecheck"); }
+    public static boolean chimaeraWing(Permissible permissible) { return permissible.hasPermission("mcmmo.item.chimaerawing"); }
 
-    public static boolean xpTriple(Player player) {
-        return player.hasPermission("mcmmo.perks.xp.triple");
-    }
+    /* BYPASS */
+    public static boolean hardcoreBypass(Permissible permissible) { return permissible.hasPermission("mcmmo.bypass.hardcoremode"); }
+    public static boolean arcaneBypass(Permissible permissible) { return permissible.hasPermission("mcmmo.bypass.arcanebypass"); }
 
-    public static boolean xpDoubleAndOneHalf(Player player) {
-        return player.hasPermission("mcmmo.perks.xp.150percentboost");
-    }
-
-    public static boolean xpDouble(Player player) {
-        return player.hasPermission("mcmmo.perks.xp.double");
-    }
-
-    public static boolean xpOneAndOneHalf(Player player) {
-        return player.hasPermission("mcmmo.perks.xp.50percentboost");
-    }
+    /* CHAT */
+    public static boolean partyChat(Permissible permissible) { return permissible.hasPermission("mcmmo.chat.partychat"); }
+    public static boolean adminChat(Permissible permissible) { return permissible.hasPermission("mcmmo.chat.adminchat"); }
 
     /*
-     * MCMMO.PERKS.COOLDOWNS*
+     * COMMANDS
      */
 
-    public static boolean cooldownsHalved(Player player) {
-        return player.hasPermission("mcmmo.perks.cooldowns.halved");
-    }
+    public static boolean addlevels(Permissible permissible) { return permissible.hasPermission("mcmmo.commands.addlevels"); }
+    public static boolean addlevelsOthers(Permissible permissible) { return permissible.hasPermission("mcmmo.commands.addlevels.others"); }
 
-    public static boolean cooldownsThirded(Player player) {
-        return player.hasPermission("mcmmo.perks.cooldowns.thirded");
-    }
+    public static boolean addxp(Permissible permissible) { return permissible.hasPermission("mcmmo.commands.addxp"); }
+    public static boolean addxpOthers(Permissible permissible) { return permissible.hasPermission("mcmmo.commands.addxp.others"); }
 
-    public static boolean cooldownsQuartered(Player player) {
-        return player.hasPermission("mcmmo.perks.cooldowns.quartered");
-    }
+    public static boolean hardcoreModify(Permissible permissible) { return permissible.hasPermission("mcmmo.commands.hardcore.modify"); }
+    public static boolean hardcoreToggle(Permissible permissible) { return permissible.hasPermission("mcmmo.commands.hardcore.toggle"); }
 
-    /*
-     * MCMMO.PERKS.ACTIVATIONTIME*
-     */
-
-    public static boolean activationTwelve(Player player) {
-        return player.hasPermission("mcmmo.perks.activationtime.twelveseconds");
-    }
+    public static boolean inspect(Permissible permissible) { return (permissible.hasPermission("mcmmo.commands.inspect")); }
+    public static boolean inspectFar(Permissible permissible) { return (permissible.hasPermission("mcmmo.commands.inspect.far")); }
+    public static boolean inspectOffline(Permissible permissible) { return (permissible.hasPermission("mcmmo.commands.inspect.offline")); }
 
-    public static boolean activationEight(Player player) {
-        return player.hasPermission("mcmmo.perks.activationtime.eightseconds");
-    }
+    public static boolean mcability(Permissible permissible) { return (permissible.hasPermission("mcmmo.commands.mcability")); }
+    public static boolean mcabilityOthers(Permissible permissible) { return (permissible.hasPermission("mcmmo.commands.mcability.others")); }
 
-    public static boolean activationFour(Player player) {
-        return player.hasPermission("mcmmo.perks.activationtime.fourseconds");
-    }
+    public static boolean mcgod(Permissible permissible) { return permissible.hasPermission("mcmmo.commands.mcgod"); }
+    public static boolean mcgodOthers(Permissible permissible) { return permissible.hasPermission("mcmmo.commands.mcgod.others"); }
 
-    /*
-     * MCMMO.ABILITY.TAMING.*
-     */
+    public static boolean mcmmoDescription(Permissible permissible) { return permissible.hasPermission("mcmmo.commands.mcmmo.description"); }
+    public static boolean mcmmoHelp(Permissible permissible) { return permissible.hasPermission("mcmmo.commands.mcmmo.help"); }
 
-    public static boolean fastFoodService(Player player) {
-        return player.hasPermission("mcmmo.ability.taming.fastfoodservice");
-    }
+    public static boolean mcrank(Permissible permissible) { return (permissible.hasPermission("mcmmo.commands.mcrank")); }
+    public static boolean mcrankOthers(Permissible permissible) { return (permissible.hasPermission("mcmmo.commands.mcrank.others")); }
+    public static boolean mcrankFar(Permissible permissible) { return (permissible.hasPermission("mcmmo.commands.mcrank.others.far")); }
+    public static boolean mcrankOffline(Permissible permissible) { return (permissible.hasPermission("mcmmo.commands.mcrank.others.offline")); }
 
-    public static boolean sharpenedClaws(Player player) {
-        return player.hasPermission("mcmmo.ability.taming.sharpenedclaws");
-    }
+    public static boolean mcrefresh(Permissible permissible) { return (permissible.hasPermission("mcmmo.commands.mcrefresh")); }
+    public static boolean mcrefreshOthers(Permissible permissible) { return (permissible.hasPermission("mcmmo.commands.mcrefresh.others")); }
 
-    public static boolean gore(Player player) {
-        return player.hasPermission("mcmmo.ability.taming.gore");
-    }
+    public static boolean mctop(Permissible permissible, SkillType skill) { return permissible.hasPermission("mcmmo.commands.mctop." + skill.toString().toLowerCase()); }
 
-    public static boolean callOfTheWild(Player player) {
-        return player.hasPermission("mcmmo.ability.taming.callofthewild");
-    }
+    public static boolean mmoedit(Permissible permissible) { return permissible.hasPermission("mcmmo.commands.mmoedit"); }
+    public static boolean mmoeditOthers(Permissible permissible) { return permissible.hasPermission("mcmmo.commands.mmoedit.others"); }
 
-    public static boolean environmentallyAware(Player player) {
-        return player.hasPermission("mcmmo.ability.taming.environmentallyaware");
-    }
+    public static boolean skillreset(Permissible permissible) { return permissible.hasPermission("mcmmo.commands.skillreset"); }
+    public static boolean skillreset(Permissible permissible, SkillType skill) { return permissible.hasPermission("mcmmo.commands.skillreset." + skill.toString().toLowerCase()); }
+    public static boolean skillresetOthers(Permissible permissible) { return permissible.hasPermission("mcmmo.commands.skillreset.others"); }
+    public static boolean skillresetOthers(Permissible permissible, SkillType skill) { return permissible.hasPermission("mcmmo.commands.skillreset.others." + skill.toString().toLowerCase()); }
 
-    public static boolean thickFur(Player player) {
-        return player.hasPermission("mcmmo.ability.taming.thickfur");
-    }
+    public static boolean xplock(Permissible permissible, SkillType skill) { return permissible.hasPermission("mcmmo.commands.xplock." + skill.toString().toLowerCase()); }
 
-    public static boolean shockProof(Player player) {
-        return player.hasPermission("mcmmo.ability.taming.shockproof");
-    }
+    public static boolean xprateSet(Permissible permissible) { return permissible.hasPermission("mcmmo.commands.xprate.set"); }
+    public static boolean xprateReset(Permissible permissible) { return permissible.hasPermission("mcmmo.commands.xprate.reset"); }
 
-    public static boolean beastLore(Player player) {
-        return player.hasPermission("mcmmo.ability.taming.beastlore");
-    }
+    public static boolean vampirismModify(Permissible permissible) { return permissible.hasPermission("mcmmo.commands.vampirism.modify"); }
+    public static boolean vampirismToggle(Permissible permissible) { return permissible.hasPermission("mcmmo.commands.vampirism.toggle"); }
 
     /*
-     * MCMMO.ABILITY.FISHING.*
+     * PERKS
      */
 
-    public static boolean shakeMob(Player player) {
-        return player.hasPermission("mcmmo.ability.fishing.shakemob");
-    }
+    public static boolean lucky(Permissible permissible, SkillType skill) { return permissible.hasPermission("mcmmo.perks.lucky." + skill.toString().toLowerCase()); }
 
-    public static boolean fishingTreasures(Player player) {
-        return player.hasPermission("mcmmo.ability.fishing.treasures");
-    }
+    /* XP PERKS */
+    public static boolean quadrupleXp(Permissible permissible) { return permissible.hasPermission("mcmmo.perks.xp.quadruple"); }
+    public static boolean tripleXp(Permissible permissible) { return permissible.hasPermission("mcmmo.perks.xp.triple"); }
+    public static boolean doubleAndOneHalfXp(Permissible permissible) { return permissible.hasPermission("mcmmo.perks.xp.150percentboost"); }
+    public static boolean doubleXp(Permissible permissible) { return permissible.hasPermission("mcmmo.perks.xp.double"); }
+    public static boolean oneAndOneHalfXp(Permissible permissible) { return permissible.hasPermission("mcmmo.perks.xp.50percentboost"); }
 
-    public static boolean fishingMagic(Player player) {
-        return player.hasPermission("mcmmo.ability.fishing.magic");
-    }
+    /* ACTIVATION PERKS */
+    public static boolean twelveSecondActivationBoost(Permissible permissible) { return permissible.hasPermission("mcmmo.perks.activationtime.twelveseconds"); }
+    public static boolean eightSecondActivationBoost(Permissible permissible) { return permissible.hasPermission("mcmmo.perks.activationtime.eightseconds"); }
+    public static boolean fourSecondActivationBoost(Permissible permissible) { return permissible.hasPermission("mcmmo.perks.activationtime.fourseconds"); }
 
-    public static boolean fishermansDiet(Player player) {
-        return player.hasPermission("mcmmo.ability.fishing.fishermansdiet");
-    }
-
-    public static boolean fishingVanillaXPBoost(Player player) {
-        return player.hasPermission("mcmmo.ability.fishing.vanillaxpboost");
-    }
+    /* COOLDOWN PERKS */
+    public static boolean halvedCooldowns(Permissible permissible) { return permissible.hasPermission("mcmmo.perks.cooldowns.halved"); }
+    public static boolean thirdedCooldowns(Permissible permissible) { return permissible.hasPermission("mcmmo.perks.cooldowns.thirded"); }
+    public static boolean quarteredCooldowns(Permissible permissible) { return permissible.hasPermission("mcmmo.perks.cooldowns.quartered"); }
 
     /*
-     * MCMMO.ABILITY.MINING.*
+     * SKILLS
      */
 
-    public static boolean superBreaker(Player player) {
-        return player.hasPermission("mcmmo.ability.mining.superbreaker");
-    }
+    public static boolean skillEnabled(Permissible permissible, SkillType skill) {return permissible.hasPermission("mcmmo.skills." + skill.toString().toLowerCase()); }
+    public static boolean doubleDrops(Permissible permissible, SkillType skill) { return permissible.hasPermission("mcmmo.ability." + skill.toString().toLowerCase() + ".doubledrops"); }
+    public static boolean vanillaXpBoost(Permissible permissible, SkillType skill) { return permissible.hasPermission("mcmmo.ability." + skill.toString().toLowerCase() + ".vanillaxpboost"); }
+    public static boolean bonusDamage(Permissible permissible, SkillType skill) { return permissible.hasPermission("mcmmo.ability." + skill.toString().toLowerCase() + ".bonusdamage"); }
 
-    public static boolean miningDoubleDrops(Player player) {
-        return player.hasPermission("mcmmo.ability.mining.doubledrops");
-    }
+    /* ACROBATICS */
+    public static boolean dodge(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.acrobatics.dodge"); }
+    public static boolean gracefulRoll(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.acrobatics.gracefulroll"); }
+    public static boolean roll(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.acrobatics.roll"); }
 
-    /*
-     * MCMMO.ABILITY.WOODCUTTING.*
-     */
+    /* ARCHERY */
+    public static boolean arrowRetrieval(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.archery.trackarrows"); }
+    public static boolean daze(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.archery.daze"); }
 
-    public static boolean treeFeller(Player player) {
-        return player.hasPermission("mcmmo.ability.woodcutting.treefeller");
-    }
+    /* AXES */
+    public static boolean armorImpact(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.axes.impact"); }
+    public static boolean criticalStrikes(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.axes.criticalhit"); }
+    public static boolean greaterImpact(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.axes.greaterimpact"); }
+    public static boolean skullSplitter(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.axes.skullsplitter"); }
 
-    public static boolean leafBlower(Player player) {
-        return player.hasPermission("mcmmo.ability.woodcutting.leafblower");
-    }
+    /* EXCAVATION */
+    public static boolean gigaDrillBreaker(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.excavation.gigadrillbreaker"); }
+    public static boolean excavationTreasureHunter(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.excavation.treasures"); }
 
-    public static boolean woodcuttingDoubleDrops(Player player) {
-        return player.hasPermission("mcmmo.ability.woodcutting.doubledrops");
-    }
+    /* FISHING */
+    public static boolean fishermansDiet(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.fishing.fishermansdiet"); }
+    public static boolean fishingTreasureHunter(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.fishing.treasures"); }
+    public static boolean magicHunter(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.fishing.magic"); }
+    public static boolean shake(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.fishing.shakemob"); }
 
-    /*
-     * MCMMO.ABILITY.REPAIR.*
-     */
-
-    public static boolean repairBonus(Player player) {
-        return player.hasPermission("mcmmo.ability.repair.repairbonus");
-    }
+    /* HERBALISM */
+    public static boolean farmersDiet(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.herbalism.farmersdiet"); }
+    public static boolean greenTerra(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.herbalism.greenterra"); }
+    public static boolean greenThumbBlock(Permissible permissible, Material material) { return permissible.hasPermission("mcmmo.ability.herbalism.greenthumb.blocks." + material.toString().replace("_", "").toLowerCase()); }
+    public static boolean greenThumbPlant(Permissible permissible, Material material) { return permissible.hasPermission("mcmmo.ability.herbalism.greenthumb.plants." + material.toString().replace("_", "").toLowerCase()); }
+    public static boolean hylianLuck(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.herbalism.hylianluck"); }
 
-    public static boolean repairMastery(Player player) {
-        return player.hasPermission("mcmmo.ability.repair.repairmastery");
-    }
+    /* MINING */
+    public static boolean biggerBombs(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.mining.blastmining.biggerbombs"); }
+    public static boolean demolitionsExpertise(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.mining.blastmining.demolitionsexpertise"); }
+    public static boolean remoteDetonation(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.mining.blastmining.detonate"); }
+    public static boolean superBreaker(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.mining.superbreaker"); }
 
-    public static boolean arcaneForging(Player player) {
-        return player.hasPermission("mcmmo.ability.repair.arcaneforging");
-    }
+    /* REPAIR */
+    public static boolean arcaneForging(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.repair.arcaneforging"); }
+    public static boolean repairMastery(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.repair.repairmastery"); }
+    public static boolean salvage(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.repair.salvage"); }
+    public static boolean superRepair(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.repair.repairbonus"); }
 
-    public static boolean woodRepair(Player player) {
-        return player.hasPermission("mcmmo.ability.repair.woodrepair");
-    }
+    public static boolean repairArmor(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.repair.armorrepair"); }
+    public static boolean repairTools(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.repair.toolrepair"); }
+    public static boolean repairOtherItems(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.repair.otherrepair"); }
 
-    public static boolean stoneRepair(Player player) {
-        return player.hasPermission("mcmmo.ability.repair.stonerepair");
-    }
-
-    public static boolean leatherRepair(Player player) {
-        return player.hasPermission("mcmmo.ability.repair.leatherrepair");
-    }
-
-    public static boolean ironRepair(Player player) {
-        return player.hasPermission("mcmmo.ability.repair.ironrepair");
-    }
-
-    public static boolean goldRepair(Player player) {
-        return player.hasPermission("mcmmo.ability.repair.goldrepair");
-    }
-
-    public static boolean diamondRepair(Player player) {
-        return player.hasPermission("mcmmo.ability.repair.diamondrepair");
-    }
-
-    public static boolean armorRepair(Player player) {
-        return player.hasPermission("mcmmo.ability.repair.armorrepair");
-    }
-
-    public static boolean toolRepair(Player player) {
-        return player.hasPermission("mcmmo.ability.repair.toolrepair");
-    }
-
-    public static boolean otherMaterialRepair(Player player) {
-        return player.hasPermission("mcmmo.ability.repair.othermaterialrepair");
-    }
-
-    public static boolean otherRepair(Player player) {
-        return player.hasPermission("mcmmo.ability.repair.otherrepair");
-    }
-
-    public static boolean stringRepair(Player player) {
-        return player.hasPermission("mcmmo.ability.repair.stringrepair");
-    }
-
-    public static boolean salvage(Player player) {
-        return player.hasPermission("mcmmo.ability.repair.salvage");
-    }
-
-
-    /*
-     * MCMMO.ABILITY.UNARMED.*
-     */
-
-    public static boolean unarmedBonus(Player player) {
-        return player.hasPermission("mcmmo.ability.unarmed.bonusdamage");
-    }
-
-    public static boolean disarm(Player player) {
-        return player.hasPermission("mcmmo.ability.unarmed.disarm");
-    }
-
-    public static boolean berserk(Player player) {
-        return player.hasPermission("mcmmo.ability.unarmed.berserk");
-    }
-
-    public static boolean deflect(Player player) {
-        return player.hasPermission("mcmmo.ability.unarmed.deflect");
-    }
-
-    public static boolean ironGrip(Player player) {
-        return player.hasPermission("mcmmo.ability.unarmed.irongrip");
-    }
-
-    /*
-     * MCMMO.ABILITY.ARCHERY.*
-     */
-
-    public static boolean trackArrows(Player player) {
-        return player.hasPermission("mcmmo.ability.archery.trackarrows");
-    }
-
-    public static boolean daze(Player player) {
-        return player.hasPermission("mcmmo.ability.archery.daze");
-    }
-
-    public static boolean archeryBonus(Player player) {
-        return player.hasPermission("mcmmo.ability.archery.bonusdamage");
-    }
-
-    /*
-     * MCMMO.ABILITY.HERBALISM.*
-     */
-
-    public static boolean herbalismDoubleDrops(Player player) {
-        return player.hasPermission("mcmmo.ability.herbalism.doubledrops");
-    }
-
-    public static boolean greenTerra(Player player) {
-        return player.hasPermission("mcmmo.ability.herbalism.greenterra");
-    }
-
-    public static boolean greenThumbBlocks(Player player) {
-        return player.hasPermission("mcmmo.ability.herbalism.greenthumbblocks");
-    }
-
-    public static boolean greenThumbCarrots(Player player) {
-        return player.hasPermission("mcmmo.ability.herbalism.greenthumbcarrots");
-    }
-
-    public static boolean greenThumbCocoa(Player player) {
-        return player.hasPermission("mcmmo.ability.herbalism.greenthumbcocoa");
-    }
-
-    public static boolean greenThumbNetherwart(Player player) {
-        return player.hasPermission("mcmmo.ability.herbalism.greenthumbnetherwart");
-    }
-
-    public static boolean greenThumbPotatoes(Player player) {
-        return player.hasPermission("mcmmo.ability.herbalism.greenthumbpotatoes");
-    }
-
-    public static boolean greenThumbWheat(Player player) {
-        return player.hasPermission("mcmmo.ability.herbalism.greenthumbwheat");
-    }
-
-    public static boolean farmersDiet(Player player) {
-        return player.hasPermission("mcmmo.ability.herbalism.farmersdiet");
-    }
-
-    public static boolean hylianLuck(Player player) {
-        return player.hasPermission("mcmmo.ability.herbalism.hylianluck");
-    }
-
-    /*
-     * MCMMO.ABILITY.EXCAVATION.*
-     */
-
-    public static boolean gigaDrillBreaker(Player player) {
-        return player.hasPermission("mcmmo.ability.excavation.gigadrillbreaker");
-    }
-
-    public static boolean excavationTreasures(Player player) {
-        return player.hasPermission("mcmmo.ability.excavation.treasures");
-    }
-
-    /*
-     * MCMMO.ABILITY.SWORDS.*
-     */
-
-    public static boolean swordsBleed(Player player) {
-        return player.hasPermission("mcmmo.ability.swords.bleed");
-    }
-
-    public static boolean serratedStrikes(Player player) {
-        return player.hasPermission("mcmmo.ability.swords.serratedstrikes");
-    }
-
-    public static boolean counterAttack(Player player) {
-        return player.hasPermission("mcmmo.ability.swords.counterattack");
-    }
-
-    /*
-     * MCMMO.ABILITY.AXES.*
-     */
-
-    public static boolean skullSplitter(Player player) {
-        return player.hasPermission("mcmmo.ability.axes.skullsplitter");
-    }
-
-    public static boolean axeBonus(Player player) {
-        return player.hasPermission("mcmmo.ability.axes.bonusdamage");
-    }
-
-    public static boolean criticalHit(Player player) {
-        return player.hasPermission("mcmmo.ability.axes.criticalhit");
-    }
-
-    public static boolean impact(Player player) {
-        return player.hasPermission("mcmmo.ability.axes.impact");
-    }
-
-    public static boolean greaterImpact(Player player) {
-        return player.hasPermission("mcmmo.ability.axes.greaterimpact");
-    }
-
-    /*
-     * MCMMO.ABILITY.ACROBATICS.*
-     */
-
-    public static boolean roll(Player player) {
-        return player.hasPermission("mcmmo.ability.acrobatics.roll");
-    }
-
-    public static boolean gracefulRoll(Player player) {
-        return player.hasPermission("mcmmo.ability.acrobatics.gracefulroll");
-    }
-
-    public static boolean dodge(Player player) {
-        return player.hasPermission("mcmmo.ability.acrobatics.dodge");
-    }
-
-    /*
-     * MCMMO.ABILITY.BLASTMINING.*
-     */
-
-    public static boolean biggerBombs(Player player) {
-        return player.hasPermission("mcmmo.ability.mining.blastmining.biggerbombs");
-    }
-
-    public static boolean demolitionsExpertise(Player player) {
-        return player.hasPermission("mcmmo.ability.mining.blastmining.demolitionsexpertise");
-    }
-
-    public static boolean blastMining(Player player) {
-        return player.hasPermission("mcmmo.ability.mining.blastmining.detonate");
-    }
-
-    /*
-     * MCMMO.ABILITY.SMELTING.* 
-     */
-
-    public static boolean fuelEfficiency(Player player) {
-        return player.hasPermission("mcmmo.ability.smelting.fuelefficiency");
-    }
-
-    public static boolean secondSmelt(Player player) {
-        return player.hasPermission("mcmmo.ability.smelting.secondsmelt");
-    }
-
-    public static boolean fluxMining(Player player) {
-        return player.hasPermission("mcmmo.ability.smelting.fluxmining");
-    }
-
-    public static boolean smeltingVanillaXPBoost(Player player) {
-        return player.hasPermission("mcmmo.ability.smelting.vanillaxpboost");
-    }
-
-    /*
-     * MCMMO.ITEM.*
-     */
-
-    public static boolean chimaeraWing(Player player) {
-        return hasPermission(player, "mcmmo.item.chimaerawing");
-    }
-
-    /*
-     * MCMMO.COMMANDS.*
-     */
-
-    public static boolean mmoeditCommand(Player player) {
-        return (player.hasPermission("mcmmo.commands.mmoedit"));
-    }
-
-    public static boolean skillResetCommand(Player player) {
-        return (player.hasPermission("mcmmo.commands.skillreset"));
-    }
-
-    public static boolean mcAbilityCommand(Player player) {
-        return (player.hasPermission("mcmmo.commands.mcability"));
-    }
-
-    public static boolean mcgodCommand(CommandSender sender) {
-        return (hasPermission(sender, "mcmmo.commands.mcgod"));
-    }
-
-    /**
-     * @deprecated Use {@link #mcAbilityCommand(player)} instead.
-     */
-    @Deprecated
-    public static boolean mcAbility(Player player) {
-        return player.hasPermission("mcmmo.commands.ability");
-    }
-
-    public static boolean partyTeleport(Player player) {
-        return player.hasPermission("mcmmo.commands.ptp");
-    }
-
-    public static boolean inspect(Player player) {
-        return player.hasPermission("mcmmo.commands.inspect");
-    }
-
-    public static boolean party(Player player) {
-        return player.hasPermission("mcmmo.commands.party");
-    }
-
-    /**
-     * @deprecated Use {@link #skillResetCommand(player)} instead.
-     */
-    @Deprecated
-    public static boolean skillReset(Player player) {
-        return player.hasPermission("mcmmo.skillreset");
-    }
-
-    /*
-     * MCMMO.CHAT.*
-     */
-
-    public static boolean partyChat(Player player) {
-        return player.hasPermission("mcmmo.chat.partychat");
-    }
-
-    public static boolean partyLock(Player player) {
-        return player.hasPermission("mcmmo.chat.partylock");
-    }
-
-    public static boolean adminChat(Player player) {
-        return player.hasPermission("mcmmo.chat.adminchat");
-    }
-
-    /*
-     * MCMMO.SKILLS.*
-     */
-
-    public static boolean taming(Player player) {
-        return player.hasPermission("mcmmo.skills.taming");
-    }
-
-    public static boolean mining(Player player) {
-        return player.hasPermission("mcmmo.skills.mining");
-    }
-
-    public static boolean fishing(Player player) {
-        return player.hasPermission("mcmmo.skills.fishing");
-    }
-
-    public static boolean woodcutting(Player player) {
-        return player.hasPermission("mcmmo.skills.woodcutting");
-    }
-
-    public static boolean repair(Player player) {
-        return player.hasPermission("mcmmo.skills.repair");
-    }
-
-    public static boolean unarmed(Player player) {
-        return player.hasPermission("mcmmo.skills.unarmed");
-    }
-
-    public static boolean archery(Player player) {
-        return player.hasPermission("mcmmo.skills.archery");
-    }
-
-    public static boolean herbalism(Player player) {
-        return player.hasPermission("mcmmo.skills.herbalism");
-    }
-
-    public static boolean excavation(Player player) {
-        return player.hasPermission("mcmmo.skills.excavation");
-    }
-
-    public static boolean swords(Player player) {
-        return player.hasPermission("mcmmo.skills.swords");
-    }
-
-    public static boolean axes(Player player) {
-        return player.hasPermission("mcmmo.skills.axes");
-    }
+    public static boolean repairDiamond(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.repair.diamondrepair"); }
+    public static boolean repairGold(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.repair.goldrepair"); }
+    public static boolean repairIron(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.repair.ironrepair"); }
+    public static boolean repairLeather(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.repair.leatherrepair"); }
+    public static boolean repairOtherMaterials(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.repair.othermaterialrepair"); }
+    public static boolean repairString(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.repair.stringrepair"); }
+    public static boolean repairStone(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.repair.stonerepair"); }
+    public static boolean repairWood(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.repair.woodrepair"); }
+
+    /* SMELTING */
+    public static boolean fluxMining(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.smelting.fluxmining"); }
+    public static boolean fuelEfficiency(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.smelting.fuelefficiency"); }
+
+    /* SWORDS */
+    public static boolean bleed(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.swords.bleed"); }
+    public static boolean counterAttack(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.swords.counterattack"); }
+    public static boolean serratedStrikes(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.swords.serratedstrikes"); }
+
+    /* TAMING */
+    public static boolean beastLore(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.taming.beastlore"); }
+    public static boolean callOfTheWild(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.taming.callofthewild"); }
+    public static boolean environmentallyAware(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.taming.environmentallyaware"); }
+    public static boolean fastFoodService(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.taming.fastfoodservice"); }
+    public static boolean gore(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.taming.gore"); }
+    public static boolean thickFur(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.taming.thickfur"); }
+    public static boolean sharpenedClaws(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.taming.sharpenedclaws"); }
+    public static boolean shockProof(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.taming.shockproof"); }
+
+    /* UNARMED */
+    public static boolean arrowDeflect(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.unarmed.deflect"); }
+    public static boolean berserk(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.unarmed.berserk"); }
+    public static boolean blockCracker(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.unarmed.blockcracker"); }
+    public static boolean disarm(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.unarmed.disarm"); }
+    public static boolean ironGrip(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.unarmed.irongrip"); }
+
+    /* WOODCUTTING */
+    public static boolean leafBlower(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.woodcutting.leafblower"); }
+    public static boolean treeFeller(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.woodcutting.treefeller"); }
+
+    /*
+     * PARTY
+     */
+
+    public static boolean party(Permissible permissible) { return permissible.hasPermission("mcmmo.commands.party"); }
+    public static boolean partySubcommand(Permissible permissible, PartySubcommandType subcommand) {return permissible.hasPermission("mcmmo.commands.party." + subcommand.toString().toLowerCase()); }
+    public static boolean friendlyFire(Permissible permissible) { return permissible.hasPermission("mcmmo.party.friendlyfire"); }
+
+    /* TELEPORT */
+    public static boolean partyTeleportAccept(Permissible permissible) { return permissible.hasPermission("mcmmo.commands.ptp.accept"); }
+    public static boolean partyTeleportAcceptAll(Permissible permissible) { return permissible.hasPermission("mcmmo.commands.ptp.acceptall"); }
+    public static boolean partyTeleportToggle(Permissible permissible) { return permissible.hasPermission("mcmmo.commands.ptp.toggle"); }
+
+    // TODO: Still think there's a better way to handle this
+    public static boolean hasDynamicPermission(CommandSender sender, String perm, String defaultType) {
+        Map<String, Object> m = new HashMap<String, Object>();
 
-    public static boolean acrobatics(Player player) {
-        return player.hasPermission("mcmmo.skills.acrobatics");
-    }
+        if(defaultType != null) {
+            m.put("default", defaultType);
+        }
 
-    public static boolean smelting(Player player) {
-        return player.hasPermission("mcmmo.skills.smelting");
-    }
+        PluginManager manager = Bukkit.getPluginManager();
 
-    /*
-     * MCMMO.PARTY.*
-     */
+        if (manager.getPermission(perm) == null) {
+            Permission.loadPermission(perm, m);
+        }
 
-    public static boolean friendlyFire(Player player) {
-        return player.hasPermission("mcmmo.party.friendlyfire");
+        return sender.hasPermission(perm);
     }
 }

+ 0 - 5
src/main/resources/config.yml

@@ -149,11 +149,6 @@ Skills:
     Herbalism:
         Level_Cap: 0
         Prevent_AFK_Leveling: true
-        Green_Thumb:
-            Cobble_To_Mossy: true
-            CobbleWall_To_MossyWall: true
-            SmoothBrick_To_MossyBrick: true
-            Dirt_To_Grass: true
     Mining:
         Level_Cap: 0
         Detonator_ID: 259

+ 50 - 17
src/main/resources/plugin.yml

@@ -272,12 +272,8 @@ permissions:
             mcmmo.ability.herbalism.doubledrops: true
             mcmmo.ability.herbalism.farmersdiet: true
             mcmmo.ability.herbalism.greenterra: true
-            mcmmo.ability.herbalism.greenthumbblocks: true
-            mcmmo.ability.herbalism.greenthumbcarrots: true
-            mcmmo.ability.herbalism.greenthumbcocoa: true
-            mcmmo.ability.herbalism.greenthumbnetherwart: true
-            mcmmo.ability.herbalism.greenthumbpotatoes: true
-            mcmmo.ability.herbalism.greenthumbwheat: true
+            mcmmo.ability.herbalism.greenthumb.blocks.all: true
+            mcmmo.ability.herbalims.greenthumb.plants.all: true
             mcmmo.ability.herbalism.hylianluck: true
     mcmmo.ability.herbalism.doubledrops:
         description: Allows double drop chance from Herbalism
@@ -285,18 +281,39 @@ permissions:
         description: Allows access to the Farmer's Diet ability
     mcmmo.ability.herbalism.greenterra:
         description: Allows access to the Green Terra ability
-    mcmmo.ability.herbalism.greenthumbblocks:
-        description: Allows access to the Green Thumb ability for blocks
-    mcmmo.ability.herbalism.greenthumbcarrots:
+    mcmmo.ability.herbalism.greenthumb.blocks.all:
+        description: Allows access to all Green Thumb abilities for blocks
+        children:
+            mcmmo.ability.herbalism.greenthumb.blocks.cobblestone: true
+            mcmmo.ability.herbalism.greenthumb.blocks.cobblewall: true
+            mcmmo.ability.herbalism.greenthumb.blocks.dirt: true
+            mcmmo.ability.herbalism.greenthumb.blocks.smoothbrick: true
+    mcmmo.ability.herbalism.greenthumb.blocks.cobblestone:
+        description: Allows access to the Green Thumb ability for cobblestone
+    mcmmo.ability.herbalism.greenthumb.blocks.cobblewall:
+        description: Allows access to the Green Thumb ability for cobblestone walls
+    mcmmo.ability.herbalism.greenthumb.blocks.dirt:
+        description: Allows access to the Green Thumb ability for dirt
+    mcmmo.ability.herbalism.greenthumb.blocks.smoothbrick:
+        description: Allows access to the Green Thumb ability for smooth brick
+    mcmmo.ability.herbalism.greenthumb.plants.all:
+        description: Allows access to all Green Thumb abilities for plants
+        children:
+            mcmmo.ability.herbalism.greenthumb.plants.carrot: true
+            mcmmo.ability.herbalism.greenthumb.plants.cocoa: true
+            mcmmo.ability.herbalism.greenthumb.plants.crops: true
+            mcmmo.ability.herbalism.greenthumb.plants.netherwarts: true
+            mcmmo.ability.herbalism.greenthumb.plants.potato: true
+    mcmmo.ability.herbalism.greenthumb.plants.carrot:
         description: Allows access to the Green Thumb ability for carrots
-    mcmmo.ability.herbalism.greenthumbcocoa:
+    mcmmo.ability.herbalism.greenthumb.plants.cocoa:
         description: Allows access to the Green Thumb ability for cocoa
-    mcmmo.ability.herbalism.greenthumbnetherwart:
+    mcmmo.ability.herbalism.greenthumb.plants.crops:
+        description: Allows access to the Green Thumb ability for wheat
+    mcmmo.ability.herbalism.greenthumb.plants.netherwarts:
         description: Allows access to the Green Thumb ability for netherwart
-    mcmmo.ability.herbalism.greenthumbpotatoes:
+    mcmmo.ability.herbalism.greenthumb.plants.potato:
         description: Allows access to the Green Thumb ability for potatoes
-    mcmmo.ability.herbalism.greenthumbwheat:
-        description: Allows access to the Green Thumb ability for wheat
     mcmmo.ability.herbalism.hylianluck:
         description: Allows access to the Hylian Luck ability
     mcmmo.ability.mining.*:
@@ -400,7 +417,7 @@ permissions:
         description: Allows access to the Flux Mining ability
     mcmmo.ability.smelting.fuelefficiency:
         description: Allows access to the Fuel Efficiency ability
-    mcmmo.ability.smelting.secondsmelt:
+    mcmmo.ability.smelting.doubledrops:
         description: Allows access to the Second Smelt ability
     mcmmo.ability.smelting.vanillaxpboost:
         description: Allows vanilla XP boost from Smelting
@@ -701,9 +718,9 @@ permissions:
     mcmmo.commands.mcmmo.all:
         description: Implies access to all mcmmo.commands.mcmmo permissions.
         children:
-            mcmmo.commands.mcmmo: true
+            mcmmo.commands.mcmmo.description: true
             mcmmo.commands.mcmmo.help: true
-    mcmmo.commands.mcmmo:
+    mcmmo.commands.mcmmo.description:
         description: Allows access to the mcmmo command
     mcmmo.commands.mcmmo.help:
         description: Allows access to the mcmmo help command
@@ -807,9 +824,12 @@ permissions:
         children:
             mcmmo.commands.party: true
             mcmmo.commands.party.accept: true
+            mcmmo.commands.party.chat: true
             mcmmo.commands.party.create: true
             mcmmo.commands.party.disband: true
             mcmmo.commands.party.expshare: true
+            mcmmo.commands.party.help: true
+            mcmmo.commands.party.info: true
             mcmmo.commands.party.invite: true
             mcmmo.commands.party.itemshare: true
             mcmmo.commands.party.join: true
@@ -819,17 +839,26 @@ permissions:
             mcmmo.commands.party.password: true
             mcmmo.commands.party.quit: true
             mcmmo.commands.party.rename: true
+            mcmmo.commands.party.teleport: true
             mcmmo.commands.party.unlock: true
     mcmmo.commands.party:
         description: Allows access to the party command
     mcmmo.commands.party.accept:
         description: Allows access to the party accept command
+    mcmmo.commands.party.chat:
+        description: Dummy permission for mcmmo.chat.partychat
+        children:
+            mcmmo.chat.partychat: true
     mcmmo.commands.party.create:
         description: Allows access to the party create command
     mcmmo.commands.party.disband:
         description: Allows access to the party disband command
     mcmmo.commands.party.expshare:
         description: Allows access to the party expshare command
+    mcmmo.commands.party.help:
+        description: Allows access to the party help command
+    mcmmo.commands.party.info:
+        description: Allows access to the party info command
     mcmmo.commands.party.invite:
         description: Allows access to the party invite command
     mcmmo.commands.party.itemshare:
@@ -848,6 +877,10 @@ permissions:
         description: Allows access to the party quit command
     mcmmo.commands.party.rename:
         description: Allows access to the party rename command
+    mcmmo.commands.party.teleport:
+        description: Dummy permission for mcmmo.commands.ptp
+        children:
+            mcmmo.commands.ptp: true
     mcmmo.commands.party.unlock:
         description: Allows access to the party unlock command
     mcmmo.commands.ptp.*: