Преглед изворни кода

Step 1 of rewriting Alchemy - Removing all the old code

nossr50 пре 6 година
родитељ
комит
1c6b0363ce
26 измењених фајлова са 1858 додато и 1899 уклоњено
  1. 96 102
      src/main/java/com/gmail/nossr50/commands/skills/AlchemyCommand.java
  2. 5 6
      src/main/java/com/gmail/nossr50/config/ConfigManager.java
  3. 0 202
      src/main/java/com/gmail/nossr50/config/skills/alchemy/PotionManager.java
  4. 0 167
      src/main/java/com/gmail/nossr50/datatypes/skills/alchemy/AlchemyPotion.java
  5. 0 86
      src/main/java/com/gmail/nossr50/datatypes/skills/alchemy/PotionStage.java
  6. 38 0
      src/main/java/com/gmail/nossr50/dumpster/AlchemyBrewCheckTask.java
  7. 118 0
      src/main/java/com/gmail/nossr50/dumpster/AlchemyBrewTask.java
  8. 167 0
      src/main/java/com/gmail/nossr50/dumpster/AlchemyPotion.java
  9. 251 0
      src/main/java/com/gmail/nossr50/dumpster/AlchemyPotionBrewer.java
  10. 0 0
      src/main/java/com/gmail/nossr50/dumpster/CheckDateTask.java
  11. 0 0
      src/main/java/com/gmail/nossr50/dumpster/HolidayManager.java
  12. 0 0
      src/main/java/com/gmail/nossr50/dumpster/ModManager.java
  13. 740 0
      src/main/java/com/gmail/nossr50/dumpster/PotionGenerator.java
  14. 170 0
      src/main/java/com/gmail/nossr50/dumpster/PotionManager.java
  15. 86 0
      src/main/java/com/gmail/nossr50/dumpster/PotionStage.java
  16. 7 5
      src/main/java/com/gmail/nossr50/listeners/BlockListener.java
  17. 114 118
      src/main/java/com/gmail/nossr50/listeners/InventoryListener.java
  18. 2 1
      src/main/java/com/gmail/nossr50/listeners/WorldListener.java
  19. 1 2
      src/main/java/com/gmail/nossr50/mcMMO.java
  20. 0 38
      src/main/java/com/gmail/nossr50/runnables/skills/AlchemyBrewCheckTask.java
  21. 0 118
      src/main/java/com/gmail/nossr50/runnables/skills/AlchemyBrewTask.java
  22. 26 38
      src/main/java/com/gmail/nossr50/skills/alchemy/Alchemy.java
  23. 36 46
      src/main/java/com/gmail/nossr50/skills/alchemy/AlchemyManager.java
  24. 0 251
      src/main/java/com/gmail/nossr50/skills/alchemy/AlchemyPotionBrewer.java
  25. 0 718
      src/main/java/com/gmail/nossr50/skills/alchemy/PotionGenerator.java
  26. 1 1
      src/main/java/com/gmail/nossr50/util/commands/CommandRegistrationManager.java

+ 96 - 102
src/main/java/com/gmail/nossr50/commands/skills/AlchemyCommand.java

@@ -1,102 +1,96 @@
-package com.gmail.nossr50.commands.skills;
-
-import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
-import com.gmail.nossr50.datatypes.skills.SubSkillType;
-import com.gmail.nossr50.locale.LocaleLoader;
-import com.gmail.nossr50.skills.alchemy.AlchemyManager;
-import com.gmail.nossr50.util.Permissions;
-import com.gmail.nossr50.util.TextComponentFactory;
-import com.gmail.nossr50.util.player.UserManager;
-import com.gmail.nossr50.util.skills.RankUtils;
-import net.md_5.bungee.api.chat.TextComponent;
-import org.bukkit.entity.Player;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class AlchemyCommand extends SkillCommand {
-    private String brewSpeed;
-    private String brewSpeedLucky;
-
-    private int tier;
-    private int ingredientCount;
-    private String ingredientList;
-
-    private boolean canCatalysis;
-    private boolean canConcoctions;
-
-    public AlchemyCommand() {
-        super(PrimarySkillType.ALCHEMY);
-    }
-
-    protected String[] calculateAbilityDisplayValues(Player player) {
-        //TODO: Needed?
-        if (UserManager.getPlayer(player) == null) {
-            player.sendMessage(LocaleLoader.getString("Profile.PendingLoad"));
-            return new String[]{"DATA NOT LOADED", "DATA NOT LOADED"};
-        }
-
-        AlchemyManager alchemyManager = UserManager.getPlayer(player).getAlchemyManager();
-        String[] displayValues = new String[2];
-
-        boolean isLucky = Permissions.lucky(player, PrimarySkillType.ALCHEMY);
-
-        displayValues[0] = decimal.format(alchemyManager.calculateBrewSpeed(false)) + "x";
-        displayValues[1] = isLucky ? decimal.format(alchemyManager.calculateBrewSpeed(true)) + "x" : null;
-
-        return displayValues;
-    }
-
-    @Override
-    protected void dataCalculations(Player player, float skillValue) {
-        // ALCHEMY_CATALYSIS
-        if (canCatalysis) {
-            String[] catalysisStrings = calculateAbilityDisplayValues(player);
-            brewSpeed = catalysisStrings[0];
-            brewSpeedLucky = catalysisStrings[1];
-        }
-
-        // ALCHEMY_CONCOCTIONS
-        if (canConcoctions) {
-            AlchemyManager alchemyManager = UserManager.getPlayer(player).getAlchemyManager();
-            tier = alchemyManager.getTier();
-            ingredientCount = alchemyManager.getIngredients().size();
-            ingredientList = alchemyManager.getIngredientList();
-        }
-    }
-
-    @Override
-    protected void permissionsCheck(Player player) {
-        canCatalysis = canUseSubskill(player, SubSkillType.ALCHEMY_CATALYSIS);
-        canConcoctions = canUseSubskill(player, SubSkillType.ALCHEMY_CONCOCTIONS);
-    }
-
-    @Override
-    protected List<String> statsDisplay(Player player, float skillValue, boolean hasEndurance, boolean isLucky) {
-        List<String> messages = new ArrayList<>();
-
-        if (canCatalysis) {
-            messages.add(getStatMessage(SubSkillType.ALCHEMY_CATALYSIS, brewSpeed)
-                    + (isLucky ? LocaleLoader.getString("Perks.Lucky.Bonus", brewSpeedLucky) : ""));
-        }
-
-        if (canConcoctions) {
-            messages.add(getStatMessage(false, true, SubSkillType.ALCHEMY_CONCOCTIONS, String.valueOf(tier), String.valueOf(RankUtils.getHighestRank(SubSkillType.ALCHEMY_CONCOCTIONS))));
-            messages.add(getStatMessage(true, true, SubSkillType.ALCHEMY_CONCOCTIONS, String.valueOf(ingredientCount), ingredientList));
-
-            //messages.add(LocaleLoader.getString("Alchemy.Concoctions.Rank", tier, RankUtils.getHighestRank(SubSkillType.ALCHEMY_CONCOCTIONS)));
-            //messages.add(LocaleLoader.getString("Alchemy.Concoctions.Ingredients", ingredientCount, ingredientList));
-        }
-
-        return messages;
-    }
-
-    @Override
-    protected List<TextComponent> getTextComponents(Player player) {
-        List<TextComponent> textComponents = new ArrayList<>();
-
-        TextComponentFactory.getSubSkillTextComponents(player, textComponents, PrimarySkillType.ALCHEMY);
-
-        return textComponents;
-    }
-}
+//package com.gmail.nossr50.commands.skills;
+//
+//import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
+//import com.gmail.nossr50.util.TextComponentFactory;
+//import net.md_5.bungee.api.chat.TextComponent;
+//import org.bukkit.entity.Player;
+//
+//import java.util.ArrayList;
+//import java.util.List;
+//
+//public class AlchemyCommand extends SkillCommand {
+////    private String brewSpeed;
+////    private String brewSpeedLucky;
+////
+////    private int tier;
+////    private int ingredientCount;
+////    private String ingredientList;
+////
+////    private boolean canCatalysis;
+////    private boolean canConcoctions;
+//
+//    public AlchemyCommand() {
+//        super(PrimarySkillType.ALCHEMY);
+//    }
+//
+////    protected String[] calculateAbilityDisplayValues(Player player) {
+////        //TODO: Needed?
+////        if (UserManager.getPlayer(player) == null) {
+////            player.sendMessage(LocaleLoader.getString("Profile.PendingLoad"));
+////            return new String[]{"DATA NOT LOADED", "DATA NOT LOADED"};
+////        }
+////
+////        AlchemyManager alchemyManager = UserManager.getPlayer(player).getAlchemyManager();
+////        String[] displayValues = new String[2];
+////
+////        boolean isLucky = Permissions.lucky(player, PrimarySkillType.ALCHEMY);
+////
+////        displayValues[0] = decimal.format(alchemyManager.calculateBrewSpeed(false)) + "x";
+////        displayValues[1] = isLucky ? decimal.format(alchemyManager.calculateBrewSpeed(true)) + "x" : null;
+////
+////        return displayValues;
+////    }
+//
+//    @Override
+//    protected void dataCalculations(Player player, float skillValue) {
+//        // ALCHEMY_CATALYSIS
+////        if (canCatalysis) {
+////            String[] catalysisStrings = calculateAbilityDisplayValues(player);
+////            brewSpeed = catalysisStrings[0];
+////            brewSpeedLucky = catalysisStrings[1];
+////        }
+////
+////        // ALCHEMY_CONCOCTIONS
+////        if (canConcoctions) {
+////            AlchemyManager alchemyManager = UserManager.getPlayer(player).getAlchemyManager();
+////            tier = alchemyManager.getTier();
+////            ingredientCount = alchemyManager.getIngredients().size();
+////            ingredientList = alchemyManager.getIngredientList();
+////        }
+//    }
+//
+//    @Override
+//    protected void permissionsCheck(Player player) {
+////        canCatalysis = canUseSubskill(player, SubSkillType.ALCHEMY_CATALYSIS);
+////        canConcoctions = canUseSubskill(player, SubSkillType.ALCHEMY_CONCOCTIONS);
+//    }
+//
+//    @Override
+//    protected List<String> statsDisplay(Player player, float skillValue, boolean hasEndurance, boolean isLucky) {
+//        List<String> messages = new ArrayList<>();
+//
+////        if (canCatalysis) {
+////            messages.add(getStatMessage(SubSkillType.ALCHEMY_CATALYSIS, brewSpeed)
+////                    + (isLucky ? LocaleLoader.getString("Perks.Lucky.Bonus", brewSpeedLucky) : ""));
+////        }
+////
+////        if (canConcoctions) {
+////            messages.add(getStatMessage(false, true, SubSkillType.ALCHEMY_CONCOCTIONS, String.valueOf(tier), String.valueOf(RankUtils.getHighestRank(SubSkillType.ALCHEMY_CONCOCTIONS))));
+////            messages.add(getStatMessage(true, true, SubSkillType.ALCHEMY_CONCOCTIONS, String.valueOf(ingredientCount), ingredientList));
+////
+////            //messages.add(LocaleLoader.getString("Alchemy.Concoctions.Rank", tier, RankUtils.getHighestRank(SubSkillType.ALCHEMY_CONCOCTIONS)));
+////            //messages.add(LocaleLoader.getString("Alchemy.Concoctions.Ingredients", ingredientCount, ingredientList));
+////        }
+//
+//        return messages;
+//    }
+//
+//    @Override
+//    protected List<TextComponent> getTextComponents(Player player) {
+//        List<TextComponent> textComponents = new ArrayList<>();
+//
+//        TextComponentFactory.getSubSkillTextComponents(player, textComponents, PrimarySkillType.ALCHEMY);
+//
+//        return textComponents;
+//    }
+//}

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

@@ -40,7 +40,6 @@ import com.gmail.nossr50.config.hocon.skills.unarmed.ConfigUnarmed;
 import com.gmail.nossr50.config.hocon.skills.woodcutting.ConfigWoodcutting;
 import com.gmail.nossr50.config.hocon.superabilities.ConfigSuperAbilities;
 import com.gmail.nossr50.config.hocon.worldblacklist.ConfigWorldBlacklist;
-import com.gmail.nossr50.config.skills.alchemy.PotionManager;
 import com.gmail.nossr50.config.treasure.ExcavationTreasureConfig;
 import com.gmail.nossr50.config.treasure.FishingTreasureConfig;
 import com.gmail.nossr50.config.treasure.HerbalismTreasureConfig;
