Selaa lähdekoodia

We cutting corners boys

nossr50 5 vuotta sitten
vanhempi
sitoutus
8a4b1bf307

+ 4 - 6
src/main/java/com/gmail/nossr50/commands/skills/RepairCommand.java

@@ -4,9 +4,7 @@ import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 import com.gmail.nossr50.datatypes.skills.SubSkillType;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.skills.repair.RepairManager;
-import com.gmail.nossr50.skills.repair.repairables.Repairable;
 import net.md_5.bungee.api.chat.TextComponent;
-import org.bukkit.Material;
 import org.bukkit.entity.Player;
 
 import java.util.ArrayList;
@@ -41,10 +39,10 @@ public class RepairCommand extends SkillCommand {
     @Override
     protected void dataCalculations(Player player, double skillValue) {
         // We're using pickaxes here, not the best but it works
-        Repairable diamondRepairable = pluginRef.getRepairableManager().getRepairable(Material.DIAMOND_PICKAXE);
-        Repairable goldRepairable = pluginRef.getRepairableManager().getRepairable(Material.GOLDEN_PICKAXE);
-        Repairable ironRepairable = pluginRef.getRepairableManager().getRepairable(Material.IRON_PICKAXE);
-        Repairable stoneRepairable = pluginRef.getRepairableManager().getRepairable(Material.STONE_PICKAXE);
+//        Repairable diamondRepairable = pluginRef.getRepairableManager().getRepairable(Material.DIAMOND_PICKAXE);
+//        Repairable goldRepairable = pluginRef.getRepairableManager().getRepairable(Material.GOLDEN_PICKAXE);
+//        Repairable ironRepairable = pluginRef.getRepairableManager().getRepairable(Material.IRON_PICKAXE);
+//        Repairable stoneRepairable = pluginRef.getRepairableManager().getRepairable(Material.STONE_PICKAXE);
 
         // TODO: This isn't really accurate - if they don't have pickaxes loaded it doesn't always mean the repair level is 0
 //        diamondLevel = (diamondRepairable == null) ? 0 : diamondRepairable.getMinimumLevel();

+ 1 - 1
src/main/java/com/gmail/nossr50/config/ConfigManager.java

@@ -276,7 +276,7 @@ public final class ConfigManager {
         customSerializers.registerType(TypeToken.of(ItemMatch.class), new CustomItemTargetSerializer());
         customSerializers.registerType(TypeToken.of(RepairTransaction.class), new RepairTransactionSerializer());
         customSerializers.registerType(TypeToken.of(RawNBT.class), new RawNBTSerializer());
-        customSerializers.registerType(TypeToken.of(RepairCost.class), new RepairCostSerializer());
+        customSerializers.registerType(TypeToken.of(RepairCost.class), new SimpleRepairCostSerializer());
     }
 
     /**

+ 0 - 28
src/main/java/com/gmail/nossr50/config/hocon/serializers/RepairCostSerializer.java

@@ -1,28 +0,0 @@
-package com.gmail.nossr50.config.hocon.serializers;
-
-import com.gmail.nossr50.datatypes.items.ItemMatch;
-import com.gmail.nossr50.skills.repair.RepairCost;
-import com.gmail.nossr50.skills.repair.SimpleRepairCost;
-import com.google.common.reflect.TypeToken;
-import ninja.leaping.configurate.ConfigurationNode;
-import ninja.leaping.configurate.objectmapping.ObjectMappingException;
-import ninja.leaping.configurate.objectmapping.serialize.TypeSerializer;
-import org.checkerframework.checker.nullness.qual.NonNull;
-import org.checkerframework.checker.nullness.qual.Nullable;
-
-public class RepairCostSerializer implements TypeSerializer<RepairCost<?>> {
-
-    private static final String TARGET_ITEM = "Target-Item";
-
-    @Nullable
-    @Override
-    public RepairCost<?> deserialize(@NonNull TypeToken<?> type, @NonNull ConfigurationNode value) throws ObjectMappingException {
-        ItemMatch itemMatch = value.getNode(TARGET_ITEM).getValue(TypeToken.of(ItemMatch.class));
-        return new SimpleRepairCost(itemMatch);
-    }
-
-    @Override
-    public void serialize(@NonNull TypeToken<?> type, @Nullable RepairCost<?> obj, @NonNull ConfigurationNode value) throws ObjectMappingException {
-        value.getNode(TARGET_ITEM).setValue(obj.getRepairCosts());
-    }
-}

+ 28 - 0
src/main/java/com/gmail/nossr50/config/hocon/serializers/SimpleRepairCostSerializer.java

@@ -0,0 +1,28 @@
+package com.gmail.nossr50.config.hocon.serializers;
+
+import com.gmail.nossr50.datatypes.items.ItemMatch;
+import com.gmail.nossr50.skills.repair.SimpleRepairCost;
+import com.google.common.reflect.TypeToken;
+import ninja.leaping.configurate.ConfigurationNode;
+import ninja.leaping.configurate.objectmapping.ObjectMappingException;
+import ninja.leaping.configurate.objectmapping.serialize.TypeSerializer;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.checkerframework.checker.nullness.qual.Nullable;
+
+public class SimpleRepairCostSerializer implements TypeSerializer<SimpleRepairCost<?>> {
+
+    private static final String ITEM_MATCH = "Item-Match";
+
+    @Nullable
+    @Override
+    public SimpleRepairCost<?> deserialize(@NonNull TypeToken<?> type, @NonNull ConfigurationNode value) throws ObjectMappingException {
+        ItemMatch<?> itemMatch = value.getNode(ITEM_MATCH).getValue(new TypeToken<ItemMatch<?>>() {});
+        SimpleRepairCost<?> simpleRepairCost = new SimpleRepairCost<>(itemMatch);
+        return simpleRepairCost;
+    }
+
+    @Override
+    public void serialize(@NonNull TypeToken<?> type, @Nullable SimpleRepairCost<?> obj, @NonNull ConfigurationNode value) throws ObjectMappingException {
+        value.getNode(ITEM_MATCH).setValue(obj.getItemMatch());
+    }
+}

+ 3 - 1
src/main/java/com/gmail/nossr50/datatypes/items/ItemMatch.java

@@ -1,5 +1,7 @@
 package com.gmail.nossr50.datatypes.items;
 
+import com.gmail.nossr50.util.nbt.NBTManager;
+
 import java.util.HashSet;
 import java.util.Objects;
 import java.util.Set;
@@ -78,7 +80,7 @@ public class ItemMatch<T extends MMOItem<?>> implements DefinedMatch<MMOItem<T>>
      */
     private boolean isStrictMatch(MMOItem<T> otherItem) {
         for(ItemMatchProperty itemMatchProperty : itemMatchProperties) {
-            if(!pluginRef.getNbtManager().hasNBT(otherItem.getRawNBT().getNbtData(), itemMatchProperty.getNbtData())) {
+            if(!NBTManager.hasNBT(otherItem.getRawNBT().getNbtData(), itemMatchProperty.getNbtData())) {
                 return false;
             }
         }

+ 2 - 2
src/main/java/com/gmail/nossr50/skills/repair/RepairManager.java

@@ -311,10 +311,10 @@ public class RepairManager extends SkillManager {
 
             Enchantment enchantment = enchant.getKey();
 
-            if (pluginRef.getRandomChanceTools().checkRandomChanceExecutionSuccess(new RandomChanceSkillStatic(getKeepEnchantChance(), getPlayer(), SubSkillType.REPAIR_ARCANE_FORGING))) {
+            if (pluginRef.getRandomChanceTools().checkRandomChanceExecutionSuccess(new RandomChanceSkillStatic(pluginRef, getKeepEnchantChance(), getPlayer(), SubSkillType.REPAIR_ARCANE_FORGING))) {
 
                 if (pluginRef.getConfigManager().getConfigRepair().getArcaneForging().isDowngradesEnabled() && enchantLevel > 1
-                        && (!pluginRef.getRandomChanceTools().checkRandomChanceExecutionSuccess(new RandomChanceSkillStatic(100 - getDowngradeEnchantChance(), getPlayer(), SubSkillType.REPAIR_ARCANE_FORGING)))) {
+                        && (!pluginRef.getRandomChanceTools().checkRandomChanceExecutionSuccess(new RandomChanceSkillStatic(pluginRef,100 - getDowngradeEnchantChance(), getPlayer(), SubSkillType.REPAIR_ARCANE_FORGING)))) {
                     item.addUnsafeEnchantment(enchantment, enchantLevel - 1);
                     downgraded = true;
                 }

+ 105 - 107
src/main/java/com/gmail/nossr50/skills/salvage/SalvageManager.java

@@ -7,8 +7,6 @@ import com.gmail.nossr50.datatypes.skills.SubSkillType;
 import com.gmail.nossr50.datatypes.skills.behaviours.SalvageBehaviour;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.skills.SkillManager;
-import com.gmail.nossr50.skills.salvage.salvageables.Salvageable;
-import com.gmail.nossr50.util.StringUtils;
 import com.gmail.nossr50.util.random.RandomChanceSkillStatic;
 import com.gmail.nossr50.util.sounds.SoundType;
 import org.bukkit.Location;
@@ -53,109 +51,109 @@ public class SalvageManager extends SkillManager {
     }
 
     public void handleSalvage(Location location, ItemStack item) {
-        Player player = getPlayer();
-
-        Salvageable salvageable = pluginRef.getSalvageableManager().getSalvageable(item.getType());
-
-        if (item.getItemMeta().isUnbreakable()) {
-            pluginRef.getNotificationManager().sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE_FAILED, "Anvil.Unbreakable");
-            return;
-        }
-
-        // Permissions checks on material and item types
-        if (!pluginRef.getPermissionTools().salvageItemType(player, salvageable.getSalvageItemType())) {
-            pluginRef.getNotificationManager().sendPlayerInformation(player, NotificationType.NO_PERMISSION, "mcMMO.NoPermission");
-            return;
-        }
-
-        if (!pluginRef.getPermissionTools().salvageMaterialType(player, salvageable.getSalvageItemMaterialCategory())) {
-            pluginRef.getNotificationManager().sendPlayerInformation(player, NotificationType.NO_PERMISSION, "mcMMO.NoPermission");
-            return;
-        }
-
-        /*int skillLevel = getSkillLevel();
-        int minimumSalvageableLevel = salvageable.getMinimumLevel();*/
-
-        // Level check
-        if (!pluginRef.getRankTools().hasUnlockedSubskill(player, SubSkillType.SALVAGE_ARCANE_SALVAGE)) {
-            pluginRef.getNotificationManager().sendPlayerInformation(player, NotificationType.REQUIREMENTS_NOT_MET, "Salvage.Skills.Adept.Level", String.valueOf(pluginRef.getRankTools().getUnlockLevel(SubSkillType.SALVAGE_ARCANE_SALVAGE)), StringUtils.getPrettyItemString(item.getType()));
-            return;
-        }
-
-        int potentialSalvageYield = salvageBehaviour.calculateSalvageableAmount(item.getDurability(), salvageable.getMaximumDurability(), salvageable.getMaximumQuantity());
-
-        if (potentialSalvageYield <= 0) {
-            pluginRef.getNotificationManager().sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE_FAILED, "Salvage.Skills.TooDamaged");
-            return;
-        }
-
-        potentialSalvageYield = Math.min(potentialSalvageYield, getSalvageLimit()); // Always get at least something back, if you're capable of salvaging it.
-
-        player.getInventory().setItemInMainHand(new ItemStack(Material.AIR));
-        location.add(0.5, 1, 0.5);
-
-        Map<Enchantment, Integer> enchants = item.getEnchantments();
-
-        ItemStack enchantBook = null;
-        if (!enchants.isEmpty()) {
-            enchantBook = arcaneSalvageCheck(enchants);
-        }
-
-        //Lottery on Salvageable Amount
-
-        int lotteryResults = 1;
-        int chanceOfSuccess = 99;
-
-        for(int x = 0; x < potentialSalvageYield-1; x++) {
-
-            if(pluginRef.getRandomChanceTools().rollDice(chanceOfSuccess, 100)) {
-                chanceOfSuccess-=2;
-                Math.max(chanceOfSuccess, 95);
-
-                lotteryResults+=1;
-            }
-        }
-
-        if(lotteryResults == potentialSalvageYield && potentialSalvageYield != 1 && pluginRef.getRankTools().isPlayerMaxRankInSubSkill(player, SubSkillType.SALVAGE_ARCANE_SALVAGE)) {
-            pluginRef.getNotificationManager().sendPlayerInformationChatOnly(player, "Salvage.Skills.Lottery.Perfect", String.valueOf(lotteryResults), StringUtils.getPrettyItemString(item.getType()));
-        } else if(salvageable.getMaximumQuantity() == 1 || getSalvageLimit() >= salvageable.getMaximumQuantity()) {
-            pluginRef.getNotificationManager().sendPlayerInformationChatOnly(player,  "Salvage.Skills.Lottery.Normal", String.valueOf(lotteryResults), StringUtils.getPrettyItemString(item.getType()));
-        } else {
-            pluginRef.getNotificationManager().sendPlayerInformationChatOnly(player,  "Salvage.Skills.Lottery.Untrained", String.valueOf(lotteryResults), StringUtils.getPrettyItemString(item.getType()));
-        }
-
-        ItemStack salvageResults = new ItemStack(salvageable.getSalvagedItemMaterial(), lotteryResults);
-
-        //Call event
-        if (pluginRef.getEventManager().callSalvageCheckEvent(player, item, salvageResults, enchantBook).isCancelled()) {
-            return;
-        }
-
-        Location anvilLoc = location.clone();
-        Location playerLoc = player.getLocation().clone();
-        double distance = anvilLoc.distance(playerLoc);
-
-        double speedLimit = .6;
-        double minSpeed = .3;
-
-        //Clamp the speed and vary it by distance
-        double vectorSpeed = Math.min(speedLimit, Math.max(minSpeed, distance * .2));
-
-        //Add a very small amount of height
-        anvilLoc.add(0, .1, 0);
-
-        if (enchantBook != null) {
-            pluginRef.getMiscTools().spawnItemTowardsLocation(anvilLoc.clone(), playerLoc.clone(), enchantBook, vectorSpeed);
-        }
-
-        pluginRef.getMiscTools().spawnItemTowardsLocation(anvilLoc.clone(), playerLoc.clone(), salvageResults, vectorSpeed);
-
-        // BWONG BWONG BWONG - CLUNK!
-        if (pluginRef.getConfigManager().getConfigSalvage().getGeneral().isAnvilUseSounds()) {
-            pluginRef.getSoundManager().sendSound(player, player.getLocation(), SoundType.ITEM_BREAK);
-        }
-
-        pluginRef.getNotificationManager().sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE, "Salvage.Skills.Success");
+//        Player player = getPlayer();
+//
+//        Salvageable salvageable = pluginRef.getSalvageableManager().getSalvageable(item.getType());
+//
+//        if (item.getItemMeta().isUnbreakable()) {
+//            pluginRef.getNotificationManager().sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE_FAILED, "Anvil.Unbreakable");
+//            return;
+//        }
+//
+//        // Permissions checks on material and item types
+//        if (!pluginRef.getPermissionTools().salvageItemType(player, salvageable.getSalvageItemType())) {
+//            pluginRef.getNotificationManager().sendPlayerInformation(player, NotificationType.NO_PERMISSION, "mcMMO.NoPermission");
+//            return;
+//        }
+//
+//        if (!pluginRef.getPermissionTools().salvageMaterialType(player, salvageable.getSalvageItemMaterialCategory())) {
+//            pluginRef.getNotificationManager().sendPlayerInformation(player, NotificationType.NO_PERMISSION, "mcMMO.NoPermission");
+//            return;
+//        }
+//
+//        /*int skillLevel = getSkillLevel();
+//        int minimumSalvageableLevel = salvageable.getMinimumLevel();*/
+//
+//        // Level check
+//        if (!pluginRef.getRankTools().hasUnlockedSubskill(player, SubSkillType.SALVAGE_ARCANE_SALVAGE)) {
+//            pluginRef.getNotificationManager().sendPlayerInformation(player, NotificationType.REQUIREMENTS_NOT_MET, "Salvage.Skills.Adept.Level", String.valueOf(pluginRef.getRankTools().getUnlockLevel(SubSkillType.SALVAGE_ARCANE_SALVAGE)), StringUtils.getPrettyItemString(item.getType()));
+//            return;
+//        }
+//
+//        int potentialSalvageYield = salvageBehaviour.calculateSalvageableAmount(item.getDurability(), salvageable.getMaximumDurability(), salvageable.getMaximumQuantity());
+//
+//        if (potentialSalvageYield <= 0) {
+//            pluginRef.getNotificationManager().sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE_FAILED, "Salvage.Skills.TooDamaged");
+//            return;
+//        }
+//
+//        potentialSalvageYield = Math.min(potentialSalvageYield, getSalvageLimit()); // Always get at least something back, if you're capable of salvaging it.
+//
+//        player.getInventory().setItemInMainHand(new ItemStack(Material.AIR));
+//        location.add(0.5, 1, 0.5);
+//
+//        Map<Enchantment, Integer> enchants = item.getEnchantments();
+//
+//        ItemStack enchantBook = null;
+//        if (!enchants.isEmpty()) {
+//            enchantBook = arcaneSalvageCheck(enchants);
+//        }
+//
+//        //Lottery on Salvageable Amount
+//
+//        int lotteryResults = 1;
+//        int chanceOfSuccess = 99;
+//
+//        for(int x = 0; x < potentialSalvageYield-1; x++) {
+//
+//            if(pluginRef.getRandomChanceTools().rollDice(chanceOfSuccess, 100)) {
+//                chanceOfSuccess-=2;
+//                Math.max(chanceOfSuccess, 95);
+//
+//                lotteryResults+=1;
+//            }
+//        }
+//
+//        if(lotteryResults == potentialSalvageYield && potentialSalvageYield != 1 && pluginRef.getRankTools().isPlayerMaxRankInSubSkill(player, SubSkillType.SALVAGE_ARCANE_SALVAGE)) {
+//            pluginRef.getNotificationManager().sendPlayerInformationChatOnly(player, "Salvage.Skills.Lottery.Perfect", String.valueOf(lotteryResults), StringUtils.getPrettyItemString(item.getType()));
+//        } else if(salvageable.getMaximumQuantity() == 1 || getSalvageLimit() >= salvageable.getMaximumQuantity()) {
+//            pluginRef.getNotificationManager().sendPlayerInformationChatOnly(player,  "Salvage.Skills.Lottery.Normal", String.valueOf(lotteryResults), StringUtils.getPrettyItemString(item.getType()));
+//        } else {
+//            pluginRef.getNotificationManager().sendPlayerInformationChatOnly(player,  "Salvage.Skills.Lottery.Untrained", String.valueOf(lotteryResults), StringUtils.getPrettyItemString(item.getType()));
+//        }
+//
+//        ItemStack salvageResults = new ItemStack(salvageable.getSalvagedItemMaterial(), lotteryResults);
+//
+//        //Call event
+//        if (pluginRef.getEventManager().callSalvageCheckEvent(player, item, salvageResults, enchantBook).isCancelled()) {
+//            return;
+//        }
+//
+//        Location anvilLoc = location.clone();
+//        Location playerLoc = player.getLocation().clone();
+//        double distance = anvilLoc.distance(playerLoc);
+//
+//        double speedLimit = .6;
+//        double minSpeed = .3;
+//
+//        //Clamp the speed and vary it by distance
+//        double vectorSpeed = Math.min(speedLimit, Math.max(minSpeed, distance * .2));
+//
+//        //Add a very small amount of height
+//        anvilLoc.add(0, .1, 0);
+//
+//        if (enchantBook != null) {
+//            pluginRef.getMiscTools().spawnItemTowardsLocation(anvilLoc.clone(), playerLoc.clone(), enchantBook, vectorSpeed);
+//        }
+//
+//        pluginRef.getMiscTools().spawnItemTowardsLocation(anvilLoc.clone(), playerLoc.clone(), salvageResults, vectorSpeed);
+//
+//        // BWONG BWONG BWONG - CLUNK!
+//        if (pluginRef.getConfigManager().getConfigSalvage().getGeneral().isAnvilUseSounds()) {
+//            pluginRef.getSoundManager().sendSound(player, player.getLocation(), SoundType.ITEM_BREAK);
+//        }
+//
+//        pluginRef.getNotificationManager().sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE, "Salvage.Skills.Success");
     }
 
     /*public double getMaxSalvagePercentage() {
@@ -236,13 +234,13 @@ public class SalvageManager extends SkillManager {
 
             if (!salvageBehaviour.isArcaneSalvageEnchantLoss()
                     || pluginRef.getPermissionTools().hasSalvageEnchantBypassPerk(player)
-                    || pluginRef.getRandomChanceTools().checkRandomChanceExecutionSuccess(new RandomChanceSkillStatic(getExtractFullEnchantChance(), getPlayer(), SubSkillType.SALVAGE_ARCANE_SALVAGE))) {
+                    || pluginRef.getRandomChanceTools().checkRandomChanceExecutionSuccess(new RandomChanceSkillStatic(pluginRef, getExtractFullEnchantChance(), getPlayer(), SubSkillType.SALVAGE_ARCANE_SALVAGE))) {
 
                 enchantMeta.addStoredEnchant(enchant.getKey(), enchantLevel, true);
             }
             else if (enchantLevel > 1
                     && salvageBehaviour.isArcaneSalvageDowngrades()
-                    && pluginRef.getRandomChanceTools().checkRandomChanceExecutionSuccess(new RandomChanceSkillStatic(getExtractPartialEnchantChance(), getPlayer(), SubSkillType.SALVAGE_ARCANE_SALVAGE))) {
+                    && pluginRef.getRandomChanceTools().checkRandomChanceExecutionSuccess(new RandomChanceSkillStatic(pluginRef, getExtractPartialEnchantChance(), getPlayer(), SubSkillType.SALVAGE_ARCANE_SALVAGE))) {
                 enchantMeta.addStoredEnchant(enchant.getKey(), enchantLevel - 1, true);
                 downgraded = true;
             } else {

+ 553 - 2
src/main/java/com/gmail/nossr50/skills/salvage/salvageables/Salvageable.java

@@ -3,6 +3,7 @@ package com.gmail.nossr50.skills.salvage.salvageables;
 import com.gmail.nossr50.datatypes.skills.ItemMaterialCategory;
 import com.gmail.nossr50.datatypes.skills.ItemType;
 import org.bukkit.Material;
+import org.bukkit.inventory.ItemStack;
 
 /**
  * Represents a 'Salvageable' item
@@ -27,8 +28,8 @@ public class Salvageable {
     public Salvageable(Material itemMaterial, Material salvagedItemMaterial, int minimumLevel, int maximumQuantity) {
         this.itemMaterial = itemMaterial;
         this.salvagedItemMaterial = salvagedItemMaterial;
-        this.salvageItemType = pluginRef.getItemTools().determineItemType(itemMaterial);
-        this.salvageItemMaterialCategory = pluginRef.getItemTools().determineMaterialType(salvagedItemMaterial);
+        this.salvageItemType = determineItemType(itemMaterial);
+        this.salvageItemMaterialCategory = determineMaterialType(salvagedItemMaterial);
         this.minimumLevel = Math.max(0, minimumLevel);
         this.maximumQuantity = Math.max(1, maximumQuantity);
         this.maximumDurability = itemMaterial.getMaxDurability();
@@ -71,4 +72,554 @@ public class Salvageable {
     public double getXpMultiplier() {
         return xpMultiplier;
     }
+
+    //TODO: Hacky work around below, it disgusts me
+    /**
+     * Determines the item type, currently used for repairables/salvageables
+     *
+     * @param material target material
+     * @return the matching ItemType returns OTHER if no match
+     */
+    public ItemType determineItemType(Material material) {
+        if (isMinecraftTool(new ItemStack(material))) {
+            return ItemType.TOOL;
+        } else if (isArmor(new ItemStack((material)))) {
+            return ItemType.ARMOR;
+        } else {
+            return ItemType.OTHER;
+        }
+    }
+
+    /**
+     * Determines the material category, currently used for repairables/salvageables
+     *
+     * @param material target material
+     * @return the matching ItemMaterialCategory, return OTHER if no match
+     */
+    public ItemMaterialCategory determineMaterialType(Material material) {
+        switch (material) {
+            case STRING:
+                return ItemMaterialCategory.STRING;
+
+            case LEATHER:
+                return ItemMaterialCategory.LEATHER;
+
+            case ACACIA_PLANKS:
+            case BIRCH_PLANKS:
+            case DARK_OAK_PLANKS:
+            case JUNGLE_PLANKS:
+            case OAK_PLANKS:
+            case SPRUCE_PLANKS:
+                return ItemMaterialCategory.WOOD;
+
+            case STONE:
+                return ItemMaterialCategory.STONE;
+
+            case IRON_INGOT:
+                return ItemMaterialCategory.IRON;
+
+            case GOLD_INGOT:
+                return ItemMaterialCategory.GOLD;
+
+            case DIAMOND:
+                return ItemMaterialCategory.DIAMOND;
+
+            default:
+                return ItemMaterialCategory.OTHER;
+        }
+    }
+
+    /**
+     * Checks if the item is a bow.
+     *
+     * @param item Item to check
+     * @return true if the item is a bow, false otherwise
+     */
+    public boolean isBow(ItemStack item) {
+        Material type = item.getType();
+
+        switch (type) {
+            case BOW:
+                return true;
+
+            default:
+                return false;
+            //return mcMMO.getModManager().isCustomBow(type);
+        }
+    }
+
+    /**
+     * Checks if the item is a sword.
+     *
+     * @param item Item to check
+     * @return true if the item is a sword, false otherwise
+     */
+    public boolean isSword(ItemStack item) {
+        Material type = item.getType();
+
+        switch (type) {
+            case DIAMOND_SWORD:
+            case GOLDEN_SWORD:
+            case IRON_SWORD:
+            case STONE_SWORD:
+            case WOODEN_SWORD:
+                return true;
+
+            default:
+                return false;
+            //return mcMMO.getModManager().isCustomSword(type);
+        }
+    }
+
+    /**
+     * Checks if the item is a hoe.
+     *
+     * @param item Item to check
+     * @return true if the item is a hoe, false otherwise
+     */
+    public boolean isHoe(ItemStack item) {
+        Material type = item.getType();
+
+        switch (type) {
+            case DIAMOND_HOE:
+            case GOLDEN_HOE:
+            case IRON_HOE:
+            case STONE_HOE:
+            case WOODEN_HOE:
+                return true;
+
+            default:
+                return false;
+            //return mcMMO.getModManager().isCustomHoe(type);
+        }
+    }
+
+    /**
+     * Checks if the item is a shovel.
+     *
+     * @param item Item to check
+     * @return true if the item is a shovel, false otherwise
+     */
+    public boolean isShovel(ItemStack item) {
+        Material type = item.getType();
+
+        switch (type) {
+            case DIAMOND_SHOVEL:
+            case GOLDEN_SHOVEL:
+            case IRON_SHOVEL:
+            case STONE_SHOVEL:
+            case WOODEN_SHOVEL:
+                return true;
+
+            default:
+                return false;
+            //return mcMMO.getModManager().isCustomShovel(type);
+        }
+    }
+
+    /**
+     * Checks if the item is an axe.
+     *
+     * @param item Item to check
+     * @return true if the item is an axe, false otherwise
+     */
+    public boolean isAxe(ItemStack item) {
+        Material type = item.getType();
+
+        switch (type) {
+            case DIAMOND_AXE:
+            case GOLDEN_AXE:
+            case IRON_AXE:
+            case STONE_AXE:
+            case WOODEN_AXE:
+                return true;
+
+            default:
+                return false;
+            //return mcMMO.getModManager().isCustomAxe(type);
+        }
+    }
+
+    /**
+     * Checks if the item is a pickaxe.
+     *
+     * @param item Item to check
+     * @return true if the item is a pickaxe, false otherwise
+     */
+    public boolean isPickaxe(ItemStack item) {
+        Material type = item.getType();
+
+        switch (type) {
+            case DIAMOND_PICKAXE:
+            case GOLDEN_PICKAXE:
+            case IRON_PICKAXE:
+            case STONE_PICKAXE:
+            case WOODEN_PICKAXE:
+                return true;
+
+            default:
+                return false;
+            //return mcMMO.getModManager().isCustomPickaxe(type);
+        }
+    }
+
+    /**
+     * Checks if the item is a helmet.
+     *
+     * @param item Item to check
+     * @return true if the item is a helmet, false otherwise
+     */
+    public boolean isHelmet(ItemStack item) {
+        Material type = item.getType();
+
+        switch (type) {
+            case DIAMOND_HELMET:
+            case GOLDEN_HELMET:
+            case IRON_HELMET:
+            case CHAINMAIL_HELMET:
+            case LEATHER_HELMET:
+                return true;
+
+            default:
+                return false;
+            //return mcMMO.getModManager().isCustomHelmet(type);
+        }
+    }
+
+    /**
+     * Checks if the item is a chestplate.
+     *
+     * @param item Item to check
+     * @return true if the item is a chestplate, false otherwise
+     */
+    public boolean isChestplate(ItemStack item) {
+        Material type = item.getType();
+
+        switch (type) {
+            case DIAMOND_CHESTPLATE:
+            case GOLDEN_CHESTPLATE:
+            case IRON_CHESTPLATE:
+            case CHAINMAIL_CHESTPLATE:
+            case LEATHER_CHESTPLATE:
+                return true;
+
+            default:
+                return false;
+            //return mcMMO.getModManager().isCustomChestplate(type);
+        }
+    }
+
+    /**
+     * Checks if the item is a pair of pants.
+     *
+     * @param item Item to check
+     * @return true if the item is a pair of pants, false otherwise
+     */
+    public boolean isLeggings(ItemStack item) {
+        Material type = item.getType();
+
+        switch (type) {
+            case DIAMOND_LEGGINGS:
+            case GOLDEN_LEGGINGS:
+            case IRON_LEGGINGS:
+            case CHAINMAIL_LEGGINGS:
+            case LEATHER_LEGGINGS:
+                return true;
+
+            default:
+                return false;
+            //return mcMMO.getModManager().isCustomLeggings(type);
+        }
+    }
+
+    /**
+     * Checks if the item is a pair of boots.
+     *
+     * @param item Item to check
+     * @return true if the item is a pair of boots, false otherwise
+     */
+    public boolean isBoots(ItemStack item) {
+        Material type = item.getType();
+
+        switch (type) {
+            case DIAMOND_BOOTS:
+            case GOLDEN_BOOTS:
+            case IRON_BOOTS:
+            case CHAINMAIL_BOOTS:
+            case LEATHER_BOOTS:
+                return true;
+
+            default:
+                return false;
+            //return mcMMO.getModManager().isCustomBoots(type);
+        }
+    }
+
+    /**
+     * Checks to see if an item is a wearable armor piece.
+     *
+     * @param item Item to check
+     * @return true if the item is armor, false otherwise
+     */
+    public boolean isArmor(ItemStack item) {
+        return isHelmet(item) || isChestplate(item) || isLeggings(item) || isBoots(item);
+    }
+
+    /**
+     * Checks to see if an item is a wearable *vanilla* armor piece.
+     *
+     * @param item Item to check
+     * @return true if the item is armor, false otherwise
+     */
+    public boolean isMinecraftArmor(ItemStack item) {
+        return isLeatherArmor(item) || isGoldArmor(item) || isIronArmor(item) || isDiamondArmor(item) || isChainmailArmor(item);
+    }
+
+    /**
+     * Checks to see if an item is a leather armor piece.
+     *
+     * @param item Item to check
+     * @return true if the item is leather armor, false otherwise
+     */
+    public boolean isLeatherArmor(ItemStack item) {
+        switch (item.getType()) {
+            case LEATHER_BOOTS:
+            case LEATHER_CHESTPLATE:
+            case LEATHER_HELMET:
+            case LEATHER_LEGGINGS:
+                return true;
+
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Checks to see if an item is a gold armor piece.
+     *
+     * @param item Item to check
+     * @return true if the item is gold armor, false otherwise
+     */
+    public boolean isGoldArmor(ItemStack item) {
+        switch (item.getType()) {
+            case GOLDEN_BOOTS:
+            case GOLDEN_CHESTPLATE:
+            case GOLDEN_HELMET:
+            case GOLDEN_LEGGINGS:
+                return true;
+
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Checks to see if an item is an iron armor piece.
+     *
+     * @param item Item to check
+     * @return true if the item is iron armor, false otherwise
+     */
+    public boolean isIronArmor(ItemStack item) {
+        switch (item.getType()) {
+            case IRON_BOOTS:
+            case IRON_CHESTPLATE:
+            case IRON_HELMET:
+            case IRON_LEGGINGS:
+                return true;
+
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Checks to see if an item is a diamond armor piece.
+     *
+     * @param item Item to check
+     * @return true if the item is diamond armor, false otherwise
+     */
+    public boolean isDiamondArmor(ItemStack item) {
+        switch (item.getType()) {
+            case DIAMOND_BOOTS:
+            case DIAMOND_CHESTPLATE:
+            case DIAMOND_HELMET:
+            case DIAMOND_LEGGINGS:
+                return true;
+
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Checks to see if an item is a chainmail armor piece.
+     *
+     * @param item Item to check
+     * @return true if the item is chainmail armor, false otherwise
+     */
+    public boolean isChainmailArmor(ItemStack item) {
+        switch (item.getType()) {
+            case CHAINMAIL_BOOTS:
+            case CHAINMAIL_CHESTPLATE:
+            case CHAINMAIL_HELMET:
+            case CHAINMAIL_LEGGINGS:
+                return true;
+
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Checks to see if an item is a *vanilla* tool.
+     *
+     * @param item Item to check
+     * @return true if the item is a tool, false otherwise
+     */
+    public boolean isMinecraftTool(ItemStack item) {
+        return isStoneTool(item) || isWoodTool(item) || isGoldTool(item) || isIronTool(item) || isDiamondTool(item) || isStringTool(item) || item.getType() == Material.TRIDENT;
+    }
+
+    /**
+     * Checks to see if an item is a stone tool.
+     *
+     * @param item Item to check
+     * @return true if the item is a stone tool, false otherwise
+     */
+    public boolean isStoneTool(ItemStack item) {
+        switch (item.getType()) {
+            case STONE_AXE:
+            case STONE_HOE:
+            case STONE_PICKAXE:
+            case STONE_SHOVEL:
+            case STONE_SWORD:
+                return true;
+
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Checks to see if an item is a wooden tool.
+     *
+     * @param item Item to check
+     * @return true if the item is a wooden tool, false otherwise
+     */
+    public boolean isWoodTool(ItemStack item) {
+        switch (item.getType()) {
+            case WOODEN_AXE:
+            case WOODEN_HOE:
+            case WOODEN_PICKAXE:
+            case WOODEN_SHOVEL:
+            case WOODEN_SWORD:
+                return true;
+
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Checks to see if an item is a wooden tool.
+     *
+     * @param material Material to check
+     * @return true if the item is a wooden tool, false otherwise
+     */
+    public boolean isWoodTool(Material material) {
+        switch (material) {
+            case WOODEN_AXE:
+            case WOODEN_HOE:
+            case WOODEN_PICKAXE:
+            case WOODEN_SHOVEL:
+            case WOODEN_SWORD:
+                return true;
+
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Checks to see if an item is a string tool.
+     *
+     * @param item Item to check
+     * @return true if the item is a string tool, false otherwise
+     */
+    public boolean isStringTool(ItemStack item) {
+        switch (item.getType()) {
+            case BOW:
+            case CARROT_ON_A_STICK:
+            case FISHING_ROD:
+                return true;
+
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Checks to see if an item is a gold tool.
+     *
+     * @param item Item to check
+     * @return true if the item is a stone tool, false otherwise
+     */
+    public boolean isGoldTool(ItemStack item) {
+        switch (item.getType()) {
+            case GOLDEN_AXE:
+            case GOLDEN_HOE:
+            case GOLDEN_PICKAXE:
+            case GOLDEN_SHOVEL:
+            case GOLDEN_SWORD:
+                return true;
+
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Checks to see if an item is an iron tool.
+     *
+     * @param item Item to check
+     * @return true if the item is an iron tool, false otherwise
+     */
+    public boolean isIronTool(ItemStack item) {
+        switch (item.getType()) {
+            case BUCKET:
+            case FLINT_AND_STEEL:
+            case IRON_AXE:
+            case IRON_HOE:
+            case IRON_PICKAXE:
+            case IRON_SHOVEL:
+            case IRON_SWORD:
+            case SHEARS:
+                return true;
+
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Checks to see if an item is a diamond tool.
+     *
+     * @param item Item to check
+     * @return true if the item is a diamond tool, false otherwise
+     */
+    public boolean isDiamondTool(ItemStack item) {
+        switch (item.getType()) {
+            case DIAMOND_AXE:
+            case DIAMOND_HOE:
+            case DIAMOND_PICKAXE:
+            case DIAMOND_SHOVEL:
+            case DIAMOND_SWORD:
+                return true;
+
+            default:
+                return false;
+        }
+    }
+
+
 }

+ 6 - 9
src/main/java/com/gmail/nossr50/util/nbt/NBTManager.java

@@ -1,7 +1,6 @@
 package com.gmail.nossr50.util.nbt;
 
 
-import com.gmail.nossr50.mcMMO;
 import net.minecraft.server.v1_14_R1.NBTBase;
 import net.minecraft.server.v1_14_R1.NBTList;
 import net.minecraft.server.v1_14_R1.NBTTagCompound;
@@ -14,10 +13,8 @@ public class NBTManager {
 
     private static final String CRAFT_META_ITEM_CLASS_PATH = "org.bukkit.craftbukkit.inventory.CraftMetaItem";
     private Class<?> craftMetaItemClass;
-    private final mcMMO pluginRef;
 
-    public NBTManager(mcMMO pluginRef) {
-        this.pluginRef = pluginRef;
+    public NBTManager() {
         init(); //Setup method references etc
     }
 
@@ -29,30 +26,30 @@ public class NBTManager {
         }
     }
 
-    public NBTTagCompound getNBT(ItemStack itemStack) {
+    public static NBTTagCompound getNBT(ItemStack itemStack) {
         Bukkit.broadcastMessage("Checking NBT for "+itemStack.toString());
         net.minecraft.server.v1_14_R1.ItemStack nmsItemStack = CraftItemStack.asNMSCopy(itemStack);
         NBTTagCompound rootTag = nmsItemStack.getTag();
         return rootTag;
     }
 
-    public NBTBase constructNBT(String nbtString) {
+    public static NBTBase constructNBT(String nbtString) {
         try {
             return CraftNBTTagConfigSerializer.deserialize(nbtString);
         } catch (Exception e) {
             e.printStackTrace();
-            pluginRef.getLogger().severe("mcMMO was unable parse the NBT string from your config! Double check that it is proper NBT!");
+            System.out.println(("[mcMMO NBT Debug] was unable parse the NBT string from your config! Double check that it is proper NBT!"));
             return null;
         }
     }
 
-    public void printNBT(ItemStack itemStack) {
+    public static void printNBT(ItemStack itemStack) {
         for(String key : getNBT(itemStack).getKeys()) {
             Bukkit.broadcastMessage("NBT Key found: "+key);
         }
     }
 
-    public boolean hasNBT(NBTBase nbt, NBTTagCompound otherNbt) {
+    public static boolean hasNBT(NBTBase nbt, NBTTagCompound otherNbt) {
         if(nbt instanceof NBTList<?>) {
 
         } else {

+ 2 - 3
src/main/java/com/gmail/nossr50/util/nbt/RawNBT.java

@@ -1,6 +1,5 @@
 package com.gmail.nossr50.util.nbt;
 
-import com.gmail.nossr50.mcMMO;
 import net.minecraft.server.v1_14_R1.NBTBase;
 
 /**
@@ -28,7 +27,7 @@ public class RawNBT {
         this.nbtContents = nbtContents;
     }
 
-    public NBTBase getNbtData(mcMMO pluginRef) {
-        return pluginRef.getNbtManager().constructNBT(nbtContents);
+    public NBTBase getNbtData() {
+        return NBTManager.constructNBT(nbtContents);
     }
 }

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

@@ -458,7 +458,35 @@ public final class CombatTools {
      * @return true if the player has access to the limit break
      */
     public boolean canUseLimitBreak(Player player, LivingEntity target, SubSkillType subSkillType) {
-        if(target instanceof Player || AdvancedConfig.getInstance().canApplyLimitBreakPVE()) {
+        boolean pveAllowed = false;
+
+        //TODO: Hacky fix below
+        switch(subSkillType) {
+            case ARCHERY_ARCHERY_LIMIT_BREAK:
+                if(pluginRef.getConfigManager().getConfigArchery().getLimitBreak().isEnabledForPVE()) {
+                    pveAllowed = true;
+                }
+                break;
+            case AXES_AXES_LIMIT_BREAK:
+                if(pluginRef.getConfigManager().getConfigAxes().getSubSkills().getConfigAxesLimitBreak().isEnabledForPVE()) {
+                    pveAllowed = true;
+                }
+                break;
+            case SWORDS_SWORDS_LIMIT_BREAK:
+                if(pluginRef.getConfigManager().getConfigSwords().getSubSkills().getSwordsLimitBreak().isEnabledForPVE()) {
+                    pveAllowed = true;
+                }
+                break;
+            case UNARMED_UNARMED_LIMIT_BREAK:
+                if(pluginRef.getConfigManager().getConfigUnarmed().getSubSkills().getUnarmedLimitBreak().isEnabledForPVE()) {
+                    pveAllowed = true;
+                }
+                break;
+            default:
+                pluginRef.getLogger().severe("This skill has no limit break PVE setting defined!");
+        }
+
+        if(target instanceof Player || pveAllowed) {
             return pluginRef.getRankTools().hasUnlockedSubskill(player, subSkillType)
                     && pluginRef.getPermissionTools().isSubSkillEnabled(player, subSkillType);
         } else {