Ver Fonte

Add custom mobs automatically as they're killed.

GJ há 11 anos atrás
pai
commit
a63f745c73

+ 2 - 0
Changelog.txt

@@ -26,6 +26,7 @@ Version 1.4.07-dev
  + Added new McMMOPlayerLevelDownEvent, fired when a player loses levels
  + Added ability to give custom names to items in treasures.yml - use the key "Custom_Name" to set, expects a string.
  + Added ability to give lore to items in treasures.yml - use the key "Lore" to set, expects a list of strings.
+ + Killing a custom entity will automatically add it to the custom entity config file with default values.
  = Fixed bug which allowed players to bypass fishing's exploit prevention
  = Fixed bug where FakeEntityDamageByEntityEvent wasn't being fired
  = Fixed bug with "Skull Splitter" not finding the locale string
@@ -38,6 +39,7 @@ Version 1.4.07-dev
  = Fixed a bug where squid were not awarding XP.
  = Fixed a bug where Combat XP was granted within 5 seconds for respawned players
  = Fixed a bug where wrong feedback messages were being send when using a command on an offline player
+ ! Reworked mod config files. **YOU WILL NEED TO UPDATE YOUR FILE TO THE NEW FORMAT**
  ! Changed default XP multiplier for repairing shears
  ! Changed format of treasures.yml. **YOU WILL NEED TO UPDATE YOUR FILE TO THE NEW FORMAT**
  ! Changed format of repair.vanilla.yml. **YOU WILL NEED TO UPDATE YOUR FILE TO THE NEW FORMAT**

+ 4 - 0
src/main/java/com/gmail/nossr50/config/ConfigLoader.java

@@ -114,4 +114,8 @@ public abstract class ConfigLoader {
             plugin.noErrorsInConfigFiles = false;
         }
     }
+
+    public File getFile() {
+        return configFile;
+    }
 }

+ 20 - 6
src/main/java/com/gmail/nossr50/config/mods/CustomArmorConfig.java

@@ -20,11 +20,10 @@ public class CustomArmorConfig extends ConfigLoader {
 
     private List<Repairable> repairables;
 
-    public List<Material> customBoots       = new ArrayList<Material>();
-    public List<Material> customChestplates = new ArrayList<Material>();
-    public List<Material> customHelmets     = new ArrayList<Material>();
-    public List<Material> customLeggings    = new ArrayList<Material>();
-    public List<Material> customArmor       = new ArrayList<Material>();
+    private List<Material> customBoots       = new ArrayList<Material>();
+    private List<Material> customChestplates = new ArrayList<Material>();
+    private List<Material> customHelmets     = new ArrayList<Material>();
+    private List<Material> customLeggings    = new ArrayList<Material>();
 
     public CustomArmorConfig() {
         super("ModConfigs", "armor.yml");
@@ -100,7 +99,22 @@ public class CustomArmorConfig extends ConfigLoader {
             }
 
             materialList.add(armorMaterial);
-            customArmor.add(armorMaterial);
         }
     }
+
+    public boolean isCustomBoots(Material material) {
+        return customBoots.contains(material);
+    }
+
+    public boolean isCustomChestplate(Material material) {
+        return customChestplates.contains(material);
+    }
+
+    public boolean isCustomHelmet(Material material) {
+        return customHelmets.contains(material);
+    }
+
+    public boolean isCustomLeggings(Material material) {
+        return customLeggings.contains(material);
+    }
 }

+ 50 - 20
src/main/java/com/gmail/nossr50/config/mods/CustomBlockConfig.java

