2022-02-23 04:09:15 +01:00
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Thu, 7 Oct 2021 14:34:59 -0700
Subject: [PATCH] Custom Potion Mixes
diff --git a/src/main/java/io/papermc/paper/potion/PotionMix.java b/src/main/java/io/papermc/paper/potion/PotionMix.java
new file mode 100644
2023-11-26 00:03:02 +01:00
index 0000000000000000000000000000000000000000..3fc922ebf972418b84181cd02e68d8ef0efd739b
2022-02-23 04:09:15 +01:00
--- /dev/null
+++ b/src/main/java/io/papermc/paper/potion/PotionMix.java
2023-10-11 01:07:21 +02:00
@@ -0,0 +1,105 @@
2022-02-23 04:09:15 +01:00
+package io.papermc.paper.potion;
+
2023-10-11 01:07:21 +02:00
+import java.util.function.Predicate;
2022-02-23 04:09:15 +01:00
+import org.bukkit.Keyed;
+import org.bukkit.NamespacedKey;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.RecipeChoice;
+import org.jetbrains.annotations.ApiStatus;
2023-10-11 01:07:21 +02:00
+import org.jetbrains.annotations.Contract;
2022-02-23 04:09:15 +01:00
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Objects;
+
+/**
+ * Represents a potion mix made in a Brewing Stand.
+ */
+@ApiStatus.NonExtendable
+public class PotionMix implements Keyed {
+
+ private final NamespacedKey key;
+ private final ItemStack result;
+ private final RecipeChoice input;
+ private final RecipeChoice ingredient;
+
+ /**
+ * Creates a new potion mix. Add it to the server with {@link org.bukkit.potion.PotionBrewer#addPotionMix(PotionMix)}.
+ *
+ * @param key a unique key for the mix
+ * @param result the resulting itemstack that will appear in the 3 bottom slots
+ * @param input the input placed into the bottom 3 slots
+ * @param ingredient the ingredient placed into the top slot
+ */
2023-11-26 00:03:02 +01:00
+ public PotionMix(final @NotNull NamespacedKey key, final @NotNull ItemStack result, final @NotNull RecipeChoice input, final @NotNull RecipeChoice ingredient) {
2022-02-23 04:09:15 +01:00
+ this.key = key;
+ this.result = result;
+ this.input = input;
+ this.ingredient = ingredient;
+ }
+
2023-11-26 00:03:02 +01:00
+ /**
+ * Create a {@link RecipeChoice} based on a Predicate. These RecipeChoices are only
+ * valid for {@link PotionMix}, not anywhere else RecipeChoices may be used.
+ *
+ * @param stackPredicate a predicate for an itemstack.
+ * @return a new RecipeChoice
+ */
+ @Contract(value = "_ -> new", pure = true)
+ public static @NotNull RecipeChoice createPredicateChoice(final @NotNull Predicate<? super ItemStack> stackPredicate) {
+ return new PredicateRecipeChoice(stackPredicate);
+ }
+
2022-02-23 04:09:15 +01:00
+ @Override
+ public @NotNull NamespacedKey getKey() {
+ return this.key;
+ }
+
+ /**
+ * Gets the resulting itemstack after the brew has finished.
+ *
+ * @return the result itemstack
+ */
+ public @NotNull ItemStack getResult() {
+ return this.result;
+ }
+
+ /**
+ * Gets the input for the bottom 3 slots in the brewing stand.
+ *
+ * @return the bottom 3 slot ingredients
+ */
+ public @NotNull RecipeChoice getInput() {
+ return this.input;
+ }
+
+ /**
+ * Gets the ingredient in the top slot of the brewing stand.
+ *
+ * @return the top slot input
+ */
+ public @NotNull RecipeChoice getIngredient() {
+ return this.ingredient;
+ }
+
+ @Override
+ public String toString() {
+ return "PotionMix{" +
+ "result=" + this.result +
+ ", base=" + this.input +
+ ", addition=" + this.ingredient +
+ '}';
+ }
+
+ @Override
2023-11-26 00:03:02 +01:00
+ public boolean equals(final Object o) {
2022-02-23 04:09:15 +01:00
+ if (this == o) return true;
2023-11-26 00:03:02 +01:00
+ if (o == null || this.getClass() != o.getClass()) return false;
+ final PotionMix potionMix = (PotionMix) o;
2022-02-23 04:09:15 +01:00
+ return this.key.equals(potionMix.key) && this.result.equals(potionMix.result) && this.input.equals(potionMix.input) && this.ingredient.equals(potionMix.ingredient);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(this.key, this.result, this.input, this.ingredient);
+ }
+}
2023-10-11 01:07:21 +02:00
diff --git a/src/main/java/io/papermc/paper/potion/PredicateRecipeChoice.java b/src/main/java/io/papermc/paper/potion/PredicateRecipeChoice.java
new file mode 100644
2023-11-26 00:03:02 +01:00
index 0000000000000000000000000000000000000000..3ede1e8f7bf0436fdc5bf395c0f9eaf11c252453
2023-10-11 01:07:21 +02:00
--- /dev/null
+++ b/src/main/java/io/papermc/paper/potion/PredicateRecipeChoice.java
@@ -0,0 +1,33 @@
+package io.papermc.paper.potion;
+
+import java.util.function.Predicate;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.RecipeChoice;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.checkerframework.framework.qual.DefaultQualifier;
+import org.jetbrains.annotations.ApiStatus;
+
+@ApiStatus.Internal
+@DefaultQualifier(NonNull.class)
2023-11-26 00:03:02 +01:00
+record PredicateRecipeChoice(Predicate<? super ItemStack> itemStackPredicate) implements RecipeChoice, Cloneable {
2023-10-11 01:07:21 +02:00
+
+ @Override
+ @Deprecated
+ public ItemStack getItemStack() {
+ throw new UnsupportedOperationException("PredicateRecipeChoice does not support this");
+ }
+
+ @Override
+ public RecipeChoice clone() {
+ try {
+ return (PredicateRecipeChoice) super.clone();
2023-11-26 00:03:02 +01:00
+ } catch (final CloneNotSupportedException ex) {
2023-10-11 01:07:21 +02:00
+ throw new AssertionError(ex);
+ }
+ }
+
+ @Override
+ public boolean test(final ItemStack itemStack) {
+ return this.itemStackPredicate.test(itemStack);
+ }
+}
2022-02-23 04:09:15 +01:00
diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
2024-07-06 21:19:14 +02:00
index 65e02f66fd275045bd1889b460cc6c0613e19755..702e622a2ef2c3dcb0e582e38b3b10f9c939ed97 100644
2022-02-23 04:09:15 +01:00
--- a/src/main/java/org/bukkit/Bukkit.java
+++ b/src/main/java/org/bukkit/Bukkit.java
2024-07-06 21:19:14 +02:00
@@ -2630,6 +2630,15 @@ public final class Bukkit {
2022-02-23 04:09:15 +01:00
public static io.papermc.paper.datapack.DatapackManager getDatapackManager() {
return server.getDatapackManager();
}
+
+ /**
+ * Gets the potion brewer.
+ *
+ * @return the potion brewer
+ */
+ public static @NotNull org.bukkit.potion.PotionBrewer getPotionBrewer() {
+ return server.getPotionBrewer();
+ }
// Paper end
@NotNull
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
2024-07-06 21:19:14 +02:00
index 04b7225486ee61ee66bc8423e46e620c6da9e41d..28e883ffb5c4db22613035899be4a627c230fbf4 100644
2022-02-23 04:09:15 +01:00
--- a/src/main/java/org/bukkit/Server.java
+++ b/src/main/java/org/bukkit/Server.java
2024-07-06 21:19:14 +02:00
@@ -2293,5 +2293,12 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
2022-02-23 04:09:15 +01:00
*/
@NotNull
io.papermc.paper.datapack.DatapackManager getDatapackManager();
+
+ /**
+ * Gets the potion brewer.
+ *
+ * @return the potion brewer
+ */
+ @NotNull org.bukkit.potion.PotionBrewer getPotionBrewer();
// Paper end
}
diff --git a/src/main/java/org/bukkit/potion/PotionBrewer.java b/src/main/java/org/bukkit/potion/PotionBrewer.java
2024-04-27 01:17:13 +02:00
index 2072f048e10eba829cef047d854b5a22c8f055a3..c1bcbeef9cb634e6cb8c4b58bf06883c37cc028b 100644
2022-02-23 04:09:15 +01:00
--- a/src/main/java/org/bukkit/potion/PotionBrewer.java
+++ b/src/main/java/org/bukkit/potion/PotionBrewer.java
2024-04-27 01:17:13 +02:00
@@ -4,10 +4,31 @@ import java.util.Collection;
import org.jetbrains.annotations.NotNull;
/**
- * Represents a brewer that can create {@link PotionEffect}s.
+ * Used to manage custom {@link io.papermc.paper.potion.PotionMix}s.
2024-04-25 19:42:24 +02:00
*/
public interface PotionBrewer {
2024-04-27 01:17:13 +02:00
+ // Paper start
+ /**
+ * Adds a new potion mix recipe.
+ *
+ * @param potionMix the potion mix to add
+ */
+ void addPotionMix(@NotNull io.papermc.paper.potion.PotionMix potionMix);
+
+ /**
+ * Removes a potion mix recipe.
+ *
+ * @param key the key of the mix to remove
+ */
+ void removePotionMix(@NotNull org.bukkit.NamespacedKey key);
+
+ /**
+ * Resets potion mixes to their default, removing all custom ones.
+ */
+ void resetPotionMixes();
+ // Paper end
+
2024-04-25 19:42:24 +02:00
/**
* Creates a {@link PotionEffect} from the given {@link PotionEffectType},
* applying duration modifiers and checks.
2024-04-27 01:17:13 +02:00
@@ -16,9 +37,15 @@ public interface PotionBrewer {
2024-04-25 19:42:24 +02:00
* @param duration The duration in ticks
* @param amplifier The amplifier of the effect
* @return The resulting potion effect
+ * @deprecated use {@link PotionEffectType#createEffect(int, int)} instead.
*/
2024-04-27 01:17:13 +02:00
+ @Deprecated(forRemoval = true, since = "1.20.5") // Paper
2024-04-25 19:42:24 +02:00
@NotNull
- public PotionEffect createEffect(@NotNull PotionEffectType potion, int duration, int amplifier);
2024-04-27 01:17:13 +02:00
+ // Paper start - make default
2024-04-25 19:42:24 +02:00
+ default PotionEffect createEffect(@NotNull PotionEffectType potion, int duration, int amplifier) {
+ return potion.createEffect(duration, amplifier);
+ }
2024-04-27 01:17:13 +02:00
+ // Paper end
2024-04-25 19:42:24 +02:00
/**
* Returns a collection of {@link PotionEffect} that would be applied from
2024-04-27 01:17:13 +02:00
@@ -28,9 +55,13 @@ public interface PotionBrewer {
2024-04-25 19:42:24 +02:00
* @return The list of effects
* @deprecated Non-Functional
*/
- @Deprecated
2024-04-27 01:17:13 +02:00
+ @Deprecated(forRemoval = true, since = "1.20.5") // Paper
2024-04-25 19:42:24 +02:00
@NotNull
- public Collection<PotionEffect> getEffectsFromDamage(int damage);
2024-04-27 01:17:13 +02:00
+ // Paper start - make default
2024-04-25 19:42:24 +02:00
+ default Collection<PotionEffect> getEffectsFromDamage(final int damage) {
+ return new java.util.ArrayList<>();
+ }
2024-04-27 01:17:13 +02:00
+ // Paper end
2024-04-25 19:42:24 +02:00
/**
* Returns a collection of {@link PotionEffect} that would be applied from
2024-04-27 01:17:13 +02:00
@@ -43,6 +74,6 @@ public interface PotionBrewer {
2024-04-25 19:42:24 +02:00
* @deprecated Upgraded / extended potions are now their own {@link PotionType} use {@link PotionType#getPotionEffects()} instead
*/
2022-02-23 04:09:15 +01:00
@NotNull
2024-04-25 19:42:24 +02:00
- @Deprecated
2024-04-27 01:17:13 +02:00
+ @Deprecated(forRemoval = true, since = "1.20.5") // Paper
2022-02-23 04:09:15 +01:00
public Collection<PotionEffect> getEffects(@NotNull PotionType type, boolean upgraded, boolean extended);
}