diff options
Diffstat (limited to 'patches/server/0686-Custom-Potion-Mixes.patch')
-rw-r--r-- | patches/server/0686-Custom-Potion-Mixes.patch | 329 |
1 files changed, 329 insertions, 0 deletions
diff --git a/patches/server/0686-Custom-Potion-Mixes.patch b/patches/server/0686-Custom-Potion-Mixes.patch new file mode 100644 index 0000000000..1a33bb32b6 --- /dev/null +++ b/patches/server/0686-Custom-Potion-Mixes.patch @@ -0,0 +1,329 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic <[email protected]> +Date: Thu, 7 Oct 2021 14:34:55 -0700 +Subject: [PATCH] Custom Potion Mixes + +== AT == +public-f net.minecraft.server.MinecraftServer potionBrewing + +diff --git a/src/main/java/io/papermc/paper/potion/PaperPotionBrewer.java b/src/main/java/io/papermc/paper/potion/PaperPotionBrewer.java +new file mode 100644 +index 0000000000000000000000000000000000000000..d9390227a2bba4e03aa9ee592ca157127633c41b +--- /dev/null ++++ b/src/main/java/io/papermc/paper/potion/PaperPotionBrewer.java +@@ -0,0 +1,56 @@ ++package io.papermc.paper.potion; ++ ++import com.google.common.base.Preconditions; ++import java.util.Collection; ++import net.minecraft.server.MinecraftServer; ++import org.bukkit.NamespacedKey; ++import org.bukkit.potion.PotionBrewer; ++import org.bukkit.potion.PotionEffect; ++import org.bukkit.potion.PotionType; ++import org.checkerframework.checker.nullness.qual.NonNull; ++import org.checkerframework.framework.qual.DefaultQualifier; ++ ++@DefaultQualifier(NonNull.class) ++public class PaperPotionBrewer implements PotionBrewer { ++ ++ private final MinecraftServer minecraftServer; ++ ++ public PaperPotionBrewer(final MinecraftServer minecraftServer) { ++ this.minecraftServer = minecraftServer; ++ } ++ ++ @Override ++ @Deprecated(forRemoval = true) ++ public Collection<PotionEffect> getEffects(PotionType type, boolean upgraded, boolean extended) { ++ final org.bukkit.NamespacedKey key = type.getKey(); ++ ++ Preconditions.checkArgument(!key.getKey().startsWith("strong_"), "Strong potion type cannot be used directly, got %s", key); ++ Preconditions.checkArgument(!key.getKey().startsWith("long_"), "Extended potion type cannot be used directly, got %s", key); ++ ++ org.bukkit.NamespacedKey effectiveKey = key; ++ if (upgraded) { ++ effectiveKey = new org.bukkit.NamespacedKey(key.namespace(), "strong_" + key.key()); ++ } else if (extended) { ++ effectiveKey = new org.bukkit.NamespacedKey(key.namespace(), "long_" + key.key()); ++ } ++ ++ final org.bukkit.potion.PotionType effectivePotionType = org.bukkit.Registry.POTION.get(effectiveKey); ++ Preconditions.checkNotNull(type, "Unknown potion type from data " + effectiveKey.asMinimalString()); // Legacy error message in 1.20.4 ++ return effectivePotionType.getPotionEffects(); ++ } ++ ++ @Override ++ public void addPotionMix(final PotionMix potionMix) { ++ this.minecraftServer.potionBrewing().addPotionMix(potionMix); ++ } ++ ++ @Override ++ public void removePotionMix(final NamespacedKey key) { ++ this.minecraftServer.potionBrewing.removePotionMix(key); ++ } ++ ++ @Override ++ public void resetPotionMixes() { ++ this.minecraftServer.potionBrewing = this.minecraftServer.potionBrewing().reload(this.minecraftServer.getWorldData().enabledFeatures()); ++ } ++} +diff --git a/src/main/java/io/papermc/paper/potion/PaperPotionMix.java b/src/main/java/io/papermc/paper/potion/PaperPotionMix.java +new file mode 100644 +index 0000000000000000000000000000000000000000..7ea357ac2f3a93db4ebdf24b5072be7d1cad3e33 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/potion/PaperPotionMix.java +@@ -0,0 +1,21 @@ ++package io.papermc.paper.potion; ++ ++import java.util.function.Predicate; ++import net.minecraft.world.item.ItemStack; ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.craftbukkit.inventory.CraftRecipe; ++import org.bukkit.inventory.RecipeChoice; ++ ++public record PaperPotionMix(ItemStack result, Predicate<ItemStack> input, Predicate<ItemStack> ingredient) { ++ ++ public PaperPotionMix(PotionMix potionMix) { ++ this(CraftItemStack.asNMSCopy(potionMix.getResult()), convert(potionMix.getInput()), convert(potionMix.getIngredient())); ++ } ++ ++ static Predicate<ItemStack> convert(final RecipeChoice choice) { ++ if (choice instanceof PredicateRecipeChoice predicateRecipeChoice) { ++ return stack -> predicateRecipeChoice.test(CraftItemStack.asBukkitCopy(stack)); ++ } ++ return CraftRecipe.toIngredient(choice, true); ++ } ++} +diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java +index f9a4b5558bacff9c478f407c2656cb08588f421f..6f72020fab6e4e175a265f85ec9efc31811bdbfd 100644 +--- a/src/main/java/net/minecraft/server/MinecraftServer.java ++++ b/src/main/java/net/minecraft/server/MinecraftServer.java +@@ -2138,6 +2138,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa + + this.worldData.setDataConfiguration(worlddataconfiguration); + this.resources.managers.updateRegistryTags(); ++ this.potionBrewing = this.potionBrewing.reload(this.worldData.enabledFeatures()); // Paper - Custom Potion Mixes + this.getPlayerList().saveAll(); + this.getPlayerList().reloadResources(); + this.functionManager.replaceLibrary(this.resources.managers.getFunctionLibrary()); +diff --git a/src/main/java/net/minecraft/world/inventory/BrewingStandMenu.java b/src/main/java/net/minecraft/world/inventory/BrewingStandMenu.java +index 8be4e04df480faaa3aac516012709e9ff852f8a5..ed3ea6d19a0f0586034574d04332be4312c601b9 100644 +--- a/src/main/java/net/minecraft/world/inventory/BrewingStandMenu.java ++++ b/src/main/java/net/minecraft/world/inventory/BrewingStandMenu.java +@@ -53,9 +53,11 @@ public class BrewingStandMenu extends AbstractContainerMenu { + this.brewingStandData = propertyDelegate; + PotionBrewing potionbrewer = playerInventory.player.level().potionBrewing(); + +- this.addSlot(new BrewingStandMenu.PotionSlot(inventory, 0, 56, 51)); +- this.addSlot(new BrewingStandMenu.PotionSlot(inventory, 1, 79, 58)); +- this.addSlot(new BrewingStandMenu.PotionSlot(inventory, 2, 102, 51)); ++ // Paper start - custom potion mixes ++ this.addSlot(new BrewingStandMenu.PotionSlot(inventory, 0, 56, 51, potionbrewer)); ++ this.addSlot(new BrewingStandMenu.PotionSlot(inventory, 1, 79, 58, potionbrewer)); ++ this.addSlot(new BrewingStandMenu.PotionSlot(inventory, 2, 102, 51, potionbrewer)); ++ // Paper end - custom potion mixes + this.ingredientSlot = this.addSlot(new BrewingStandMenu.IngredientsSlot(potionbrewer, inventory, 3, 79, 17)); + this.addSlot(new BrewingStandMenu.FuelSlot(inventory, 4, 17, 17)); + this.addDataSlots(propertyDelegate); +@@ -98,7 +100,7 @@ public class BrewingStandMenu extends AbstractContainerMenu { + if (!this.moveItemStackTo(itemstack1, 3, 4, false)) { + return ItemStack.EMPTY; + } +- } else if (BrewingStandMenu.PotionSlot.mayPlaceItem(itemstack)) { ++ } else if (BrewingStandMenu.PotionSlot.mayPlaceItem(itemstack, this.player.player.level().potionBrewing())) { // Paper - custom potion mixes + if (!this.moveItemStackTo(itemstack1, 0, 3, false)) { + return ItemStack.EMPTY; + } +@@ -147,13 +149,15 @@ public class BrewingStandMenu extends AbstractContainerMenu { + + private static class PotionSlot extends Slot { + +- public PotionSlot(Container inventory, int index, int x, int y) { ++ private final PotionBrewing potionBrewing; // Paper - custom potion mixes ++ public PotionSlot(Container inventory, int index, int x, int y, PotionBrewing potionBrewing) { // Paper - custom potion mixes + super(inventory, index, x, y); ++ this.potionBrewing = potionBrewing; // Paper - custom potion mixes + } + + @Override + public boolean mayPlace(ItemStack stack) { +- return PotionSlot.mayPlaceItem(stack); ++ return PotionSlot.mayPlaceItem(stack, this.potionBrewing); // Paper - custom potion mixes + } + + @Override +@@ -172,8 +176,8 @@ public class BrewingStandMenu extends AbstractContainerMenu { + super.onTake(player, stack); + } + +- public static boolean mayPlaceItem(ItemStack stack) { +- return stack.is(Items.POTION) || stack.is(Items.SPLASH_POTION) || stack.is(Items.LINGERING_POTION) || stack.is(Items.GLASS_BOTTLE); ++ public static boolean mayPlaceItem(ItemStack stack, PotionBrewing potionBrewing) { // Paper - custom potion mixes ++ return stack.is(Items.POTION) || stack.is(Items.SPLASH_POTION) || stack.is(Items.LINGERING_POTION) || stack.is(Items.GLASS_BOTTLE) || potionBrewing.isCustomInput(stack); // Paper - Custom Potion Mixes + } + } + +diff --git a/src/main/java/net/minecraft/world/item/alchemy/PotionBrewing.java b/src/main/java/net/minecraft/world/item/alchemy/PotionBrewing.java +index 50e81e3babd331077eda8daa769eb2b3f99e8ca2..ca01f3344005b295c7ae98f6d5b03f79513b12a4 100644 +--- a/src/main/java/net/minecraft/world/item/alchemy/PotionBrewing.java ++++ b/src/main/java/net/minecraft/world/item/alchemy/PotionBrewing.java +@@ -19,6 +19,7 @@ public class PotionBrewing { + private final List<Ingredient> containers; + private final List<PotionBrewing.Mix<Potion>> potionMixes; + private final List<PotionBrewing.Mix<Item>> containerMixes; ++ private final it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap<org.bukkit.NamespacedKey, io.papermc.paper.potion.PaperPotionMix> customMixes = new it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap<>(); // Paper - Custom Potion Mixes + + PotionBrewing(List<Ingredient> potionTypes, List<PotionBrewing.Mix<Potion>> potionRecipes, List<PotionBrewing.Mix<Item>> itemRecipes) { + this.containers = potionTypes; +@@ -27,7 +28,7 @@ public class PotionBrewing { + } + + public boolean isIngredient(ItemStack stack) { +- return this.isContainerIngredient(stack) || this.isPotionIngredient(stack); ++ return this.isContainerIngredient(stack) || this.isPotionIngredient(stack) || this.isCustomIngredient(stack); // Paper - Custom Potion Mixes + } + + private boolean isContainer(ItemStack stack) { +@@ -71,6 +72,11 @@ public class PotionBrewing { + } + + public boolean hasMix(ItemStack input, ItemStack ingredient) { ++ // Paper start - Custom Potion Mixes ++ if (this.hasCustomMix(input, ingredient)) { ++ return true; ++ } ++ // Paper end - Custom Potion Mixes + return this.isContainer(input) && (this.hasContainerMix(input, ingredient) || this.hasPotionMix(input, ingredient)); + } + +@@ -103,6 +109,13 @@ public class PotionBrewing { + if (input.isEmpty()) { + return input; + } else { ++ // Paper start - Custom Potion Mixes ++ for (io.papermc.paper.potion.PaperPotionMix mix : this.customMixes.values()) { ++ if (mix.input().test(input) && mix.ingredient().test(ingredient)) { ++ return mix.result().copy(); ++ } ++ } ++ // Paper end - Custom Potion Mixes + Optional<Holder<Potion>> optional = input.getOrDefault(DataComponents.POTION_CONTENTS, PotionContents.EMPTY).potion(); + if (optional.isEmpty()) { + return input; +@@ -190,6 +203,50 @@ public class PotionBrewing { + builder.addMix(Potions.SLOW_FALLING, Items.REDSTONE, Potions.LONG_SLOW_FALLING); + } + ++ // Paper start - Custom Potion Mixes ++ public boolean isCustomIngredient(ItemStack stack) { ++ for (io.papermc.paper.potion.PaperPotionMix mix : this.customMixes.values()) { ++ if (mix.ingredient().test(stack)) { ++ return true; ++ } ++ } ++ return false; ++ } ++ ++ public boolean isCustomInput(ItemStack stack) { ++ for (io.papermc.paper.potion.PaperPotionMix mix : this.customMixes.values()) { ++ if (mix.input().test(stack)) { ++ return true; ++ } ++ } ++ return false; ++ } ++ ++ private boolean hasCustomMix(ItemStack input, ItemStack ingredient) { ++ for (io.papermc.paper.potion.PaperPotionMix mix : this.customMixes.values()) { ++ if (mix.input().test(input) && mix.ingredient().test(ingredient)) { ++ return true; ++ } ++ } ++ return false; ++ } ++ ++ public void addPotionMix(io.papermc.paper.potion.PotionMix mix) { ++ if (this.customMixes.containsKey(mix.getKey())) { ++ throw new IllegalArgumentException("Duplicate recipe ignored with ID " + mix.getKey()); ++ } ++ this.customMixes.putAndMoveToFirst(mix.getKey(), new io.papermc.paper.potion.PaperPotionMix(mix)); ++ } ++ ++ public boolean removePotionMix(org.bukkit.NamespacedKey key) { ++ return this.customMixes.remove(key) != null; ++ } ++ ++ public PotionBrewing reload(FeatureFlagSet flags) { ++ return bootstrap(flags); ++ } ++ // Paper end - Custom Potion Mixes ++ + public static class Builder { + private final List<Ingredient> containers = new ArrayList<>(); + private final List<PotionBrewing.Mix<Potion>> potionMixes = new ArrayList<>(); +diff --git a/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java +index 3ebfd564d4bbf00da5919e966f3d047285845640..887957ce1ddc2f32569405642f35df468c08271f 100644 +--- a/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java ++++ b/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java +@@ -311,12 +311,12 @@ public class BrewingStandBlockEntity extends BaseContainerBlockEntity implements + + @Override + public boolean canPlaceItem(int slot, ItemStack stack) { ++ PotionBrewing potionbrewer = this.level != null ? this.level.potionBrewing() : PotionBrewing.EMPTY; // Paper - move up + if (slot == 3) { +- PotionBrewing potionbrewer = this.level != null ? this.level.potionBrewing() : PotionBrewing.EMPTY; + + return potionbrewer.isIngredient(stack); + } else { +- return slot == 4 ? stack.is(Items.BLAZE_POWDER) : (stack.is(Items.POTION) || stack.is(Items.SPLASH_POTION) || stack.is(Items.LINGERING_POTION) || stack.is(Items.GLASS_BOTTLE)) && this.getItem(slot).isEmpty(); ++ return slot == 4 ? stack.is(Items.BLAZE_POWDER) : (stack.is(Items.POTION) || stack.is(Items.SPLASH_POTION) || stack.is(Items.LINGERING_POTION) || stack.is(Items.GLASS_BOTTLE) || potionbrewer.isCustomInput(stack)) && this.getItem(slot).isEmpty(); // Paper - Custom Potion Mixes + } + } + +diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +index 5bfa93a55e486a9d26fc174db87f0f6705522363..9ef7950eefea0693e51622cd55258fa1a884e961 100644 +--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +@@ -304,6 +304,7 @@ public final class CraftServer implements Server { + private final io.papermc.paper.datapack.PaperDatapackManager datapackManager; // Paper + public static Exception excessiveVelEx; // Paper - Velocity warnings + private final io.papermc.paper.logging.SysoutCatcher sysoutCatcher = new io.papermc.paper.logging.SysoutCatcher(); // Paper ++ private final io.papermc.paper.potion.PaperPotionBrewer potionBrewer; // Paper - Custom Potion Mixes + + static { + ConfigurationSerialization.registerClass(CraftOfflinePlayer.class); +@@ -385,6 +386,7 @@ public final class CraftServer implements Server { + if (this.configuration.getBoolean("settings.use-map-color-cache")) { + MapPalette.setMapColorCache(new CraftMapColorCache(this.logger)); + } ++ this.potionBrewer = new io.papermc.paper.potion.PaperPotionBrewer(console); // Paper - custom potion mixes + datapackManager = new io.papermc.paper.datapack.PaperDatapackManager(console.getPackRepository()); // Paper + } + +@@ -3093,5 +3095,9 @@ public final class CraftServer implements Server { + return datapackManager; + } + ++ @Override ++ public io.papermc.paper.potion.PaperPotionBrewer getPotionBrewer() { ++ return this.potionBrewer; ++ } + // Paper end + } +diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java +index 139dff90561ac6c51954c6289918a07aeea13a1b..6ba29875d78ede4aa7978ff689e588f7fed11528 100644 +--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java ++++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java +@@ -15,6 +15,11 @@ public interface CraftRecipe extends Recipe { + void addToCraftingManager(); + + default Ingredient toNMS(RecipeChoice bukkit, boolean requireNotEmpty) { ++ // Paper start ++ return toIngredient(bukkit, requireNotEmpty); ++ } ++ static Ingredient toIngredient(RecipeChoice bukkit, boolean requireNotEmpty) { ++ // Paper end + Ingredient stack; + + if (bukkit == null) { |