@@ -93,7 +92,7 @@ public final class ConfigManager {
     /* MISC MANAGERS */
     private TypeSerializerCollection customSerializers;
     private ExperienceMapManager experienceMapManager;
-    private PotionManager potionManager;
+//    private PotionManager potionManager;
 
     /* CONFIG INSTANCES */
 
@@ -333,7 +332,7 @@ public final class ConfigManager {
         //Set the global XP val
         experienceMapManager.setGlobalXpMult(getConfigExperience().getGlobalXPMultiplier());
         experienceMapManager.buildBlockXPMaps(); //Block XP value maps
-        potionManager = new PotionManager();
+//        potionManager = new PotionManager();
     }
 
     /**
@@ -470,9 +469,9 @@ public final class ConfigManager {
         return advancedConfig;
     }
 
-    public PotionManager getPotionManager() {
-        return potionManager;
-    }
+//    public PotionManager getPotionManager() {
+//        return potionManager;
+//    }
 
     public CoreSkillsConfig getCoreSkillsConfig() {
         return coreSkillsConfig;

+ 0 - 202
src/main/java/com/gmail/nossr50/config/skills/alchemy/PotionManager.java

@@ -1,202 +0,0 @@
-package com.gmail.nossr50.config.skills.alchemy;
-
-import com.gmail.nossr50.datatypes.skills.alchemy.AlchemyPotion;
-import com.gmail.nossr50.mcMMO;
-import com.gmail.nossr50.skills.alchemy.PotionGenerator;
-import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
-import org.bukkit.Material;
-import org.bukkit.inventory.ItemStack;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Eventually I'm going to delete all of our Alchemy code and rewrite it from scratch
- */
-@ConfigSerializable
-public class PotionManager {
-
-    /* CONSTANTS */
-    public static final String POTIONS = "Potions";
-//    public static final String NAME = "Name";
-//    public static final String POTION_DATA = "PotionData";
-//    public static final String POTION_TYPE = "PotionType";
-//    public static final String WATER = "WATER";
-//    public static final String EXTENDED = "Extended";
-//    public static final String UPGRADED = "Upgraded";
-//    public static final String MATERIAL = "Material";
-//    public static final String LORE = "Lore";
-//    public static final String EFFECTS = "Effects";
-//    public static final String COLOR = "Color";
-//    public static final String CHILDREN = "Children";
-
-    /* INGREDIENTS */
-
-    private List<ItemStack> ingredientTierOne;
-    private List<ItemStack> ingredientTierTwo;
-    private List<ItemStack> ingredientTierThree;
-    private List<ItemStack> ingredientTierFour;
-    private List<ItemStack> ingredientTierFive;
-    private List<ItemStack> ingredientTierSix;
-    private List<ItemStack> ingredientTierSeven;
-    private List<ItemStack> ingredientTierEight;
-
-    private Map<String, AlchemyPotion> potionMap = new HashMap<>();
-
-    public PotionManager() {
-        initIngredientLists();
-        initPotionMap();
-    }
-
-    /**
-     * This grabs an instance of this config class from the Config Manager
-     * This method is deprecated and will be removed in the future
-     *
-     * @return the instance of this config
-     * @see mcMMO#getConfigManager()
-     * @deprecated Please use mcMMO.getConfigManager() to grab a specific config instead
-     */
-    @Deprecated
-    public static PotionManager getInstance() {
-        return mcMMO.getConfigManager().getPotionManager();
-    }
-
-    @Override
-    public void unload() {
-        potionMap.clear();
-    }
-
-    /**
-     * I just want anyone who reads this to know
-     * This entire class is an abomination
-     * What you see below is a hacky solution to keep Alchemy functioning with the new config system
-     * Alchemy will be rewritten, until then, this disgusting class exists.
-     */
-    private void initIngredientLists() {
-        ingredientTierOne = new ArrayList<>();
-        ingredientTierTwo = new ArrayList<>();
-        ingredientTierThree = new ArrayList<>();
-        ingredientTierFour = new ArrayList<>();
-        ingredientTierFive = new ArrayList<>();
-        ingredientTierSix = new ArrayList<>();
-        ingredientTierSeven = new ArrayList<>();
-        ingredientTierEight = new ArrayList<>();
-
-        ingredientTierOne.add(new ItemStack(Material.BLAZE_POWDER));
-        ingredientTierOne.add(new ItemStack(Material.FERMENTED_SPIDER_EYE));
-        ingredientTierOne.add(new ItemStack(Material.GHAST_TEAR));
-        ingredientTierOne.add(new ItemStack(Material.GLOWSTONE_DUST));
-        ingredientTierOne.add(new ItemStack(Material.GOLDEN_CARROT));
-        ingredientTierOne.add(new ItemStack(Material.MAGMA_CREAM));
-        ingredientTierOne.add(new ItemStack(Material.NETHER_WART));
-        ingredientTierOne.add(new ItemStack(Material.REDSTONE));
-        ingredientTierOne.add(new ItemStack(Material.GLISTERING_MELON_SLICE));
-        ingredientTierOne.add(new ItemStack(Material.SPIDER_EYE));
-        ingredientTierOne.add(new ItemStack(Material.SUGAR));
-        ingredientTierOne.add(new ItemStack(Material.GUNPOWDER));
-        ingredientTierOne.add(new ItemStack(Material.PUFFERFISH));
-        ingredientTierOne.add(new ItemStack(Material.DRAGON_BREATH));
-
-        ingredientTierTwo.add(new ItemStack(Material.CARROT));
-        ingredientTierTwo.add(new ItemStack(Material.SLIME_BALL));
-        ingredientTierTwo.add(new ItemStack(Material.PHANTOM_MEMBRANE));
-
-        ingredientTierThree.add(new ItemStack(Material.QUARTZ));
-        ingredientTierThree.add(new ItemStack(Material.RED_MUSHROOM));
-
-        ingredientTierFour.add(new ItemStack(Material.APPLE));
-        ingredientTierFour.add(new ItemStack(Material.ROTTEN_FLESH));
-
-        ingredientTierFive.add(new ItemStack(Material.BROWN_MUSHROOM));
-        ingredientTierFive.add(new ItemStack(Material.INK_SAC));
-
-        ingredientTierSix.add(new ItemStack(Material.FERN));
-
-        ingredientTierSeven.add(new ItemStack(Material.POISONOUS_POTATO));
-
-        ingredientTierEight.add(new ItemStack(Material.GOLDEN_APPLE));
-    }
-
-    private void loadConcoctionsTier(List<ItemStack> ingredientList, List<String> ingredients) {
-        if (ingredients != null && ingredients.size() > 0) {
-            for (String ingredientString : ingredients) {
-                ItemStack ingredient = loadIngredient(ingredientString);
-
-                if (ingredient != null) {
-                    ingredientList.add(ingredient);
-                }
-            }
-        }
-    }
-
-    private void initPotionMap() {
-        PotionGenerator potionGenerator = new PotionGenerator();
-
-    }
-
-    /**
-     * Parse a string representation of an ingredient.
-     * Format: '&lt;MATERIAL&gt;[:data]'
-     * Returns null if input cannot be parsed.
-     *
-     * @param ingredient String representing an ingredient.
-     * @return Parsed ingredient.
-     */
-    private ItemStack loadIngredient(String ingredient) {
-        if (ingredient == null || ingredient.isEmpty()) {
-            return null;
-        }
-
-        Material material = Material.getMaterial(ingredient);
-
-        if (material != null) {
-            return new ItemStack(material, 1);
-        }
-
-        return null;
-    }
-
-    public List<ItemStack> getIngredients(int tier) {
-        switch (tier) {
-            case 8:
-                return ingredientTierEight;
-            case 7:
-                return ingredientTierSeven;
-            case 6:
-                return ingredientTierSix;
-            case 5:
-                return ingredientTierFive;
-            case 4:
-                return ingredientTierFour;
-            case 3:
-                return ingredientTierThree;
-            case 2:
-                return ingredientTierTwo;
-            case 1:
-            default:
-                return ingredientTierOne;
-        }
-    }
-
-    public boolean isValidPotion(ItemStack item) {
-        return getPotion(item) != null;
-    }
-
-    public AlchemyPotion getPotion(String name) {
-        return potionMap.get(name);
-    }
-
-    public AlchemyPotion getPotion(ItemStack item) {
-        for (AlchemyPotion potion : potionMap.values()) {
-            if (potion.isSimilar(item)) {
-                return potion;
-            }
-        }
-        return null;
-    }
-
-
-
-}

+ 0 - 167
src/main/java/com/gmail/nossr50/datatypes/skills/alchemy/AlchemyPotion.java

@@ -1,167 +0,0 @@
-package com.gmail.nossr50.datatypes.skills.alchemy;
-
-import com.gmail.nossr50.config.skills.alchemy.PotionManager;
-import org.bukkit.Color;
-import org.bukkit.Material;
-import org.bukkit.inventory.ItemStack;
-import org.bukkit.inventory.meta.PotionMeta;
-import org.bukkit.potion.Potion;
-import org.bukkit.potion.PotionData;
-import org.bukkit.potion.PotionEffect;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-public class AlchemyPotion {
-    private Material material;
-    private PotionData data;
-    private String name;
-    private List<String> lore;
-    private List<PotionEffect> effects;
-    private Color color;
-    private Map<ItemStack, String> children;
-
-    public AlchemyPotion(Material material, PotionData data, String name, List<String> lore, List<PotionEffect> effects, Color color, Map<ItemStack, String> children) {
-        this.material = material;
-        this.data = data;
-        this.lore = lore;
-        this.name = name;
-        this.effects = effects;
-        this.children = children;
-        this.color = color;
-    }
-
-    public String toString() {
-        return "AlchemyPotion{" + data + ", " + name + ", Effects[" + effects.size() + "], Children[" + children.size() + "]}";
-    }
-
-    public ItemStack toItemStack(int amount) {
-        ItemStack potion = new ItemStack(material, amount);
-        PotionMeta meta = (PotionMeta) potion.getItemMeta();
-
-        meta.setBasePotionData(data);
-        if (this.getName() != null) {
-            meta.setDisplayName(this.getName());
-        }
-
-        if (this.getLore() != null && !this.getLore().isEmpty()) {
-            meta.setLore(this.getLore());
-        }
-
-        if (!this.getEffects().isEmpty()) {
-            for (PotionEffect effect : this.getEffects()) {
-                meta.addCustomEffect(effect, true);
-            }
-        }
-
-        if (this.getColor() != null) {
-            meta.setColor(this.getColor());
-        }
-
-        potion.setItemMeta(meta);
-        return potion;
-    }
-
-    public Material getMaterial() {
-        return material;
-    }
-
-    public Potion toPotion(int amount) {
-        return Potion.fromItemStack(this.toItemStack(amount));
-    }
-
-    public PotionData getData() {
-        return data;
-    }
-
-    public void setData(PotionData data) {
-        this.data = data;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public List<String> getLore() {
-        return lore;
-    }
-
-    public void setLore(List<String> lore) {
-        this.lore = lore;
-    }
-
-    public List<PotionEffect> getEffects() {
-        return effects;
-    }
-
-    public void setEffects(List<PotionEffect> effects) {
-        this.effects = effects;
-    }
-
-    public Color getColor() {
-        return color;
-    }
-
-    public void setColor(Color color) {
-        this.color = color;
-    }
-
-    public Map<ItemStack, String> getChildren() {
-        return children;
-    }
-
-    public void setChildren(Map<ItemStack, String> children) {
-        this.children = children;
-    }
-
-    public AlchemyPotion getChild(ItemStack ingredient) {
-        if (!children.isEmpty()) {
-            for (Entry<ItemStack, String> child : children.entrySet()) {
-                if (ingredient.isSimilar(child.getKey())) {
-                    return PotionManager.getInstance().getPotion(child.getValue());
-                }
-            }
-        }
-        return null;
-    }
-
-    public boolean isSimilar(ItemStack item) {
-        if (item.getType() != material) {
-            return false;
-        }
-        if (!item.hasItemMeta()) {
-            return false;
-        }
-        PotionMeta meta = (PotionMeta) item.getItemMeta();
-        PotionData that = meta.getBasePotionData();
-        if (data.getType() != that.getType()) {
-            return false;
-        }
-        if (data.isExtended() != that.isExtended()) {
-            return false;
-        }
-        if (data.isUpgraded() != that.isUpgraded()) {
-            return false;
-        }
-        for (PotionEffect effect : effects) {
-            if (!meta.hasCustomEffect(effect.getType())) {
-                return false;
-            }
-        }
-        if (!meta.hasLore() && !lore.isEmpty()) {
-            return false;
-        }
-        if (!(lore.isEmpty() && !meta.hasLore()) && !meta.getLore().equals(lore)) {
-            return false;
-        }
-        if (!meta.hasDisplayName() && name != null) {
-            return false;
-        }
-        return (name == null && !meta.hasDisplayName()) || meta.getDisplayName().equals(name);
-    }
-}

+ 0 - 86
src/main/java/com/gmail/nossr50/datatypes/skills/alchemy/PotionStage.java

@@ -1,86 +0,0 @@
-package com.gmail.nossr50.datatypes.skills.alchemy;
-
-import org.bukkit.Material;
-import org.bukkit.potion.PotionData;
-import org.bukkit.potion.PotionEffect;
-import org.bukkit.potion.PotionType;
-
-import java.util.List;
-
-public enum PotionStage {
-    FIVE(5),
-    FOUR(4),
-    THREE(3),
-    TWO(2),
-    ONE(1);
-
-    int numerical;
-
-    PotionStage(int numerical) {
-        this.numerical = numerical;
-    }
-
-    private static PotionStage getPotionStageNumerical(int numerical) {
-        for (PotionStage potionStage : values()) {
-            if (numerical >= potionStage.toNumerical()) {
-                return potionStage;
-            }
-        }
-
-        return ONE;
-    }
-
-    public static PotionStage getPotionStage(AlchemyPotion input, AlchemyPotion output) {
-        PotionStage potionStage = getPotionStage(output);
-        if (!isWaterBottle(input) && getPotionStage(input) == potionStage) {
-            potionStage = PotionStage.FIVE;
-        }
-
-        return potionStage;
-    }
-
-    private static boolean isWaterBottle(AlchemyPotion input) {
-        return input.getData().getType() == PotionType.WATER;
-    }
-
-    public static PotionStage getPotionStage(AlchemyPotion alchemyPotion) {
-        PotionData data = alchemyPotion.getData();
-        List<PotionEffect> effects = alchemyPotion.getEffects();
-
-        int stage = 1;
-
-        // Check if potion has an effect of any sort
-        if (data.getType().getEffectType() != null || !effects.isEmpty()) {
-            stage++;
-        }
-
-        // Check if potion has a glowstone dust amplifier
-        // Else check if the potion has a custom effect with an amplifier added by mcMMO
-        if (data.isUpgraded()) {
-            stage++;
-        } else if (!effects.isEmpty()) {
-            for (PotionEffect effect : effects) {
-                if (effect.getAmplifier() > 0) {
-                    stage++;
-                    break;
-                }
-            }
-        }
-
-        // Check if potion has a redstone dust amplifier
-        if (data.isExtended()) {
-            stage++;
-        }
-
-        // Check if potion has a gunpowder amplifier
-        if (alchemyPotion.getMaterial() == Material.SPLASH_POTION || alchemyPotion.getMaterial() == Material.LINGERING_POTION) {
-            stage++;
-        }
-
-        return PotionStage.getPotionStageNumerical(stage);
-    }
-
-    public int toNumerical() {
-        return numerical;
-    }
-}

+ 38 - 0
src/main/java/com/gmail/nossr50/dumpster/AlchemyBrewCheckTask.java

@@ -0,0 +1,38 @@
+//package com.gmail.nossr50.runnables.skills;
+//
+//import com.gmail.nossr50.skills.alchemy.Alchemy;
+//import com.gmail.nossr50.skills.alchemy.AlchemyPotionBrewer;
+//import org.bukkit.Location;
+//import org.bukkit.block.BrewingStand;
+//import org.bukkit.entity.Player;
+//import org.bukkit.inventory.ItemStack;
+//import org.bukkit.scheduler.BukkitRunnable;
+//
+//import java.util.Arrays;
+//
+//public class AlchemyBrewCheckTask extends BukkitRunnable {
+//    private Player player;
+//    private BrewingStand brewingStand;
+//    private ItemStack[] oldInventory;
+//
+//    public AlchemyBrewCheckTask(Player player, BrewingStand brewingStand) {
+//        this.player = player;
+//        this.brewingStand = brewingStand;
+//        this.oldInventory = Arrays.copyOfRange(brewingStand.getInventory().getContents(), 0, 4);
+//    }
+//
+//    @Override
+//    public void run() {
+//        Location location = brewingStand.getLocation();
+//        ItemStack[] newInventory = Arrays.copyOfRange(brewingStand.getInventory().getContents(), 0, 4);
+//        boolean validBrew = brewingStand.getFuelLevel() > 0 && AlchemyPotionBrewer.isValidBrew(player, newInventory);
+//
+//        if (Alchemy.brewingStandMap.containsKey(location)) {
+//            if (oldInventory[Alchemy.INGREDIENT_SLOT] == null || newInventory[Alchemy.INGREDIENT_SLOT] == null || !oldInventory[Alchemy.INGREDIENT_SLOT].isSimilar(newInventory[Alchemy.INGREDIENT_SLOT]) || !validBrew) {
+//                Alchemy.brewingStandMap.get(location).cancelBrew();
+//            }
+//        } else if (validBrew) {
+//            Alchemy.brewingStandMap.put(location, new AlchemyBrewTask(brewingStand, player));
+//        }
+//    }
+//}

+ 118 - 0
src/main/java/com/gmail/nossr50/dumpster/AlchemyBrewTask.java

@@ -0,0 +1,118 @@
+//package com.gmail.nossr50.runnables.skills;
+//
+//import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
+//import com.gmail.nossr50.datatypes.skills.SubSkillType;
+//import com.gmail.nossr50.events.skills.alchemy.McMMOPlayerBrewEvent;
+//import com.gmail.nossr50.events.skills.alchemy.McMMOPlayerCatalysisEvent;
+//import com.gmail.nossr50.mcMMO;
+//import com.gmail.nossr50.skills.alchemy.Alchemy;
+//import com.gmail.nossr50.skills.alchemy.AlchemyPotionBrewer;
+//import com.gmail.nossr50.util.Misc;
+//import com.gmail.nossr50.util.Permissions;
+//import com.gmail.nossr50.util.player.UserManager;
+//import org.bukkit.Location;
+//import org.bukkit.Material;
+//import org.bukkit.block.BlockState;
+//import org.bukkit.block.BrewingStand;
+//import org.bukkit.entity.Player;
+//import org.bukkit.scheduler.BukkitRunnable;
+//
+//public class AlchemyBrewTask extends BukkitRunnable {
+//
+//    private BlockState brewingStand;
+//    private Location location;
+//    private double brewSpeed;
+//    private double brewTimer;
+//    private Player player;
+//    private int fuel;
+//    private boolean firstRun = true;
+//
+//    public AlchemyBrewTask(BlockState brewingStand, Player player) {
+//        this.brewingStand = brewingStand;
+//        this.location = brewingStand.getLocation();
+//        this.player = player;
+//
+//        brewSpeed = 1.0;
+//        brewTimer = 400;
+//
+//        if (player != null
+//                && !Misc.isNPCEntity(player)
+//                && Permissions.isSubSkillEnabled(player, SubSkillType.ALCHEMY_CATALYSIS)
+//                && UserManager.getPlayer(player) != null) {
+//
+//            double catalysis = UserManager.getPlayer(player).getAlchemyManager().calculateBrewSpeed(Permissions.lucky(player, PrimarySkillType.ALCHEMY));
+//
+//            McMMOPlayerCatalysisEvent event = new McMMOPlayerCatalysisEvent(player, catalysis);
+//            mcMMO.p.getServer().getPluginManager().callEvent(event);
+//
+//            if (!event.isCancelled()) {
+//                brewSpeed = catalysis;
+//            }
+//        }
+//
+//        if (Alchemy.brewingStandMap.containsKey(location)) {
+//            Alchemy.brewingStandMap.get(location).cancel();
+//        }
+//
+//        fuel = ((BrewingStand) brewingStand).getFuelLevel();
+//
+//        if (((BrewingStand) brewingStand).getBrewingTime() == -1) // Only decrement on our end if it isn't a vanilla ingredient.
+//            fuel--;
+//
+//        Alchemy.brewingStandMap.put(location, this);
+//        this.runTaskTimer(mcMMO.p, 1, 1);
+//    }
+//
+//    @Override
+//    public void run() {
+//        if (player == null || !player.isValid() || brewingStand == null || brewingStand.getType() != Material.BREWING_STAND || !AlchemyPotionBrewer.isValidIngredient(player, ((BrewingStand) brewingStand).getInventory().getContents()[Alchemy.INGREDIENT_SLOT])) {
+//            if (Alchemy.brewingStandMap.containsKey(location)) {
+//                Alchemy.brewingStandMap.remove(location);
+//            }
+//
+//            this.cancel();
+//
+//            return;
+//        }
+//
+//        if (firstRun) {
+//            firstRun = false;
+//            ((BrewingStand) brewingStand).setFuelLevel(fuel);
+//        }
+//
+//        brewTimer -= brewSpeed;
+//
+//        // Vanilla potion brewing completes when BrewingTime == 1
+//        if (brewTimer < Math.max(brewSpeed, 2)) {
+//            this.cancel();
+//            finish();
+//        } else {
+//            ((BrewingStand) brewingStand).setBrewingTime((int) brewTimer);
+//        }
+//    }
+//
+//    private void finish() {
+//        McMMOPlayerBrewEvent event = new McMMOPlayerBrewEvent(player, brewingStand);
+//        mcMMO.p.getServer().getPluginManager().callEvent(event);
+//
+//        if (!event.isCancelled()) {
+//            AlchemyPotionBrewer.finishBrewing(brewingStand, player, false);
+//        }
+//
+//        Alchemy.brewingStandMap.remove(location);
+//    }
+//
+//    public void finishImmediately() {
+//        this.cancel();
+//
+//        AlchemyPotionBrewer.finishBrewing(brewingStand, player, true);
+//        Alchemy.brewingStandMap.remove(location);
+//    }
+//
+//    public void cancelBrew() {
+//        this.cancel();
+//
+//        ((BrewingStand) brewingStand).setBrewingTime(-1);
+//        Alchemy.brewingStandMap.remove(location);
+//    }
+//}

+ 167 - 0
src/main/java/com/gmail/nossr50/dumpster/AlchemyPotion.java

@@ -0,0 +1,167 @@
+//package com.gmail.nossr50.datatypes.skills.alchemy;
+//
+//import com.gmail.nossr50.config.PotionManager;
+//import org.bukkit.Color;
+//import org.bukkit.Material;
+//import org.bukkit.inventory.ItemStack;
+//import org.bukkit.inventory.meta.PotionMeta;
+//import org.bukkit.potion.Potion;
+//import org.bukkit.potion.PotionData;
+//import org.bukkit.potion.PotionEffect;
+//
+//import java.util.List;
+//import java.util.Map;
+//import java.util.Map.Entry;
+//
+//public class AlchemyPotion {
+//    private Material material;
+//    private PotionData data;
+//    private String name;
+//    private List<String> lore;
+//    private List<PotionEffect> effects;
+//    private Color color;
+//    private Map<ItemStack, String> children;
+//
+//    public AlchemyPotion(Material material, PotionData data, String name, List<String> lore, List<PotionEffect> effects, Color color, Map<ItemStack, String> children) {
+//        this.material = material;
+//        this.data = data;
+//        this.lore = lore;
+//        this.name = name;
+//        this.effects = effects;
+//        this.children = children;
+//        this.color = color;
+//    }
+//
+//    public String toString() {
+//        return "AlchemyPotion{" + data + ", " + name + ", Effects[" + effects.size() + "], Children[" + children.size() + "]}";
+//    }
+//
+//    public ItemStack toItemStack(int amount) {
+//        ItemStack potion = new ItemStack(material, amount);
+//        PotionMeta meta = (PotionMeta) potion.getItemMeta();
+//
+//        meta.setBasePotionData(data);
+//        if (this.getName() != null) {
+//            meta.setDisplayName(this.getName());
+//        }
+//
+//        if (this.getLore() != null && !this.getLore().isEmpty()) {
+//            meta.setLore(this.getLore());
+//        }
+//
+//        if (!this.getEffects().isEmpty()) {
+//            for (PotionEffect effect : this.getEffects()) {
+//                meta.addCustomEffect(effect, true);
+//            }
+//        }
+//
+//        if (this.getColor() != null) {
+//            meta.setColor(this.getColor());
+//        }
+//
+//        potion.setItemMeta(meta);
+//        return potion;
+//    }
+//
+//    public Material getMaterial() {
+//        return material;
+//    }
+//
+//    public Potion toPotion(int amount) {
+//        return Potion.fromItemStack(this.toItemStack(amount));
+//    }
+//
+//    public PotionData getData() {
+//        return data;
+//    }
+//
+//    public void setData(PotionData data) {
+//        this.data = data;
+//    }
+//
+//    public String getName() {
+//        return name;
+//    }
+//
+//    public void setName(String name) {
+//        this.name = name;
+//    }
+//
+//    public List<String> getLore() {
+//        return lore;
+//    }
+//
+//    public void setLore(List<String> lore) {
+//        this.lore = lore;
+//    }
+//
+//    public List<PotionEffect> getEffects() {
+//        return effects;
+//    }
+//
+//    public void setEffects(List<PotionEffect> effects) {
+//        this.effects = effects;
+//    }
+//
+//    public Color getColor() {
+//        return color;
+//    }
+//
+//    public void setColor(Color color) {
+//        this.color = color;
+//    }
+//
+//    public Map<ItemStack, String> getChildren() {
+//        return children;
+//    }
+//
+//    public void setChildren(Map<ItemStack, String> children) {
+//        this.children = children;
+//    }
+//
+//    public AlchemyPotion getChild(ItemStack ingredient) {
+//        if (!children.isEmpty()) {
+//            for (Entry<ItemStack, String> child : children.entrySet()) {
+//                if (ingredient.isSimilar(child.getKey())) {
+//                    return PotionManager.getInstance().getPotion(child.getValue());
+//                }
+//            }
+//        }
+//        return null;
+//    }
+//
+//    public boolean isSimilar(ItemStack item) {
+//        if (item.getType() != material) {
+//            return false;
+//        }
+//        if (!item.hasItemMeta()) {
+//            return false;
+//        }
+//        PotionMeta meta = (PotionMeta) item.getItemMeta();
+//        PotionData that = meta.getBasePotionData();
+//        if (data.getType() != that.getType()) {
+//            return false;
+//        }
+//        if (data.isExtended() != that.isExtended()) {
+//            return false;
+//        }
+//        if (data.isUpgraded() != that.isUpgraded()) {
+//            return false;
+//        }
+//        for (PotionEffect effect : effects) {
+//            if (!meta.hasCustomEffect(effect.getType())) {
+//                return false;
+//            }
+//        }
+//        if (!meta.hasLore() && !lore.isEmpty()) {
+//            return false;
+//        }
+//        if (!(lore.isEmpty() && !meta.hasLore()) && !meta.getLore().equals(lore)) {
+//            return false;
+//        }
+//        if (!meta.hasDisplayName() && name != null) {
+//            return false;
+//        }
+//        return (name == null && !meta.hasDisplayName()) || meta.getDisplayName().equals(name);
+//    }
+//}

+ 251 - 0
src/main/java/com/gmail/nossr50/dumpster/AlchemyPotionBrewer.java

@@ -0,0 +1,251 @@
+//package com.gmail.nossr50.skills.alchemy;
+//
+//import com.gmail.nossr50.config.PotionManager;
+//import com.gmail.nossr50.datatypes.skills.SubSkillType;
+//import com.gmail.nossr50.datatypes.skills.alchemy.AlchemyPotion;
+//import com.gmail.nossr50.datatypes.skills.alchemy.PotionStage;
+//import com.gmail.nossr50.events.fake.FakeBrewEvent;
+//import com.gmail.nossr50.mcMMO;
+//import com.gmail.nossr50.runnables.player.PlayerUpdateInventoryTask;
+//import com.gmail.nossr50.runnables.skills.AlchemyBrewCheckTask;
+//import com.gmail.nossr50.util.Permissions;
+//import com.gmail.nossr50.util.player.UserManager;
+//import org.bukkit.Material;
+//import org.bukkit.block.BlockState;
+//import org.bukkit.block.BrewingStand;
+//import org.bukkit.entity.HumanEntity;
+//import org.bukkit.entity.Player;
+//import org.bukkit.event.inventory.ClickType;
+//import org.bukkit.inventory.BrewerInventory;
+//import org.bukkit.inventory.Inventory;
+//import org.bukkit.inventory.InventoryView;
+//import org.bukkit.inventory.ItemStack;
+//
+//import java.util.ArrayList;
+//import java.util.List;
+//
+//public final class AlchemyPotionBrewer {
+//    public static boolean isValidBrew(Player player, ItemStack[] contents) {
+//        if (!isValidIngredient(player, contents[Alchemy.INGREDIENT_SLOT])) {
+//            return false;
+//        }
+//
+//        for (int i = 0; i < 3; i++) {
+//            if (contents[i] == null || contents[i].getType() != Material.POTION && contents[i].getType() != Material.SPLASH_POTION && contents[i].getType() != Material.LINGERING_POTION) {
+//                continue;
+//            }
+//
+//            if (getChildPotion(PotionManager.getInstance().getPotion(contents[i]), contents[Alchemy.INGREDIENT_SLOT]) != null) {
+//                return true;
+//            }
+//        }
+//
+//        return false;
+//    }
+//
+//    private static AlchemyPotion getChildPotion(AlchemyPotion potion, ItemStack ingredient) {
+//        if (potion != null) {
+//            return potion.getChild(ingredient);
+//        }
+//
+//        return null;
+//    }
+//
+//    public static boolean isEmpty(ItemStack item) {
+//        return item == null || item.getType() == Material.AIR || item.getAmount() == 0;
+//    }
+//
+//    private static void removeIngredient(BrewerInventory inventory, Player player) {
+//        ItemStack ingredient = inventory.getIngredient() == null ? null : inventory.getIngredient().clone();
+//
+//        if (isEmpty(ingredient) || !isValidIngredient(player, ingredient)) {
+//        } else if (ingredient.getAmount() <= 1) {
+//            inventory.setIngredient(null);
+//        } else {
+//            ingredient.setAmount(ingredient.getAmount() - 1);
+//            inventory.setIngredient(ingredient);
+//        }
+//    }
+//
+//    private static boolean hasIngredient(BrewerInventory inventory, Player player) {
+//        ItemStack ingredient = inventory.getIngredient() == null ? null : inventory.getIngredient().clone();
+//
+//        return !isEmpty(ingredient) && isValidIngredient(player, ingredient);
+//    }
+//
+//    public static boolean isValidIngredient(Player player, ItemStack item) {
+//        if (isEmpty(item)) {
+//            return false;
+//        }
+//
+//        for (ItemStack ingredient : getValidIngredients(player)) {
+//            if (item.isSimilar(ingredient)) {
+//                return true;
+//            }
+//        }
+//
+//        return false;
+//    }
+//
+//    private static List<ItemStack> getValidIngredients(Player player) {
+//        if (player == null || UserManager.getPlayer(player) == null) {
+//            return PotionManager.getInstance().getIngredients(1);
+//        }
+//
+//        return PotionManager.getInstance().getIngredients(!Permissions.isSubSkillEnabled(player, SubSkillType.ALCHEMY_CONCOCTIONS) ? 1 : UserManager.getPlayer(player).getAlchemyManager().getTier());
+//    }
+//
+//    public static void finishBrewing(BlockState brewingStand, Player player, boolean forced) {
+//        if (!(brewingStand instanceof BrewingStand)) {
+//            return;
+//        }
+//
+//        BrewerInventory inventory = ((BrewingStand) brewingStand).getInventory();
+//        ItemStack ingredient = inventory.getIngredient() == null ? null : inventory.getIngredient().clone();
+//
+//        if (!hasIngredient(inventory, player)) {
+//            return;
+//        }
+//
+//        List<AlchemyPotion> inputList = new ArrayList<>();
+//
+//        for (int i = 0; i < 3; i++) {
+//            ItemStack item = inventory.getItem(i);
+//
+//            if (isEmpty(item) || item.getType() == Material.GLASS_BOTTLE || !mcMMO.getConfigManager().getPotionManager().isValidPotion(item)) {
+//                continue;
+//            }
+//
+//            AlchemyPotion input = mcMMO.getConfigManager().getPotionManager().getPotion(item);
+//            AlchemyPotion output = input.getChild(ingredient);
+//
+//            inputList.add(input);
+//
+//            if (output != null) {
+//                inventory.setItem(i, output.toItemStack(item.getAmount()).clone());
+//            }
+//        }
+//
+//        FakeBrewEvent event = new FakeBrewEvent(brewingStand.getBlock(), inventory, ((BrewingStand) brewingStand).getFuelLevel());
+//        mcMMO.p.getServer().getPluginManager().callEvent(event);
+//
+//        if (event.isCancelled() || inputList.isEmpty()) {
+//            return;
+//        }
+//
+//        removeIngredient(inventory, player);
+//
+//        for (AlchemyPotion input : inputList) {
+//            AlchemyPotion output = input.getChild(ingredient);
+//
+//            if (output != null && player != null) {
+//                PotionStage potionStage = PotionStage.getPotionStage(input, output);
+//
+//                //TODO: hmm
+//                if (UserManager.hasPlayerDataKey(player)) {
+//                    UserManager.getPlayer(player).getAlchemyManager().handlePotionBrewSuccesses(potionStage, 1);
+//                }
+//            }
+//        }
+//
+//        if (!forced) {
+//            scheduleUpdate(inventory);
+//        }
+//    }
+//
+//    public static boolean transferItems(InventoryView view, int fromSlot, ClickType click) {
+//        boolean success = false;
+//
+//        if (click.isLeftClick()) {
+//            success = transferItems(view, fromSlot);
+//        } else if (click.isRightClick()) {
+//            success = transferOneItem(view, fromSlot);
+//        }
+//
+//        return success;
+//    }
+//
+//    private static boolean transferOneItem(InventoryView view, int fromSlot) {
+//        ItemStack from = view.getItem(fromSlot).clone();
+//        ItemStack to = view.getItem(Alchemy.INGREDIENT_SLOT).clone();
+//
+//        if (isEmpty(from)) {
+//            return false;
+//        }
+//
+//        boolean emptyTo = isEmpty(to);
+//        int fromAmount = from.getAmount();
+//
+//        if (!emptyTo && fromAmount >= from.getType().getMaxStackSize()) {
+//            return false;
+//        } else if (emptyTo || from.isSimilar(to)) {
+//            if (emptyTo) {
+//                to = from.clone();
+//                to.setAmount(1);
+//            } else {
+//                to.setAmount(to.getAmount() + 1);
+//            }
+//
+//            from.setAmount(fromAmount - 1);
+//            view.setItem(Alchemy.INGREDIENT_SLOT, to);
+//            view.setItem(fromSlot, from);
+//
+//            return true;
+//        }
+//
+//        return false;
+//    }
+//
+//    /**
+//     * Transfer items between two ItemStacks, returning the leftover status
+//     */
+//    private static boolean transferItems(InventoryView view, int fromSlot) {
+//        ItemStack from = view.getItem(fromSlot).clone();
+//        ItemStack to = view.getItem(Alchemy.INGREDIENT_SLOT).clone();
+//
+//        if (isEmpty(from)) {
+//            return false;
+//        } else if (isEmpty(to)) {
+//            view.setItem(Alchemy.INGREDIENT_SLOT, from);
+//            view.setItem(fromSlot, null);
+//
+//            return true;
+//        } else if (from.isSimilar(to)) {
+//            int fromAmount = from.getAmount();
+//            int toAmount = to.getAmount();
+//            int maxSize = to.getType().getMaxStackSize();
+//
+//            if (fromAmount + toAmount > maxSize) {
+//                int left = fromAmount + toAmount - maxSize;
+//
+//                to.setAmount(maxSize);
+//                view.setItem(Alchemy.INGREDIENT_SLOT, to);
+//
+//                from.setAmount(left);
+//                view.setItem(fromSlot, from);
+//
+//                return true;
+//            }
+//
+//            to.setAmount(fromAmount + toAmount);
+//            view.setItem(fromSlot, null);
+//            view.setItem(Alchemy.INGREDIENT_SLOT, to);
+//
+//            return true;
+//        }
+//
+//        return false;
+//    }
+//
+//    public static void scheduleCheck(Player player, BrewingStand brewingStand) {
+//        new AlchemyBrewCheckTask(player, brewingStand).runTask(mcMMO.p);
+//    }
+//
+//    public static void scheduleUpdate(Inventory inventory) {
+//        for (HumanEntity humanEntity : inventory.getViewers()) {
+//            if (humanEntity instanceof Player) {
+//                new PlayerUpdateInventoryTask((Player) humanEntity).runTask(mcMMO.p);
+//            }
+//        }
+//    }
+//}

+ 0 - 0
src/main/java/com/gmail/nossr50/runnables/CheckDateTask.java → src/main/java/com/gmail/nossr50/dumpster/CheckDateTask.java


+ 0 - 0
src/main/java/com/gmail/nossr50/util/HolidayManager.java → src/main/java/com/gmail/nossr50/dumpster/HolidayManager.java


+ 0 - 0
src/main/java/com/gmail/nossr50/util/ModManager.java → src/main/java/com/gmail/nossr50/dumpster/ModManager.java


+ 740 - 0
src/main/java/com/gmail/nossr50/dumpster/PotionGenerator.java

@@ -0,0 +1,740 @@
+//package com.gmail.nossr50.skills.alchemy;
+//
+//import com.gmail.nossr50.datatypes.skills.alchemy.AlchemyPotion;
+//import com.gmail.nossr50.mcMMO;
+//import org.bukkit.ChatColor;
+//import org.bukkit.Color;
+//import org.bukkit.Material;
+//import org.bukkit.potion.PotionData;
+//import org.bukkit.potion.PotionEffect;
+//import org.bukkit.potion.PotionEffectType;
+//import org.bukkit.potion.PotionType;
+//
+//import java.util.ArrayList;
+//import java.util.HashMap;
+//import java.util.List;
+//import java.util.Map;
+//import java.util.Map.Entry;
+//
+///**
+// * This class is an abomination
+// * Alchemy will be rewritten, unfortunately during 2.2 (the config rewrite) I stumbled upon this class
+// * This class is far from proper, however due to the nature of how the current implementation of Alchemy works, it'd be a royal pain to rewrite this class to "fix" it
+// * Especially considering I plan to rewrite Alchemy, it does not seem worth the time involved to fix this monster
+// *
+// * Shield your eyes
+// * It was worse before I cleaned it up
+// */
+//public class PotionGenerator {
+//    private HashMap<String, AlchemyPotion> potionHashMap;
+////    private HashMap<ProtoPotion, HashMap<Ingredient, ProtoPotion>> childPotionMap; //Yuck
+//
+//    public PotionGenerator() {
+//        potionHashMap = new HashMap<>();
+////        childPotionMap = new HashMap<>();
+//        init();
+//    }
+//
+//    private void init() {
+//        Map<ProtoPotion, Map<Ingredient, ProtoPotion>> vanillaPotions = new HashMap<>();
+//        Map<ProtoPotion, Map<Ingredient, ProtoPotion>> mcMMOPotions = new HashMap<>();
+//
+//        populateVanillaPotions(vanillaPotions);
+//        populateCustomPotions(mcMMOPotions);
+//
+//        List<ProtoPotion> sorted = new ArrayList<>();
+//
+//        sorted.addAll(vanillaPotions.keySet());
+//        sorted.addAll(mcMMOPotions.keySet());
+//
+//        sorted.sort((a, b) -> {
+//            // All normal potions first
+//            if (a.mat == Material.POTION && b.mat != Material.POTION) {
+//                return -1;
+//            }
+//            if (b.mat == Material.POTION && a.mat != Material.POTION) {
+//                return 1;
+//            }
+//            // All splash potions second
+//            if (a.mat == Material.SPLASH_POTION && b.mat != Material.SPLASH_POTION) {
+//                return -1;
+//            }
+//            if (b.mat == Material.SPLASH_POTION && a.mat != Material.SPLASH_POTION) {
+//                return 1;
+//            }
+//            // Vanilla Potions first
+//            if (a.effect == null && b.effect != null) {
+//                return -1;
+//            }
+//            if (b.effect == null && a.effect != null) {
+//                return 1;
+//            }
+//            // Vanilla potions
+//            if (a.effect == null && b.effect == null) {
+//                // Order by PotionType
+//                if (a.data.getType() != b.data.getType()) {
+//                    return Integer.compare(a.data.getType().ordinal(), b.data.getType().ordinal());
+//                }
+//                // Plain before extended or upgraded
+//                if (!a.data.isExtended() && !a.data.isUpgraded() && (b.data.isExtended() || b.data.isUpgraded())) {
+//                    return -1;
+//                }
+//                if (!b.data.isExtended() && !b.data.isUpgraded() && (a.data.isExtended() || a.data.isUpgraded())) {
+//                    return 1;
+//                }
+//                // Extended before Upgraded
+//                if (a.data.isExtended() && b.data.isUpgraded()) {
+//                    return -1;
+//                }
+//                if (b.data.isExtended() && a.data.isUpgraded()) {
+//                    return -1;
+//                }
+//                // Same potion somehow?
+//                return 0;
+//            }
+//            // mcMMO Potions
+//            else {
+//                if ((a.baseName.contains("II") || a.baseName.contains("EXTENDED")) && !(b.baseName.contains("II") || b.baseName.contains("EXTENDED"))) {
+//                    return 1;
+//                }
+//                if ((b.baseName.contains("II") || b.baseName.contains("EXTENDED")) && !(a.baseName.contains("II") || a.baseName.contains("EXTENDED"))) {
+//                    return -1;
+//                }
+//                if (!a.baseName.contains("II") && b.baseName.contains("II")) {
+//                    return -1;
+//                }
+//                if (!b.baseName.contains("II") && a.baseName.contains("II")) {
+//                    return 1;
+//                }
+//                return a.baseName.split("_")[0].compareTo(b.baseName.split("_")[0]);
+//            }
+//        });
+//
+//        /* Hacky solution, this entire class disgusts me */
+//        HashMap<String, AlchemyPotion> potionHashMap = new HashMap<>();
+//
+//        for(ProtoPotion potion : sorted)
+//        {
+//            AlchemyPotion alchemyPotion;
+//
+//            if(vanillaPotions.containsKey(potion)) {
+//                potion getChildren(potion);
+//
+//            } else {
+//                getChildren(potion);
+//            }
+//            potionHashMap.put(alchemyPotion.getName(), alchemyPotion);
+//        }
+//
+////        for (ProtoPotion potion : sorted) {
+////            System.out.println("    " + potion.name + ":");
+////            Map<Ingredient, ProtoPotion> children;
+////            if (vanillaPotions.containsKey(potion)) {
+////                children = vanillaPotions.get(potion);
+////            } else {
+////                System.out.println("        Name: " + prettify(potion.name));
+////                children = mcMMOPotions.get(potion);
+////            }
+////            System.out.println("        Material: " + potion.mat.name());
+////            System.out.println("        PotionData:");
+////            System.out.println("            PotionType: " + potion.data.getType().name());
+////            if (potion.data.isExtended()) {
+////                System.out.println("            Extended: true");
+////            }
+////            if (potion.data.isUpgraded()) {
+////                System.out.println("            Upgraded: true");
+////            }
+////            if (potion.effect != null) {
+////                System.out.println("        Effects: [\"" + getName(potion.effect.getType()) + " " + potion.effect.getAmplifier() + " " + potion.effect.getDuration() + "\"]");
+////            }
+////            if (children == null || children.isEmpty()) {
+////                continue;
+////            }
+////            System.out.println("        Children:");
+////            for (Entry<Ingredient, ProtoPotion> child : children.entrySet()) {
+////                System.out.println("            " + child.getKey().name + ": " + child.getValue().name);
+////            }
+////        }
+//    }
+//
+//    public HashMap<String, AlchemyPotion> getPotionHashMap() {
+//        return potionHashMap;
+//    }
+//
+//    /**
+//     * I just want anyone who reads this to know
+//     * This entire class is an abomination
+//     * What you see below is a hacky solution to keep Alchemy functioning with the new config system
+//     * Alchemy will be rewritten, until then, this disgusting class exists.
+//     * @param protoPotion target ProtoPotion
+//     * @return converted ProtoPotion
+//     */
+//    private AlchemyPotion convertWriteableToAlchemyPotion(ProtoPotion protoPotion, ) {
+//        try {
+//
+//            String name = protoPotion.name;
+//
+//            if (name != null) {
+//                name = prettify(ChatColor.translateAlternateColorCodes('&', name));
+//            }
+//
+//            PotionData data = protoPotion.data;
+//            Material material = Material.POTION;
+//
+//            if(protoPotion.mat != null)
+//                material = protoPotion.mat;
+//
+//            //Lore is unused as far as I can tell
+//            List<String> lore = new ArrayList<>();
+//
+//            List<PotionEffect> effects = new ArrayList<>();
+//            effects.add(protoPotion.effect);
+//
+//            Color color = this.generateColor(effects);
+//
+//
+//            return new AlchemyPotion(material, data, name, lore, effects, color, getChildren(protoPotion));
+//        } catch (Exception e) {
+//            mcMMO.p.getLogger().warning("Failed to load Alchemy potion: " + potion_section.getString());
+//            return null;
+//        }
+//    }
+//
+//    public Color generateColor(List<PotionEffect> effects) {
+//        if (effects != null && !effects.isEmpty()) {
+//            List<Color> colors = new ArrayList<>();
+//            for (PotionEffect effect : effects) {
+//                if (effect.getType().getColor() != null) {
+//                    colors.add(effect.getType().getColor());
+//                }
+//            }
+//            if (!colors.isEmpty()) {
+//                if (colors.size() > 1) {
+//                    return calculateAverageColor(colors);
+//                }
+//                return colors.get(0);
+//            }
+//        }
+//        return null;
+//    }
+//
+//    public Color calculateAverageColor(List<Color> colors) {
+//        int red = 0;
+//        int green = 0;
+//        int blue = 0;
+//        for (Color color : colors) {
+//            red += color.getRed();
+//            green += color.getGreen();
+//            blue += color.getBlue();
+//        }
+//        Color color = Color.fromRGB(red / colors.size(), green / colors.size(), blue / colors.size());
+//        return color;
+//    }
+//
+//    private static String prettify(String name) {
+//        String[] substrings = name.split("_");
+//        String prettyString = "";
+//        int size = 1;
+//
+//        for (String string : substrings) {
+//            prettyString = prettyString.concat(getCapitalized(string));
+//
+//            if (size < substrings.length) {
+//                prettyString = prettyString.concat(" ");
+//            }
+//
+//            size++;
+//        }
+//
+//        return prettyString;
+//    }
+//
+//    public static String getCapitalized(String target) {
+//        if (target.equals("II")) { // hacks
+//            return target;
+//        }
+//        return target.substring(0, 1).toUpperCase() + target.substring(1).toLowerCase();
+//    }
+//
+//    private static String getName(PotionEffectType type) {
+//        switch (type.getId()) {
+//            case 1:
+//                return "SPEED";
+//            case 2:
+//                return "SLOW";
+//            case 3:
+//                return "FAST_DIGGING";
+//            case 4:
+//                return "SLOW_DIGGING";
+//            case 5:
+//                return "INCREASE_DAMAGE";
+//            case 6:
+//                return "HEAL";
+//            case 7:
+//                return "HARM";
+//            case 8:
+//                return "JUMP";
+//            case 9:
+//                return "CONFUSION";
+//            case 10:
+//                return "REGENERATION";
+//            case 11:
+//                return "DAMAGE_RESISTANCE";
+//            case 12:
+//                return "FIRE_RESISTANCE";
+//            case 13:
+//                return "WATER_BREATHING";
+//            case 14:
+//                return "INVISIBILITY";
+//            case 15:
+//                return "BLINDNESS";
+//            case 16:
+//                return "NIGHT_VISION";
+//            case 17:
+//                return "HUNGER";
+//            case 18:
+//                return "WEAKNESS";
+//            case 19:
+//                return "POISON";
+//            case 20:
+//                return "WITHER";
+//            case 21:
+//                return "HEALTH_BOOST";
+//            case 22:
+//                return "ABSORPTION";
+//            case 23:
+//                return "SATURATION";
+//            case 24:
+//                return "GLOWING";
+//            case 25:
+//                return "LEVITATION";
+//            case 26:
+//                return "LUCK";
+//            case 27:
+//                return "UNLUCK";
+//            case 28:
+//                return "SLOW_FALLING";
+//            case 29:
+//                return "CONDUIT_POWER";
+//            case 30:
+//                return "DOLPHINS_GRACE";
+//            default:
+//                return "UNKNOWN_EFFECT_TYPE_" + type.getId();
+//        }
+//    }
+//
+//    private void populateVanillaPotions(Map<ProtoPotion, Map<Ingredient, ProtoPotion>> vanillaPotions) {
+//        for (PotionType type : PotionType.values()) {
+//            for (Material material : new Material[]{Material.POTION, Material.SPLASH_POTION, Material.LINGERING_POTION}) {
+//                ProtoPotion protoPotion = new ProtoPotion(material, type);
+//                getChildren(protoPotion);
+//                vanillaPotions.put(protoPotion, getChildren(protoPotion));
+//                if (type.isExtendable()) {
+//                    protoPotion = new ProtoPotion(material, new PotionData(type, true, false));
+//                    vanillaPotions.put(protoPotion, getChildren(protoPotion));
+//                }
+//                if (type.isUpgradeable()) {
+//                    protoPotion = new ProtoPotion(material, new PotionData(type, false, true));
+//                    vanillaPotions.put(protoPotion, getChildren(protoPotion));
+//                }
+//            }
+//        }
+//        for (Entry<ProtoPotion, Map<Ingredient, ProtoPotion>> entry : vanillaPotions.entrySet()) {
+//            if (entry.getKey().mat == Material.POTION) {
+//                entry.getValue().put(new Ingredient(Material.GUNPOWDER), new ProtoPotion(Material.SPLASH_POTION, entry.getKey().data));
+//            }
+//            if (entry.getKey().mat == Material.SPLASH_POTION) {
+//                entry.getValue().put(new Ingredient(Material.DRAGON_BREATH), new ProtoPotion(Material.LINGERING_POTION, entry.getKey().data));
+//            }
+//        }
+//
+//        //Store children
+//    }
+//
+//    private HashMap<Ingredient, ProtoPotion> getChildren(ProtoPotion protoPotion) {
+//        HashMap<Ingredient, ProtoPotion> children = new HashMap<>();
+//
+//        switch (protoPotion.data.getType()) {
+//            case WATER:
+//                assert (!protoPotion.data.isExtended());
+//                assert (!protoPotion.data.isUpgraded());
+//                children.put(new Ingredient(Material.NETHER_WART), new ProtoPotion(protoPotion.mat, PotionType.AWKWARD));
+//                children.put(new Ingredient(Material.FERMENTED_SPIDER_EYE), new ProtoPotion(protoPotion.mat, PotionType.WEAKNESS));
+//                children.put(new Ingredient(Material.REDSTONE), new ProtoPotion(protoPotion.mat, PotionType.MUNDANE));
+//                children.put(new Ingredient(Material.GLOWSTONE_DUST), new ProtoPotion(protoPotion.mat, PotionType.THICK));
+//                children.put(new Ingredient(Material.BLAZE_POWDER), new ProtoPotion(protoPotion.mat, PotionType.MUNDANE));
+//                children.put(new Ingredient(Material.SUGAR), new ProtoPotion(protoPotion.mat, PotionType.MUNDANE));
+//                children.put(new Ingredient(Material.RABBIT_FOOT), new ProtoPotion(protoPotion.mat, PotionType.MUNDANE));
+//                children.put(new Ingredient(Material.SPIDER_EYE), new ProtoPotion(protoPotion.mat, PotionType.MUNDANE));
+//                children.put(new Ingredient(Material.MAGMA_CREAM), new ProtoPotion(protoPotion.mat, PotionType.MUNDANE));
+//                children.put(new Ingredient(Material.GLISTERING_MELON_SLICE), new ProtoPotion(protoPotion.mat, PotionType.MUNDANE));
+//                children.put(new Ingredient(Material.GHAST_TEAR), new ProtoPotion(protoPotion.mat, PotionType.MUNDANE));
+//                return children;
+//            case AWKWARD:
+//                assert (!protoPotion.data.isExtended());
+//                assert (!protoPotion.data.isUpgraded());
+//                children.put(new Ingredient(Material.GOLDEN_CARROT), new ProtoPotion(protoPotion.mat, PotionType.NIGHT_VISION));
+//                children.put(new Ingredient(Material.RABBIT_FOOT), new ProtoPotion(protoPotion.mat, PotionType.JUMP));
+//                children.put(new Ingredient(Material.MAGMA_CREAM), new ProtoPotion(protoPotion.mat, PotionType.FIRE_RESISTANCE));
+//                children.put(new Ingredient(Material.SUGAR), new ProtoPotion(protoPotion.mat, PotionType.SPEED));
+//                children.put(new Ingredient(Material.PUFFERFISH), new ProtoPotion(protoPotion.mat, PotionType.WATER_BREATHING));
+//                children.put(new Ingredient(Material.GLISTERING_MELON_SLICE), new ProtoPotion(protoPotion.mat, PotionType.INSTANT_HEAL));
+//                children.put(new Ingredient(Material.SPIDER_EYE), new ProtoPotion(protoPotion.mat, PotionType.POISON));
+//                children.put(new Ingredient(Material.GHAST_TEAR), new ProtoPotion(protoPotion.mat, PotionType.REGEN));
+//                children.put(new Ingredient(Material.BLAZE_POWDER), new ProtoPotion(protoPotion.mat, PotionType.STRENGTH));
+//                children.put(new Ingredient(Material.TURTLE_HELMET), new ProtoPotion(protoPotion.mat, PotionType.TURTLE_MASTER));
+//                children.put(new Ingredient(Material.PHANTOM_MEMBRANE), new ProtoPotion(protoPotion.mat, PotionType.SLOW_FALLING));
+//                // mcMMO custom potions
+//                double mod = 1;
+//                if (protoPotion.mat == Material.SPLASH_POTION) {
+//                    mod = 0.75;
+//                }
+//                if (protoPotion.mat == Material.LINGERING_POTION) {
+//                    mod = 0.25;
+//                }
+//                children.put(new Ingredient(Material.BROWN_MUSHROOM), new ProtoPotion(protoPotion.mat, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.CONFUSION, (int) (450 * mod), 0), "NAUSEA"));
+//                children.put(new Ingredient(Material.CARROT), new ProtoPotion(protoPotion.mat, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.FAST_DIGGING, (int) (3600 * mod), 0), "HASTE"));
+//                children.put(new Ingredient(Material.SLIME_BALL), new ProtoPotion(protoPotion.mat, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.SLOW_DIGGING, (int) (3600 * mod), 0), "DULLNESS"));
+//                children.put(new Ingredient(Material.GOLDEN_APPLE), new ProtoPotion(protoPotion.mat, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.DAMAGE_RESISTANCE, (int) (450 * mod), 0), "RESISTANCE"));
+//                children.put(new Ingredient(Material.INK_SAC), new ProtoPotion(protoPotion.mat, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.BLINDNESS, (int) (225 * mod), 0), "BLINDNESS"));
+//                children.put(new Ingredient(Material.ROTTEN_FLESH), new ProtoPotion(protoPotion.mat, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.HUNGER, (int) (900 * mod), 0), "HUNGER"));
+//                children.put(new Ingredient(Material.POISONOUS_POTATO), new ProtoPotion(protoPotion.mat, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.WITHER, (int) (450 * mod), 0), "DECAY"));
+//                children.put(new Ingredient(Material.QUARTZ), new ProtoPotion(protoPotion.mat, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.ABSORPTION, (int) (1800 * mod), 0), "ABSORPTION"));
+//                children.put(new Ingredient(Material.FERN), new ProtoPotion(protoPotion.mat, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.SATURATION, (int) (8 * mod), 0), "SATURATION"));
+//                children.put(new Ingredient(Material.APPLE), new ProtoPotion(protoPotion.mat, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.HEALTH_BOOST, (int) (1800 * mod), 0), "HEALTH_BOOST"));
+//                return children;
+//            case FIRE_RESISTANCE:
+//                assert (!protoPotion.data.isUpgraded());
+//                if (protoPotion.data.isExtended()) {
+//                    children.put(new Ingredient(Material.FERMENTED_SPIDER_EYE), new ProtoPotion(protoPotion.mat, new PotionData(PotionType.SLOWNESS, true, false)));
+//                } else {
+//                    children.put(new Ingredient(Material.FERMENTED_SPIDER_EYE), new ProtoPotion(protoPotion.mat, PotionType.SLOWNESS));
+//                    children.put(new Ingredient(Material.REDSTONE), new ProtoPotion(protoPotion.mat, new PotionData(protoPotion.data.getType(), true, false)));
+//                }
+//                return children;
+//            case INSTANT_DAMAGE:
+//                assert (!protoPotion.data.isExtended());
+//                if (!protoPotion.data.isUpgraded()) {
+//                    children.put(new Ingredient(Material.GLOWSTONE_DUST), new ProtoPotion(protoPotion.mat, new PotionData(protoPotion.data.getType(), false, true)));
+//                }
+//                return children;
+//            case INSTANT_HEAL:
+//                assert (!protoPotion.data.isExtended());
+//                if (!protoPotion.data.isUpgraded()) {
+//                    children.put(new Ingredient(Material.FERMENTED_SPIDER_EYE), new ProtoPotion(protoPotion.mat, PotionType.INSTANT_DAMAGE));
+//                    children.put(new Ingredient(Material.GLOWSTONE_DUST), new ProtoPotion(protoPotion.mat, new PotionData(protoPotion.data.getType(), false, true)));
+//                } else {
+//                    children.put(new Ingredient(Material.FERMENTED_SPIDER_EYE), new ProtoPotion(protoPotion.mat, new PotionData(PotionType.INSTANT_DAMAGE, false, true)));
+//                }
+//                return children;
+//            case INVISIBILITY:
+//                assert (!protoPotion.data.isUpgraded());
+//                if (!protoPotion.data.isExtended()) {
+//                    children.put(new Ingredient(Material.REDSTONE), new ProtoPotion(protoPotion.mat, new PotionData(protoPotion.data.getType(), true, false)));
+//                }
+//                return children;
+//            case JUMP:
+//                if (!protoPotion.data.isUpgraded() && !protoPotion.data.isExtended()) {
+//                    children.put(new Ingredient(Material.FERMENTED_SPIDER_EYE), new ProtoPotion(protoPotion.mat, PotionType.SLOWNESS));
+//                    children.put(new Ingredient(Material.GLOWSTONE_DUST), new ProtoPotion(protoPotion.mat, new PotionData(protoPotion.data.getType(), false, true)));
+//                    children.put(new Ingredient(Material.REDSTONE), new ProtoPotion(protoPotion.mat, new PotionData(protoPotion.data.getType(), true, false)));
+//                }
+//                return children;
+//            case NIGHT_VISION:
+//                assert (!protoPotion.data.isUpgraded());
+//                if (!protoPotion.data.isExtended()) {
+//                    children.put(new Ingredient(Material.FERMENTED_SPIDER_EYE), new ProtoPotion(protoPotion.mat, PotionType.INVISIBILITY));
+//                    children.put(new Ingredient(Material.REDSTONE), new ProtoPotion(protoPotion.mat, new PotionData(protoPotion.data.getType(), true, false)));
+//                } else {
+//                    children.put(new Ingredient(Material.FERMENTED_SPIDER_EYE), new ProtoPotion(protoPotion.mat, new PotionData(PotionType.INVISIBILITY, true, false)));
+//                }
+//                return children;
+//            case POISON:
+//                if (!protoPotion.data.isUpgraded() && !protoPotion.data.isExtended()) {
+//                    children.put(new Ingredient(Material.FERMENTED_SPIDER_EYE), new ProtoPotion(protoPotion.mat, PotionType.INSTANT_DAMAGE));
+//                    children.put(new Ingredient(Material.GLOWSTONE_DUST), new ProtoPotion(protoPotion.mat, new PotionData(protoPotion.data.getType(), false, true)));
+//                    children.put(new Ingredient(Material.REDSTONE), new ProtoPotion(protoPotion.mat, new PotionData(protoPotion.data.getType(), true, false)));
+//                } else {
+//                    children.put(new Ingredient(Material.FERMENTED_SPIDER_EYE), new ProtoPotion(protoPotion.mat, new PotionData(PotionType.INSTANT_DAMAGE, false, true)));
+//                }
+//                return children;
+//            case REGEN:
+//                if (!protoPotion.data.isUpgraded() && !protoPotion.data.isExtended()) {
+//                    children.put(new Ingredient(Material.GLOWSTONE_DUST), new ProtoPotion(protoPotion.mat, new PotionData(protoPotion.data.getType(), false, true)));
+//                    children.put(new Ingredient(Material.REDSTONE), new ProtoPotion(protoPotion.mat, new PotionData(protoPotion.data.getType(), true, false)));
+//                }
+//                return children;
+//            case SLOWNESS:
+//                assert (!protoPotion.data.isUpgraded());
+//                if (!protoPotion.data.isExtended()) {
+//                    children.put(new Ingredient(Material.REDSTONE), new ProtoPotion(protoPotion.mat, new PotionData(protoPotion.data.getType(), true, false)));
+//                }
+//                return children;
+//            case SLOW_FALLING:
+//                assert (!protoPotion.data.isUpgraded());
+//                if (!protoPotion.data.isExtended()) {
+//                    children.put(new Ingredient(Material.REDSTONE), new ProtoPotion(protoPotion.mat, new PotionData(protoPotion.data.getType(), true, false)));
+//                }
+//                return children;
+//            case SPEED:
+//                if (!protoPotion.data.isUpgraded() && !protoPotion.data.isExtended()) {
+//                    children.put(new Ingredient(Material.FERMENTED_SPIDER_EYE), new ProtoPotion(protoPotion.mat, PotionType.SLOWNESS));
+//                    children.put(new Ingredient(Material.GLOWSTONE_DUST), new ProtoPotion(protoPotion.mat, new PotionData(protoPotion.data.getType(), false, true)));
+//                    children.put(new Ingredient(Material.REDSTONE), new ProtoPotion(protoPotion.mat, new PotionData(protoPotion.data.getType(), true, false)));
+//                } else {
+//                    children.put(new Ingredient(Material.FERMENTED_SPIDER_EYE), new ProtoPotion(protoPotion.mat, new PotionData(PotionType.SLOWNESS, true, false)));
+//                }
+//                return children;
+//            case STRENGTH:
+//                if (!protoPotion.data.isUpgraded() && !protoPotion.data.isExtended()) {
+//                    children.put(new Ingredient(Material.GLOWSTONE_DUST), new ProtoPotion(protoPotion.mat, new PotionData(protoPotion.data.getType(), false, true)));
+//                    children.put(new Ingredient(Material.REDSTONE), new ProtoPotion(protoPotion.mat, new PotionData(protoPotion.data.getType(), true, false)));
+//                }
+//                return children;
+//            case TURTLE_MASTER:
+//                if (!protoPotion.data.isUpgraded() && !protoPotion.data.isExtended()) {
+//                    children.put(new Ingredient(Material.GLOWSTONE_DUST), new ProtoPotion(protoPotion.mat, new PotionData(protoPotion.data.getType(), false, true)));
+//                    children.put(new Ingredient(Material.REDSTONE), new ProtoPotion(protoPotion.mat, new PotionData(protoPotion.data.getType(), true, false)));
+//                }
+//                return children;
+//            case WATER_BREATHING:
+//                assert (!protoPotion.data.isUpgraded());
+//                if (!protoPotion.data.isExtended()) {
+//                    children.put(new Ingredient(Material.FERMENTED_SPIDER_EYE), new ProtoPotion(protoPotion.mat, PotionType.INSTANT_DAMAGE));
+//                    children.put(new Ingredient(Material.REDSTONE), new ProtoPotion(protoPotion.mat, new PotionData(protoPotion.data.getType(), true, false)));
+//                }
+//                return children;
+//            case WEAKNESS:
+//                assert (!protoPotion.data.isUpgraded());
+//                if (!protoPotion.data.isExtended()) {
+//                    children.put(new Ingredient(Material.REDSTONE), new ProtoPotion(protoPotion.mat, new PotionData(protoPotion.data.getType(), true, false)));
+//                }
+//                return children;
+//            case LUCK:
+//            case MUNDANE:
+//            case THICK:
+//            case UNCRAFTABLE:
+//                assert (!protoPotion.data.isExtended());
+//                assert (!protoPotion.data.isUpgraded());
+//                return children;
+//            default:
+//                return children;
+//        }
+//    }
+//
+//    private static void populateCustomPotions(Map<ProtoPotion, Map<Ingredient, ProtoPotion>> customPotions) {
+//        for (Material material : new Material[]{Material.POTION, Material.SPLASH_POTION, Material.LINGERING_POTION}) {
+//            ProtoPotion newPotion;
+//            double mod = 1;
+//            if (material == Material.SPLASH_POTION) {
+//                mod = 0.75;
+//            }
+//            if (material == Material.LINGERING_POTION) {
+//                mod = 0.25;
+//            }
+//            HashMap<Ingredient, ProtoPotion> newPotionChildren;
+//            newPotion = new ProtoPotion(material, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.CONFUSION, (int) (450 * mod), 0), "NAUSEA");
+//            newPotionChildren = new HashMap<>();
+//            newPotionChildren.put(new Ingredient(Material.GLOWSTONE_DUST), new ProtoPotion(material, PotionType.UNCRAFTABLE, new PotionEffect(newPotion.effect.getType(), newPotion.effect.getDuration() / 2, 1), newPotion.baseName + "_II"));
+//            newPotionChildren.put(new Ingredient(Material.REDSTONE), new ProtoPotion(material, PotionType.UNCRAFTABLE, new PotionEffect(newPotion.effect.getType(), newPotion.effect.getDuration() * 2, 0), newPotion.baseName + "_EXTENDED"));
+//            for (ProtoPotion child : newPotionChildren.values()) {
+//                customPotions.put(child, new HashMap<>());
+//            }
+//            customPotions.put(newPotion, newPotionChildren);
+//            newPotion = new ProtoPotion(material, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.FAST_DIGGING, (int) (3600 * mod), 0), "HASTE");
+//            newPotionChildren = new HashMap<>();
+//            newPotionChildren.put(new Ingredient(Material.GLOWSTONE_DUST), new ProtoPotion(material, PotionType.UNCRAFTABLE, new PotionEffect(newPotion.effect.getType(), newPotion.effect.getDuration() / 2, 1), newPotion.baseName + "_II"));
+//            newPotionChildren.put(new Ingredient(Material.REDSTONE), new ProtoPotion(material, PotionType.UNCRAFTABLE, new PotionEffect(newPotion.effect.getType(), newPotion.effect.getDuration() * 2, 0), newPotion.baseName + "_EXTENDED"));
+//            for (ProtoPotion child : newPotionChildren.values()) {
+//                customPotions.put(child, new HashMap<>());
+//            }
+//            customPotions.put(newPotion, newPotionChildren);
+//            newPotion = new ProtoPotion(material, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.SLOW_DIGGING, (int) (3600 * mod), 0), "DULLNESS");
+//            newPotionChildren = new HashMap<>();
+//            newPotionChildren.put(new Ingredient(Material.GLOWSTONE_DUST), new ProtoPotion(material, PotionType.UNCRAFTABLE, new PotionEffect(newPotion.effect.getType(), newPotion.effect.getDuration() / 2, 1), newPotion.baseName + "_II"));
+//            newPotionChildren.put(new Ingredient(Material.REDSTONE), new ProtoPotion(material, PotionType.UNCRAFTABLE, new PotionEffect(newPotion.effect.getType(), newPotion.effect.getDuration() * 2, 0), newPotion.baseName + "_EXTENDED"));
+//            for (ProtoPotion child : newPotionChildren.values()) {
+//                customPotions.put(child, new HashMap<>());
+//            }
+//            customPotions.put(newPotion, newPotionChildren);
+//            newPotion = new ProtoPotion(material, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.DAMAGE_RESISTANCE, (int) (450 * mod), 0), "RESISTANCE");
+//            newPotionChildren = new HashMap<>();
+//            newPotionChildren.put(new Ingredient(Material.GLOWSTONE_DUST), new ProtoPotion(material, PotionType.UNCRAFTABLE, new PotionEffect(newPotion.effect.getType(), newPotion.effect.getDuration() / 2, 1), newPotion.baseName + "_II"));
+//            newPotionChildren.put(new Ingredient(Material.REDSTONE), new ProtoPotion(material, PotionType.UNCRAFTABLE, new PotionEffect(newPotion.effect.getType(), newPotion.effect.getDuration() * 2, 0), newPotion.baseName + "_EXTENDED"));
+//            for (ProtoPotion child : newPotionChildren.values()) {
+//                customPotions.put(child, new HashMap<>());
+//            }
+//            customPotions.put(newPotion, newPotionChildren);
+//            newPotion = new ProtoPotion(material, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.BLINDNESS, (int) (225 * mod), 0), "BLINDNESS");
+//            newPotionChildren = new HashMap<>();
+//            newPotionChildren.put(new Ingredient(Material.GLOWSTONE_DUST), new ProtoPotion(material, PotionType.UNCRAFTABLE, new PotionEffect(newPotion.effect.getType(), newPotion.effect.getDuration() / 2, 1), newPotion.baseName + "_II"));
+//            newPotionChildren.put(new Ingredient(Material.REDSTONE), new ProtoPotion(material, PotionType.UNCRAFTABLE, new PotionEffect(newPotion.effect.getType(), newPotion.effect.getDuration() * 2, 0), newPotion.baseName + "_EXTENDED"));
+//            for (ProtoPotion child : newPotionChildren.values()) {
+//                customPotions.put(child, new HashMap<>());
+//            }
+//            customPotions.put(newPotion, newPotionChildren);
+//            newPotion = new ProtoPotion(material, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.HUNGER, (int) (900 * mod), 0), "HUNGER");
+//            newPotionChildren = new HashMap<>();
+//            newPotionChildren.put(new Ingredient(Material.GLOWSTONE_DUST), new ProtoPotion(material, PotionType.UNCRAFTABLE, new PotionEffect(newPotion.effect.getType(), newPotion.effect.getDuration() / 2, 1), newPotion.baseName + "_II"));
+//            newPotionChildren.put(new Ingredient(Material.REDSTONE), new ProtoPotion(material, PotionType.UNCRAFTABLE, new PotionEffect(newPotion.effect.getType(), newPotion.effect.getDuration() * 2, 0), newPotion.baseName + "_EXTENDED"));
+//            for (ProtoPotion child : newPotionChildren.values()) {
+//                customPotions.put(child, new HashMap<>());
+//            }
+//            customPotions.put(newPotion, newPotionChildren);
+//            newPotion = new ProtoPotion(material, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.WITHER, (int) (450 * mod), 0), "DECAY");
+//            newPotionChildren = new HashMap<>();
+//            newPotionChildren.put(new Ingredient(Material.GLOWSTONE_DUST), new ProtoPotion(material, PotionType.UNCRAFTABLE, new PotionEffect(newPotion.effect.getType(), newPotion.effect.getDuration() / 2, 1), newPotion.baseName + "_II"));
+//            newPotionChildren.put(new Ingredient(Material.REDSTONE), new ProtoPotion(material, PotionType.UNCRAFTABLE, new PotionEffect(newPotion.effect.getType(), newPotion.effect.getDuration() * 2, 0), newPotion.baseName + "_EXTENDED"));
+//            for (ProtoPotion child : newPotionChildren.values()) {
+//                customPotions.put(child, new HashMap<>());
+//            }
+//            customPotions.put(newPotion, newPotionChildren);
+//            newPotion = new ProtoPotion(material, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.ABSORPTION, (int) (1800 * mod), 0), "ABSORPTION");
+//            newPotionChildren = new HashMap<>();
+//            newPotionChildren.put(new Ingredient(Material.GLOWSTONE_DUST), new ProtoPotion(material, PotionType.UNCRAFTABLE, new PotionEffect(newPotion.effect.getType(), newPotion.effect.getDuration() / 2, 1), newPotion.baseName + "_II"));
+//            newPotionChildren.put(new Ingredient(Material.REDSTONE), new ProtoPotion(material, PotionType.UNCRAFTABLE, new PotionEffect(newPotion.effect.getType(), newPotion.effect.getDuration() * 2, 0), newPotion.baseName + "_EXTENDED"));
+//            for (ProtoPotion child : newPotionChildren.values()) {
+//                customPotions.put(child, new HashMap<>());
+//            }
+//            customPotions.put(newPotion, newPotionChildren);
+//            newPotion = new ProtoPotion(material, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.SATURATION, (int) (8 * mod), 0), "SATURATION");
+//            newPotionChildren = new HashMap<>();
+//            newPotionChildren.put(new Ingredient(Material.GLOWSTONE_DUST), new ProtoPotion(material, PotionType.UNCRAFTABLE, new PotionEffect(newPotion.effect.getType(), newPotion.effect.getDuration() / 2, 1), newPotion.baseName + "_II"));
+//            newPotionChildren.put(new Ingredient(Material.REDSTONE), new ProtoPotion(material, PotionType.UNCRAFTABLE, new PotionEffect(newPotion.effect.getType(), newPotion.effect.getDuration() * 2, 0), newPotion.baseName + "_EXTENDED"));
+//            for (ProtoPotion child : newPotionChildren.values()) {
+//                customPotions.put(child, new HashMap<>());
+//            }
+//            customPotions.put(newPotion, newPotionChildren);
+//            newPotion = new ProtoPotion(material, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.HEALTH_BOOST, (int) (1800 * mod), 0), "HEALTH_BOOST");
+//            newPotionChildren = new HashMap<>();
+//            newPotionChildren.put(new Ingredient(Material.GLOWSTONE_DUST), new ProtoPotion(material, PotionType.UNCRAFTABLE, new PotionEffect(newPotion.effect.getType(), newPotion.effect.getDuration() / 2, 1), newPotion.baseName + "_II"));
+//            newPotionChildren.put(new Ingredient(Material.REDSTONE), new ProtoPotion(material, PotionType.UNCRAFTABLE, new PotionEffect(newPotion.effect.getType(), newPotion.effect.getDuration() * 2, 0), newPotion.baseName + "_EXTENDED"));
+//            for (ProtoPotion child : newPotionChildren.values()) {
+//                customPotions.put(child, new HashMap<>());
+//            }
+//            customPotions.put(newPotion, newPotionChildren);
+//        }
+//
+//        // Add all material state changes
+//        for (Entry<ProtoPotion, Map<Ingredient, ProtoPotion>> entry : customPotions.entrySet()) {
+//            if (entry.getKey().mat == Material.POTION) {
+//                PotionEffect effect = new PotionEffect(entry.getKey().effect.getType(), (int) (entry.getKey().effect.getDuration() * 0.75), entry.getKey().effect.getAmplifier());
+//                entry.getValue().put(new Ingredient(Material.GUNPOWDER), new ProtoPotion(Material.SPLASH_POTION, entry.getKey().data, effect, entry.getKey().baseName));
+//            } else if (entry.getKey().mat == Material.SPLASH_POTION) {
+//                PotionEffect effect = new PotionEffect(entry.getKey().effect.getType(), (int) (entry.getKey().effect.getDuration() * 0.33), entry.getKey().effect.getAmplifier());
+//                entry.getValue().put(new Ingredient(Material.DRAGON_BREATH), new ProtoPotion(Material.LINGERING_POTION, entry.getKey().data, effect, entry.getKey().baseName));
+//            }
+//        }
+//    }
+//
+//    public static class Ingredient {
+//
+//        public Material mat;
+//        public int data;
+//        public String name;
+//
+//        public Ingredient(Material mat) {
+//            this.mat = mat;
+//            this.data = 0;
+//            name = mat.name();
+//        }
+//
+//    }
+//
+//    public static class ProtoPotion {
+//
+//        public String name;
+//        public Material mat;
+//        public PotionData data;
+//        public PotionEffect effect;
+//        public String baseName;
+//
+//        public ProtoPotion(PotionData data) {
+//            this(Material.POTION, data);
+//        }
+//
+//        public ProtoPotion(Material type, PotionData data) {
+//            this(type, data, null, getMCName(data.getType()));
+//        }
+//
+//        public ProtoPotion(Material mat, PotionType type, PotionEffect effect, String baseName) {
+//            this(mat, new PotionData(type, false, false), effect, baseName);
+//        }
+//
+//        public ProtoPotion(Material type, PotionData data, PotionEffect effect, String baseName) {
+//            this.data = data;
+//            this.effect = effect;
+//            this.mat = type;
+//            this.baseName = baseName;
+//            this.name = "POTION_OF_" + baseName;
+//            if (mat == Material.SPLASH_POTION) {
+//                this.name = "SPLASH_" + this.name;
+//            }
+//            if (mat == Material.LINGERING_POTION) {
+//                this.name = "LINGERING_" + this.name;
+//            }
+//            if (data.isExtended()) {
+//                this.name += "_EXTENDED";
+//            }
+//            if (data.isUpgraded()) {
+//                this.name += "_II";
+//            }
+//        }
+//
+//        public ProtoPotion(PotionType type) {
+//            this(new PotionData(type, false, false));
+//        }
+//
+//        public ProtoPotion(Material mat, PotionType type) {
+//            this(mat, new PotionData(type, false, false));
+//        }
+//
+//        private static String getMCName(PotionType type) {
+//            switch (type) {
+//                case INSTANT_DAMAGE:
+//                    return "HARMING";
+//                case INSTANT_HEAL:
+//                    return "HEALING";
+//                case JUMP:
+//                    return "LEAPING";
+//                case REGEN:
+//                    return "REGENERATION";
+//                case SPEED:
+//                    return "SWIFTNESS";
+//                case UNCRAFTABLE:
+//                    return "EMPTY";
+//                case LUCK:
+//                case MUNDANE:
+//                case NIGHT_VISION:
+//                case POISON:
+//                case INVISIBILITY:
+//                case SLOWNESS:
+//                case AWKWARD:
+//                case STRENGTH:
+//                case THICK:
+//                case FIRE_RESISTANCE:
+//                case WATER:
+//                case WATER_BREATHING:
+//                case WEAKNESS:
+//                case TURTLE_MASTER:
+//                case SLOW_FALLING:
+//                    return type.name();
+//                default:
+//                    return "";
+//            }
+//        }
+//
+//        public int hashCode() {
+//            return name.hashCode();
+//        }
+//
+//        public boolean equals(Object obj) {
+//            if (!(obj instanceof ProtoPotion)) {
+//                return false;
+//            }
+//            return name.equals(((ProtoPotion) obj).name);
+//        }
+//
+//        public void setChildren()
+//    }
+//}

+ 170 - 0
src/main/java/com/gmail/nossr50/dumpster/PotionManager.java

@@ -0,0 +1,170 @@
+//package com.gmail.nossr50.config;
+//
+//import com.gmail.nossr50.datatypes.skills.alchemy.AlchemyPotion;
+//import com.gmail.nossr50.skills.alchemy.PotionGenerator;
+//import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
+//import org.bukkit.Material;
+//import org.bukkit.inventory.ItemStack;
+//
+//import java.util.ArrayList;
+//import java.util.HashMap;
+//import java.util.List;
+//import java.util.Map;
+//
+///**
+// * Eventually I'm going to delete all of our Alchemy code and rewrite it from scratch
+// */
+//@ConfigSerializable
+//public class PotionManager {
+//
+//    /* CONSTANTS */
+//    public static final String POTIONS = "Potions";
+//
+//    /* INGREDIENTS */
+//    private List<ItemStack> ingredientTierOne;
+//    private List<ItemStack> ingredientTierTwo;
+//    private List<ItemStack> ingredientTierThree;
+//    private List<ItemStack> ingredientTierFour;
+//    private List<ItemStack> ingredientTierFive;
+//    private List<ItemStack> ingredientTierSix;
+//    private List<ItemStack> ingredientTierSeven;
+//    private List<ItemStack> ingredientTierEight;
+//
+//    private Map<String, AlchemyPotion> potionMap = new HashMap<>();
+//
+//    public PotionManager() {
+//        initIngredientLists();
+//        initPotionMap();
+//    }
+//
+//    /**
+//     * I just want anyone who reads this to know
+//     * This entire class is an abomination
+//     * What you see below is a hacky solution to keep Alchemy functioning with the new config system
+//     * Alchemy will be rewritten, until then, this disgusting class exists.
+//     */
+//    private void initIngredientLists() {
+//        ingredientTierOne = new ArrayList<>();
+//        ingredientTierTwo = new ArrayList<>();
+//        ingredientTierThree = new ArrayList<>();
+//        ingredientTierFour = new ArrayList<>();
+//        ingredientTierFive = new ArrayList<>();
+//        ingredientTierSix = new ArrayList<>();
+//        ingredientTierSeven = new ArrayList<>();
+//        ingredientTierEight = new ArrayList<>();
+//
+//        ingredientTierOne.add(new ItemStack(Material.BLAZE_POWDER));
+//        ingredientTierOne.add(new ItemStack(Material.FERMENTED_SPIDER_EYE));
+//        ingredientTierOne.add(new ItemStack(Material.GHAST_TEAR));
+//        ingredientTierOne.add(new ItemStack(Material.GLOWSTONE_DUST));
+//        ingredientTierOne.add(new ItemStack(Material.GOLDEN_CARROT));
+//        ingredientTierOne.add(new ItemStack(Material.MAGMA_CREAM));
+//        ingredientTierOne.add(new ItemStack(Material.NETHER_WART));
+//        ingredientTierOne.add(new ItemStack(Material.REDSTONE));
+//        ingredientTierOne.add(new ItemStack(Material.GLISTERING_MELON_SLICE));
+//        ingredientTierOne.add(new ItemStack(Material.SPIDER_EYE));
+//        ingredientTierOne.add(new ItemStack(Material.SUGAR));
+//        ingredientTierOne.add(new ItemStack(Material.GUNPOWDER));
+//        ingredientTierOne.add(new ItemStack(Material.PUFFERFISH));
+//        ingredientTierOne.add(new ItemStack(Material.DRAGON_BREATH));
+//
+//        ingredientTierTwo.add(new ItemStack(Material.CARROT));
+//        ingredientTierTwo.add(new ItemStack(Material.SLIME_BALL));
+//        ingredientTierTwo.add(new ItemStack(Material.PHANTOM_MEMBRANE));
+//
+//        ingredientTierThree.add(new ItemStack(Material.QUARTZ));
+//        ingredientTierThree.add(new ItemStack(Material.RED_MUSHROOM));
+//
+//        ingredientTierFour.add(new ItemStack(Material.APPLE));
+//        ingredientTierFour.add(new ItemStack(Material.ROTTEN_FLESH));
+//
+//        ingredientTierFive.add(new ItemStack(Material.BROWN_MUSHROOM));
+//        ingredientTierFive.add(new ItemStack(Material.INK_SAC));
+//
+//        ingredientTierSix.add(new ItemStack(Material.FERN));
+//
+//        ingredientTierSeven.add(new ItemStack(Material.POISONOUS_POTATO));
+//
+//        ingredientTierEight.add(new ItemStack(Material.GOLDEN_APPLE));
+//    }
+//
+//    private void loadConcoctionsTier(List<ItemStack> ingredientList, List<String> ingredients) {
+//        if (ingredients != null && ingredients.size() > 0) {
+//            for (String ingredientString : ingredients) {
+//                ItemStack ingredient = loadIngredient(ingredientString);
+//
+//                if (ingredient != null) {
+//                    ingredientList.add(ingredient);
+//                }
+//            }
+//        }
+//    }
+//
+//    private void initPotionMap() {
+//        PotionGenerator potionGenerator = new PotionGenerator();
+//        potionMap = potionMap
+//    }
+//
+//    /**
+//     * Parse a string representation of an ingredient.
+//     * Format: '&lt;MATERIAL&gt;[:data]'
+//     * Returns null if input cannot be parsed.
+//     *
+//     * @param ingredient String representing an ingredient.
+//     * @return Parsed ingredient.
+//     */
+//    private ItemStack loadIngredient(String ingredient) {
+//        if (ingredient == null || ingredient.isEmpty()) {
+//            return null;
+//        }
+//
+//        Material material = Material.getMaterial(ingredient);
+//
+//        if (material != null) {
+//            return new ItemStack(material, 1);
+//        }
+//
+//        return null;
+//    }
+//
+//    public List<ItemStack> getIngredients(int tier) {
+//        switch (tier) {
+//            case 8:
+//                return ingredientTierEight;
+//            case 7:
+//                return ingredientTierSeven;
+//            case 6:
+//                return ingredientTierSix;
+//            case 5:
+//                return ingredientTierFive;
+//            case 4:
+//                return ingredientTierFour;
+//            case 3:
+//                return ingredientTierThree;
+//            case 2:
+//                return ingredientTierTwo;
+//            case 1:
+//            default:
+//                return ingredientTierOne;
+//        }
+//    }
+//
+//    public boolean isValidPotion(ItemStack item) {
+//        return getPotion(item) != null;
+//    }
+//
+//    public AlchemyPotion getPotion(String name) {
+//        return potionMap.get(name);
+//    }
+//
+//    public AlchemyPotion getPotion(ItemStack item) {
+//        for (AlchemyPotion potion : potionMap.values()) {
+//            if (potion.isSimilar(item)) {
+//                return potion;
+//            }
+//        }
+//        return null;
+//    }
+//
+//
+//}

+ 86 - 0
src/main/java/com/gmail/nossr50/dumpster/PotionStage.java

@@ -0,0 +1,86 @@
+//package com.gmail.nossr50.datatypes.skills.alchemy;
+//
+//import org.bukkit.Material;
+//import org.bukkit.potion.PotionData;
+//import org.bukkit.potion.PotionEffect;
+//import org.bukkit.potion.PotionType;
+//
+//import java.util.List;
+//
+//public enum PotionStage {
+//    FIVE(5),
+//    FOUR(4),
+//    THREE(3),
+//    TWO(2),
+//    ONE(1);
+//
+//    int numerical;
+//
+//    PotionStage(int numerical) {
+//        this.numerical = numerical;
+//    }
+//
+//    private static PotionStage getPotionStageNumerical(int numerical) {
+//        for (PotionStage potionStage : values()) {
+//            if (numerical >= potionStage.toNumerical()) {
+//                return potionStage;
+//            }
+//        }
+//
+//        return ONE;
+//    }
+//
+//    public static PotionStage getPotionStage(AlchemyPotion input, AlchemyPotion output) {
+//        PotionStage potionStage = getPotionStage(output);
+//        if (!isWaterBottle(input) && getPotionStage(input) == potionStage) {
+//            potionStage = PotionStage.FIVE;
+//        }
+//
+//        return potionStage;
+//    }
+//
+//    private static boolean isWaterBottle(AlchemyPotion input) {
+//        return input.getData().getType() == PotionType.WATER;
+//    }
+//
+//    public static PotionStage getPotionStage(AlchemyPotion alchemyPotion) {
+//        PotionData data = alchemyPotion.getData();
+//        List<PotionEffect> effects = alchemyPotion.getEffects();
+//
+//        int stage = 1;
+//
+//        // Check if potion has an effect of any sort
+//        if (data.getType().getEffectType() != null || !effects.isEmpty()) {
+//            stage++;
+//        }
+//
+//        // Check if potion has a glowstone dust amplifier
+//        // Else check if the potion has a custom effect with an amplifier added by mcMMO
+//        if (data.isUpgraded()) {
+//            stage++;
+//        } else if (!effects.isEmpty()) {
+//            for (PotionEffect effect : effects) {
+//                if (effect.getAmplifier() > 0) {
+//                    stage++;
+//                    break;
+//                }
+//            }
+//        }
+//
+//        // Check if potion has a redstone dust amplifier
+//        if (data.isExtended()) {
+//            stage++;
+//        }
+//
+//        // Check if potion has a gunpowder amplifier
+//        if (alchemyPotion.getMaterial() == Material.SPLASH_POTION || alchemyPotion.getMaterial() == Material.LINGERING_POTION) {
+//            stage++;
+//        }
+//
+//        return PotionStage.getPotionStageNumerical(stage);
+//    }
+//
+//    public int toNumerical() {
+//        return numerical;
+//    }
+//}

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

@@ -11,7 +11,6 @@ import com.gmail.nossr50.datatypes.skills.ToolType;
 import com.gmail.nossr50.events.fake.FakeBlockBreakEvent;
 import com.gmail.nossr50.events.fake.FakeBlockDamageEvent;
 import com.gmail.nossr50.mcMMO;
-import com.gmail.nossr50.skills.alchemy.Alchemy;
 import com.gmail.nossr50.skills.excavation.ExcavationManager;
 import com.gmail.nossr50.skills.herbalism.Herbalism;
 import com.gmail.nossr50.skills.herbalism.HerbalismManager;
@@ -33,7 +32,10 @@ import org.bukkit.GameMode;
 import org.bukkit.Location;
 import org.bukkit.Material;
 import org.bukkit.Tag;
-import org.bukkit.block.*;
+import org.bukkit.block.Block;
+import org.bukkit.block.BlockFace;
+import org.bukkit.block.BlockState;
+import org.bukkit.block.Furnace;
 import org.bukkit.entity.Item;
 import org.bukkit.entity.Player;
 import org.bukkit.event.EventHandler;
@@ -254,9 +256,9 @@ public class BlockListener implements Listener {
         }
 
         /* ALCHEMY - Cancel any brew in progress for that BrewingStand */
-        if (blockState instanceof BrewingStand && Alchemy.brewingStandMap.containsKey(location)) {
-            Alchemy.brewingStandMap.get(location).cancelBrew();
-        }
+//        if (blockState instanceof BrewingStand && Alchemy.brewingStandMap.containsKey(location)) {
+//            Alchemy.brewingStandMap.get(location).cancelBrew();
+//        }
 
         Player player = event.getPlayer();
 

+ 114 - 118
src/main/java/com/gmail/nossr50/listeners/InventoryListener.java

@@ -4,18 +4,14 @@ import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.config.WorldBlacklist;
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 import com.gmail.nossr50.datatypes.skills.SubSkillType;
-import com.gmail.nossr50.events.fake.FakeBrewEvent;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.runnables.player.PlayerUpdateInventoryTask;
-import com.gmail.nossr50.skills.alchemy.Alchemy;
-import com.gmail.nossr50.skills.alchemy.AlchemyPotionBrewer;
 import com.gmail.nossr50.util.ItemUtils;
 import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.player.UserManager;
 import com.gmail.nossr50.util.skills.SkillUtils;
 import com.gmail.nossr50.worldguard.WorldGuardManager;
 import com.gmail.nossr50.worldguard.WorldGuardUtils;
-import org.bukkit.Location;
 import org.bukkit.Material;
 import org.bukkit.block.Block;
 import org.bukkit.block.BlockState;
@@ -237,78 +233,78 @@ public class InventoryListener implements Listener {
                 return;
         }
 
-        BrewingStand stand = (BrewingStand) holder;
-        ItemStack clicked = event.getCurrentItem();
-        ItemStack cursor = event.getCursor();
-
-        if ((clicked != null && (clicked.getType() == Material.POTION || clicked.getType() == Material.SPLASH_POTION || clicked.getType() == Material.LINGERING_POTION)) || (cursor != null && (cursor.getType() == Material.POTION || cursor.getType() == Material.SPLASH_POTION || cursor.getType() == Material.LINGERING_POTION))) {
-            AlchemyPotionBrewer.scheduleCheck(player, stand);
-            return;
-        }
-
-        ClickType click = event.getClick();
-        InventoryType.SlotType slot = event.getSlotType();
-
-        if (click.isShiftClick()) {
-            switch (slot) {
-                case FUEL:
-                    AlchemyPotionBrewer.scheduleCheck(player, stand);
-                    return;
-                case CONTAINER:
-                case QUICKBAR:
-                    if (!AlchemyPotionBrewer.isValidIngredient(player, clicked)) {
-                        return;
-                    }
-
-                    if (!AlchemyPotionBrewer.transferItems(event.getView(), event.getRawSlot(), click)) {
-                        return;
-                    }
-
-                    event.setCancelled(true);
-                    AlchemyPotionBrewer.scheduleUpdate(inventory);
-                    AlchemyPotionBrewer.scheduleCheck(player, stand);
-                    return;
-                default:
-            }
-        } else if (slot == InventoryType.SlotType.FUEL) {
-            boolean emptyClicked = AlchemyPotionBrewer.isEmpty(clicked);
-
-            if (AlchemyPotionBrewer.isEmpty(cursor)) {
-                if (emptyClicked && click == ClickType.NUMBER_KEY) {
-                    AlchemyPotionBrewer.scheduleCheck(player, stand);
-                    return;
-                }
-
-                AlchemyPotionBrewer.scheduleCheck(player, stand);
-            } else if (emptyClicked) {
-                if (AlchemyPotionBrewer.isValidIngredient(player, cursor)) {
-                    int amount = cursor.getAmount();
-
-                    if (click == ClickType.LEFT || (click == ClickType.RIGHT && amount == 1)) {
-                        event.setCancelled(true);
-                        event.setCurrentItem(cursor.clone());
-                        event.setCursor(null);
-
-                        AlchemyPotionBrewer.scheduleUpdate(inventory);
-                        AlchemyPotionBrewer.scheduleCheck(player, stand);
-                    } else if (click == ClickType.RIGHT) {
-                        event.setCancelled(true);
-
-                        ItemStack one = cursor.clone();
-                        one.setAmount(1);
-
-                        ItemStack rest = cursor.clone();
-                        rest.setAmount(amount - 1);
-
-                        event.setCurrentItem(one);
-                        event.setCursor(rest);
-
-                        AlchemyPotionBrewer.scheduleUpdate(inventory);
-                        AlchemyPotionBrewer.scheduleCheck(player, stand);
-                    }
-                }
-            }
-        }
+//        BrewingStand stand = (BrewingStand) holder;
+//        ItemStack clicked = event.getCurrentItem();
+//        ItemStack cursor = event.getCursor();
+
+//        if ((clicked != null && (clicked.getType() == Material.POTION || clicked.getType() == Material.SPLASH_POTION || clicked.getType() == Material.LINGERING_POTION)) || (cursor != null && (cursor.getType() == Material.POTION || cursor.getType() == Material.SPLASH_POTION || cursor.getType() == Material.LINGERING_POTION))) {
+//            AlchemyPotionBrewer.scheduleCheck(player, stand);
+//            return;
+//        }
+//
+//        ClickType click = event.getClick();
+//        InventoryType.SlotType slot = event.getSlotType();
+
+//        if (click.isShiftClick()) {
+//            switch (slot) {
+//                case FUEL:
+//                    AlchemyPotionBrewer.scheduleCheck(player, stand);
+//                    return;
+//                case CONTAINER:
+//                case QUICKBAR:
+//                    if (!AlchemyPotionBrewer.isValidIngredient(player, clicked)) {
+//                        return;
+//                    }
+//
+//                    if (!AlchemyPotionBrewer.transferItems(event.getView(), event.getRawSlot(), click)) {
+//                        return;
+//                    }
+//
+//                    event.setCancelled(true);
+//                    AlchemyPotionBrewer.scheduleUpdate(inventory);
+//                    AlchemyPotionBrewer.scheduleCheck(player, stand);
+//                    return;
+//                default:
+//            }
+//        } else if (slot == InventoryType.SlotType.FUEL) {
+//            boolean emptyClicked = AlchemyPotionBrewer.isEmpty(clicked);
+//
+//            if (AlchemyPotionBrewer.isEmpty(cursor)) {
+//                if (emptyClicked && click == ClickType.NUMBER_KEY) {
+//                    AlchemyPotionBrewer.scheduleCheck(player, stand);
+//                    return;
+//                }
+//
+//                AlchemyPotionBrewer.scheduleCheck(player, stand);
+//            } else if (emptyClicked) {
+//                if (AlchemyPotionBrewer.isValidIngredient(player, cursor)) {
+//                    int amount = cursor.getAmount();
+//
+//                    if (click == ClickType.LEFT || (click == ClickType.RIGHT && amount == 1)) {
+//                        event.setCancelled(true);
+//                        event.setCurrentItem(cursor.clone());
+//                        event.setCursor(null);
+//
+//                        AlchemyPotionBrewer.scheduleUpdate(inventory);
+//                        AlchemyPotionBrewer.scheduleCheck(player, stand);
+//                    } else if (click == ClickType.RIGHT) {
+//                        event.setCancelled(true);
+//
+//                        ItemStack one = cursor.clone();
+//                        one.setAmount(1);
+//
+//                        ItemStack rest = cursor.clone();
+//                        rest.setAmount(amount - 1);
+//
+//                        event.setCurrentItem(one);
+//                        event.setCursor(rest);
+//
+//                        AlchemyPotionBrewer.scheduleUpdate(inventory);
+//                        AlchemyPotionBrewer.scheduleCheck(player, stand);
+//                    }
+//                }
+//            }
+//        }
     }
 
     @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
@@ -335,48 +331,48 @@ public class InventoryListener implements Listener {
             return;
         }
 
-        if (!event.getInventorySlots().contains(Alchemy.INGREDIENT_SLOT)) {
-            return;
-        }
-
-        ItemStack cursor = event.getCursor();
-        ItemStack ingredient = ((BrewerInventory) inventory).getIngredient();
-
-        if (AlchemyPotionBrewer.isEmpty(ingredient) || ingredient.isSimilar(cursor)) {
-            Player player = (Player) whoClicked;
-
-            /* WORLD GUARD MAIN FLAG CHECK */
-            if (WorldGuardUtils.isWorldGuardLoaded()) {
-                if (!WorldGuardManager.getInstance().hasMainFlag(player))
-                    return;
-            }
-
-            if (AlchemyPotionBrewer.isValidIngredient(player, cursor)) {
-                // Not handled: dragging custom ingredients over ingredient slot (does not trigger any event)
-                AlchemyPotionBrewer.scheduleCheck(player, (BrewingStand) holder);
-                return;
-            }
-
-            event.setCancelled(true);
-            AlchemyPotionBrewer.scheduleUpdate(inventory);
-        }
+//        if (!event.getInventorySlots().contains(Alchemy.INGREDIENT_SLOT)) {
+//            return;
+//        }
+//
+//        ItemStack cursor = event.getCursor();
+//        ItemStack ingredient = ((BrewerInventory) inventory).getIngredient();
+//
+//        if (AlchemyPotionBrewer.isEmpty(ingredient) || ingredient.isSimilar(cursor)) {
+//            Player player = (Player) whoClicked;
+//
+//            /* WORLD GUARD MAIN FLAG CHECK */
+//            if (WorldGuardUtils.isWorldGuardLoaded()) {
+//                if (!WorldGuardManager.getInstance().hasMainFlag(player))
+//                    return;
+//            }
+//
+//            if (AlchemyPotionBrewer.isValidIngredient(player, cursor)) {
+//                // Not handled: dragging custom ingredients over ingredient slot (does not trigger any event)
+//                AlchemyPotionBrewer.scheduleCheck(player, (BrewingStand) holder);
+//                return;
+//            }
+//
+//            event.setCancelled(true);
+//            AlchemyPotionBrewer.scheduleUpdate(inventory);
+//        }
     }
 
     // Apparently sometimes vanilla brewing beats our task listener to the actual brew. We handle this by cancelling the vanilla event and finishing our brew ourselves.
