Browse Source

Fixing Alchemy Part 1

nossr50 6 years ago
parent
commit
774ee65677

+ 1 - 0
Changelog.txt

@@ -31,6 +31,7 @@ Version 2.2.0
     Added new locale string 'Commands.Reload.Finished'
     Added new permission 'mcmmo.commands.reload'
     NOTE: Not every config key that was renamed will be listed here
+    Lily pads were removed from the Alchemy Ingredient list as they are unused
     Admins will now be notified if a player trips over-fishing exploit detection 3+ times in a row (Locale: "Fishing.OverFishingDetected")
         Note: Admins are players who are op or have adminchat permission.
 

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

@@ -40,7 +40,7 @@ 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.PotionConfig;
+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,6 +93,7 @@ public final class ConfigManager {
     /* MISC MANAGERS */
     private TypeSerializerCollection customSerializers;
     private ExperienceMapManager experienceMapManager;
+    private PotionManager potionManager;
 
     /* CONFIG INSTANCES */
 
@@ -141,7 +142,7 @@ public final class ConfigManager {
     private SerializedConfigLoader<ConfigPartyData> partyData;
 
     //YAML CONFIGS
-    private PotionConfig potionConfig;
+
 
     private MainConfig mainConfig;
     private FishingTreasureConfig fishingTreasureConfig;
@@ -196,7 +197,7 @@ public final class ConfigManager {
     }
 
     private void initYAMLConfigs() {
-        potionConfig = new PotionConfig();
+
     }
 
     private void initSerializedDataFiles() {
@@ -332,6 +333,7 @@ public final class ConfigManager {
         //Set the global XP val
         experienceMapManager.setGlobalXpMult(getConfigExperience().getGlobalXPMultiplier());
         experienceMapManager.buildBlockXPMaps(); //Block XP value maps
+        potionManager = new PotionManager();
     }
 
     /**
@@ -468,8 +470,8 @@ public final class ConfigManager {
         return advancedConfig;
     }
 
-    public PotionConfig getPotionConfig() {
-        return potionConfig;
+    public PotionManager getPotionManager() {
+        return potionManager;
     }
 
     public CoreSkillsConfig getCoreSkillsConfig() {

+ 0 - 356
src/main/java/com/gmail/nossr50/config/skills/alchemy/PotionConfig.java

@@ -1,356 +0,0 @@
-package com.gmail.nossr50.config.skills.alchemy;
-
-import com.gmail.nossr50.config.ConfigCollection;
-import com.gmail.nossr50.config.ConfigConstants;
-import com.gmail.nossr50.datatypes.skills.alchemy.AlchemyPotion;
-import com.gmail.nossr50.mcMMO;
-import com.google.common.reflect.TypeToken;
-import ninja.leaping.configurate.ConfigurationNode;
-import ninja.leaping.configurate.objectmapping.ObjectMappingException;
-import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
-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;
-
-/**
- * Eventually I'm going to delete all of our Alchemy code and rewrite it from scratch
- */
-@ConfigSerializable
-public class PotionConfig extends ConfigCollection {
-
-    /* CONSTANTS */
-
-    public static final String CONCOCTIONS = "Concoctions";
-    public static final String TIER_ONE_INGREDIENTS = "Tier_One_Ingredients";
-    public static final String TIER_TWO_INGREDIENTS = "Tier_Two_Ingredients";
-    public static final String TIER_THREE_INGREDIENTS = "Tier_Three_Ingredients";
-    public static final String TIER_FOUR_INGREDIENTS = "Tier_Four_Ingredients";
-    public static final String TIER_FIVE_INGREDIENTS = "Tier_Five_Ingredients";
-    public static final String TIER_SIX_INGREDIENTS = "Tier_Six_Ingredients";
-    public static final String TIER_SEVEN_INGREDIENTS = "Tier_Seven_Ingredients";
-    public static final String TIER_EIGHT_INGREDIENTS = "Tier_Eight_Ingredients";
-    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> concoctionsIngredientsTierOne;
-    private List<ItemStack> concoctionsIngredientsTierTwo;
-    private List<ItemStack> concoctionsIngredientsTierThree;
-    private List<ItemStack> concoctionsIngredientsTierFour;
-    private List<ItemStack> concoctionsIngredientsTierFive;
-    private List<ItemStack> concoctionsIngredientsTierSix;
-    private List<ItemStack> concoctionsIngredientsTierSeven;
-    private List<ItemStack> concoctionsIngredientsTierEight;
-
-    private Map<String, AlchemyPotion> potionMap = new HashMap<>();
-
-    public PotionConfig() {
-        super("skillranks", mcMMO.p.getDataFolder().getAbsoluteFile(), ConfigConstants.RELATIVE_PATH_CONFIG_DIR, true, true, true, true);
-        initIngredientLists();
-        register();
-    }
-
-    /**
-     * 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 PotionConfig getInstance() {
-        return mcMMO.getConfigManager().getPotionConfig();
-    }
-
-    @Override
-    public void unload() {
-        potionMap.clear();
-    }
-
-    private void initIngredientLists() {
-        concoctionsIngredientsTierOne = new ArrayList<>();
-        concoctionsIngredientsTierTwo = new ArrayList<>();
-        concoctionsIngredientsTierThree = new ArrayList<>();
-        concoctionsIngredientsTierFour = new ArrayList<>();
-        concoctionsIngredientsTierFive = new ArrayList<>();
-        concoctionsIngredientsTierSix = new ArrayList<>();
-        concoctionsIngredientsTierSeven = new ArrayList<>();
-        concoctionsIngredientsTierEight = new ArrayList<>();
-    }
-
-    /**
-     * The version of this config
-     *
-     * @return
-     */
-    @Override
-    public double getConfigVersion() {
-        return 1;
-    }
-
-    @Override
-    public void register() {
-        loadConcoctions();
-        loadPotionMap();
-    }
-
-    private void loadConcoctions() {
-        try {
-            //TODO: Rewrite this
-            loadConcoctionsTier(concoctionsIngredientsTierOne, getListFromNode(CONCOCTIONS, TIER_ONE_INGREDIENTS));
-            loadConcoctionsTier(concoctionsIngredientsTierTwo, getListFromNode(CONCOCTIONS, TIER_TWO_INGREDIENTS));
-            loadConcoctionsTier(concoctionsIngredientsTierThree, getListFromNode(CONCOCTIONS, TIER_THREE_INGREDIENTS));
-            loadConcoctionsTier(concoctionsIngredientsTierFour, getListFromNode(CONCOCTIONS, TIER_FOUR_INGREDIENTS));
-            loadConcoctionsTier(concoctionsIngredientsTierFive, getListFromNode(CONCOCTIONS, TIER_FIVE_INGREDIENTS));
-            loadConcoctionsTier(concoctionsIngredientsTierSix, getListFromNode(CONCOCTIONS, TIER_SIX_INGREDIENTS));
-            loadConcoctionsTier(concoctionsIngredientsTierSeven, getListFromNode(CONCOCTIONS, TIER_SEVEN_INGREDIENTS));
-            loadConcoctionsTier(concoctionsIngredientsTierEight, getListFromNode(CONCOCTIONS, TIER_EIGHT_INGREDIENTS));
-
-            concoctionsIngredientsTierTwo.addAll(concoctionsIngredientsTierOne);
-            concoctionsIngredientsTierThree.addAll(concoctionsIngredientsTierTwo);
-            concoctionsIngredientsTierFour.addAll(concoctionsIngredientsTierThree);
-            concoctionsIngredientsTierFive.addAll(concoctionsIngredientsTierFour);
-            concoctionsIngredientsTierSix.addAll(concoctionsIngredientsTierFive);
-            concoctionsIngredientsTierSeven.addAll(concoctionsIngredientsTierSix);
-            concoctionsIngredientsTierEight.addAll(concoctionsIngredientsTierSeven);
-        } catch (ObjectMappingException e) {
-            e.printStackTrace();
-        }
-    }
-
-    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);
-                }
-            }
-        }
-    }
-
-    /**
-     * Find the Potions configuration section and load all defined potions.
-     */
-    private void loadPotionMap() {
-        //ConfigurationSection potionSection = config.getConfigurationSection("Potions");
-        int pass = 0;
-        int fail = 0;
-
-        for (ConfigurationNode potionNode : getChildren(POTIONS)) {
-            //Grab the child node corresponding to this potion
-            String potionName = potionNode.getString();
-            AlchemyPotion potion = loadPotion(getUserRootNode().getNode(POTIONS, potionName));
-
-            if (potion != null) {
-                potionMap.put(potionName, potion);
-                pass++;
-            } else {
-                fail++;
-            }
-        }
-
-        mcMMO.p.debug("Loaded " + pass + " Alchemy potions, skipped " + fail + ".");
-    }
-
-    /**
-     * Parse a ConfigurationSection representing a AlchemyPotion.
-     * Returns null if input cannot be parsed.
-     *
-     * @param potion_section ConfigurationSection to be parsed.
-     * @return Parsed AlchemyPotion.
-     */
-    private AlchemyPotion loadPotion(ConfigurationNode potion_section) {
-        try {
-
-            String name = potion_section.getString(NAME);
-
-            if (name != null) {
-                name = ChatColor.translateAlternateColorCodes('&', name);
-            }
-
-            PotionData data;
-            //If the potion data is null
-            ConfigurationNode potionData = potion_section.getNode(POTION_DATA);
-
-            PotionType potionType = potionData.getNode(POTION_TYPE) != null ? PotionType.valueOf(potionData.getNode(POTION_TYPE).getString()) : PotionType.valueOf(WATER);
-            boolean potionExtended = potionData.getNode(EXTENDED) != null ? potionData.getNode(EXTENDED).getBoolean() : false;
-            boolean potionUpgraded = potionData.getNode(UPGRADED) != null ? potionData.getNode(UPGRADED).getBoolean() : false;
-
-            data = new PotionData(potionType, potionExtended, potionUpgraded);
-
-            Material material = Material.POTION;
-
-            String materialTypeString = potion_section.getNode(MATERIAL) != null ? potion_section.getNode(MATERIAL).getString() : null;
-
-
-            if (materialTypeString != null) {
-                material = Material.valueOf(materialTypeString);
-            }
-
-            List<String> lore = new ArrayList<>();
-            if (potion_section.getNode(LORE) != null) {
-                for (String line : potion_section.getNode(LORE).getList(TypeToken.of(String.class))) {
-                    lore.add(ChatColor.translateAlternateColorCodes('&', line));
-                }
-            }
-
-            List<PotionEffect> effects = new ArrayList<>();
-            if (potion_section.getNode(EFFECTS) != null) {
-                for (String effect : potion_section.getNode(EFFECTS).getList(TypeToken.of(String.class))) {
-                    String[] parts = effect.split(" ");
-
-                    PotionEffectType type = parts.length > 0 ? PotionEffectType.getByName(parts[0]) : null;
-                    int amplifier = parts.length > 1 ? Integer.parseInt(parts[1]) : 0;
-                    int duration = parts.length > 2 ? Integer.parseInt(parts[2]) : 0;
-
-                    if (type != null) {
-                        effects.add(new PotionEffect(type, duration, amplifier));
-                    } else {
-                        mcMMO.p.getLogger().warning("Failed to parse effect for potion " + name + ": " + effect);
-                    }
-                }
-            }
-
-            Color color;
-            if (potion_section.getNode(COLOR) != null) {
-                color = Color.fromRGB(potion_section.getNode(COLOR).getInt());
-            } else {
-                color = this.generateColor(effects);
-            }
-
-            Map<ItemStack, String> children = new HashMap<>();
-            if (potion_section.getNode(CHILDREN) != null) {
-                for (String child : potion_section.getNode(CHILDREN).getList(TypeToken.of(String.class))) {
-                    ItemStack ingredient = loadIngredient(child);
-                    if (ingredient != null) {
-                        children.put(ingredient, potion_section.getNode(CHILDREN).getNode(child).getString());
-                    } else {
-                        mcMMO.p.getLogger().warning("Failed to parse child for potion " + name + ": " + child);
-                    }
-                }
-            }
-
-            return new AlchemyPotion(material, data, name, lore, effects, color, children);
-        } catch (Exception e) {
-            mcMMO.p.getLogger().warning("Failed to load Alchemy potion: " + potion_section.getString());
-            return null;
-        }
-    }
-
-    /**
-     * 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 concoctionsIngredientsTierEight;
-            case 7:
-                return concoctionsIngredientsTierSeven;
-            case 6:
-                return concoctionsIngredientsTierSix;
-            case 5:
-                return concoctionsIngredientsTierFive;
-            case 4:
-                return concoctionsIngredientsTierFour;
-            case 3:
-                return concoctionsIngredientsTierThree;
-            case 2:
-                return concoctionsIngredientsTierTwo;
-            case 1:
-            default:
-                return concoctionsIngredientsTierOne;
-        }
-    }
-
-    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;
-    }
-
-    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;
-    }
-
-}

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

@@ -0,0 +1,202 @@
+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;
+    }
+
+
+
+}

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

@@ -1,6 +1,6 @@
 package com.gmail.nossr50.datatypes.skills.alchemy;
 
-import com.gmail.nossr50.config.skills.alchemy.PotionConfig;
+import com.gmail.nossr50.config.skills.alchemy.PotionManager;
 import org.bukkit.Color;
 import org.bukkit.Material;
 import org.bukkit.inventory.ItemStack;
@@ -123,7 +123,7 @@ public class AlchemyPotion {
         if (!children.isEmpty()) {
             for (Entry<ItemStack, String> child : children.entrySet()) {
                 if (ingredient.isSimilar(child.getKey())) {
-                    return PotionConfig.getInstance().getPotion(child.getValue());
+                    return PotionManager.getInstance().getPotion(child.getValue());
                 }
             }
         }

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

@@ -1,6 +1,6 @@
 package com.gmail.nossr50.skills.alchemy;
 
-import com.gmail.nossr50.config.skills.alchemy.PotionConfig;
+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;
@@ -26,7 +26,7 @@ public class AlchemyManager extends SkillManager {
     }
 
     public List<ItemStack> getIngredients() {
-        return PotionConfig.getInstance().getIngredients(getTier());
+        return PotionManager.getInstance().getIngredients(getTier());
     }
 
     public String getIngredientList() {

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

@@ -1,6 +1,6 @@
 package com.gmail.nossr50.skills.alchemy;
 
-import com.gmail.nossr50.config.skills.alchemy.PotionConfig;
+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;
@@ -35,7 +35,7 @@ public final class AlchemyPotionBrewer {
                 continue;
             }
 
-            if (getChildPotion(PotionConfig.getInstance().getPotion(contents[i]), contents[Alchemy.INGREDIENT_SLOT]) != null) {
+            if (getChildPotion(PotionManager.getInstance().getPotion(contents[i]), contents[Alchemy.INGREDIENT_SLOT]) != null) {
                 return true;
             }
         }
@@ -89,10 +89,10 @@ public final class AlchemyPotionBrewer {
 
     private static List<ItemStack> getValidIngredients(Player player) {
         if (player == null || UserManager.getPlayer(player) == null) {
-            return PotionConfig.getInstance().getIngredients(1);
+            return PotionManager.getInstance().getIngredients(1);
         }
 
-        return PotionConfig.getInstance().getIngredients(!Permissions.isSubSkillEnabled(player, SubSkillType.ALCHEMY_CONCOCTIONS) ? 1 : UserManager.getPlayer(player).getAlchemyManager().getTier());
+        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) {
@@ -112,11 +112,11 @@ public final class AlchemyPotionBrewer {
         for (int i = 0; i < 3; i++) {
             ItemStack item = inventory.getItem(i);
 
-            if (isEmpty(item) || item.getType() == Material.GLASS_BOTTLE || !PotionConfig.getInstance().isValidPotion(item)) {
+            if (isEmpty(item) || item.getType() == Material.GLASS_BOTTLE || !PotionManager.getInstance().isValidPotion(item)) {
                 continue;
             }
 
-            AlchemyPotion input = PotionConfig.getInstance().getPotion(item);
+            AlchemyPotion input = PotionManager.getInstance().getPotion(item);
             AlchemyPotion output = input.getChild(ingredient);
 
             inputList.add(input);

+ 254 - 160
src/main/java/com/gmail/nossr50/skills/alchemy/PotionGenerator.java

@@ -1,6 +1,12 @@
 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;
@@ -13,8 +19,14 @@ import java.util.Map;
 import java.util.Map.Entry;
 
 public class PotionGenerator {
+    private HashMap<String, AlchemyPotion> potionHashMap;
 
-    public static void main(String[] args) {
+    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<>();
@@ -22,6 +34,7 @@ public class PotionGenerator {
         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) {
@@ -84,35 +97,118 @@ public class PotionGenerator {
                 return a.baseName.split("_")[0].compareTo(b.baseName.split("_")[0]);
             }
         });
-        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);
+
+        /* 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) {
@@ -207,24 +303,19 @@ public class PotionGenerator {
         }
     }
 
-    private static void populateVanillaPotions(Map<WriteablePotion, Map<Ingredient, WriteablePotion>> vanillaPotions) {
+    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 data = new WriteablePotion(material, type);
-                HashMap<Ingredient, WriteablePotion> children = new HashMap<>();
-                getChildren(data, children);
-                vanillaPotions.put(data, children);
+                WriteablePotion writeablePotion = new WriteablePotion(material, type);
+                getChildren(writeablePotion);
+                vanillaPotions.put(writeablePotion, getChildren(writeablePotion));
                 if (type.isExtendable()) {
-                    data = new WriteablePotion(material, new PotionData(type, true, false));
-                    children = new HashMap<>();
-                    getChildren(data, children);
-                    vanillaPotions.put(data, children);
+                    writeablePotion = new WriteablePotion(material, new PotionData(type, true, false));
+                    vanillaPotions.put(writeablePotion, getChildren(writeablePotion));
                 }
                 if (type.isUpgradeable()) {
-                    data = new WriteablePotion(material, new PotionData(type, false, true));
-                    children = new HashMap<>();
-                    getChildren(data, children);
-                    vanillaPotions.put(data, children);
+                    writeablePotion = new WriteablePotion(material, new PotionData(type, false, true));
+                    vanillaPotions.put(writeablePotion, getChildren(writeablePotion));
                 }
             }
         }
@@ -236,175 +327,178 @@ public class PotionGenerator {
                 entry.getValue().put(new Ingredient(Material.DRAGON_BREATH), new WriteablePotion(Material.LINGERING_POTION, entry.getKey().data));
             }
         }
+
+        //Store children
     }
 
-    private static void getChildren(WriteablePotion current, HashMap<Ingredient, WriteablePotion> children) {
-        switch (current.data.getType()) {
+    private HashMap<Ingredient, WriteablePotion> getChildren(WriteablePotion writeablePotion) {
+        HashMap<Ingredient, WriteablePotion> children = new HashMap<>();
+
+        switch (writeablePotion.data.getType()) {
             case WATER:
-                assert (!current.data.isExtended());
-                assert (!current.data.isUpgraded());
-                children.put(new Ingredient(Material.NETHER_WART), new WriteablePotion(current.mat, PotionType.AWKWARD));
-                children.put(new Ingredient(Material.FERMENTED_SPIDER_EYE), new WriteablePotion(current.mat, PotionType.WEAKNESS));
-                children.put(new Ingredient(Material.REDSTONE), new WriteablePotion(current.mat, PotionType.MUNDANE));
-                children.put(new Ingredient(Material.GLOWSTONE_DUST), new WriteablePotion(current.mat, PotionType.THICK));
-                children.put(new Ingredient(Material.BLAZE_POWDER), new WriteablePotion(current.mat, PotionType.MUNDANE));
-                children.put(new Ingredient(Material.SUGAR), new WriteablePotion(current.mat, PotionType.MUNDANE));
-                children.put(new Ingredient(Material.RABBIT_FOOT), new WriteablePotion(current.mat, PotionType.MUNDANE));
-                children.put(new Ingredient(Material.SPIDER_EYE), new WriteablePotion(current.mat, PotionType.MUNDANE));
-                children.put(new Ingredient(Material.MAGMA_CREAM), new WriteablePotion(current.mat, PotionType.MUNDANE));
-                children.put(new Ingredient(Material.GLISTERING_MELON_SLICE), new WriteablePotion(current.mat, PotionType.MUNDANE));
-                children.put(new Ingredient(Material.GHAST_TEAR), new WriteablePotion(current.mat, PotionType.MUNDANE));
-                return;
+                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 (!current.data.isExtended());
-                assert (!current.data.isUpgraded());
-                children.put(new Ingredient(Material.GOLDEN_CARROT), new WriteablePotion(current.mat, PotionType.NIGHT_VISION));
-                children.put(new Ingredient(Material.RABBIT_FOOT), new WriteablePotion(current.mat, PotionType.JUMP));
-                children.put(new Ingredient(Material.MAGMA_CREAM), new WriteablePotion(current.mat, PotionType.FIRE_RESISTANCE));
-                children.put(new Ingredient(Material.SUGAR), new WriteablePotion(current.mat, PotionType.SPEED));
-                children.put(new Ingredient(Material.PUFFERFISH), new WriteablePotion(current.mat, PotionType.WATER_BREATHING));
-                children.put(new Ingredient(Material.GLISTERING_MELON_SLICE), new WriteablePotion(current.mat, PotionType.INSTANT_HEAL));
-                children.put(new Ingredient(Material.SPIDER_EYE), new WriteablePotion(current.mat, PotionType.POISON));
-                children.put(new Ingredient(Material.GHAST_TEAR), new WriteablePotion(current.mat, PotionType.REGEN));
-                children.put(new Ingredient(Material.BLAZE_POWDER), new WriteablePotion(current.mat, PotionType.STRENGTH));
-                children.put(new Ingredient(Material.TURTLE_HELMET), new WriteablePotion(current.mat, PotionType.TURTLE_MASTER));
-                children.put(new Ingredient(Material.PHANTOM_MEMBRANE), new WriteablePotion(current.mat, PotionType.SLOW_FALLING));
+                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 (current.mat == Material.SPLASH_POTION) {
+                if (writeablePotion.mat == Material.SPLASH_POTION) {
                     mod = 0.75;
                 }
-                if (current.mat == Material.LINGERING_POTION) {
+                if (writeablePotion.mat == Material.LINGERING_POTION) {
                     mod = 0.25;
                 }
-                children.put(new Ingredient(Material.BROWN_MUSHROOM), new WriteablePotion(current.mat, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.CONFUSION, (int) (450 * mod), 0), "NAUSEA"));
-                children.put(new Ingredient(Material.CARROT), new WriteablePotion(current.mat, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.FAST_DIGGING, (int) (3600 * mod), 0), "HASTE"));
-                children.put(new Ingredient(Material.SLIME_BALL), new WriteablePotion(current.mat, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.SLOW_DIGGING, (int) (3600 * mod), 0), "DULLNESS"));
-                children.put(new Ingredient(Material.GOLDEN_APPLE), new WriteablePotion(current.mat, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.DAMAGE_RESISTANCE, (int) (450 * mod), 0), "RESISTANCE"));
-                children.put(new Ingredient(Material.INK_SAC), new WriteablePotion(current.mat, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.BLINDNESS, (int) (225 * mod), 0), "BLINDNESS"));
-                children.put(new Ingredient(Material.ROTTEN_FLESH), new WriteablePotion(current.mat, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.HUNGER, (int) (900 * mod), 0), "HUNGER"));
-                children.put(new Ingredient(Material.POISONOUS_POTATO), new WriteablePotion(current.mat, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.WITHER, (int) (450 * mod), 0), "DECAY"));
-                children.put(new Ingredient(Material.QUARTZ), new WriteablePotion(current.mat, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.ABSORPTION, (int) (1800 * mod), 0), "ABSORPTION"));
-                children.put(new Ingredient(Material.FERN), new WriteablePotion(current.mat, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.SATURATION, (int) (8 * mod), 0), "SATURATION"));
-                children.put(new Ingredient(Material.APPLE), new WriteablePotion(current.mat, PotionType.UNCRAFTABLE, new PotionEffect(PotionEffectType.HEALTH_BOOST, (int) (1800 * mod), 0), "HEALTH_BOOST"));
-                return;
+                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 (!current.data.isUpgraded());
-                if (current.data.isExtended()) {
-                    children.put(new Ingredient(Material.FERMENTED_SPIDER_EYE), new WriteablePotion(current.mat, new PotionData(PotionType.SLOWNESS, true, false)));
+                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(current.mat, PotionType.SLOWNESS));
-                    children.put(new Ingredient(Material.REDSTONE), new WriteablePotion(current.mat, new PotionData(current.data.getType(), true, false)));
+                    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;
+                return children;
             case INSTANT_DAMAGE:
-                assert (!current.data.isExtended());
-                if (!current.data.isUpgraded()) {
-                    children.put(new Ingredient(Material.GLOWSTONE_DUST), new WriteablePotion(current.mat, new PotionData(current.data.getType(), false, true)));
+                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;
+                return children;
             case INSTANT_HEAL:
-                assert (!current.data.isExtended());
-                if (!current.data.isUpgraded()) {
-                    children.put(new Ingredient(Material.FERMENTED_SPIDER_EYE), new WriteablePotion(current.mat, PotionType.INSTANT_DAMAGE));
-                    children.put(new Ingredient(Material.GLOWSTONE_DUST), new WriteablePotion(current.mat, new PotionData(current.data.getType(), false, true)));
+                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(current.mat, new PotionData(PotionType.INSTANT_DAMAGE, false, true)));
+                    children.put(new Ingredient(Material.FERMENTED_SPIDER_EYE), new WriteablePotion(writeablePotion.mat, new PotionData(PotionType.INSTANT_DAMAGE, false, true)));
                 }
-                return;
+                return children;
             case INVISIBILITY:
-                assert (!current.data.isUpgraded());
-                if (!current.data.isExtended()) {
-                    children.put(new Ingredient(Material.REDSTONE), new WriteablePotion(current.mat, new PotionData(current.data.getType(), true, false)));
+                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;
+                return children;
             case JUMP:
-                if (!current.data.isUpgraded() && !current.data.isExtended()) {
-                    children.put(new Ingredient(Material.FERMENTED_SPIDER_EYE), new WriteablePotion(current.mat, PotionType.SLOWNESS));
-                    children.put(new Ingredient(Material.GLOWSTONE_DUST), new WriteablePotion(current.mat, new PotionData(current.data.getType(), false, true)));
-                    children.put(new Ingredient(Material.REDSTONE), new WriteablePotion(current.mat, new PotionData(current.data.getType(), true, false)));
+                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;
+                return children;
             case NIGHT_VISION:
-                assert (!current.data.isUpgraded());
-                if (!current.data.isExtended()) {
-                    children.put(new Ingredient(Material.FERMENTED_SPIDER_EYE), new WriteablePotion(current.mat, PotionType.INVISIBILITY));
-                    children.put(new Ingredient(Material.REDSTONE), new WriteablePotion(current.mat, new PotionData(current.data.getType(), true, false)));
+                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(current.mat, new PotionData(PotionType.INVISIBILITY, true, false)));
+                    children.put(new Ingredient(Material.FERMENTED_SPIDER_EYE), new WriteablePotion(writeablePotion.mat, new PotionData(PotionType.INVISIBILITY, true, false)));
                 }
-                return;
+                return children;
             case POISON:
-                if (!current.data.isUpgraded() && !current.data.isExtended()) {
-                    children.put(new Ingredient(Material.FERMENTED_SPIDER_EYE), new WriteablePotion(current.mat, PotionType.INSTANT_DAMAGE));
-                    children.put(new Ingredient(Material.GLOWSTONE_DUST), new WriteablePotion(current.mat, new PotionData(current.data.getType(), false, true)));
-                    children.put(new Ingredient(Material.REDSTONE), new WriteablePotion(current.mat, new PotionData(current.data.getType(), true, false)));
+                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(current.mat, new PotionData(PotionType.INSTANT_DAMAGE, false, true)));
+                    children.put(new Ingredient(Material.FERMENTED_SPIDER_EYE), new WriteablePotion(writeablePotion.mat, new PotionData(PotionType.INSTANT_DAMAGE, false, true)));
                 }
-                return;
+                return children;
             case REGEN:
-                if (!current.data.isUpgraded() && !current.data.isExtended()) {
-                    children.put(new Ingredient(Material.GLOWSTONE_DUST), new WriteablePotion(current.mat, new PotionData(current.data.getType(), false, true)));
-                    children.put(new Ingredient(Material.REDSTONE), new WriteablePotion(current.mat, new PotionData(current.data.getType(), true, false)));
+                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;
+                return children;
             case SLOWNESS:
-                assert (!current.data.isUpgraded());
-                if (!current.data.isExtended()) {
-                    children.put(new Ingredient(Material.REDSTONE), new WriteablePotion(current.mat, new PotionData(current.data.getType(), true, false)));
+                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;
+                return children;
             case SLOW_FALLING:
-                assert (!current.data.isUpgraded());
-                if (!current.data.isExtended()) {
-                    children.put(new Ingredient(Material.REDSTONE), new WriteablePotion(current.mat, new PotionData(current.data.getType(), true, false)));
+                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;
+                return children;
             case SPEED:
-                if (!current.data.isUpgraded() && !current.data.isExtended()) {
-                    children.put(new Ingredient(Material.FERMENTED_SPIDER_EYE), new WriteablePotion(current.mat, PotionType.SLOWNESS));
-                    children.put(new Ingredient(Material.GLOWSTONE_DUST), new WriteablePotion(current.mat, new PotionData(current.data.getType(), false, true)));
-                    children.put(new Ingredient(Material.REDSTONE), new WriteablePotion(current.mat, new PotionData(current.data.getType(), true, false)));
+                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(current.mat, new PotionData(PotionType.SLOWNESS, true, false)));
+                    children.put(new Ingredient(Material.FERMENTED_SPIDER_EYE), new WriteablePotion(writeablePotion.mat, new PotionData(PotionType.SLOWNESS, true, false)));
                 }
-                return;
+                return children;
             case STRENGTH:
-                if (!current.data.isUpgraded() && !current.data.isExtended()) {
-                    children.put(new Ingredient(Material.GLOWSTONE_DUST), new WriteablePotion(current.mat, new PotionData(current.data.getType(), false, true)));
-                    children.put(new Ingredient(Material.REDSTONE), new WriteablePotion(current.mat, new PotionData(current.data.getType(), true, false)));
+                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;
+                return children;
             case TURTLE_MASTER:
-                if (!current.data.isUpgraded() && !current.data.isExtended()) {
-                    children.put(new Ingredient(Material.GLOWSTONE_DUST), new WriteablePotion(current.mat, new PotionData(current.data.getType(), false, true)));
-                    children.put(new Ingredient(Material.REDSTONE), new WriteablePotion(current.mat, new PotionData(current.data.getType(), true, false)));
+                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;
+                return children;
             case WATER_BREATHING:
-                assert (!current.data.isUpgraded());
-                if (!current.data.isExtended()) {
-                    children.put(new Ingredient(Material.FERMENTED_SPIDER_EYE), new WriteablePotion(current.mat, PotionType.INSTANT_DAMAGE));
-                    children.put(new Ingredient(Material.REDSTONE), new WriteablePotion(current.mat, new PotionData(current.data.getType(), true, false)));
+                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;
+                return children;
             case WEAKNESS:
-                assert (!current.data.isUpgraded());
-                if (!current.data.isExtended()) {
-                    children.put(new Ingredient(Material.REDSTONE), new WriteablePotion(current.mat, new PotionData(current.data.getType(), true, false)));
+                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;
+                return children;
             case LUCK:
             case MUNDANE:
             case THICK:
             case UNCRAFTABLE:
-                assert (!current.data.isExtended());
-                assert (!current.data.isUpgraded());
-                return;
+                assert (!writeablePotion.data.isExtended());
+                assert (!writeablePotion.data.isUpgraded());
+                return children;
             default:
-                assert (false);
-                break;
+                return children;
         }
     }