@@ -16,17 +16,16 @@ import com.gmail.nossr50.datatypes.mods.CustomBlock;
 public class CustomBlockConfig extends ConfigLoader {
     private static CustomBlockConfig instance;
 
-    public List<MaterialData> customExcavationBlocks  = new ArrayList<MaterialData>();
-    public List<MaterialData> customHerbalismBlocks   = new ArrayList<MaterialData>();
-    public List<MaterialData> customMiningBlocks      = new ArrayList<MaterialData>();
-    public List<MaterialData> customWoodcuttingBlocks = new ArrayList<MaterialData>();
-    public List<MaterialData> customOres              = new ArrayList<MaterialData>();
-    public List<MaterialData> customLogs              = new ArrayList<MaterialData>();
-    public List<MaterialData> customLeaves            = new ArrayList<MaterialData>();
-    public List<MaterialData> customAbilityBlocks     = new ArrayList<MaterialData>();
-    public List<MaterialData> customItems             = new ArrayList<MaterialData>();
-
-    public HashMap<MaterialData, CustomBlock> customBlockMap = new HashMap<MaterialData, CustomBlock>();
+    private List<MaterialData> customExcavationBlocks  = new ArrayList<MaterialData>();
+    private List<MaterialData> customHerbalismBlocks   = new ArrayList<MaterialData>();
+    private List<MaterialData> customMiningBlocks      = new ArrayList<MaterialData>();
+    private List<MaterialData> customWoodcuttingBlocks = new ArrayList<MaterialData>();
+    private List<MaterialData> customOres              = new ArrayList<MaterialData>();
+    private List<MaterialData> customLogs              = new ArrayList<MaterialData>();
+    private List<MaterialData> customLeaves            = new ArrayList<MaterialData>();
+    private List<MaterialData> customAbilityBlocks     = new ArrayList<MaterialData>();
+
+    private HashMap<MaterialData, CustomBlock> customBlockMap = new HashMap<MaterialData, CustomBlock>();
 
     public CustomBlockConfig() {
         super("ModConfigs", "blocks.yml");
@@ -65,7 +64,7 @@ public class CustomBlockConfig extends ConfigLoader {
             Material blockMaterial = Material.matchMaterial(blockInfo[0]);
 
             if (blockMaterial == null) {
-                plugin.getLogger().warning("Invalid material name. This item will be skipped.");
+                plugin.getLogger().warning("Invalid material name. This item will be skipped. - " + blockInfo[0]);
                 continue;
             }
 
@@ -77,16 +76,13 @@ public class CustomBlockConfig extends ConfigLoader {
                 continue;
             }
 
-            customItems.add(blockMaterialData);
-
             int xp = config.getInt(skillType + "." + blockName + ".XP_Gain");
-            int tier = config.getInt(skillType + "." + blockName + ".Tier", 1);
 
             boolean shouldDropItem = config.getBoolean(skillType + "." + blockName + ".Drop_Item");
             Material dropMaterial = Material.matchMaterial(config.getString(skillType + "." + blockName + ".Drop_Item_Name"));
 
             if (shouldDropItem && dropMaterial == null) {
-                plugin.getLogger().warning("Incomplete item drop information. This block will drop itself.");
+                plugin.getLogger().warning("Incomplete item drop information. This block will drop itself. - " + blockInfo[0]);
                 shouldDropItem = false;
             }
 
@@ -103,8 +99,6 @@ public class CustomBlockConfig extends ConfigLoader {
             int minimumDropAmount = config.getInt(skillType + "." + blockName + ".Min_Drop_Item_Amount", 1);
             int maxiumDropAmount = config.getInt(skillType + "." + blockName + ".Max_Drop_Item_Amount", 1);
 
-            CustomBlock block = new CustomBlock(minimumDropAmount, maxiumDropAmount, itemDrop, tier, xp, blockData, blockMaterial);
-
             if (skillType.equals("Mining") && config.getBoolean(skillType + "." + blockName + ".Is_Ore")) {
                 customOres.add(blockMaterialData);
             }
@@ -114,11 +108,47 @@ public class CustomBlockConfig extends ConfigLoader {
                 }
                 else {
                     customLeaves.add(blockMaterialData);
-                    block.setXpGain(0); // Leaves don't grant XP
+                    xp = 0; // Leaves don't grant XP
                 }
             }
 
-            customBlockMap.put(blockMaterialData, block);
+            customBlockMap.put(blockMaterialData, new CustomBlock(minimumDropAmount, maxiumDropAmount, itemDrop, xp));
         }
     }
+
+    public CustomBlock getCustomBlock(MaterialData data) {
+        return customBlockMap.get(data);
+    }
+
+    public boolean isCustomOre(MaterialData data) {
+        return customOres.contains(data);
+    }
+
+    public boolean isCustomLog(MaterialData data) {
+        return customLogs.contains(data);
+    }
+
+    public boolean isCustomLeaf(MaterialData data) {
+        return customLeaves.contains(data);
+    }
+
+    public boolean isCustomAbilityBlock(MaterialData data) {
+        return customAbilityBlocks.contains(data);
+    }
+
+    public boolean isCustomExcavationBlock(MaterialData data) {
+        return customExcavationBlocks.contains(data);
+    }
+
+    public boolean isCustomHerbalismBlock(MaterialData data) {
+        return customHerbalismBlocks.contains(data);
+    }
+
+    public boolean isCustomMiningBlock(MaterialData data) {
+        return customMiningBlocks.contains(data);
+    }
+
+    public boolean isCustomWoodcuttingBlock(MaterialData data) {
+        return customWoodcuttingBlocks.contains(data);
+    }
 }

+ 65 - 44
src/main/java/com/gmail/nossr50/config/mods/CustomEntityConfig.java

@@ -1,27 +1,21 @@
 package com.gmail.nossr50.config.mods;
 
-import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.List;
-import java.util.Set;
 
-import org.apache.commons.lang.ClassUtils;
-import org.bukkit.configuration.ConfigurationSection;
-import org.bukkit.inventory.ItemStack;
+import org.bukkit.Material;
+import org.bukkit.entity.Entity;
+import org.bukkit.material.MaterialData;
 
 import com.gmail.nossr50.config.ConfigLoader;
 import com.gmail.nossr50.datatypes.mods.CustomEntity;
 
