Prechádzať zdrojové kódy

fix issues with Alchemy and older MC versions

nossr50 1 rok pred
rodič
commit
75561350c1

+ 2 - 2
Changelog.txt

@@ -1,8 +1,8 @@
 Version 2.2.007
 Version 2.2.007
     Compatibility with the 1.20.5 / 1.20.6 MC Update
     Compatibility with the 1.20.5 / 1.20.6 MC Update
-    Added armadillo to combat experience in experience.yml
     Fixed bug where Alchemy was not brewing certain potions (haste, etc)
     Fixed bug where Alchemy was not brewing certain potions (haste, etc)
-    Alchemy now has more warning/errors that will print out to help debug
+    Fixed bug where the probability of success of Graceful Roll was not being calculated correctly
+    Added armadillo to combat experience in experience.yml
     Fixed bug where Green Thumb did not replant if seed was in the off hand
     Fixed bug where Green Thumb did not replant if seed was in the off hand
 
 
     NOTES:
     NOTES:

+ 12 - 1
pom.xml

@@ -222,6 +222,11 @@
     </pluginRepositories>
     </pluginRepositories>
 
 
     <repositories>
     <repositories>
+        <!-- Protocol Lib Repository -->
+        <repository>
+            <id>dmulloy2-repo</id>
+            <url>https://repo.dmulloy2.net/repository/public/</url>
+        </repository>
         <repository>
         <repository>
             <id>spigot-repo</id>
             <id>spigot-repo</id>
             <url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
             <url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
@@ -268,6 +273,12 @@
             <version>3.25.3</version>
             <version>3.25.3</version>
             <scope>test</scope>
             <scope>test</scope>
         </dependency>
         </dependency>
+        <dependency>
+            <groupId>com.comphenix.protocol</groupId>
+            <artifactId>ProtocolLib</artifactId>
+            <version>LATEST</version>
+            <scope>compile</scope>
+        </dependency>
         <dependency>
         <dependency>
             <groupId>com.h2database</groupId>
             <groupId>com.h2database</groupId>
             <artifactId>h2</artifactId>
             <artifactId>h2</artifactId>
@@ -364,7 +375,7 @@
         <dependency>
         <dependency>
             <groupId>org.spigotmc</groupId>
             <groupId>org.spigotmc</groupId>
             <artifactId>spigot-api</artifactId>
             <artifactId>spigot-api</artifactId>
-            <version>1.20.5-R0.1-SNAPSHOT</version>
+            <version>1.19.2-R0.1-SNAPSHOT</version>
             <scope>provided</scope>
             <scope>provided</scope>
         </dependency>
         </dependency>
         <dependency>
         <dependency>

+ 11 - 7
src/main/java/com/gmail/nossr50/config/skills/alchemy/PotionConfig.java

@@ -15,15 +15,14 @@ import org.bukkit.inventory.meta.PotionMeta;
 import org.bukkit.potion.PotionEffect;
 import org.bukkit.potion.PotionEffect;
 import org.bukkit.potion.PotionEffectType;
 import org.bukkit.potion.PotionEffectType;
 import org.bukkit.potion.PotionType;
 import org.bukkit.potion.PotionType;
+import org.codehaus.plexus.util.StringUtils;
 import org.jetbrains.annotations.VisibleForTesting;
 import org.jetbrains.annotations.VisibleForTesting;
 
 
 import java.io.File;
 import java.io.File;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 
 import static com.gmail.nossr50.util.PotionUtil.*;
 import static com.gmail.nossr50.util.PotionUtil.*;
