mirror of
https://github.com/PaperMC/Paper.git
synced 2024-11-25 12:05:53 +01:00
77a5779e24
Upstream has released updates that appear to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing Bukkit Changes: 2ec53f49 PR-1050: Fix empty result check for Complex Recipes 10671012 PR-1044: Add CrafterCraftEvent 4d87ffe0 Use correct method in JavaDoc ae5e5817 SPIGOT-7850: Add API for Bogged shear state 46b6d445 SPIGOT-7837: Support data pack banner patterns d5d0cefc Fix JavaDoc error b3c2b83d PR-1036: Add API for InventoryView derivatives 1fe2c75a SPIGOT-7809: Add ShieldMeta CraftBukkit Changes: 8ee6fd1b8 SPIGOT-7857: Improve ItemMeta block data deserialization 8f26c30c6 SPIGOT-7857: Fix spurious internal NBT tag when deserializing BlockStateMeta 759061b93 SPIGOT-7855: Fire does not spread or burn blocks 00fc9fb64 SPIGOT-7853: AnvilInventory#getRepairCost() always returns 0 7501e2e04 PR-1450: Add CrafterCraftEvent 8c51673e7 SPIGOT-5731: PortalCreateEvent#getEntity returns null for nether portals ignited by flint and steel d53d0d0b1 PR-1456: Fix inverted logic in CraftCrafterView#setSlotDisabled 682a678c8 SPIGOT-7850: Add API for Bogged shear state fccf5243a SPIGOT-7837: Support data pack banner patterns 9c3bd4390 PR-1431: Add API for InventoryView derivatives 0cc6acbc4 SPIGOT-7849: Fix FoodComponent serialize with "using-converts-to" using null 2c5474952 Don't rely on tags for CraftItemMetas 20d107e46 SPIGOT-7846: Fix ItemMeta for hanging signs 76f59e315 Remove redundant clone in Dropper InventoryMoveItemEvent e61a53d25 SPIGOT-7817: Call InventoryMoveItemEvent for Crafters 894682e2d SPIGOT-7839: Remove redundant Java version checks 2c12b2187 SPIGOT-7809: Add ShieldMeta and fix setting shield base colours Spigot Changes: fb8fb722 Rebuild patches 34bd42b7 SPIGOT-7835: Fix issue with custom hopper settings
330 lines
17 KiB
Diff
330 lines
17 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
|
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 04286e907ff14cc8c45dbfc6ab12f520afcca2ca..8142e4a238066404f3d1685f9cee1a2b91cdd371 100644
|
|
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
@@ -2160,6 +2160,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 993abd8b0b80bfc7a1ce936eaaf3e0804fc9e0a4..eb2cdb36366e376b4e91aea847170b82ca26d274 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 c8f9972ad1c2330908cc840d426f29c20b242ca8..a2fafef89d5354e2cb02f5672810909950a57777 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
|
|
@@ -315,12 +315,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 6f6d4a82c350864a60f084eb341d59cf025cde77..ee6bdc985e8396e873bfd5c1f1d0046e2e830784 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
|
@@ -308,6 +308,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);
|
|
@@ -391,6 +392,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
|
|
}
|
|
|
|
@@ -3049,5 +3051,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) {
|