+import org.apache.commons.lang.ClassUtils;
+
 public class CustomEntityConfig extends ConfigLoader {
     private static CustomEntityConfig instance;
 
-    public List<String> customHostileEntityTypes = new ArrayList<String>();
-    public List<String> customNeutralEntityTypes = new ArrayList<String>();
-    public List<String> customPassiveEntityTypes = new ArrayList<String>();
-    public List<String> customEntityTypes        = new ArrayList<String>();
-
-    public HashMap<String, CustomEntity> customEntityClassMap = new HashMap<String, CustomEntity>();
-    public HashMap<String, CustomEntity> customEntityTypeMap  = new HashMap<String, CustomEntity>();
+    private HashMap<String, CustomEntity> customEntityClassMap = new HashMap<String, CustomEntity>();
+    private HashMap<String, CustomEntity> customEntityTypeMap  = new HashMap<String, CustomEntity>();
 
     public CustomEntityConfig() {
         super("ModConfigs", "entities.yml");
@@ -38,23 +32,9 @@ public class CustomEntityConfig extends ConfigLoader {
 
     @Override
     protected void loadKeys() {
-        loadMobs("Hostile", customHostileEntityTypes);
-        loadMobs("Neutral", customNeutralEntityTypes);
-        loadMobs("Passive", customPassiveEntityTypes);
-    }
-
-    private void loadMobs(String entityType, List<String> entityTypeList) {
-        ConfigurationSection entitySection = config.getConfigurationSection(entityType);
-
-        if (entitySection == null) {
-            return;
-        }
-
-        Set<String> entityConfigSet = entitySection.getKeys(false);
-
-        for (String entityName : entityConfigSet) {
+        for (String entityName : config.getKeys(false)) {
             Class<?> clazz = null;
-            String className = config.getString(entityType + "." + entityName + ".Class", "");
+            String className = config.getString(entityName + ".Class", "");
 
             try {
                 clazz = ClassUtils.getClass(className);
@@ -65,27 +45,68 @@ public class CustomEntityConfig extends ConfigLoader {
             }
 
             String entityTypeName = entityName.replace("_", ".");
-            double xpMultiplier = config.getDouble(entityType + "." + entityName + ".XP_Multiplier", 1.0D);
-            boolean canBeTamed = config.getBoolean(entityType + "." + entityName + ".Tameable", false);
-            int tamingXp = config.getInt(entityType + "." + entityName + "Taming_XP", 0);
-            boolean canBeSummoned = config.getBoolean(entityType + "." + entityName + "CanBeSummoned", false);
-            int callOfTheWildId = config.getInt(entityType + "." + entityName + "COTW_Material_ID", 0);
-            int callOfTheWildData = config.getInt(entityType + "." + entityName + "COTW_Material_Data", 0);
-            int callOfTheWildAmount = config.getInt(entityType + "." + entityName + "COTW_Material_Amount", 0);
-
-            CustomEntity entity;
-
-            if (canBeSummoned && (callOfTheWildId == 0 || callOfTheWildAmount == 0)) {
-                plugin.getLogger().warning("Incomplete Call of the Wild information. This enitity will not be able to be summoned by Call of the Wild.");
+            double xpMultiplier = config.getDouble(entityName + ".XP_Multiplier", 1.0D);
+
+            boolean canBeTamed = config.getBoolean(entityName + ".Tameable");
+            int tamingXp = config.getInt(entityName + ".Taming_XP");
+
+            boolean canBeSummoned = config.getBoolean(entityName + ".CanBeSummoned");
+            Material callOfTheWildMaterial = Material.matchMaterial(config.getString(entityName + ".COTW_Material", ""));
+            byte callOfTheWildData = (byte) config.getInt(entityName + ".COTW_Material_Data");
+            int callOfTheWildAmount = config.getInt(entityName + ".COTW_Material_Amount");
+
+            if (canBeSummoned && (callOfTheWildMaterial == null || callOfTheWildAmount == 0)) {
+                plugin.getLogger().warning("Incomplete Call of the Wild information. This entity will not be able to be summoned by Call of the Wild.");
                 canBeSummoned = false;
             }
 
-            entity = new CustomEntity(xpMultiplier, canBeTamed, tamingXp, canBeSummoned, new ItemStack(callOfTheWildId, callOfTheWildData), callOfTheWildAmount);
+            CustomEntity entity = new CustomEntity(xpMultiplier, canBeTamed, tamingXp, canBeSummoned, (canBeSummoned ? new MaterialData(callOfTheWildMaterial, callOfTheWildData).toItemStack(1) : null), callOfTheWildAmount);
 
-            entityTypeList.add(entityTypeName);
             customEntityTypeMap.put(entityTypeName, entity);
             customEntityClassMap.put(clazz == null ? null : clazz.getName(), entity);
-            customEntityTypes.add(entityTypeName);
         }
     }
+
+    public boolean isCustomEntity(Entity entity) {
+        if (customEntityTypeMap.containsKey(entity.getType().toString())) {
+            return true;
+        }
+
+        try {
+            return customEntityClassMap.containsKey(((Class<?>) entity.getClass().getDeclaredField("entityClass").get(entity)).getName());
+        }
+        catch (Exception e) {
+            if (e instanceof NoSuchFieldException || e instanceof IllegalArgumentException || e instanceof IllegalAccessException) {
+                return customEntityClassMap.containsKey(entity.getClass().getName());
+            }
+
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    public CustomEntity getCustomEntity(Entity entity) {
+        CustomEntity customEntity = customEntityTypeMap.get(entity.getType().toString());
+
+        if (customEntity == null) {
+            try {
+                customEntity = customEntityClassMap.get(((Class<?>) entity.getClass().getDeclaredField("entityClass").get(entity)).getName());
+            }
+            catch (Exception e) {
+                if (e instanceof NoSuchFieldException || e instanceof IllegalArgumentException || e instanceof IllegalAccessException) {
+                    customEntity = customEntityClassMap.get(entity.getClass().getName());
+                }
+                else {
+                    e.printStackTrace();
+                }
+            }
+        }
+
+        return customEntity;
+    }
+
+    public void addEntity(CustomEntity customEntity, String className, String entityName) {
+        customEntityTypeMap.put(entityName, customEntity);
+        customEntityClassMap.put(className, customEntity);
+    }
 }

+ 41 - 12
src/main/java/com/gmail/nossr50/config/mods/CustomToolConfig.java

@@ -21,15 +21,14 @@ public class CustomToolConfig extends ConfigLoader {
     private static CustomToolConfig instance;
     private List<Repairable> repairables;
 
-    public List<Material> customAxes     = new ArrayList<Material>();
-    public List<Material> customBows     = new ArrayList<Material>();
-    public List<Material> customHoes     = new ArrayList<Material>();
-    public List<Material> customPickaxes = new ArrayList<Material>();
-    public List<Material> customShovels  = new ArrayList<Material>();
-    public List<Material> customSwords   = new ArrayList<Material>();
-    public List<Material> customTool     = new ArrayList<Material>();
+    private List<Material> customAxes     = new ArrayList<Material>();
+    private List<Material> customBows     = new ArrayList<Material>();
+    private List<Material> customHoes     = new ArrayList<Material>();
+    private List<Material> customPickaxes = new ArrayList<Material>();
+    private List<Material> customShovels  = new ArrayList<Material>();
+    private List<Material> customSwords   = new ArrayList<Material>();
 
-    public HashMap<Material, CustomTool> customToolMap = new HashMap<Material, CustomTool>();
+    private HashMap<Material, CustomTool> customToolMap = new HashMap<Material, CustomTool>();
 
     private CustomToolConfig() {
         super("ModConfigs", "tools.yml");
@@ -77,7 +76,7 @@ public class CustomToolConfig extends ConfigLoader {
             Material toolMaterial = Material.matchMaterial(toolName);
 
             if (toolMaterial == null) {
-                plugin.getLogger().warning("Invalid material name. This item will be skipped.");
+                plugin.getLogger().warning("Invalid material name. This item will be skipped. - " + toolName);
                 continue;
             }
 
@@ -85,7 +84,7 @@ public class CustomToolConfig extends ConfigLoader {
             Material repairMaterial = Material.matchMaterial(config.getString(toolType + "." + toolName + ".Repair_Material", ""));
 
             if (repairMaterial == null) {
-                plugin.getLogger().warning("Incomplete repair information. This item will be unrepairable.");
+                plugin.getLogger().warning("Incomplete repair information. This item will be unrepairable. - " + toolName);
                 repairable = false;
             }
 
@@ -113,9 +112,39 @@ public class CustomToolConfig extends ConfigLoader {
             CustomTool tool = new CustomTool(tier, abilityEnabled, multiplier);
 
             materialList.add(toolMaterial);
-            customTool.add(toolMaterial);
             customToolMap.put(toolMaterial, tool);
         }
     }
-}
 
+    public boolean isCustomAxe(Material material) {
+        return customAxes.contains(material);
+    }
+
+    public boolean isCustomBow(Material material) {
+        return customBows.contains(material);
+    }
+
+    public boolean isCustomHoe(Material material) {
+        return customHoes.contains(material);
+    }
+
+    public boolean isCustomPickaxe(Material material) {
+        return customPickaxes.contains(material);
+    }
+
+    public boolean isCustomShovel(Material material) {
+        return customShovels.contains(material);
+    }
+
+    public boolean isCustomSword(Material material) {
+        return customSwords.contains(material);
+    }
+
+    public boolean isCustomTool(Material material) {
+        return customToolMap.containsKey(material);
+    }
+
+    public CustomTool getCustomTool(Material material) {
+        return customToolMap.get(material);
+    }
+}

+ 1 - 48
src/main/java/com/gmail/nossr50/datatypes/mods/CustomBlock.java

@@ -1,80 +1,33 @@
 package com.gmail.nossr50.datatypes.mods;
 
-import org.bukkit.Material;
 import org.bukkit.inventory.ItemStack;
 
 public class CustomBlock {
-    private Material type;
-    private byte dataValue;
     private int xpGain;
-    private int tier;
     private ItemStack itemDrop;
     private int minimumDropAmount;
     private int maximumDropAmount;
 
-    public CustomBlock(int minimumDropAmount, int maximumDropAmount, ItemStack itemDrop, int tier, int xpGain, byte dataValue, Material type) {
-        this.type = type;
-        this.dataValue = dataValue;
+    public CustomBlock(int minimumDropAmount, int maximumDropAmount, ItemStack itemDrop, int xpGain) {
         this.xpGain = xpGain;
-        this.tier = tier;
         this.itemDrop = itemDrop;
         this.minimumDropAmount = minimumDropAmount;
         this.maximumDropAmount = maximumDropAmount;
     }
 
-    public Material getType() {
-        return type;
-    }
-
-    public void setType(Material type) {
-        this.type = type;
-    }
-
-    public byte getDataValue() {
-        return dataValue;
-    }
-
-    public void setDataValue(byte dataValue) {
-        this.dataValue = dataValue;
-    }
-
     public int getXpGain() {
         return xpGain;
     }
 
-    public void setXpGain(int xpGain) {
-        this.xpGain = xpGain;
-    }
-
-    public int getTier() {
-        return tier;
-    }
-
-    public void setTier(int tier) {
-        this.tier = tier;
-    }
-
     public ItemStack getItemDrop() {
         return itemDrop;
     }
 
-    public void setItemDrop(ItemStack itemDrop) {
-        this.itemDrop = itemDrop;
-    }
-
     public int getMinimumDropAmount() {
         return minimumDropAmount;
     }
 
-    public void setMinimumDropAmount(int minimumDropAmount) {
-        this.minimumDropAmount = minimumDropAmount;
-    }
-
     public int getMaximumDropAmount() {
         return maximumDropAmount;
     }
-
-    public void setMaximumDropAmount(int maximumDropAmount) {
-        this.maximumDropAmount = maximumDropAmount;
-    }
 }

+ 2 - 26
src/main/java/com/gmail/nossr50/datatypes/mods/CustomEntity.java

@@ -23,47 +23,23 @@ public class CustomEntity {
         return xpMultiplier;
     }
 
-    public void setXpMultiplier(double xpMultiplier) {
-        this.xpMultiplier = xpMultiplier;
-    }
-
-    public boolean isCanBeTamed() {
+    public boolean canBeTamed() {
         return canBeTamed;
     }
 
-    public void setCanBeTamed(boolean canBeTamed) {
-        this.canBeTamed = canBeTamed;
-    }
-
     public int getTamingXP() {
         return tamingXP;
     }
 
-    public void setTamingXP(int tamingXP) {
-        this.tamingXP = tamingXP;
-    }
-
-    public boolean isCanBeSummoned() {
+    public boolean canBeSummoned() {
         return canBeSummoned;
     }
 
-    public void setCanBeSummoned(boolean canBeSummoned) {
-        this.canBeSummoned = canBeSummoned;
-    }
-
     public ItemStack getCallOfTheWildItem() {
         return callOfTheWildItem;
     }
 
-    public void setCallOfTheWildItem(ItemStack callOfTheWildItem) {
-        this.callOfTheWildItem = callOfTheWildItem;
-    }
-
     public int getCallOfTheWildAmount() {
         return callOfTheWildAmount;
     }
-
-    public void setCallOfTheWildAmount(int callOfTheWildAmount) {
-        this.callOfTheWildAmount = callOfTheWildAmount;
-    }
 }

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

@@ -5,6 +5,7 @@ import org.bukkit.entity.LivingEntity;
 import org.bukkit.entity.Player;
 import org.bukkit.inventory.ItemStack;
 
+import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.skills.AbilityType;
 import com.gmail.nossr50.datatypes.skills.SkillType;
@@ -98,7 +99,7 @@ public class AxesManager extends SkillManager {
             if (ItemUtils.isArmor(armor) && Axes.impactChance > Misc.getRandom().nextInt(getActivationChance())) {
                 double durabilityModifier = 1 / (armor.getEnchantmentLevel(Enchantment.DURABILITY) + 1); // Modifier to simulate the durability enchantment behavior
                 double modifiedDurabilityDamage = durabilityDamage * durabilityModifier;
-                short maxDurability = armor.getType().getMaxDurability();
+                short maxDurability = mcMMO.getRepairableManager().getRepairable(armor.getType()).getMaximumDurability();
                 double maxDurabilityDamage = maxDurability * Axes.impactMaxDurabilityModifier;
 
                 armor.setDurability((short) (Math.min(modifiedDurabilityDamage, maxDurabilityDamage) + armor.getDurability()));

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

@@ -87,7 +87,7 @@ public class Repair {
     protected static int getSalvagedAmount(ItemStack inHand) {
         // Temporary workaround until they get their stuff fixed.
         if (mcMMO.p.getServer().getName().equals("MCPC+")) {
-            if (ItemUtils.isPickaxe(inHand) || ItemUtils.isAxe(inHand) || inHand.getType() == Material.BOW || inHand.getType() == Material.BUCKET) {
+            if (ItemUtils.isPickaxe(inHand) || ItemUtils.isAxe(inHand) || ItemUtils.isBow(inHand) || inHand.getType() == Material.BUCKET) {
                 return 3;
             }
             else if (ItemUtils.isShovel(inHand) || inHand.getType() == Material.FLINT_AND_STEEL) {
@@ -120,7 +120,7 @@ public class Repair {
         int quantity = 0;
         MaterialData repairData = new MaterialData(repairMaterial, repairMetadata);
         Recipe recipe = mcMMO.p.getServer().getRecipesFor(item).get(0);
-    
+
         if (recipe instanceof ShapelessRecipe) {
             for (ItemStack ingredient : ((ShapelessRecipe) recipe).getIngredientList()) {
                 if (ingredient != null && ingredient.getType() == repairMaterial && (repairMetadata == -1 || ingredient.getData() == repairData)) {

+ 29 - 11
src/main/java/com/gmail/nossr50/util/ItemUtils.java

@@ -14,6 +14,25 @@ import com.gmail.nossr50.config.party.ItemWeightConfig;
 import com.gmail.nossr50.locale.LocaleLoader;
 
 public class ItemUtils {
+
+    /**
+     * Checks if the item is a bow.
+     *
+     * @param item Item to check
+     * @return true if the item is a bow, false otherwise
+     */
+    public static boolean isBow(ItemStack item) {
+        Material type = item.getType();
+
+        switch (type) {
+            case BOW:
+                return true;
+
+            default:
+                return (Config.getInstance().getToolModsEnabled() && CustomToolConfig.getInstance().isCustomBow(type));
+        }
+    }
+
     /**
      * Checks if the item is a sword.
      *
@@ -32,7 +51,7 @@ public class ItemUtils {
                 return true;
 
             default:
-                return (Config.getInstance().getToolModsEnabled() && CustomToolConfig.getInstance().customSwords.contains(type));
+                return (Config.getInstance().getToolModsEnabled() && CustomToolConfig.getInstance().isCustomSword(type));
         }
     }
 
@@ -54,7 +73,7 @@ public class ItemUtils {
                 return true;
 
             default:
-                return (Config.getInstance().getToolModsEnabled() && CustomToolConfig.getInstance().customHoes.contains(type));
+                return (Config.getInstance().getToolModsEnabled() && CustomToolConfig.getInstance().isCustomHoe(type));
         }
     }
 
@@ -76,7 +95,7 @@ public class ItemUtils {
                 return true;
 
             default:
-                return (Config.getInstance().getToolModsEnabled() && CustomToolConfig.getInstance().customShovels.contains(type));
+                return (Config.getInstance().getToolModsEnabled() && CustomToolConfig.getInstance().isCustomShovel(type));
         }
     }
 
@@ -98,7 +117,7 @@ public class ItemUtils {
                 return true;
 
             default:
-                return (Config.getInstance().getToolModsEnabled() && CustomToolConfig.getInstance().customAxes.contains(type));
+                return (Config.getInstance().getToolModsEnabled() && CustomToolConfig.getInstance().isCustomAxe(type));
         }
     }
 
@@ -120,7 +139,7 @@ public class ItemUtils {
                 return true;
 
             default:
-                return (Config.getInstance().getToolModsEnabled() && CustomToolConfig.getInstance().customPickaxes.contains(type));
+                return (Config.getInstance().getToolModsEnabled() && CustomToolConfig.getInstance().isCustomPickaxe(type));
         }
     }
 
@@ -142,7 +161,7 @@ public class ItemUtils {
                 return true;
 
             default:
-                return Config.getInstance().getArmorModsEnabled() && CustomArmorConfig.getInstance().customHelmets.contains(type);
+                return Config.getInstance().getArmorModsEnabled() && CustomArmorConfig.getInstance().isCustomHelmet(type);
         }
     }
 
@@ -164,7 +183,7 @@ public class ItemUtils {
                 return true;
 
             default:
-                return Config.getInstance().getArmorModsEnabled() && CustomArmorConfig.getInstance().customChestplates.contains(type);
+                return Config.getInstance().getArmorModsEnabled() && CustomArmorConfig.getInstance().isCustomChestplate(type);
         }
     }
 
@@ -186,7 +205,7 @@ public class ItemUtils {
                 return true;
 
             default:
-                return Config.getInstance().getArmorModsEnabled() && CustomArmorConfig.getInstance().customLeggings.contains(type);
+                return Config.getInstance().getArmorModsEnabled() && CustomArmorConfig.getInstance().isCustomLeggings(type);
         }
     }
 
@@ -208,7 +227,7 @@ public class ItemUtils {
                 return true;
 
             default:
-                return Config.getInstance().getArmorModsEnabled() && CustomArmorConfig.getInstance().customBoots.contains(type);
+                return Config.getInstance().getArmorModsEnabled() && CustomArmorConfig.getInstance().isCustomBoots(type);
         }
     }
 
@@ -469,12 +488,11 @@ public class ItemUtils {
             case SHEARS:
             case FISHING_ROD:
             case CARROT_STICK:
-            case BOW:
             case FLINT_AND_STEEL:
                 return true;
 
             default:
-                return isArmor(item) || isSword(item) || isAxe(item) || isShovel(item) || isPickaxe(item);
+                return isArmor(item) || isSword(item) || isAxe(item) || isShovel(item) || isPickaxe(item) || isBow(item);
         }
     }
 

+ 80 - 62
src/main/java/com/gmail/nossr50/util/ModUtils.java

@@ -1,11 +1,15 @@
 package com.gmail.nossr50.util;
 
+
+import java.io.File;
+
 import org.bukkit.block.BlockState;
+import org.bukkit.configuration.file.YamlConfiguration;
 import org.bukkit.entity.Entity;
 import org.bukkit.inventory.ItemStack;
 
+import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.config.Config;
-import com.gmail.nossr50.config.mods.CustomArmorConfig;
 import com.gmail.nossr50.config.mods.CustomBlockConfig;
 import com.gmail.nossr50.config.mods.CustomEntityConfig;
 import com.gmail.nossr50.config.mods.CustomToolConfig;
@@ -13,11 +17,11 @@ import com.gmail.nossr50.datatypes.mods.CustomBlock;
 import com.gmail.nossr50.datatypes.mods.CustomEntity;
 import com.gmail.nossr50.datatypes.mods.CustomTool;
 
+
 public final class ModUtils {
     private static Config configInstance = Config.getInstance();
 
     private static boolean customToolsEnabled    = configInstance.getToolModsEnabled();
-    private static boolean customArmorEnabled    = configInstance.getArmorModsEnabled();
     private static boolean customBlocksEnabled   = configInstance.getBlockModsEnabled();
     private static boolean customEntitiesEnabled = configInstance.getEntityModsEnabled();
 
@@ -30,38 +34,27 @@ public final class ModUtils {
      * @return the tool if it exists, null otherwise
      */
     public static CustomTool getToolFromItemStack(ItemStack item) {
-        return CustomToolConfig.getInstance().customToolMap.get(item.getType());
+        return CustomToolConfig.getInstance().getCustomTool(item.getType());
+    }
+
+    /**
+     * Get the custom entity associated with an entity.
+     *
+     * @param entity The entity to check
+     * @return the entity is if exists, null otherwise
+     */
+    public static CustomEntity getCustomEntity(Entity entity) {
+        return CustomEntityConfig.getInstance().getCustomEntity(entity);
     }
 
     /**
      * Get the custom block associated with an block.
      *
-     * @param blockState The block to check
+     * @param blockState The BlockState of the bloc to check
      * @return the block if it exists, null otherwise
      */
     public static CustomBlock getCustomBlock(BlockState blockState) {
-        return CustomBlockConfig.getInstance().customBlockMap.get(blockState.getData());
-    }
-
-    public static CustomEntity getCustomEntity(Entity entity) {
-        CustomEntity customEntity = CustomEntityConfig.getInstance().customEntityTypeMap.get(entity.getType().toString());
-
-        if (customEntity == null) {
-            try {
-                customEntity = CustomEntityConfig.getInstance().customEntityClassMap.get(((Class<?>) entity.getClass().getDeclaredField("entityClass").get(entity)).getName());
-            }
-            catch (NoSuchFieldException e){
-                return null;
-            }
-            catch (IllegalArgumentException e) {
-                return null;
-            }
-            catch (IllegalAccessException e) {
-                return null;
-            }
-        }
-
-        return customEntity;
+        return CustomBlockConfig.getInstance().getCustomBlock(blockState.getData());
     }
 
     /**
@@ -71,7 +64,7 @@ public final class ModUtils {
      * @return true if the block represents a custom woodcutting block, false otherwise
      */
     public static boolean isCustomWoodcuttingBlock(BlockState blockState) {
-        return customBlocksEnabled && CustomBlockConfig.getInstance().customWoodcuttingBlocks.contains(blockState.getData());
+        return customBlocksEnabled && CustomBlockConfig.getInstance().isCustomWoodcuttingBlock(blockState.getData());
     }
 
     /**
@@ -81,7 +74,7 @@ public final class ModUtils {
      * @return true if the block represents an ability block, false otherwise
      */
     public static boolean isCustomAbilityBlock(BlockState blockState) {
-        return customBlocksEnabled && CustomBlockConfig.getInstance().customAbilityBlocks.contains(blockState.getData());
+        return customBlocksEnabled && CustomBlockConfig.getInstance().isCustomAbilityBlock(blockState.getData());
     }
 
     /**
@@ -91,7 +84,7 @@ public final class ModUtils {
      * @return true if the block represents a custom mining block, false otherwise
      */
     public static boolean isCustomMiningBlock(BlockState blockState) {
-        return customBlocksEnabled && CustomBlockConfig.getInstance().customMiningBlocks.contains(blockState.getData());
+        return customBlocksEnabled && CustomBlockConfig.getInstance().isCustomMiningBlock(blockState.getData());
     }
 
     /**
@@ -101,7 +94,7 @@ public final class ModUtils {
      * @return true if the block represents a custom excavation block, false otherwise
      */
     public static boolean isCustomExcavationBlock(BlockState blockState) {
-        return customBlocksEnabled && CustomBlockConfig.getInstance().customExcavationBlocks.contains(blockState.getData());
+        return customBlocksEnabled && CustomBlockConfig.getInstance().isCustomExcavationBlock(blockState.getData());
     }
 
     /**
@@ -111,7 +104,7 @@ public final class ModUtils {
      * @return true if the block represents a custom herbalism block, false otherwise
      */
     public static boolean isCustomHerbalismBlock(BlockState blockState) {
-        return customBlocksEnabled && CustomBlockConfig.getInstance().customHerbalismBlocks.contains(blockState.getData());
+        return customBlocksEnabled && CustomBlockConfig.getInstance().isCustomHerbalismBlock(blockState.getData());
     }
 
     /**
@@ -121,7 +114,7 @@ public final class ModUtils {
      * @return true if the block represents leaves, false otherwise
      */
     public static boolean isCustomLeafBlock(BlockState blockState) {
-        return customBlocksEnabled && CustomBlockConfig.getInstance().customLeaves.contains(blockState.getData());
+        return customBlocksEnabled && CustomBlockConfig.getInstance().isCustomLeaf(blockState.getData());
     }
 
     /**
@@ -131,7 +124,7 @@ public final class ModUtils {
      * @return true if the block represents a log, false otherwise
      */
     public static boolean isCustomLogBlock(BlockState blockState) {
-        return customBlocksEnabled && CustomBlockConfig.getInstance().customLogs.contains(blockState.getData());
+        return customBlocksEnabled && CustomBlockConfig.getInstance().isCustomLog(blockState.getData());
     }
 
     /**
@@ -141,7 +134,7 @@ public final class ModUtils {
      * @return true if the block represents an ore, false otherwise
      */
     public static boolean isCustomOreBlock(BlockState blockState) {
-        return customBlocksEnabled && CustomBlockConfig.getInstance().customOres.contains(blockState.getData());
+        return customBlocksEnabled && CustomBlockConfig.getInstance().isCustomOre(blockState.getData());
     }
 
     /**
@@ -151,40 +144,17 @@ public final class ModUtils {
      * @return true if the item is a custom tool, false otherwise
      */
     public static boolean isCustomTool(ItemStack item) {
-        return customToolsEnabled && CustomToolConfig.getInstance().customTool.contains(item.getType());
+        return customToolsEnabled && CustomToolConfig.getInstance().isCustomTool(item.getType());
     }
 
     /**
-     * Checks to see if an item is custom armor.
+     * Checks to see if an entity is a custom entity.
      *
-     * @param item Item to check
-     * @return true if the item is custom armor, false otherwise
+     * @param entity Entity to check
+     * @return true if the entity is a custom entity, false otherwise
      */
-    public static boolean isCustomArmor(ItemStack item) {
-        return customArmorEnabled && CustomArmorConfig.getInstance().customArmor.contains(item.getType());
-    }
-
     public static boolean isCustomEntity(Entity entity) {
-        if (!customEntitiesEnabled) {
-            return false;
-        }
-
-        if (CustomEntityConfig.getInstance().customEntityTypeMap.containsKey(entity.getType().toString())) {
-            return true;
-        }
-
-        try {
-            return CustomEntityConfig.getInstance().customEntityClassMap.containsKey(((Class<?>) entity.getClass().getDeclaredField("entityClass").get(entity)).getName());
-        }
-        catch (NoSuchFieldException e){
-            return false;
-        }
-        catch (IllegalArgumentException e) {
-            return false;
-        }
-        catch (IllegalAccessException e) {
-            return false;
-        }
+        return customEntitiesEnabled && CustomEntityConfig.getInstance().isCustomEntity(entity);
     }
 
     /**
@@ -197,4 +167,52 @@ public final class ModUtils {
         //TODO: Finish this method
         return false;
     }
+
+    public static void addCustomEntity(Entity entity) {
+        if (!customEntitiesEnabled) {
+            return;
+        }
+
+        File entityFile = CustomEntityConfig.getInstance().getFile();
+        YamlConfiguration entitiesFile = YamlConfiguration.loadConfiguration(entityFile);
+
+        String entityName = entity.getType().toString();
+        String sanitizedEntityName = entityName.replace(".", "_");
+
+        if (entitiesFile.getKeys(false).contains(sanitizedEntityName)) {
+            return;
+        }
+
+        entitiesFile.set(sanitizedEntityName + ".XP_Multiplier", 1.0D);
+        entitiesFile.set(sanitizedEntityName + ".Tameable", false);
+        entitiesFile.set(sanitizedEntityName + ".Taming_XP", 0);
+        entitiesFile.set(sanitizedEntityName + ".CanBeSummoned", false);
+        entitiesFile.set(sanitizedEntityName + ".COTW_Material", "");
+        entitiesFile.set(sanitizedEntityName + ".COTW_Material_Data", 0);
+        entitiesFile.set(sanitizedEntityName + ".COTW_Material_Amount", 0);
+
+        String className = "";
+
+        try {
+            className = ((Class<?>) entity.getClass().getDeclaredField("entityClass").get(entity)).getName();
+        }
+        catch (Exception e) {
+            if (e instanceof NoSuchFieldException || e instanceof IllegalArgumentException || e instanceof IllegalAccessException) {
+                className = entity.getClass().getName();
+            }
+            else {
+                e.printStackTrace();
+            }
+        }
+
+        CustomEntityConfig.getInstance().addEntity(new CustomEntity(1.0D, false, 0, false, null, 0), className, entityName);
+
+        try {
+            entitiesFile.save(entityFile);
+            mcMMO.p.debug(entity.getType().toString() + " was added to the custom entities file!");
+        }
+        catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
 }

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

@@ -498,10 +498,6 @@ public final class CombatUtils {
                         baseXP = ExperienceConfig.getInstance().getCombatXP(type);
                         break;
 
-                    case UNKNOWN:
-                        baseXP = 1.0;
-                        break;
-
                     case SKELETON:
                         switch (((Skeleton) target).getSkeletonType()) {
                             case WITHER:
@@ -520,6 +516,8 @@ public final class CombatUtils {
                         break;
 
                     default:
+                        baseXP = 1.0;
+                        ModUtils.addCustomEntity(target);
                         break;
                 }
             }

+ 0 - 2
src/main/resources/blocks.yml

@@ -43,7 +43,6 @@ Mining:
     Block_1|0:
         XP_Gain: 99
         Is_Ore: true
-        Tier: 1
         Drop_Item: false
         Drop_Item_Name: BLOCK_DROP
         Drop_Item_Data_Value: 0
@@ -52,7 +51,6 @@ Mining:
     Block_2|0:
         XP_Gain: 99
         Is_Ore: true
-        Tier: 1
         Drop_Item: false
         Drop_Item_Name: BLOCK_DROP
         Drop_Item_Data_Value: 0

+ 39 - 63
src/main/resources/entities.yml

@@ -1,66 +1,42 @@
 #
-#  Settings for Hostile Mobs
-###
-Hostile:
-    Mob_1:
-        Class: CLASS_NAME
-        XP_Multiplier: 1.0
-        Tameable: false
-        Taming_XP: 250
-        CanBeSummoned: false
-        COTW_Material_ID: 999
-        COTW_Material_Data: 9
-        COTW_Material_Amount: 99
-    Mob_2:
-        Class: CLASS_NAME
-        XP_Multiplier: 1.0
-        Tameable: false
-        Taming_XP: 250
-        CanBeSummoned: false
-        COTW_Material_ID: 999
-        COTW_Material_Data: 9
-        COTW_Material_Amount: 99
-#
-#  Settings for Neutral Mobs
-###
-Neutral:
-    Mob_1:
-        Class: CLASS_NAME
-        XP_Multiplier: 1.0
-        Tameable: false
-        Taming_XP: 250
-        CanBeSummoned: false
-        COTW_Material_ID: 999
-        COTW_Material_Data: 9
-        COTW_Material_Amount: 99
-    Mob_2:
-        Class: CLASS_NAME
-        XP_Multiplier: 1.0
-        Tameable: false
-        Taming_XP: 250
-        CanBeSummoned: false
-        COTW_Material_ID: 999
-        COTW_Material_Data: 9
-        COTW_Material_Amount: 99
+#  Settings for Custom Mobs
 #
-#  Settings for Passive Mobs
+#  Mob name should be the entity type of the mob - usually "ModName_EntityName"
+#  Be sure to use the "_" character in place of any "." characters in the mob name.
 ###
-Passive:
-    Mob_1:
-        Class: CLASS_NAME
-        XP_Multiplier: 1.0
-        Tameable: false
-        Taming_XP: 250
-        CanBeSummoned: false
-        COTW_Material_ID: 999
-        COTW_Material_Data: 9
-        COTW_Material_Amount: 99
-    Mob_2:
-        Class: CLASS_NAME
-        XP_Multiplier: 1.0
-        Tameable: false
-        Taming_XP: 250
-        CanBeSummoned: false
-        COTW_Material_ID: 999
-        COTW_Material_Data: 9
-        COTW_Material_Amount: 99
+Mob_1:
+    Class: CLASS_NAME
+    XP_Multiplier: 1.0
+    Tameable: false
+    Taming_XP: 250
+    CanBeSummoned: false
+    COTW_Material: MATERIAL_NAME
+    COTW_Material_Data: 9
+    COTW_Material_Amount: 99
+Mob_2:
+    Class: CLASS_NAME
+    XP_Multiplier: 1.0
+    Tameable: false
+    Taming_XP: 250
+    CanBeSummoned: false
+    COTW_Material: MATERIAL_NAME
+    COTW_Material_Data: 9
+    COTW_Material_Amount: 99
+Mob_3:
+    Class: CLASS_NAME
+    XP_Multiplier: 1.0
+    Tameable: false
+    Taming_XP: 250
+    CanBeSummoned: false
+    COTW_Material: MATERIAL_NAME
+    COTW_Material_Data: 9
+    COTW_Material_Amount: 99
+Mob_4:
+    Class: CLASS_NAME
+    XP_Multiplier: 1.0
+    Tameable: false
+    Taming_XP: 250
+    CanBeSummoned: false
+    COTW_Material: MATERIAL_NAME
+    COTW_Material_Data: 9
+    COTW_Material_Amount: 99