+import static com.gmail.nossr50.util.text.StringUtils.convertKeyToName;
 
 
 public class PotionConfig extends LegacyConfigLoader {
 public class PotionConfig extends LegacyConfigLoader {
 
 
@@ -130,7 +129,7 @@ public class PotionConfig extends LegacyConfigLoader {
             final String key = potion_section.getName();
             final String key = potion_section.getName();
             final String displayName = potion_section.getString("Name") != null
             final String displayName = potion_section.getString("Name") != null
                     ? LocaleLoader.addColors(potion_section.getString("Name"))
                     ? LocaleLoader.addColors(potion_section.getString("Name"))
-                    : null;
+                    : convertKeyToName(key);
 
 
             final ConfigurationSection potionData = potion_section.getConfigurationSection("PotionData");
             final ConfigurationSection potionData = potion_section.getConfigurationSection("PotionData");
             boolean extended = false;
             boolean extended = false;
@@ -165,12 +164,16 @@ public class PotionConfig extends LegacyConfigLoader {
                 return null;
                 return null;
             }
             }
 
 
+            // Set the name of the potion
+            potionMeta.setDisplayName(displayName);
+
             // extended and upgraded seem to be mutually exclusive
             // extended and upgraded seem to be mutually exclusive
             if (extended && upgraded) {
             if (extended && upgraded) {
                 mcMMO.p.getLogger().warning("Potion " + key + " has both Extended and Upgraded set to true," +
                 mcMMO.p.getLogger().warning("Potion " + key + " has both Extended and Upgraded set to true," +
                         " defaulting to Extended.");
                         " defaulting to Extended.");
                 upgraded = false;
                 upgraded = false;
             }
             }
+
             String potionTypeStr = potionData.getString("PotionType", null);
             String potionTypeStr = potionData.getString("PotionType", null);
             if (potionTypeStr == null) {
             if (potionTypeStr == null) {
                 mcMMO.p.getLogger().severe("PotionConfig: Missing PotionType for " + displayName + ", from configuration section:" +
                 mcMMO.p.getLogger().severe("PotionConfig: Missing PotionType for " + displayName + ", from configuration section:" +
@@ -186,7 +189,9 @@ public class PotionConfig extends LegacyConfigLoader {
             }
             }
 
 
             if (potionType == null) {
             if (potionType == null) {
-                mcMMO.p.getLogger().severe("PotionConfig: Failed to parse potion type for: " + potionTypeStr);
+                mcMMO.p.getLogger().severe("PotionConfig: Failed to parse potion type for: " + potionTypeStr
+                        + ", upgraded: " + upgraded + ", extended: " + extended + " for potion " + displayName
+                        + ", from configuration section: " + potion_section);
                 return null;
                 return null;
             }
             }
 
 
@@ -357,5 +362,4 @@ public class PotionConfig extends LegacyConfigLoader {
         }
         }
         return Color.fromRGB(red / colors.size(), green / colors.size(), blue / colors.size());
         return Color.fromRGB(red / colors.size(), green / colors.size(), blue / colors.size());
     }
     }
-
 }
 }

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

@@ -7,7 +7,6 @@ import org.bukkit.inventory.meta.PotionMeta;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.jetbrains.annotations.Nullable;
 
 
-import java.util.ArrayList;
 import java.util.Map;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Map.Entry;
 import java.util.Objects;
 import java.util.Objects;
@@ -16,18 +15,18 @@ import static com.gmail.nossr50.util.PotionUtil.samePotionType;
 import static java.util.Objects.requireNonNull;
 import static java.util.Objects.requireNonNull;
 
 
 public class AlchemyPotion {
 public class AlchemyPotion {
-    private final ItemStack potion;
-    private final Map<ItemStack, String> alchemyPotionChildren;
+    private final @NotNull ItemStack potionItemstack;
+    private final @NotNull Map<ItemStack, String> alchemyPotionChildren;
 
 
-    public AlchemyPotion(ItemStack potion, Map<ItemStack, String> alchemyPotionChildren) {
-        this.potion = requireNonNull(potion, "potion cannot be null");
+    public AlchemyPotion(@NotNull ItemStack potionItemStack, @NotNull Map<ItemStack, String> alchemyPotionChildren) {
+        this.potionItemstack = requireNonNull(potionItemStack, "potionItemStack cannot be null");
         this.alchemyPotionChildren = requireNonNull(alchemyPotionChildren, "alchemyPotionChildren cannot be null");
         this.alchemyPotionChildren = requireNonNull(alchemyPotionChildren, "alchemyPotionChildren cannot be null");
     }
     }
 
 
     public @NotNull ItemStack toItemStack(int amount) {
     public @NotNull ItemStack toItemStack(int amount) {
-        final ItemStack potion = new ItemStack(this.potion);
-        potion.setAmount(Math.max(1, amount));
-        return potion;
+        final ItemStack clone = potionItemstack.clone();
+        clone.setAmount(Math.max(1, amount));
+        return clone;
     }
     }
 
 
     public Map<ItemStack, String> getAlchemyPotionChildren() {
     public Map<ItemStack, String> getAlchemyPotionChildren() {
@@ -49,7 +48,7 @@ public class AlchemyPotion {
         requireNonNull(otherPotion, "otherPotion cannot be null");
         requireNonNull(otherPotion, "otherPotion cannot be null");
         // TODO: Investigate?
         // TODO: Investigate?
         // We currently don't compare base potion effects, likely because they are derived from the potion type
         // We currently don't compare base potion effects, likely because they are derived from the potion type
-        if (otherPotion.getType() != potion.getType() || !otherPotion.hasItemMeta()) {
+        if (otherPotion.getType() != potionItemstack.getType() || !otherPotion.hasItemMeta()) {
             return false;
             return false;
         }
         }
 
 
@@ -76,25 +75,19 @@ public class AlchemyPotion {
             return false;
             return false;
         }
         }
 
 
-        if (!otherPotionMeta.hasDisplayName() && getAlchemyPotionMeta().hasDisplayName()) {
-            return false;
-        }
-
-        var alchemyPotionName = getAlchemyPotionMeta().hasDisplayName() ? getAlchemyPotionMeta().getDisplayName() : null;
-
-        return (alchemyPotionName == null && !otherPotionMeta.hasDisplayName()) || otherPotionMeta.getDisplayName().equals(alchemyPotionName);
+        return true;
     }
     }
 
 
     public PotionMeta getAlchemyPotionMeta() {
     public PotionMeta getAlchemyPotionMeta() {
-        return (PotionMeta) potion.getItemMeta();
+        return (PotionMeta) potionItemstack.getItemMeta();
     }
     }
 
 
     public boolean isSplash() {
     public boolean isSplash() {
-        return potion.getType() == Material.SPLASH_POTION;
+        return potionItemstack.getType() == Material.SPLASH_POTION;
     }
     }
 
 
     public boolean isLingering() {
     public boolean isLingering() {
-        return potion.getType() == Material.LINGERING_POTION;
+        return potionItemstack.getType() == Material.LINGERING_POTION;
     }
     }
 
 
     @Override
     @Override
@@ -102,18 +95,18 @@ public class AlchemyPotion {
         if (this == o) return true;
         if (this == o) return true;
         if (o == null || getClass() != o.getClass()) return false;
         if (o == null || getClass() != o.getClass()) return false;
         AlchemyPotion that = (AlchemyPotion) o;
         AlchemyPotion that = (AlchemyPotion) o;
-        return Objects.equals(potion, that.potion) && Objects.equals(alchemyPotionChildren, that.alchemyPotionChildren);
+        return Objects.equals(potionItemstack, that.potionItemstack) && Objects.equals(alchemyPotionChildren, that.alchemyPotionChildren);
     }
     }
 
 
     @Override
     @Override
     public int hashCode() {
     public int hashCode() {
-        return Objects.hash(potion, alchemyPotionChildren);
+        return Objects.hash(potionItemstack, alchemyPotionChildren);
     }
     }
 
 
     @Override
     @Override
     public String toString() {
     public String toString() {
         return "AlchemyPotion{" +
         return "AlchemyPotion{" +
-                "potion=" + potion +
+                "potion=" + potionItemstack +
                 ", alchemyPotionChildren=" + alchemyPotionChildren +
                 ", alchemyPotionChildren=" + alchemyPotionChildren +
                 '}';
                 '}';
     }
     }

+ 2 - 2
src/main/java/com/gmail/nossr50/datatypes/skills/subskills/acrobatics/Roll.java

@@ -136,7 +136,7 @@ public class Roll extends AcrobaticsSubSkill {
          * Graceful is double the odds of a normal roll
          * Graceful is double the odds of a normal roll
          */
          */
         Probability probability = getRollProbability(player);
         Probability probability = getRollProbability(player);
-        Probability gracefulProbability = Probability.ofPercent(probability.getValue() * 2);
+        Probability gracefulProbability = Probability.ofValue(probability.getValue() * 2);
         String[] gracefulRollStrings = ProbabilityUtil.getRNGDisplayValues(gracefulProbability);
         String[] gracefulRollStrings = ProbabilityUtil.getRNGDisplayValues(gracefulProbability);
         gracefulRollChance = gracefulRollStrings[0];
         gracefulRollChance = gracefulRollStrings[0];
         gracefulRollChanceLucky = gracefulRollStrings[1];
         gracefulRollChanceLucky = gracefulRollStrings[1];
@@ -274,7 +274,7 @@ public class Roll extends AcrobaticsSubSkill {
     @NotNull
     @NotNull
     public static Probability getGracefulProbability(Player player) {
     public static Probability getGracefulProbability(Player player) {
         double gracefulOdds = ProbabilityUtil.getSubSkillProbability(SubSkillType.ACROBATICS_ROLL, player).getValue() * 2;
         double gracefulOdds = ProbabilityUtil.getSubSkillProbability(SubSkillType.ACROBATICS_ROLL, player).getValue() * 2;
-        return Probability.ofPercent(gracefulOdds);
+        return Probability.ofValue(gracefulOdds);
     }
     }
 
 
     /**
     /**

+ 18 - 0
src/main/java/com/gmail/nossr50/protocollib/ProtocolLibManager.java

@@ -0,0 +1,18 @@
+package com.gmail.nossr50.protocollib;
+
+import com.gmail.nossr50.mcMMO;
+import org.bukkit.plugin.Plugin;
+
+// TODO: Finish this class
+public class ProtocolLibManager {
+    Plugin protocolLibPluginRef;
+    mcMMO pluginRef;
+    public ProtocolLibManager(mcMMO pluginRef) {
+        this.pluginRef = pluginRef;
+    }
+
+    public boolean isProtocolLibPresent() {
+        protocolLibPluginRef = pluginRef.getServer().getPluginManager().getPlugin("ProtocolLib");
+        return protocolLibPluginRef != null;
+    }
+}

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

@@ -3,6 +3,7 @@ package com.gmail.nossr50.runnables.skills;
 import com.gmail.nossr50.skills.alchemy.Alchemy;
 import com.gmail.nossr50.skills.alchemy.Alchemy;
 import com.gmail.nossr50.skills.alchemy.AlchemyPotionBrewer;
 import com.gmail.nossr50.skills.alchemy.AlchemyPotionBrewer;
 import com.gmail.nossr50.util.CancellableRunnable;
 import com.gmail.nossr50.util.CancellableRunnable;
+import org.bukkit.Bukkit;
 import org.bukkit.Location;
 import org.bukkit.Location;
 import org.bukkit.block.BrewingStand;
 import org.bukkit.block.BrewingStand;
 import org.bukkit.entity.Player;
 import org.bukkit.entity.Player;
@@ -31,8 +32,7 @@ public class AlchemyBrewCheckTask extends CancellableRunnable {
             if (oldInventory[Alchemy.INGREDIENT_SLOT] == null || newInventory[Alchemy.INGREDIENT_SLOT] == null || !oldInventory[Alchemy.INGREDIENT_SLOT].isSimilar(newInventory[Alchemy.INGREDIENT_SLOT]) || !validBrew) {
             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();
                 Alchemy.brewingStandMap.get(location).cancelBrew();
             }
             }
-        }
-        else if (validBrew) {
+        } else if (validBrew) {
             Alchemy.brewingStandMap.put(location, new AlchemyBrewTask(brewingStand, player));
             Alchemy.brewingStandMap.put(location, new AlchemyBrewTask(brewingStand, player));
         }
         }
     }
     }

+ 44 - 11
src/main/java/com/gmail/nossr50/runnables/skills/AlchemyBrewTask.java

@@ -11,6 +11,7 @@ import com.gmail.nossr50.util.CancellableRunnable;
 import com.gmail.nossr50.util.Misc;
 import com.gmail.nossr50.util.Misc;
 import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.player.UserManager;
 import com.gmail.nossr50.util.player.UserManager;
+import org.bukkit.Bukkit;
 import org.bukkit.Location;
 import org.bukkit.Location;
 import org.bukkit.Material;
 import org.bukkit.Material;
 import org.bukkit.block.BlockState;
 import org.bukkit.block.BlockState;
@@ -67,33 +68,65 @@ public class AlchemyBrewTask extends CancellableRunnable {
 
 
     @Override
     @Override
     public void run() {
     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])) {
+        // Check if preconditions for brewing are not met
+        if (shouldCancelBrewing()) {
             if (Alchemy.brewingStandMap.containsKey(location)) {
             if (Alchemy.brewingStandMap.containsKey(location)) {
                 Alchemy.brewingStandMap.remove(location);
                 Alchemy.brewingStandMap.remove(location);
             }
             }
-
             this.cancel();
             this.cancel();
-
             return;
             return;
         }
         }
 
 
-        if (firstRun) {
-            firstRun = false;
-            ((BrewingStand) brewingStand).setFuelLevel(fuel);
-        }
+        // Initialize the brewing stand on the first run
+        initializeBrewing();
 
 
+        // Update the brewing process timer
         brewTimer -= brewSpeed;
         brewTimer -= brewSpeed;
 
 
-        // Vanilla potion brewing completes when BrewingTime == 1
-        if (brewTimer < Math.max(brewSpeed, 2)) {
+        // Check if the brewing process should finish
+        if (isBrewingComplete()) {
             this.cancel();
             this.cancel();
             finish();
             finish();
+        } else {
+            updateBrewingTime();
+        }
+    }
+
+    private boolean shouldCancelBrewing() {
+        if (player == null) {
+            return true;
+        }
+        if (!player.isValid()) {
+            return true;
+        }
+        if (brewingStand == null) {
+            return true;
+        }
+        if (brewingStand.getType() != Material.BREWING_STAND) {
+            return true;
         }
         }
-        else {
-            ((BrewingStand) brewingStand).setBrewingTime((int) brewTimer);
+        if (!AlchemyPotionBrewer.isValidIngredient(player, ((BrewingStand) brewingStand).getInventory().getContents()[Alchemy.INGREDIENT_SLOT])) {
+            return true;
         }
         }
+        return false;
     }
     }
 
 
+    private void initializeBrewing() {
+        if (firstRun) {
+            firstRun = false;
+            ((BrewingStand) brewingStand).setFuelLevel(fuel);
+        }
+    }
+
+    private boolean isBrewingComplete() {
+        return brewTimer < Math.max(brewSpeed, 2);
+    }
+
+    private void updateBrewingTime() {
+        ((BrewingStand) brewingStand).setBrewingTime((int) brewTimer);
+    }
+
+
     private void finish() {
     private void finish() {
         McMMOPlayerBrewEvent event = new McMMOPlayerBrewEvent(player, brewingStand);
         McMMOPlayerBrewEvent event = new McMMOPlayerBrewEvent(player, brewingStand);
         mcMMO.p.getServer().getPluginManager().callEvent(event);
         mcMMO.p.getServer().getPluginManager().callEvent(event);

+ 0 - 34
src/main/java/com/gmail/nossr50/skills/alchemy/Alchemy.java

@@ -11,40 +11,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.Map;
 
 
 public final class Alchemy {
 public final class Alchemy {
-    /*public enum Tier {
-        EIGHT(8),
-        SEVEN(7),
-        SIX(6),
-        FIVE(5),
-        FOUR(4),
-        THREE(3),
-        TWO(2),
-        ONE(1);
-
-        int numerical;
-
-        private Tier(int numerical) {
-            this.numerical = numerical;
-        }
-
-        public int toNumerical() {
-            return numerical;
-        }
-
-        public static Tier fromNumerical(int numerical) {
-            for (Tier tier : Tier.values()) {
-                if (tier.toNumerical() == numerical) {
-                    return tier;
-                }
-            }
-            return null;
-        }
-
-        protected int getLevel() {
-            return mcMMO.p.getAdvancedConfig().getConcoctionsTierLevel(this);
-        }
-    }*/
-
     public static final int INGREDIENT_SLOT = 3;
     public static final int INGREDIENT_SLOT = 3;
 
 
     public static int    catalysisMaxBonusLevel = mcMMO.p.getAdvancedConfig().getCatalysisMaxBonusLevel();
     public static int    catalysisMaxBonusLevel = mcMMO.p.getAdvancedConfig().getCatalysisMaxBonusLevel();

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

@@ -9,6 +9,7 @@ import com.gmail.nossr50.runnables.player.PlayerUpdateInventoryTask;
 import com.gmail.nossr50.runnables.skills.AlchemyBrewCheckTask;
 import com.gmail.nossr50.runnables.skills.AlchemyBrewCheckTask;
 import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.player.UserManager;
 import com.gmail.nossr50.util.player.UserManager;
+import org.bukkit.Bukkit;
 import org.bukkit.Material;
 import org.bukkit.Material;
 import org.bukkit.block.BlockState;
 import org.bukkit.block.BlockState;
 import org.bukkit.block.BrewingStand;
 import org.bukkit.block.BrewingStand;
@@ -31,7 +32,9 @@ public final class AlchemyPotionBrewer {
         }
         }
 
 
         for (int i = 0; i < 3; i++) {
         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) {
+            if (contents[i] == null || contents[i].getType() != Material.POTION
+                    && contents[i].getType() != Material.SPLASH_POTION
+                    && contents[i].getType() != Material.LINGERING_POTION) {
                 continue;
                 continue;
             }
             }
 
 
@@ -101,52 +104,71 @@ public final class AlchemyPotionBrewer {
     }
     }
 
 
     public static void finishBrewing(BlockState brewingStand, Player player, boolean forced) {
     public static void finishBrewing(BlockState brewingStand, Player player, boolean forced) {
+        // Check if the brewing stand block state is an actual brewing stand
         if (!(brewingStand instanceof BrewingStand)) {
         if (!(brewingStand instanceof BrewingStand)) {
             return;
             return;
         }
         }
 
 
-        BrewerInventory inventory = ((BrewingStand) brewingStand).getInventory();
-        ItemStack ingredient = inventory.getIngredient() == null ? null : inventory.getIngredient().clone();
+        // Retrieve the inventory of the brewing stand and clone the current ingredient for safe manipulation
+        final BrewerInventory inventory = ((BrewingStand) brewingStand).getInventory();
+        final ItemStack ingredient = inventory.getIngredient() == null ? null : inventory.getIngredient().clone();
 
 
+        // Check if the brewing stand has a valid ingredient; if not, exit the method
         if (!hasIngredient(inventory, player)) {
         if (!hasIngredient(inventory, player)) {
+            // debug
             return;
             return;
         }
         }
 
 
+        // Initialize lists to hold the potions before and after brewing, initially setting them to null
         List<AlchemyPotion> inputList = new ArrayList<>(Collections.nCopies(3, null));
         List<AlchemyPotion> inputList = new ArrayList<>(Collections.nCopies(3, null));
         List<ItemStack> outputList = new ArrayList<>(Collections.nCopies(3, null));
         List<ItemStack> outputList = new ArrayList<>(Collections.nCopies(3, null));
 
 
+        // Process each of the three slots in the brewing stand
         for (int i = 0; i < 3; i++) {
         for (int i = 0; i < 3; i++) {
             ItemStack item = inventory.getItem(i);
             ItemStack item = inventory.getItem(i);
 
 
-            if (isEmpty(item) || item.getType() == Material.GLASS_BOTTLE || !mcMMO.p.getPotionConfig().isValidPotion(item)) {
+            // Skip the slot if it's empty, contains a glass bottle, or holds an invalid potion
+            if (isEmpty(item)
+                    || item.getType() == Material.GLASS_BOTTLE
+                    || !mcMMO.p.getPotionConfig().isValidPotion(item)) {
+                // debug
                 continue;
                 continue;
             }
             }
 
 
+            // Retrieve the potion configurations for the input and resulting output potion
             AlchemyPotion input = mcMMO.p.getPotionConfig().getPotion(item);
             AlchemyPotion input = mcMMO.p.getPotionConfig().getPotion(item);
             AlchemyPotion output = input.getChild(ingredient);
             AlchemyPotion output = input.getChild(ingredient);
 
 
+            // Update the input list with the current potion
             inputList.set(i, input);
             inputList.set(i, input);
 
 
+            // If there is a valid output potion, add it to the output list
             if (output != null) {
             if (output != null) {
                 outputList.set(i, output.toItemStack(item.getAmount()).clone());
                 outputList.set(i, output.toItemStack(item.getAmount()).clone());
             }
             }
         }
         }
 
 
+        // Create a fake brewing event and pass it to the plugin's event system
         FakeBrewEvent event = new FakeBrewEvent(brewingStand.getBlock(), inventory, outputList, ((BrewingStand) brewingStand).getFuelLevel());
         FakeBrewEvent event = new FakeBrewEvent(brewingStand.getBlock(), inventory, outputList, ((BrewingStand) brewingStand).getFuelLevel());
         mcMMO.p.getServer().getPluginManager().callEvent(event);
         mcMMO.p.getServer().getPluginManager().callEvent(event);
 
 
+        // If the event is cancelled or there are no potions processed, exit the method
         if (event.isCancelled() || inputList.isEmpty()) {
         if (event.isCancelled() || inputList.isEmpty()) {
+            // debug
             return;
             return;
         }
         }
 
 
+        // Update the brewing inventory with the new potions
         for (int i = 0; i < 3; i++) {
         for (int i = 0; i < 3; i++) {
             if(outputList.get(i) != null) {
             if(outputList.get(i) != null) {
                 inventory.setItem(i, outputList.get(i));
                 inventory.setItem(i, outputList.get(i));
             }
             }
         }
         }
 
 
+        // Remove the used ingredient from the brewing inventory
         removeIngredient(inventory, player);
         removeIngredient(inventory, player);
 
 
+        // Handle potion brewing success and related effects for each potion processed
         for (AlchemyPotion input : inputList) {
         for (AlchemyPotion input : inputList) {
             if (input == null) continue;
             if (input == null) continue;
 
 
@@ -155,13 +177,14 @@ public final class AlchemyPotionBrewer {
             if (output != null && player != null) {
             if (output != null && player != null) {
                 PotionStage potionStage = PotionStage.getPotionStage(input, output);
                 PotionStage potionStage = PotionStage.getPotionStage(input, output);
 
 
-                //TODO: hmm
+                // Update player alchemy skills or effects based on brewing success
                 if (UserManager.hasPlayerDataKey(player)) {
                 if (UserManager.hasPlayerDataKey(player)) {
                     UserManager.getPlayer(player).getAlchemyManager().handlePotionBrewSuccesses(potionStage, 1);
                     UserManager.getPlayer(player).getAlchemyManager().handlePotionBrewSuccesses(potionStage, 1);
                 }
                 }
             }
             }
         }
         }
 
 
+        // If the brewing was not forced by external conditions, schedule a new update
         if (!forced) {
         if (!forced) {
             scheduleUpdate(inventory);
             scheduleUpdate(inventory);
         }
         }

+ 4 - 4
src/main/java/com/gmail/nossr50/util/PotionUtil.java

@@ -39,6 +39,7 @@ public class PotionUtil {
     static {
     static {
         // We used to use uncraftable as the potion type
         // We used to use uncraftable as the potion type
         // this type isn't available anymore, so water will do
         // this type isn't available anymore, so water will do
+        potionDataClass = getPotionDataClass();
         legacyPotionTypes.put("UNCRAFTABLE", "WATER");
         legacyPotionTypes.put("UNCRAFTABLE", "WATER");
         legacyPotionTypes.put("JUMP", "LEAPING");
         legacyPotionTypes.put("JUMP", "LEAPING");
         legacyPotionTypes.put("SPEED", "SWIFTNESS");
         legacyPotionTypes.put("SPEED", "SWIFTNESS");
@@ -55,9 +56,8 @@ public class PotionUtil {
         methodPotionTypeGetEffectType = getPotionTypeEffectType();
         methodPotionTypeGetEffectType = getPotionTypeEffectType();
         methodPotionTypeGetPotionEffects = getPotionTypeGetPotionEffects();
         methodPotionTypeGetPotionEffects = getPotionTypeGetPotionEffects();
         methodSetBasePotionData = getSetBasePotionData();
         methodSetBasePotionData = getSetBasePotionData();
-        potionDataClass = getPotionDataClass();
 
 
-        if (methodPotionMetaGetBasePotionData != null) {
+        if (potionDataClass != null) {
             COMPATIBILITY_MODE = PotionCompatibilityType.PRE_1_20_5;
             COMPATIBILITY_MODE = PotionCompatibilityType.PRE_1_20_5;
         } else {
         } else {
             COMPATIBILITY_MODE = PotionCompatibilityType.POST_1_20_5;
             COMPATIBILITY_MODE = PotionCompatibilityType.POST_1_20_5;
@@ -161,7 +161,7 @@ public class PotionUtil {
      */
      */
     private static @Nullable Method getBasePotionData() {
     private static @Nullable Method getBasePotionData() {
         try {
         try {
-            return PotionType.class.getMethod("getBasePotionData");
+            return PotionMeta.class.getMethod("getBasePotionData");
         } catch (NoSuchMethodException e) {
         } catch (NoSuchMethodException e) {
             return null;
             return null;
         }
         }
@@ -419,7 +419,7 @@ public class PotionUtil {
      * @param upgraded true if the potion is upgraded
      * @param upgraded true if the potion is upgraded
      */
      */
     public static void setBasePotionType(PotionMeta potionMeta, PotionType potionType, boolean extended, boolean upgraded) {
     public static void setBasePotionType(PotionMeta potionMeta, PotionType potionType, boolean extended, boolean upgraded) {
-        if (COMPATIBILITY_MODE == PotionCompatibilityType.PRE_1_20_5) {
+        if (methodPotionMetaSetBasePotionType == null) {
             setBasePotionTypeLegacy(potionMeta, potionType, extended, upgraded);
             setBasePotionTypeLegacy(potionMeta, potionType, extended, upgraded);
         } else {
         } else {
             setBasePotionTypeModern(potionMeta, potionType);
             setBasePotionTypeModern(potionMeta, potionType);

+ 5 - 0
src/main/java/com/gmail/nossr50/util/text/StringUtils.java

@@ -186,4 +186,9 @@ public class StringUtils {
         }
         }
     }
     }
 
 
+    public static String convertKeyToName(@NotNull String key) {
+        // used when no display name is given for a potion
+        final String noUnderscores = key.replace("_", " ").toLowerCase(Locale.ENGLISH);
+        return org.codehaus.plexus.util.StringUtils.capitalise(noUnderscores);
+    }
 }
 }

+ 1 - 1
src/main/resources/plugin.yml

@@ -14,7 +14,7 @@ author: nossr50
 authors: [GJ, NuclearW, bm01, Glitchfinder, TfT_02, t00thpick1, Riking, electronicboy, kashike]
 authors: [GJ, NuclearW, bm01, Glitchfinder, TfT_02, t00thpick1, Riking, electronicboy, kashike]
 website: https://www.mcmmo.org
 website: https://www.mcmmo.org
 main: com.gmail.nossr50.mcMMO
 main: com.gmail.nossr50.mcMMO
-softdepend: [WorldGuard, CombatTag, HealthBar, PlaceholderAPI]
+softdepend: [WorldGuard, CombatTag, HealthBar, PlaceholderAPI, ProtocolLib]
 load: POSTWORLD
 load: POSTWORLD
 folia-supported: true
 folia-supported: true
 api-version: 1.13
 api-version: 1.13

+ 18 - 34
src/test/java/com/gmail/nossr50/util/PotionUtilTest.java

@@ -1,46 +1,30 @@
 package com.gmail.nossr50.util;
 package com.gmail.nossr50.util;
 
 
-import org.bukkit.potion.PotionType;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.Test;
 
 
 import static com.gmail.nossr50.util.PotionUtil.convertLegacyNames;
 import static com.gmail.nossr50.util.PotionUtil.convertLegacyNames;
-import static com.gmail.nossr50.util.PotionUtil.matchPotionType;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 
 
 class PotionUtilTest {
 class PotionUtilTest {
 
 
-    @Test
-    void testDisplay() {
-//        System.out.println("\n");
-//        System.out.println("\n");
-//        System.out.println("\n");
-//        System.out.println("\n");
-//        for(var s : PotionType.values()) {
-//            System.out.println("PotionType.getKey().getKey(): " + s.getKey().getKey());
-//            System.out.println("PotionType.name(): " + s.name());
-//            System.out.println("PotionType.toString():" + s.toString());
-//            System.out.println("\n");
-//        }
-    }
-
-    @Test
-    void testMatchPotionType() {
-        String potionTypeStr = "UNCRAFTABLE";
-        PotionType potionType = matchPotionType(potionTypeStr, false, false);
-        assertEquals(PotionType.WATER, potionType);
-
-        String potionTypeStr2 = "NIGHT_VISION";
-        PotionType potionType2 = matchPotionType(potionTypeStr2, false, false);
-        assertEquals(PotionType.NIGHT_VISION, potionType2);
-
-        String nightVisionLong = "NIGHT_VISION";
-        PotionType potionType3 = matchPotionType(nightVisionLong, false, true);
-        assertEquals(PotionType.LONG_NIGHT_VISION, potionType3);
-
-        nightVisionLong = "LONG_NIGHT_VISION";
-        potionType3 = matchPotionType(nightVisionLong, false, true);
-        assertEquals(PotionType.LONG_NIGHT_VISION, potionType3);
-    }
+//    @Test
+//    void testMatchPotionType() {
+//        String potionTypeStr = "UNCRAFTABLE";
+//        PotionType potionType = matchPotionType(potionTypeStr, false, false);
+//        assertEquals(PotionType.WATER, potionType);
+//
+//        String potionTypeStr2 = "NIGHT_VISION";
+//        PotionType potionType2 = matchPotionType(potionTypeStr2, false, false);
+//        assertEquals(PotionType.NIGHT_VISION, potionType2);
+//
+//        String nightVisionLong = "NIGHT_VISION";
+//        PotionType potionType3 = matchPotionType(nightVisionLong, false, true);
+//        assertEquals(PotionType.LONG_NIGHT_VISION, potionType3);
+//
+//        nightVisionLong = "LONG_NIGHT_VISION";
+//        potionType3 = matchPotionType(nightVisionLong, false, true);
+//        assertEquals(PotionType.LONG_NIGHT_VISION, potionType3);
+//    }
 
 
     @Test
     @Test
     void testConvertLegacyNames() {
     void testConvertLegacyNames() {