-    @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
-    public void onBrew(BrewEvent event) {
-        /* WORLD BLACKLIST CHECK */
-        if (WorldBlacklist.isWorldBlacklisted(event.getBlock().getWorld()))
-            return;
-
-        if (event instanceof FakeBrewEvent)
-            return;
-        Location location = event.getBlock().getLocation();
-        if (Alchemy.brewingStandMap.containsKey(location)) {
-            Alchemy.brewingStandMap.get(location).finishImmediately();
-            event.setCancelled(true);
-        }
-    }
+//    @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
+//    public void onBrew(BrewEvent event) {
+//        /* WORLD BLACKLIST CHECK */
+//        if (WorldBlacklist.isWorldBlacklisted(event.getBlock().getWorld()))
+//            return;
+//
+//        if (event instanceof FakeBrewEvent)
+//            return;
+//        Location location = event.getBlock().getLocation();
+//        if (Alchemy.brewingStandMap.containsKey(location)) {
+//            Alchemy.brewingStandMap.get(location).finishImmediately();
+//            event.setCancelled(true);
+//        }
+//    }
 
     @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
     public void onInventoryMoveItemEvent(InventoryMoveItemEvent event) {
@@ -411,9 +407,9 @@ public class InventoryListener implements Listener {
             return;
         }
 
-        if (MainConfig.getInstance().getEnabledForHoppers() && AlchemyPotionBrewer.isValidIngredient(null, item)) {
-            AlchemyPotionBrewer.scheduleCheck(null, (BrewingStand) holder);
-        }
+//        if (MainConfig.getInstance().getEnabledForHoppers() && AlchemyPotionBrewer.isValidIngredient(null, item)) {
+//            AlchemyPotionBrewer.scheduleCheck(null, (BrewingStand) holder);
+//        }
     }
 
     @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)

