package io.papermc.paper.potion; import java.util.Objects; import java.util.function.Predicate; import org.bukkit.Keyed; import org.bukkit.NamespacedKey; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.RecipeChoice; import org.jetbrains.annotations.Contract; import org.jspecify.annotations.NullMarked; /** * Represents a potion mix made in a Brewing Stand. */ @NullMarked public final 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 */ public PotionMix(final NamespacedKey key, final ItemStack result, final RecipeChoice input, final RecipeChoice ingredient) { this.key = key; this.result = result; this.input = input; this.ingredient = ingredient; } /** * 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 RecipeChoice createPredicateChoice(final Predicate stackPredicate) { return new PredicateRecipeChoice(stackPredicate); } @Override public NamespacedKey getKey() { return this.key; } /** * Gets the resulting itemstack after the brew has finished. * * @return the result itemstack */ public ItemStack getResult() { return this.result; } /** * Gets the input for the bottom 3 slots in the brewing stand. * * @return the bottom 3 slot ingredients */ public RecipeChoice getInput() { return this.input; } /** * Gets the ingredient in the top slot of the brewing stand. * * @return the top slot input */ public RecipeChoice getIngredient() { return this.ingredient; } @Override public String toString() { return "PotionMix{" + "result=" + this.result + ", base=" + this.input + ", addition=" + this.ingredient + '}'; } @Override public boolean equals(final Object o) { if (this == o) return true; if (o == null || this.getClass() != o.getClass()) return false; final PotionMix potionMix = (PotionMix) o; 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); } }