+ 2 - 1
src/main/java/com/gmail/nossr50/listeners/WorldListener.java

@@ -91,6 +91,7 @@ public class WorldListener implements Listener {
 
         Chunk chunk = event.getChunk();
 
-        mcMMO.getPlaceStore().chunkUnloaded(chunk.getX(), chunk.getZ(), event.getWorld());
+        if(chunk != null)
+            mcMMO.getPlaceStore().chunkUnloaded(chunk.getX(), chunk.getZ(), event.getWorld());
     }
 }

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

@@ -25,7 +25,6 @@ import com.gmail.nossr50.runnables.player.ClearRegisteredXPGainTask;
 import com.gmail.nossr50.runnables.player.PlayerProfileLoadingTask;
 import com.gmail.nossr50.runnables.player.PowerLevelUpdatingTask;
 import com.gmail.nossr50.runnables.skills.BleedTimerTask;
-import com.gmail.nossr50.skills.alchemy.Alchemy;
 import com.gmail.nossr50.skills.repair.repairables.RepairableManager;
 import com.gmail.nossr50.skills.salvage.salvageables.SalvageableManager;
 import com.gmail.nossr50.util.*;
@@ -391,7 +390,7 @@ public class mcMMO extends JavaPlugin {
     @Override
     public void onDisable() {
         try {
-            Alchemy.finishAllBrews();   // Finish all partially complete AlchemyBrewTasks to prevent vanilla brewing continuation on restart
+//            Alchemy.finishAllBrews();   // Finish all partially complete AlchemyBrewTasks to prevent vanilla brewing continuation on restart
             UserManager.saveAll();      // Make sure to save player information if the server shuts down
             UserManager.clearAll();
             PartyManager.saveParties(); // Save our parties

+ 0 - 38
src/main/java/com/gmail/nossr50/runnables/skills/AlchemyBrewCheckTask.java

@@ -1,38 +0,0 @@
-package com.gmail.nossr50.runnables.skills;
-
-import com.gmail.nossr50.skills.alchemy.Alchemy;
-import com.gmail.nossr50.skills.alchemy.AlchemyPotionBrewer;
-import org.bukkit.Location;
-import org.bukkit.block.BrewingStand;
-import org.bukkit.entity.Player;
-import org.bukkit.inventory.ItemStack;
-import org.bukkit.scheduler.BukkitRunnable;
-
-import java.util.Arrays;
-
-public class AlchemyBrewCheckTask extends BukkitRunnable {
-    private Player player;
-    private BrewingStand brewingStand;
-    private ItemStack[] oldInventory;
-
-    public AlchemyBrewCheckTask(Player player, BrewingStand brewingStand) {
-        this.player = player;
-        this.brewingStand = brewingStand;
-        this.oldInventory = Arrays.copyOfRange(brewingStand.getInventory().getContents(), 0, 4);
-    }
-
-    @Override
-    public void run() {
-        Location location = brewingStand.getLocation();
-        ItemStack[] newInventory = Arrays.copyOfRange(brewingStand.getInventory().getContents(), 0, 4);
-        boolean validBrew = brewingStand.getFuelLevel() > 0 && AlchemyPotionBrewer.isValidBrew(player, newInventory);
-
-        if (Alchemy.brewingStandMap.containsKey(location)) {
-            if (oldInventory[Alchemy.INGREDIENT_SLOT] == null || newInventory[Alchemy.INGREDIENT_SLOT] == null || !oldInventory[Alchemy.INGREDIENT_SLOT].isSimilar(newInventory[Alchemy.INGREDIENT_SLOT]) || !validBrew) {
-                Alchemy.brewingStandMap.get(location).cancelBrew();
-            }
-        } else if (validBrew) {
-            Alchemy.brewingStandMap.put(location, new AlchemyBrewTask(brewingStand, player));
-        }
-    }
-}

+ 0 - 118
src/main/java/com/gmail/nossr50/runnables/skills/AlchemyBrewTask.java

@@ -1,118 +0,0 @@
-package com.gmail.nossr50.runnables.skills;
-
-import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
-import com.gmail.nossr50.datatypes.skills.SubSkillType;
-import com.gmail.nossr50.events.skills.alchemy.McMMOPlayerBrewEvent;
-import com.gmail.nossr50.events.skills.alchemy.McMMOPlayerCatalysisEvent;
-import com.gmail.nossr50.mcMMO;
-import com.gmail.nossr50.skills.alchemy.Alchemy;
-import com.gmail.nossr50.skills.alchemy.AlchemyPotionBrewer;
-import com.gmail.nossr50.util.Misc;
-import com.gmail.nossr50.util.Permissions;
-import com.gmail.nossr50.util.player.UserManager;
-import org.bukkit.Location;
-import org.bukkit.Material;
-import org.bukkit.block.BlockState;
-import org.bukkit.block.BrewingStand;
-import org.bukkit.entity.Player;
-import org.bukkit.scheduler.BukkitRunnable;
-
-public class AlchemyBrewTask extends BukkitRunnable {
-
-    private BlockState brewingStand;
-    private Location location;
-    private double brewSpeed;
-    private double brewTimer;
-    private Player player;
-    private int fuel;
-    private boolean firstRun = true;
-
-    public AlchemyBrewTask(BlockState brewingStand, Player player) {
-        this.brewingStand = brewingStand;
-        this.location = brewingStand.getLocation();
-        this.player = player;
-
-        brewSpeed = 1.0;
-        brewTimer = 400;
-
-        if (player != null
-                && !Misc.isNPCEntity(player)
-                && Permissions.isSubSkillEnabled(player, SubSkillType.ALCHEMY_CATALYSIS)
-                && UserManager.getPlayer(player) != null) {
-
-            double catalysis = UserManager.getPlayer(player).getAlchemyManager().calculateBrewSpeed(Permissions.lucky(player, PrimarySkillType.ALCHEMY));
-
-            McMMOPlayerCatalysisEvent event = new McMMOPlayerCatalysisEvent(player, catalysis);
-            mcMMO.p.getServer().getPluginManager().callEvent(event);
-
-            if (!event.isCancelled()) {
-                brewSpeed = catalysis;
-            }
-        }
-
-        if (Alchemy.brewingStandMap.containsKey(location)) {
-            Alchemy.brewingStandMap.get(location).cancel();
-        }
-
-        fuel = ((BrewingStand) brewingStand).getFuelLevel();
-
-        if (((BrewingStand) brewingStand).getBrewingTime() == -1) // Only decrement on our end if it isn't a vanilla ingredient.
-            fuel--;
-
-        Alchemy.brewingStandMap.put(location, this);
-        this.runTaskTimer(mcMMO.p, 1, 1);
-    }
-
-    @Override
-    public void run() {
-        if (player == null || !player.isValid() || brewingStand == null || brewingStand.getType() != Material.BREWING_STAND || !AlchemyPotionBrewer.isValidIngredient(player, ((BrewingStand) brewingStand).getInventory().getContents()[Alchemy.INGREDIENT_SLOT])) {
-            if (Alchemy.brewingStandMap.containsKey(location)) {
-                Alchemy.brewingStandMap.remove(location);
-            }
-
-            this.cancel();
-
-            return;
-        }
-
-        if (firstRun) {
-            firstRun = false;
-            ((BrewingStand) brewingStand).setFuelLevel(fuel);
-        }
-
-        brewTimer -= brewSpeed;
-
-        // Vanilla potion brewing completes when BrewingTime == 1
-        if (brewTimer < Math.max(brewSpeed, 2)) {
-            this.cancel();
-            finish();
-        } else {
-            ((BrewingStand) brewingStand).setBrewingTime((int) brewTimer);
-        }
-    }
-
-    private void finish() {
-        McMMOPlayerBrewEvent event = new McMMOPlayerBrewEvent(player, brewingStand);
-        mcMMO.p.getServer().getPluginManager().callEvent(event);
-
-        if (!event.isCancelled()) {
-            AlchemyPotionBrewer.finishBrewing(brewingStand, player, false);
-        }
-
-        Alchemy.brewingStandMap.remove(location);
-    }
-
-    public void finishImmediately() {
-        this.cancel();
-
-        AlchemyPotionBrewer.finishBrewing(brewingStand, player, true);
-        Alchemy.brewingStandMap.remove(location);
-    }
-
-    public void cancelBrew() {
-        this.cancel();
-
-        ((BrewingStand) brewingStand).setBrewingTime(-1);
-        Alchemy.brewingStandMap.remove(location);
-    }
-}

+ 26 - 38
src/main/java/com/gmail/nossr50/skills/alchemy/Alchemy.java

@@ -1,17 +1,5 @@
 package com.gmail.nossr50.skills.alchemy;
 
-import com.gmail.nossr50.config.AdvancedConfig;
-import com.gmail.nossr50.datatypes.skills.SubSkillType;
-import com.gmail.nossr50.mcMMO;
-import com.gmail.nossr50.runnables.skills.AlchemyBrewTask;
-import com.gmail.nossr50.util.skills.RankUtils;
-import org.bukkit.Location;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
 public final class Alchemy {
     /*public enum Tier {
         EIGHT(8),
@@ -47,30 +35,30 @@ public final class Alchemy {
         }
     }*/
 
-    public static final int INGREDIENT_SLOT = 3;
-
-    public static int catalysisUnlockLevel = RankUtils.getUnlockLevel(SubSkillType.ALCHEMY_CATALYSIS);
-    public static int catalysisMaxBonusLevel = AdvancedConfig.getInstance().getCatalysisMaxBonusLevel();
-    public static double catalysisMinSpeed = AdvancedConfig.getInstance().getCatalysisMinSpeed();
-    public static double catalysisMaxSpeed = AdvancedConfig.getInstance().getCatalysisMaxSpeed();
-
-    public static Map<Location, AlchemyBrewTask> brewingStandMap = new HashMap<>();
-
-    private Alchemy() {
-    }
-
-    /**
-     * Finish all active brews.  Used upon Disable to prevent vanilla potions from being brewed upon next Enable.
-     */
-    public static void finishAllBrews() {
-        mcMMO.p.debug("Completing " + brewingStandMap.size() + " unfinished Alchemy brews.");
-
-        List<AlchemyBrewTask> toFinish = new ArrayList<>();
-
-        toFinish.addAll(brewingStandMap.values());
-
-        for (AlchemyBrewTask alchemyBrewTask : toFinish) {
-            alchemyBrewTask.finishImmediately();
-        }
-    }
+//    public static final int INGREDIENT_SLOT = 3;
+//
+//    public static int catalysisUnlockLevel = RankUtils.getUnlockLevel(SubSkillType.ALCHEMY_CATALYSIS);
+//    public static int catalysisMaxBonusLevel = AdvancedConfig.getInstance().getCatalysisMaxBonusLevel();
+//    public static double catalysisMinSpeed = AdvancedConfig.getInstance().getCatalysisMinSpeed();
+//    public static double catalysisMaxSpeed = AdvancedConfig.getInstance().getCatalysisMaxSpeed();
+//
+//    public static Map<Location, AlchemyBrewTask> brewingStandMap = new HashMap<>();
+//
+//    private Alchemy() {
+//    }
+//
+//    /**
+//     * Finish all active brews.  Used upon Disable to prevent vanilla potions from being brewed upon next Enable.
+//     */
+//    public static void finishAllBrews() {
+//        mcMMO.p.debug("Completing " + brewingStandMap.size() + " unfinished Alchemy brews.");
+//
+//        List<AlchemyBrewTask> toFinish = new ArrayList<>();
+//
+//        toFinish.addAll(brewingStandMap.values());
+//
+//        for (AlchemyBrewTask alchemyBrewTask : toFinish) {
+//            alchemyBrewTask.finishImmediately();
+//        }
+//    }
 }

+ 36 - 46
src/main/java/com/gmail/nossr50/skills/alchemy/AlchemyManager.java

@@ -1,19 +1,8 @@
 package com.gmail.nossr50.skills.alchemy;
 
-import com.gmail.nossr50.config.skills.alchemy.PotionManager;
-import com.gmail.nossr50.datatypes.experience.XPGainReason;
-import com.gmail.nossr50.datatypes.experience.XPGainSource;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
-import com.gmail.nossr50.datatypes.skills.SubSkillType;
-import com.gmail.nossr50.datatypes.skills.alchemy.PotionStage;
-import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.skills.SkillManager;
-import com.gmail.nossr50.util.StringUtils;
-import com.gmail.nossr50.util.skills.RankUtils;
-import org.bukkit.inventory.ItemStack;
-
-import java.util.List;
 
 public class AlchemyManager extends SkillManager {
 
@@ -21,39 +10,40 @@ public class AlchemyManager extends SkillManager {
         super(mcMMOPlayer, PrimarySkillType.ALCHEMY);
     }
 
-    public int getTier() {
-        return RankUtils.getRank(getPlayer(), SubSkillType.ALCHEMY_CONCOCTIONS);
-    }
-
-    public List<ItemStack> getIngredients() {
-        return PotionManager.getInstance().getIngredients(getTier());
-    }
-
-    public String getIngredientList() {
-        StringBuilder list = new StringBuilder();
-
-        for (ItemStack ingredient : getIngredients()) {
-            String string = StringUtils.getPrettyItemString(ingredient.getType());
-
-            list.append(", ").append(string);
-        }
-
-        return list.substring(2);
-    }
-
-    public double calculateBrewSpeed(boolean isLucky) {
-        int skillLevel = getSkillLevel();
-
-        if (skillLevel < Alchemy.catalysisUnlockLevel) {
-            return Alchemy.catalysisMinSpeed;
-        }
-
-        double LUCKY_MODIFIER = 4.0 / 3.0;
-        return Math.min(Alchemy.catalysisMaxSpeed, Alchemy.catalysisMinSpeed + (Alchemy.catalysisMaxSpeed - Alchemy.catalysisMinSpeed) * (skillLevel - Alchemy.catalysisUnlockLevel) / (Alchemy.catalysisMaxBonusLevel - Alchemy.catalysisUnlockLevel)) * (isLucky ? LUCKY_MODIFIER : 1.0);
-    }
-
-    public void handlePotionBrewSuccesses(PotionStage potionStage, int amount) {
-        //TODO: This code disturbs me
-        applyXpGain((float) (mcMMO.getConfigManager().getConfigExperience().getExperienceAlchemy().getPotionXPByStage(potionStage.toNumerical()) * amount), XPGainReason.PVE, XPGainSource.PASSIVE);
-    }
+//
+//    public int getTier() {
+//        return RankUtils.getRank(getPlayer(), SubSkillType.ALCHEMY_CONCOCTIONS);
+//    }
+//
+//    public List<ItemStack> getIngredients() {
+//        return PotionManager.getInstance().getIngredients(getTier());
+//    }
+//
+//    public String getIngredientList() {
+//        StringBuilder list = new StringBuilder();
+//
+//        for (ItemStack ingredient : getIngredients()) {
+//            String string = StringUtils.getPrettyItemString(ingredient.getType());
+//
+//            list.append(", ").append(string);
+//        }
+//
+//        return list.substring(2);
+//    }
+//
+//    public double calculateBrewSpeed(boolean isLucky) {
+//        int skillLevel = getSkillLevel();
+//
+//        if (skillLevel < Alchemy.catalysisUnlockLevel) {
+//            return Alchemy.catalysisMinSpeed;
+//        }
+//
+//        double LUCKY_MODIFIER = 4.0 / 3.0;
+//        return Math.min(Alchemy.catalysisMaxSpeed, Alchemy.catalysisMinSpeed + (Alchemy.catalysisMaxSpeed - Alchemy.catalysisMinSpeed) * (skillLevel - Alchemy.catalysisUnlockLevel) / (Alchemy.catalysisMaxBonusLevel - Alchemy.catalysisUnlockLevel)) * (isLucky ? LUCKY_MODIFIER : 1.0);
+//    }
+//
+//    public void handlePotionBrewSuccesses(PotionStage potionStage, int amount) {
+//        //TODO: This code disturbs me
+//        applyXpGain((float) (mcMMO.getConfigManager().getConfigExperience().getExperienceAlchemy().getPotionXPByStage(potionStage.toNumerical()) * amount), XPGainReason.PVE, XPGainSource.PASSIVE);
+//    }
 }

+ 0 - 251
src/main/java/com/gmail/nossr50/skills/alchemy/AlchemyPotionBrewer.java

@@ -1,251 +0,0 @@
-package com.gmail.nossr50.skills.alchemy;
-
-import com.gmail.nossr50.config.skills.alchemy.PotionManager;
-import com.gmail.nossr50.datatypes.skills.SubSkillType;
-import com.gmail.nossr50.datatypes.skills.alchemy.AlchemyPotion;
-import com.gmail.nossr50.datatypes.skills.alchemy.PotionStage;
-import com.gmail.nossr50.events.fake.FakeBrewEvent;
-import com.gmail.nossr50.mcMMO;
-import com.gmail.nossr50.runnables.player.PlayerUpdateInventoryTask;
-import com.gmail.nossr50.runnables.skills.AlchemyBrewCheckTask;
-import com.gmail.nossr50.util.Permissions;
-import com.gmail.nossr50.util.player.UserManager;
-import org.bukkit.Material;
-import org.bukkit.block.BlockState;
-import org.bukkit.block.BrewingStand;
-import org.bukkit.entity.HumanEntity;
-import org.bukkit.entity.Player;
-import org.bukkit.event.inventory.ClickType;
-import org.bukkit.inventory.BrewerInventory;
-import org.bukkit.inventory.Inventory;
-import org.bukkit.inventory.InventoryView;
-import org.bukkit.inventory.ItemStack;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public final class AlchemyPotionBrewer {
-    public static boolean isValidBrew(Player player, ItemStack[] contents) {
-        if (!isValidIngredient(player, contents[Alchemy.INGREDIENT_SLOT])) {
-            return false;
-        }
-
-        for (int i = 0; i < 3; i++) {
-            if (contents[i] == null || contents[i].getType() != Material.POTION && contents[i].getType() != Material.SPLASH_POTION && contents[i].getType() != Material.LINGERING_POTION) {
-                continue;
-            }
-
-            if (getChildPotion(PotionManager.getInstance().getPotion(contents[i]), contents[Alchemy.INGREDIENT_SLOT]) != null) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    private static AlchemyPotion getChildPotion(AlchemyPotion potion, ItemStack ingredient) {
-        if (potion != null) {
-            return potion.getChild(ingredient);
-        }
-
-        return null;
-    }
-
-    public static boolean isEmpty(ItemStack item) {
-        return item == null || item.getType() == Material.AIR || item.getAmount() == 0;
-    }
-
-    private static void removeIngredient(BrewerInventory inventory, Player player) {
-        ItemStack ingredient = inventory.getIngredient() == null ? null : inventory.getIngredient().clone();
-
-        if (isEmpty(ingredient) || !isValidIngredient(player, ingredient)) {
-        } else if (ingredient.getAmount() <= 1) {
-            inventory.setIngredient(null);
-        } else {
-            ingredient.setAmount(ingredient.getAmount() - 1);
-            inventory.setIngredient(ingredient);
-        }
-    }
-
-    private static boolean hasIngredient(BrewerInventory inventory, Player player) {
-        ItemStack ingredient = inventory.getIngredient() == null ? null : inventory.getIngredient().clone();
-
-        return !isEmpty(ingredient) && isValidIngredient(player, ingredient);
-    }
-
-    public static boolean isValidIngredient(Player player, ItemStack item) {
-        if (isEmpty(item)) {
-            return false;
-        }
-
-        for (ItemStack ingredient : getValidIngredients(player)) {
-            if (item.isSimilar(ingredient)) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    private static List<ItemStack> getValidIngredients(Player player) {
-        if (player == null || UserManager.getPlayer(player) == null) {
-            return PotionManager.getInstance().getIngredients(1);
-        }
-
-        return PotionManager.getInstance().getIngredients(!Permissions.isSubSkillEnabled(player, SubSkillType.ALCHEMY_CONCOCTIONS) ? 1 : UserManager.getPlayer(player).getAlchemyManager().getTier());
-    }
-
-    public static void finishBrewing(BlockState brewingStand, Player player, boolean forced) {
-        if (!(brewingStand instanceof BrewingStand)) {
-            return;
-        }
-
-        BrewerInventory inventory = ((BrewingStand) brewingStand).getInventory();
-        ItemStack ingredient = inventory.getIngredient() == null ? null : inventory.getIngredient().clone();
-
-        if (!hasIngredient(inventory, player)) {
-            return;
-        }
-
-        List<AlchemyPotion> inputList = new ArrayList<>();
-
-        for (int i = 0; i < 3; i++) {
-            ItemStack item = inventory.getItem(i);
-
-            if (isEmpty(item) || item.getType() == Material.GLASS_BOTTLE || !PotionManager.getInstance().isValidPotion(item)) {
-                continue;
-            }
-
-            AlchemyPotion input = PotionManager.getInstance().getPotion(item);
-            AlchemyPotion output = input.getChild(ingredient);
-
-            inputList.add(input);
-
-            if (output != null) {
-                inventory.setItem(i, output.toItemStack(item.getAmount()).clone());
-            }
-        }
-
-        FakeBrewEvent event = new FakeBrewEvent(brewingStand.getBlock(), inventory, ((BrewingStand) brewingStand).getFuelLevel());
-        mcMMO.p.getServer().getPluginManager().callEvent(event);
-
-        if (event.isCancelled() || inputList.isEmpty()) {
-            return;
-        }
-
-        removeIngredient(inventory, player);
-
-        for (AlchemyPotion input : inputList) {
-            AlchemyPotion output = input.getChild(ingredient);
-
-            if (output != null && player != null) {
-                PotionStage potionStage = PotionStage.getPotionStage(input, output);
-
-                //TODO: hmm
-                if (UserManager.hasPlayerDataKey(player)) {
-                    UserManager.getPlayer(player).getAlchemyManager().handlePotionBrewSuccesses(potionStage, 1);
-                }
-            }
-        }
-
-        if (!forced) {
-            scheduleUpdate(inventory);
-        }
-    }
-
-    public static boolean transferItems(InventoryView view, int fromSlot, ClickType click) {
-        boolean success = false;
-
-        if (click.isLeftClick()) {
-            success = transferItems(view, fromSlot);
-        } else if (click.isRightClick()) {
-            success = transferOneItem(view, fromSlot);
-        }
-
-        return success;
-    }
-
-    private static boolean transferOneItem(InventoryView view, int fromSlot) {
-        ItemStack from = view.getItem(fromSlot).clone();
-        ItemStack to = view.getItem(Alchemy.INGREDIENT_SLOT).clone();
-
-        if (isEmpty(from)) {
-            return false;
-        }
-
-        boolean emptyTo = isEmpty(to);
-        int fromAmount = from.getAmount();
-
-        if (!emptyTo && fromAmount >= from.getType().getMaxStackSize()) {
-            return false;
-        } else if (emptyTo || from.isSimilar(to)) {
-            if (emptyTo) {
-                to = from.clone();
-                to.setAmount(1);
-            } else {
-                to.setAmount(to.getAmount() + 1);
-            }
-
-            from.setAmount(fromAmount - 1);
-            view.setItem(Alchemy.INGREDIENT_SLOT, to);
-            view.setItem(fromSlot, from);
-
-            return true;
-        }
-
-        return false;
-    }
-
-    /**
-     * Transfer items between two ItemStacks, returning the leftover status
-     */
-    private static boolean transferItems(InventoryView view, int fromSlot) {
-        ItemStack from = view.getItem(fromSlot).clone();
-        ItemStack to = view.getItem(Alchemy.INGREDIENT_SLOT).clone();
-
-        if (isEmpty(from)) {
-            return false;
-        } else if (isEmpty(to)) {
-            view.setItem(Alchemy.INGREDIENT_SLOT, from);
-            view.setItem(fromSlot, null);
-
-            return true;
-        } else if (from.isSimilar(to)) {
-            int fromAmount = from.getAmount();
-            int toAmount = to.getAmount();
-            int maxSize = to.getType().getMaxStackSize();
-
-            if (fromAmount + toAmount > maxSize) {
-                int left = fromAmount + toAmount - maxSize;
-
-                to.setAmount(maxSize);
-                view.setItem(Alchemy.INGREDIENT_SLOT, to);
-
-                from.setAmount(left);
-                view.setItem(fromSlot, from);
-
-                return true;
-            }
-
-            to.setAmount(fromAmount + toAmount);
-            view.setItem(fromSlot, null);
-            view.setItem(Alchemy.INGREDIENT_SLOT, to);
-
-            return true;
-        }
-
-        return false;
-    }
-
-    public static void scheduleCheck(Player player, BrewingStand brewingStand) {
-        new AlchemyBrewCheckTask(player, brewingStand).runTask(mcMMO.p);
-    }
-
-    public static void scheduleUpdate(Inventory inventory) {
-        for (HumanEntity humanEntity : inventory.getViewers()) {
-            if (humanEntity instanceof Player) {
-                new PlayerUpdateInventoryTask((Player) humanEntity).runTask(mcMMO.p);
-            }
-        }
-    }
-}

+ 0 - 718
src/main/java/com/gmail/nossr50/skills/alchemy/PotionGenerator.java

@@ -1,718 +0,0 @@
-package com.gmail.nossr50.skills.alchemy;
-
-import com.gmail.nossr50.datatypes.skills.alchemy.AlchemyPotion;
-import com.gmail.nossr50.mcMMO;
-import com.google.common.reflect.TypeToken;
-import org.bukkit.ChatColor;
-import org.bukkit.Color;
-import org.bukkit.Material;
-import org.bukkit.inventory.ItemStack;
-import org.bukkit.potion.PotionData;
-import org.bukkit.potion.PotionEffect;
-import org.bukkit.potion.PotionEffectType;
-import org.bukkit.potion.PotionType;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-public class PotionGenerator {
-    private HashMap<String, AlchemyPotion> potionHashMap;
-
-    public PotionGenerator() {
-        potionHashMap = new HashMap<>();
-        init();
-    }
-
-    private void init() {
-        Map<WriteablePotion, Map<Ingredient, WriteablePotion>> vanillaPotions = new HashMap<>();
-        populateVanillaPotions(vanillaPotions);
-        Map<WriteablePotion, Map<Ingredient, WriteablePotion>> mcMMOPotions = new HashMap<>();
-        populateCustomPotions(mcMMOPotions);
-        List<WriteablePotion> sorted = new ArrayList<>();
-        sorted.addAll(vanillaPotions.keySet());
-        sorted.addAll(mcMMOPotions.keySet());
-
-        sorted.sort((a, b) -> {
-            // All normal potions first
-            if (a.mat == Material.POTION && b.mat != Material.POTION) {
-                return -1;
-            }
-            if (b.mat == Material.POTION && a.mat != Material.POTION) {
-                return 1;
-            }
-            // All splash potions second
-            if (a.mat == Material.SPLASH_POTION && b.mat != Material.SPLASH_POTION) {
-                return -1;
-            }
-            if (b.mat == Material.SPLASH_POTION && a.mat != Material.SPLASH_POTION) {
-                return 1;
-            }
-            // Vanilla Potions first
-            if (a.effect == null && b.effect != null) {
-                return -1;
-            }
-            if (b.effect == null && a.effect != null) {
-                return 1;
-            }
-            // Vanilla potions
-            if (a.effect == null && b.effect == null) {
-                // Order by PotionType
-                if (a.data.getType() != b.data.getType()) {
-                    return Integer.compare(a.data.getType().ordinal(), b.data.getType().ordinal());
-                }
-                // Plain before extended or upgraded
-                if (!a.data.isExtended() && !a.data.isUpgraded() && (b.data.isExtended() || b.data.isUpgraded())) {
-                    return -1;
-                }
-                if (!b.data.isExtended() && !b.data.isUpgraded() && (a.data.isExtended() || a.data.isUpgraded())) {
-                    return 1;
-                }
-                // Extended before Upgraded
-                if (a.data.isExtended() && b.data.isUpgraded()) {
-                    return -1;
-                }
-                if (b.data.isExtended() && a.data.isUpgraded()) {
-                    return -1;
-                }
-                // Same potion somehow?
-                return 0;
-            }
-            // mcMMO Potions
-            else {
-                if ((a.baseName.contains("II") || a.baseName.contains("EXTENDED")) && !(b.baseName.contains("II") || b.baseName.contains("EXTENDED"))) {
-                    return 1;
-                }
-                if ((b.baseName.contains("II") || b.baseName.contains("EXTENDED")) && !(a.baseName.contains("II") || a.baseName.contains("EXTENDED"))) {
-                    return -1;
-                }
-                if (!a.baseName.contains("II") && b.baseName.contains("II")) {
-                    return -1;
-                }
-                if (!b.baseName.contains("II") && a.baseName.contains("II")) {
-                    return 1;
-                }
-                return a.baseName.split("_")[0].compareTo(b.baseName.split("_")[0]);
-            }
-        });
-
-        /* Hacky solution, this entire class disgusts me */
-        HashMap<String, AlchemyPotion> potionHashMap = new HashMap<>();
-
-        for(WriteablePotion potion : sorted)
-        {
-            AlchemyPotion alchemyPotion = convertWriteableToAlchemyPotion(potion);
-            potionHashMap.put(alchemyPotion.getName(), alchemyPotion);
-        }
-
-
-
-
-//        for (WriteablePotion potion : sorted) {
-//            System.out.println("    " + potion.name + ":");
-//            Map<Ingredient, WriteablePotion> children;
-//            if (vanillaPotions.containsKey(potion)) {
-//                children = vanillaPotions.get(potion);
-//            } else {
-//                System.out.println("        Name: " + prettify(potion.name));
-//                children = mcMMOPotions.get(potion);
-//            }
-//            System.out.println("        Material: " + potion.mat.name());
-//            System.out.println("        PotionData:");
-//            System.out.println("            PotionType: " + potion.data.getType().name());
-//            if (potion.data.isExtended()) {
-//                System.out.println("            Extended: true");
-//            }
-//            if (potion.data.isUpgraded()) {
-//                System.out.println("            Upgraded: true");
-//            }
-//            if (potion.effect != null) {
-//                System.out.println("        Effects: [\"" + getName(potion.effect.getType()) + " " + potion.effect.getAmplifier() + " " + potion.effect.getDuration() + "\"]");
-//            }
-//            if (children == null || children.isEmpty()) {
-//                continue;
-//            }
-//            System.out.println("        Children:");
-//            for (Entry<Ingredient, WriteablePotion> child : children.entrySet()) {
-//                System.out.println("            " + child.getKey().name + ": " + child.getValue().name);
-//            }
-//        }
-    }
-
-    /**
-     * I just want anyone who reads this to know
-     * This entire class is an abomination
-     * What you see below is a hacky solution to keep Alchemy functioning with the new config system
-     * Alchemy will be rewritten, until then, this disgusting class exists.
-     * @param writeablePotion target WriteablePotion
-     * @return converted WriteablePotion
-     */
-    private AlchemyPotion convertWriteableToAlchemyPotion(WriteablePotion writeablePotion) {
-        try {
-
-            String name = writeablePotion.name;
-
-            if (name != null) {
-                name = prettify(ChatColor.translateAlternateColorCodes('&', name));
-            }
-
-            PotionData data = writeablePotion.data;
-            Material material = Material.POTION;
-
-            if(writeablePotion.mat != null)
-                material = writeablePotion.mat;
-
-            //Lore is unused as far as I can tell
-            List<String> lore = new ArrayList<>();
-
-            List<PotionEffect> effects = new ArrayList<>();
-            effects.add(writeablePotion.effect);
-
-            Color color = this.generateColor(effects);
-
-
-            return new AlchemyPotion(material, data, name, lore, effects, color, getChildren(writeablePotion));
-        } catch (Exception e) {
-            mcMMO.p.getLogger().warning("Failed to load Alchemy potion: " + potion_section.getString());
-            return null;
-        }
-    }
-
-    public Color generateColor(List<PotionEffect> effects) {
-        if (effects != null && !effects.isEmpty()) {
-            List<Color> colors = new ArrayList<>();
-            for (PotionEffect effect : effects) {
-                if (effect.getType().getColor() != null) {
-                    colors.add(effect.getType().getColor());
-                }
-            }
-            if (!colors.isEmpty()) {
-                if (colors.size() > 1) {
-                    return calculateAverageColor(colors);
-                }
-                return colors.get(0);
-            }
-        }
-        return null;
-    }
-
-    public Color calculateAverageColor(List<Color> colors) {
-        int red = 0;
-        int green = 0;
-        int blue = 0;
-        for (Color color : colors) {
-            red += color.getRed();
-            green += color.getGreen();
-            blue += color.getBlue();
-        }
-        Color color = Color.fromRGB(red / colors.size(), green / colors.size(), blue / colors.size());
-        return color;
-    }
-
-    private static String prettify(String name) {
-        String[] substrings = name.split("_");
-        String prettyString = "";
-        int size = 1;
-
-        for (String string : substrings) {
-            prettyString = prettyString.concat(getCapitalized(string));
-
-            if (size < substrings.length) {
-                prettyString = prettyString.concat(" ");
-            }
-
-            size++;
-        }
-
-        return prettyString;
-    }
-
-    public static String getCapitalized(String target) {
-        if (target.equals("II")) { // hacks
-            return target;
-        }
-        return target.substring(0, 1).toUpperCase() + target.substring(1).toLowerCase();
-    }
-
-    private static String getName(PotionEffectType type) {
-        switch (type.getId()) {
-            case 1:
-                return "SPEED";
-            case 2:
-                return "SLOW";
-            case 3:
-                return "FAST_DIGGING";
-            case 4:
-                return "SLOW_DIGGING";
-            case 5:
-                return "INCREASE_DAMAGE";
-            case 6:
-                return "HEAL";
-            case 7:
-                return "HARM";
-            case 8:
-                return "JUMP";
-            case 9:
-                return "CONFUSION";
-            case 10:
-                return "REGENERATION";
-            case 11:
-                return "DAMAGE_RESISTANCE";
-            case 12:
-                return "FIRE_RESISTANCE";
-            case 13:
-                return "WATER_BREATHING";
-            case 14:
-                return "INVISIBILITY";
-            case 15:
-                return "BLINDNESS";
-            case 16:
-                return "NIGHT_VISION";
-            case 17:
-                return "HUNGER";
-            case 18:
-                return "WEAKNESS";
-            case 19:
-                return "POISON";
-            case 20:
-                return "WITHER";
-            case 21:
-                return "HEALTH_BOOST";
-            case 22:
-                return "ABSORPTION";
-            case 23:
-                return "SATURATION";
-            case 24:
-                return "GLOWING";
-            case 25:
-                return "LEVITATION";
-            case 26:
-                return "LUCK";
-            case 27:
-                return "UNLUCK";
-            case 28:
-                return "SLOW_FALLING";
-            case 29:
-                return "CONDUIT_POWER";
-            case 30:
-                return "DOLPHINS_GRACE";
-            default:
-                return "UNKNOWN_EFFECT_TYPE_" + type.getId();
-        }
-    }
-
-    private void populateVanillaPotions(Map<WriteablePotion, Map<Ingredient, WriteablePotion>> vanillaPotions) {
-        for (PotionType type : PotionType.values()) {
-            for (Material material : new Material[]{Material.POTION, Material.SPLASH_POTION, Material.LINGERING_POTION}) {
-                WriteablePotion writeablePotion = new WriteablePotion(material, type);
-                getChildren(writeablePotion);
-                vanillaPotions.put(writeablePotion, getChildren(writeablePotion));
-                if (type.isExtendable()) {
-                    writeablePotion = new WriteablePotion(material, new PotionData(type, true, false));
-                    vanillaPotions.put(writeablePotion, getChildren(writeablePotion));
-                }
-                if (type.isUpgradeable()) {
-                    writeablePotion = new WriteablePotion(material, new PotionData(type, false, true));
-                    vanillaPotions.put(writeablePotion, getChildren(writeablePotion));
-                }
-            }
-        }
-        for (Entry<WriteablePotion, Map<Ingredient, WriteablePotion>> entry : vanillaPotions.entrySet()) {
-            if (entry.getKey().mat == Material.POTION) {
-                entry.getValue().put(new Ingredient(Material.GUNPOWDER), new WriteablePotion(Material.SPLASH_POTION, entry.getKey().data));
-            }
-            if (entry.getKey().mat == Material.SPLASH_POTION) {
-                entry.getValue().put(new Ingredient(Material.DRAGON_BREATH), new WriteablePotion(Material.LINGERING_POTION, entry.getKey().data));
-            }
-        }
-
-        //Store children
-    }
-
-    private HashMap<Ingredient, WriteablePotion> getChildren(WriteablePotion writeablePotion) {
-        HashMap<Ingredient, WriteablePotion> children = new HashMap<>();
-
-        switch (writeablePotion.data.getType()) {
-            case WATER:
-                assert (!writeablePotion.data.isExtended());
-                assert (!writeablePotion.data.isUpgraded());
-                children.put(new Ingredient(Material.NETHER_WART), new WriteablePotion(writeablePotion.mat, PotionType.AWKWARD));
-                children.put(new Ingredient(Material.FERMENTED_SPIDER_EYE), new WriteablePotion(writeablePotion.mat, PotionType.WEAKNESS));
-                children.put(new Ingredient(Material.REDSTONE), new WriteablePotion(writeablePotion.mat, PotionType.MUNDANE));
-                children.put(new Ingredient(Material.GLOWSTONE_DUST), new WriteablePotion(writeablePotion.mat, PotionType.THICK));
-                children.put(new Ingredient(Material.BLAZE_POWDER), new WriteablePotion(writeablePotion.mat, PotionType.MUNDANE));
-                children.put(new Ingredient(Material.SUGAR), new WriteablePotion(writeablePotion.mat, PotionType.MUNDANE));
-                children.put(new Ingredient(Material.RABBIT_FOOT), new WriteablePotion(writeablePotion.mat, PotionType.MUNDANE));
-                children.put(new Ingredient(Material.SPIDER_EYE), new WriteablePotion(writeablePotion.mat, PotionType.MUNDANE));
-                children.put(new Ingredient(Material.MAGMA_CREAM), new WriteablePotion(writeablePotion.mat, PotionType.MUNDANE));
-                children.put(new Ingredient(Material.GLISTERING_MELON_SLICE), new WriteablePotion(writeablePotion.mat, PotionType.MUNDANE));
-                children.put(new Ingredient(Material.GHAST_TEAR), new WriteablePotion(writeablePotion.mat, PotionType.MUNDANE));
-                return children;
-            case AWKWARD:
-                assert (!writeablePotion.data.isExtended());
-                assert (!writeablePotion.data.isUpgraded());
-                children.put(new Ingredient(Material.GOLDEN_CARROT), new WriteablePotion(writeablePotion.mat, PotionType.NIGHT_VISION));
-                children.put(new Ingredient(Material.RABBIT_FOOT), new WriteablePotion(writeablePotion.mat, PotionType.JUMP));
-                children.put(new Ingredient(Material.MAGMA_CREAM), new WriteablePotion(writeablePotion.mat, PotionType.FIRE_RESISTANCE));
-                children.put(new Ingredient(Material.SUGAR), new WriteablePotion(writeablePotion.mat, PotionType.SPEED));
-                children.put(new Ingredient(Material.PUFFERFISH), new WriteablePotion(writeablePotion.mat, PotionType.WATER_BREATHING));
-                children.put(new Ingredient(Material.GLISTERING_MELON_SLICE), new WriteablePotion(writeablePotion.mat, PotionType.INSTANT_HEAL));
-                children.put(new Ingredient(Material.SPIDER_EYE), new WriteablePotion(writeablePotion.mat, PotionType.POISON));
-                children.put(new Ingredient(Material.GHAST_TEAR), new WriteablePotion(writeablePotion.mat, PotionType.REGEN));
-                children.put(new Ingredient(Material.BLAZE_POWDER), new WriteablePotion(writeablePotion.mat, PotionType.STRENGTH));
-                children.put(new Ingredient(Material.TURTLE_HELMET), new WriteablePotion(writeablePotion.mat, PotionType.TURTLE_MASTER));
-                children.put(new Ingredient(Material.PHANTOM_MEMBRANE), new WriteablePotion(writeablePotion.mat, PotionType.SLOW_FALLING));
-                // mcMMO custom potions
-                double mod = 1;
-                if (writeablePotion.mat == Material.SPLASH_POTION) {
-                    mod = 0.75;
-                }
-                if (writeablePotion.mat == Material.LINGERING_POTION) {
-                    mod = 0.25;
-                }
-                children.put(new Ingredient(Material.BROWN_MUSHROOM), new WriteablePotion(writeablePotion.mat, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.CONFUSION, (int) (450 * mod), 0), "NAUSEA"));
-                children.put(new Ingredient(Material.CARROT), new WriteablePotion(writeablePotion.mat, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.FAST_DIGGING, (int) (3600 * mod), 0), "HASTE"));
-                children.put(new Ingredient(Material.SLIME_BALL), new WriteablePotion(writeablePotion.mat, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.SLOW_DIGGING, (int) (3600 * mod), 0), "DULLNESS"));
-                children.put(new Ingredient(Material.GOLDEN_APPLE), new WriteablePotion(writeablePotion.mat, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.DAMAGE_RESISTANCE, (int) (450 * mod), 0), "RESISTANCE"));
-                children.put(new Ingredient(Material.INK_SAC), new WriteablePotion(writeablePotion.mat, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.BLINDNESS, (int) (225 * mod), 0), "BLINDNESS"));
-                children.put(new Ingredient(Material.ROTTEN_FLESH), new WriteablePotion(writeablePotion.mat, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.HUNGER, (int) (900 * mod), 0), "HUNGER"));
-                children.put(new Ingredient(Material.POISONOUS_POTATO), new WriteablePotion(writeablePotion.mat, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.WITHER, (int) (450 * mod), 0), "DECAY"));
-                children.put(new Ingredient(Material.QUARTZ), new WriteablePotion(writeablePotion.mat, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.ABSORPTION, (int) (1800 * mod), 0), "ABSORPTION"));
-                children.put(new Ingredient(Material.FERN), new WriteablePotion(writeablePotion.mat, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.SATURATION, (int) (8 * mod), 0), "SATURATION"));
-                children.put(new Ingredient(Material.APPLE), new WriteablePotion(writeablePotion.mat, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.HEALTH_BOOST, (int) (1800 * mod), 0), "HEALTH_BOOST"));
-                return children;
-            case FIRE_RESISTANCE:
-                assert (!writeablePotion.data.isUpgraded());
-                if (writeablePotion.data.isExtended()) {
-                    children.put(new Ingredient(Material.FERMENTED_SPIDER_EYE), new WriteablePotion(writeablePotion.mat, new PotionData(PotionType.SLOWNESS, true, false)));
-                } else {
-                    children.put(new Ingredient(Material.FERMENTED_SPIDER_EYE), new WriteablePotion(writeablePotion.mat, PotionType.SLOWNESS));
-                    children.put(new Ingredient(Material.REDSTONE), new WriteablePotion(writeablePotion.mat, new PotionData(writeablePotion.data.getType(), true, false)));
-                }
-                return children;
-            case INSTANT_DAMAGE:
-                assert (!writeablePotion.data.isExtended());
-                if (!writeablePotion.data.isUpgraded()) {
-                    children.put(new Ingredient(Material.GLOWSTONE_DUST), new WriteablePotion(writeablePotion.mat, new PotionData(writeablePotion.data.getType(), false, true)));
-                }
-                return children;
-            case INSTANT_HEAL:
-                assert (!writeablePotion.data.isExtended());
-                if (!writeablePotion.data.isUpgraded()) {
-                    children.put(new Ingredient(Material.FERMENTED_SPIDER_EYE), new WriteablePotion(writeablePotion.mat, PotionType.INSTANT_DAMAGE));
-                    children.put(new Ingredient(Material.GLOWSTONE_DUST), new WriteablePotion(writeablePotion.mat, new PotionData(writeablePotion.data.getType(), false, true)));
-                } else {
-                    children.put(new Ingredient(Material.FERMENTED_SPIDER_EYE), new WriteablePotion(writeablePotion.mat, new PotionData(PotionType.INSTANT_DAMAGE, false, true)));
-                }
-                return children;
-            case INVISIBILITY:
-                assert (!writeablePotion.data.isUpgraded());
-                if (!writeablePotion.data.isExtended()) {
-                    children.put(new Ingredient(Material.REDSTONE), new WriteablePotion(writeablePotion.mat, new PotionData(writeablePotion.data.getType(), true, false)));
-                }
-                return children;
-            case JUMP:
-                if (!writeablePotion.data.isUpgraded() && !writeablePotion.data.isExtended()) {
-                    children.put(new Ingredient(Material.FERMENTED_SPIDER_EYE), new WriteablePotion(writeablePotion.mat, PotionType.SLOWNESS));
-                    children.put(new Ingredient(Material.GLOWSTONE_DUST), new WriteablePotion(writeablePotion.mat, new PotionData(writeablePotion.data.getType(), false, true)));
-                    children.put(new Ingredient(Material.REDSTONE), new WriteablePotion(writeablePotion.mat, new PotionData(writeablePotion.data.getType(), true, false)));
-                }
-                return children;
-            case NIGHT_VISION:
-                assert (!writeablePotion.data.isUpgraded());
-                if (!writeablePotion.data.isExtended()) {
-                    children.put(new Ingredient(Material.FERMENTED_SPIDER_EYE), new WriteablePotion(writeablePotion.mat, PotionType.INVISIBILITY));
-                    children.put(new Ingredient(Material.REDSTONE), new WriteablePotion(writeablePotion.mat, new PotionData(writeablePotion.data.getType(), true, false)));
-                } else {
-                    children.put(new Ingredient(Material.FERMENTED_SPIDER_EYE), new WriteablePotion(writeablePotion.mat, new PotionData(PotionType.INVISIBILITY, true, false)));
-                }
-                return children;
-            case POISON:
-                if (!writeablePotion.data.isUpgraded() && !writeablePotion.data.isExtended()) {
-                    children.put(new Ingredient(Material.FERMENTED_SPIDER_EYE), new WriteablePotion(writeablePotion.mat, PotionType.INSTANT_DAMAGE));
-                    children.put(new Ingredient(Material.GLOWSTONE_DUST), new WriteablePotion(writeablePotion.mat, new PotionData(writeablePotion.data.getType(), false, true)));
-                    children.put(new Ingredient(Material.REDSTONE), new WriteablePotion(writeablePotion.mat, new PotionData(writeablePotion.data.getType(), true, false)));
-                } else {
-                    children.put(new Ingredient(Material.FERMENTED_SPIDER_EYE), new WriteablePotion(writeablePotion.mat, new PotionData(PotionType.INSTANT_DAMAGE, false, true)));
-                }
-                return children;
-            case REGEN:
-                if (!writeablePotion.data.isUpgraded() && !writeablePotion.data.isExtended()) {
-                    children.put(new Ingredient(Material.GLOWSTONE_DUST), new WriteablePotion(writeablePotion.mat, new PotionData(writeablePotion.data.getType(), false, true)));
-                    children.put(new Ingredient(Material.REDSTONE), new WriteablePotion(writeablePotion.mat, new PotionData(writeablePotion.data.getType(), true, false)));
-                }
-                return children;
-            case SLOWNESS:
-                assert (!writeablePotion.data.isUpgraded());
-                if (!writeablePotion.data.isExtended()) {
-                    children.put(new Ingredient(Material.REDSTONE), new WriteablePotion(writeablePotion.mat, new PotionData(writeablePotion.data.getType(), true, false)));
-                }
-                return children;
-            case SLOW_FALLING:
-                assert (!writeablePotion.data.isUpgraded());
-                if (!writeablePotion.data.isExtended()) {
-                    children.put(new Ingredient(Material.REDSTONE), new WriteablePotion(writeablePotion.mat, new PotionData(writeablePotion.data.getType(), true, false)));
-                }
-                return children;
-            case SPEED:
-                if (!writeablePotion.data.isUpgraded() && !writeablePotion.data.isExtended()) {
-                    children.put(new Ingredient(Material.FERMENTED_SPIDER_EYE), new WriteablePotion(writeablePotion.mat, PotionType.SLOWNESS));
-                    children.put(new Ingredient(Material.GLOWSTONE_DUST), new WriteablePotion(writeablePotion.mat, new PotionData(writeablePotion.data.getType(), false, true)));
-                    children.put(new Ingredient(Material.REDSTONE), new WriteablePotion(writeablePotion.mat, new PotionData(writeablePotion.data.getType(), true, false)));
-                } else {
-                    children.put(new Ingredient(Material.FERMENTED_SPIDER_EYE), new WriteablePotion(writeablePotion.mat, new PotionData(PotionType.SLOWNESS, true, false)));
-                }
-                return children;
-            case STRENGTH:
-                if (!writeablePotion.data.isUpgraded() && !writeablePotion.data.isExtended()) {
-                    children.put(new Ingredient(Material.GLOWSTONE_DUST), new WriteablePotion(writeablePotion.mat, new PotionData(writeablePotion.data.getType(), false, true)));
-                    children.put(new Ingredient(Material.REDSTONE), new WriteablePotion(writeablePotion.mat, new PotionData(writeablePotion.data.getType(), true, false)));
-                }
-                return children;
-            case TURTLE_MASTER:
-                if (!writeablePotion.data.isUpgraded() && !writeablePotion.data.isExtended()) {
-                    children.put(new Ingredient(Material.GLOWSTONE_DUST), new WriteablePotion(writeablePotion.mat, new PotionData(writeablePotion.data.getType(), false, true)));
-                    children.put(new Ingredient(Material.REDSTONE), new WriteablePotion(writeablePotion.mat, new PotionData(writeablePotion.data.getType(), true, false)));
-                }
-                return children;
-            case WATER_BREATHING:
-                assert (!writeablePotion.data.isUpgraded());
-                if (!writeablePotion.data.isExtended()) {
-                    children.put(new Ingredient(Material.FERMENTED_SPIDER_EYE), new WriteablePotion(writeablePotion.mat, PotionType.INSTANT_DAMAGE));
-                    children.put(new Ingredient(Material.REDSTONE), new WriteablePotion(writeablePotion.mat, new PotionData(writeablePotion.data.getType(), true, false)));
-                }
-                return children;
-            case WEAKNESS:
-                assert (!writeablePotion.data.isUpgraded());
-                if (!writeablePotion.data.isExtended()) {
-                    children.put(new Ingredient(Material.REDSTONE), new WriteablePotion(writeablePotion.mat, new PotionData(writeablePotion.data.getType(), true, false)));
-                }
-                return children;
-            case LUCK:
-            case MUNDANE:
-            case THICK:
-            case UNCRAFTABLE:
-                assert (!writeablePotion.data.isExtended());
-                assert (!writeablePotion.data.isUpgraded());
-                return children;
-            default:
-                return children;
-        }
-    }
-
-    private static void populateCustomPotions(Map<WriteablePotion, Map<Ingredient, WriteablePotion>> mcMMOPotions) {
-        for (Material material : new Material[]{Material.POTION, Material.SPLASH_POTION, Material.LINGERING_POTION}) {
-            WriteablePotion data;
-            double mod = 1;
-            if (material == Material.SPLASH_POTION) {
-                mod = 0.75;
-            }
-            if (material == Material.LINGERING_POTION) {
-                mod = 0.25;
-            }
-            HashMap<Ingredient, WriteablePotion> children;
-            data = new WriteablePotion(material, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.CONFUSION, (int) (450 * mod), 0), "NAUSEA");
-            children = new HashMap<>();
-            children.put(new Ingredient(Material.GLOWSTONE_DUST), new WriteablePotion(material, PotionType.UNCRAFTABLE, new PotionEffect(data.effect.getType(), data.effect.getDuration() / 2, 1), data.baseName + "_II"));
-            children.put(new Ingredient(Material.REDSTONE), new WriteablePotion(material, PotionType.UNCRAFTABLE, new PotionEffect(data.effect.getType(), data.effect.getDuration() * 2, 0), data.baseName + "_EXTENDED"));
-            for (WriteablePotion child : children.values()) {
-                mcMMOPotions.put(child, new HashMap<>());
-            }
-            mcMMOPotions.put(data, children);
-            data = new WriteablePotion(material, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.FAST_DIGGING, (int) (3600 * mod), 0), "HASTE");
-            children = new HashMap<>();
-            children.put(new Ingredient(Material.GLOWSTONE_DUST), new WriteablePotion(material, PotionType.UNCRAFTABLE, new PotionEffect(data.effect.getType(), data.effect.getDuration() / 2, 1), data.baseName + "_II"));
-            children.put(new Ingredient(Material.REDSTONE), new WriteablePotion(material, PotionType.UNCRAFTABLE, new PotionEffect(data.effect.getType(), data.effect.getDuration() * 2, 0), data.baseName + "_EXTENDED"));
-            for (WriteablePotion child : children.values()) {
-                mcMMOPotions.put(child, new HashMap<>());
-            }
-            mcMMOPotions.put(data, children);
-            data = new WriteablePotion(material, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.SLOW_DIGGING, (int) (3600 * mod), 0), "DULLNESS");
-            children = new HashMap<>();
-            children.put(new Ingredient(Material.GLOWSTONE_DUST), new WriteablePotion(material, PotionType.UNCRAFTABLE, new PotionEffect(data.effect.getType(), data.effect.getDuration() / 2, 1), data.baseName + "_II"));
-            children.put(new Ingredient(Material.REDSTONE), new WriteablePotion(material, PotionType.UNCRAFTABLE, new PotionEffect(data.effect.getType(), data.effect.getDuration() * 2, 0), data.baseName + "_EXTENDED"));
-            for (WriteablePotion child : children.values()) {
-                mcMMOPotions.put(child, new HashMap<>());
-            }
-            mcMMOPotions.put(data, children);
-            data = new WriteablePotion(material, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.DAMAGE_RESISTANCE, (int) (450 * mod), 0), "RESISTANCE");
-            children = new HashMap<>();
-            children.put(new Ingredient(Material.GLOWSTONE_DUST), new WriteablePotion(material, PotionType.UNCRAFTABLE, new PotionEffect(data.effect.getType(), data.effect.getDuration() / 2, 1), data.baseName + "_II"));
-            children.put(new Ingredient(Material.REDSTONE), new WriteablePotion(material, PotionType.UNCRAFTABLE, new PotionEffect(data.effect.getType(), data.effect.getDuration() * 2, 0), data.baseName + "_EXTENDED"));
-            for (WriteablePotion child : children.values()) {
-                mcMMOPotions.put(child, new HashMap<>());
-            }
-            mcMMOPotions.put(data, children);
-            data = new WriteablePotion(material, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.BLINDNESS, (int) (225 * mod), 0), "BLINDNESS");
-            children = new HashMap<>();
-            children.put(new Ingredient(Material.GLOWSTONE_DUST), new WriteablePotion(material, PotionType.UNCRAFTABLE, new PotionEffect(data.effect.getType(), data.effect.getDuration() / 2, 1), data.baseName + "_II"));
-            children.put(new Ingredient(Material.REDSTONE), new WriteablePotion(material, PotionType.UNCRAFTABLE, new PotionEffect(data.effect.getType(), data.effect.getDuration() * 2, 0), data.baseName + "_EXTENDED"));
-            for (WriteablePotion child : children.values()) {
-                mcMMOPotions.put(child, new HashMap<>());
-            }
-            mcMMOPotions.put(data, children);
-            data = new WriteablePotion(material, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.HUNGER, (int) (900 * mod), 0), "HUNGER");
-            children = new HashMap<>();
-            children.put(new Ingredient(Material.GLOWSTONE_DUST), new WriteablePotion(material, PotionType.UNCRAFTABLE, new PotionEffect(data.effect.getType(), data.effect.getDuration() / 2, 1), data.baseName + "_II"));
-            children.put(new Ingredient(Material.REDSTONE), new WriteablePotion(material, PotionType.UNCRAFTABLE, new PotionEffect(data.effect.getType(), data.effect.getDuration() * 2, 0), data.baseName + "_EXTENDED"));
-            for (WriteablePotion child : children.values()) {
-                mcMMOPotions.put(child, new HashMap<>());
-            }
-            mcMMOPotions.put(data, children);
-            data = new WriteablePotion(material, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.WITHER, (int) (450 * mod), 0), "DECAY");
-            children = new HashMap<>();
-            children.put(new Ingredient(Material.GLOWSTONE_DUST), new WriteablePotion(material, PotionType.UNCRAFTABLE, new PotionEffect(data.effect.getType(), data.effect.getDuration() / 2, 1), data.baseName + "_II"));
-            children.put(new Ingredient(Material.REDSTONE), new WriteablePotion(material, PotionType.UNCRAFTABLE, new PotionEffect(data.effect.getType(), data.effect.getDuration() * 2, 0), data.baseName + "_EXTENDED"));
-            for (WriteablePotion child : children.values()) {
-                mcMMOPotions.put(child, new HashMap<>());
-            }
-            mcMMOPotions.put(data, children);
-            data = new WriteablePotion(material, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.ABSORPTION, (int) (1800 * mod), 0), "ABSORPTION");
-            children = new HashMap<>();
-            children.put(new Ingredient(Material.GLOWSTONE_DUST), new WriteablePotion(material, PotionType.UNCRAFTABLE, new PotionEffect(data.effect.getType(), data.effect.getDuration() / 2, 1), data.baseName + "_II"));
-            children.put(new Ingredient(Material.REDSTONE), new WriteablePotion(material, PotionType.UNCRAFTABLE, new PotionEffect(data.effect.getType(), data.effect.getDuration() * 2, 0), data.baseName + "_EXTENDED"));
-            for (WriteablePotion child : children.values()) {
-                mcMMOPotions.put(child, new HashMap<>());
-            }
-            mcMMOPotions.put(data, children);
-            data = new WriteablePotion(material, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.SATURATION, (int) (8 * mod), 0), "SATURATION");
-            children = new HashMap<>();
-            children.put(new Ingredient(Material.GLOWSTONE_DUST), new WriteablePotion(material, PotionType.UNCRAFTABLE, new PotionEffect(data.effect.getType(), data.effect.getDuration() / 2, 1), data.baseName + "_II"));
-            children.put(new Ingredient(Material.REDSTONE), new WriteablePotion(material, PotionType.UNCRAFTABLE, new PotionEffect(data.effect.getType(), data.effect.getDuration() * 2, 0), data.baseName + "_EXTENDED"));
-            for (WriteablePotion child : children.values()) {
-                mcMMOPotions.put(child, new HashMap<>());
-            }
-            mcMMOPotions.put(data, children);
-            data = new WriteablePotion(material, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.HEALTH_BOOST, (int) (1800 * mod), 0), "HEALTH_BOOST");
-            children = new HashMap<>();
-            children.put(new Ingredient(Material.GLOWSTONE_DUST), new WriteablePotion(material, PotionType.UNCRAFTABLE, new PotionEffect(data.effect.getType(), data.effect.getDuration() / 2, 1), data.baseName + "_II"));
-            children.put(new Ingredient(Material.REDSTONE), new WriteablePotion(material, PotionType.UNCRAFTABLE, new PotionEffect(data.effect.getType(), data.effect.getDuration() * 2, 0), data.baseName + "_EXTENDED"));
-            for (WriteablePotion child : children.values()) {
-                mcMMOPotions.put(child, new HashMap<>());
-            }
-            mcMMOPotions.put(data, children);
-        }
-
-        // Add all material state changes
-        for (Entry<WriteablePotion, Map<Ingredient, WriteablePotion>> entry : mcMMOPotions.entrySet()) {
-            if (entry.getKey().mat == Material.POTION) {
-                PotionEffect effect = new PotionEffect(entry.getKey().effect.getType(), (int) (entry.getKey().effect.getDuration() * 0.75), entry.getKey().effect.getAmplifier());
-                entry.getValue().put(new Ingredient(Material.GUNPOWDER), new WriteablePotion(Material.SPLASH_POTION, entry.getKey().data, effect, entry.getKey().baseName));
-            } else if (entry.getKey().mat == Material.SPLASH_POTION) {
-                PotionEffect effect = new PotionEffect(entry.getKey().effect.getType(), (int) (entry.getKey().effect.getDuration() * 0.33), entry.getKey().effect.getAmplifier());
-                entry.getValue().put(new Ingredient(Material.DRAGON_BREATH), new WriteablePotion(Material.LINGERING_POTION, entry.getKey().data, effect, entry.getKey().baseName));
-            }
-        }
-    }
-
-    public static class Ingredient {
-
-        public Material mat;
-        public int data;
-        public String name;
-
-        public Ingredient(Material mat) {
-            this.mat = mat;
-            this.data = 0;
-            name = mat.name();
-        }
-
-    }
-
-    public static class WriteablePotion {
-
-        public String name;
-        public Material mat;
-        public PotionData data;
-        public PotionEffect effect;
-        public String baseName;
-
-        public WriteablePotion(PotionData data) {
-            this(Material.POTION, data);
-        }
-
-        public WriteablePotion(Material type, PotionData data) {
-            this(type, data, null, getMCName(data.getType()));
-        }
-
-        public WriteablePotion(Material mat, PotionType type, PotionEffect effect, String baseName) {
-            this(mat, new PotionData(type, false, false), effect, baseName);
-        }
-
-        public WriteablePotion(Material type, PotionData data, PotionEffect effect, String baseName) {
-            this.data = data;
-            this.effect = effect;
-            this.mat = type;
-            this.baseName = baseName;
-            this.name = "POTION_OF_" + baseName;
-            if (mat == Material.SPLASH_POTION) {
-                this.name = "SPLASH_" + this.name;
-            }
-            if (mat == Material.LINGERING_POTION) {
-                this.name = "LINGERING_" + this.name;
-            }
-            if (data.isExtended()) {
-                this.name += "_EXTENDED";
-            }
-            if (data.isUpgraded()) {
-                this.name += "_II";
-            }
-        }
-
-        public WriteablePotion(PotionType type) {
-            this(new PotionData(type, false, false));
-        }
-
-        public WriteablePotion(Material mat, PotionType type) {
-            this(mat, new PotionData(type, false, false));
-        }
-
-        private static String getMCName(PotionType type) {
-            switch (type) {
-                case INSTANT_DAMAGE:
-                    return "HARMING";
-                case INSTANT_HEAL:
-                    return "HEALING";
-                case JUMP:
-                    return "LEAPING";
-                case REGEN:
-                    return "REGENERATION";
-                case SPEED:
-                    return "SWIFTNESS";
-                case UNCRAFTABLE:
-                    return "EMPTY";
-                case LUCK:
-                case MUNDANE:
-                case NIGHT_VISION:
-                case POISON:
-                case INVISIBILITY:
-                case SLOWNESS:
-                case AWKWARD:
-                case STRENGTH:
-                case THICK:
-                case FIRE_RESISTANCE:
-                case WATER:
-                case WATER_BREATHING:
-                case WEAKNESS:
-                case TURTLE_MASTER:
-                case SLOW_FALLING:
-                    return type.name();
-                default:
-                    return "";
-            }
-        }
-
-        public int hashCode() {
-            return name.hashCode();
-        }
-
-        public boolean equals(Object obj) {
-            if (!(obj instanceof WriteablePotion)) {
-                return false;
-            }
-            return name.equals(((WriteablePotion) obj).name);
-        }
-    }
-}

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

@@ -52,7 +52,7 @@ public final class CommandRegistrationManager {
                     break;
 
                 case ALCHEMY:
-                    command.setExecutor(new AlchemyCommand());
+//                    command.setExecutor(new AlchemyCommand());
                     break;
 
                 case ARCHERY: