mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-30 12:57:41 +01:00
ac554ad46d
Updated Upstream (Bukkit/CraftBukkit) 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: fa99e752 PR-1007: Add ItemMeta#getAsComponentString() 94a91782 Fix copy-pasted BlockType.Typed documentation 9b34ac8c Largely restore deprecated PotionData API 51a6449b PR-1008: Deprecate ITEMS_TOOLS, removed in 1.20.5 702d15fe Fix Javadoc reference 42f6cdf4 PR-919: Add internal ItemType and BlockType, delegate Material methods to them 237bb37b SPIGOT-1166, SPIGOT-7647: Expose Damager BlockState in EntityDamageByBlockEvent 035ea146 SPIGOT-6993: Allow #setVelocity to change the speed of a fireball and add a note to #setDirection about it 8c7880fb PR-1004: Improve field rename handling and centralize conversion between bukkit and string more 87c90e93 SPIGOT-7650: Add DamageSource for EntityDeathEvent and PlayerDeathEvent CraftBukkit Changes: 4af0f22e8 SPIGOT-7664: Item meta should prevail over block states c2ccc46ec SPIGOT-7666: Fix access to llama and horse special slot 124ac66d7 SPIGOT-7665: Fix ThrownPotion#getEffects() implementation only bringing custom effects 66f1f439a Restore null page behaviour of signed books even though not strictly allowed by API 6118e5398 Fix regression listening to minecraft:brand custom payloads c1a26b366 Fix unnecessary and potential not thread-safe chat visibility check 12360a7ec Remove unused imports 147b098b4 PR-1397: Add ItemMeta#getAsComponentString() 428aefe0e Largely restore deprecated PotionData API afe5b5ee9 PR-1275: Add internal ItemType and BlockType, delegate Material methods to them 8afeafa7d SPIGOT-1166, SPIGOT-7647: Expose Damager BlockState in EntityDamageByBlockEvent 4e7d749d4 SPIGOT-6993: Allow #setVelocity to change the speed of a fireball and add a note to #setDirection about it 441880757 Support both entity_data and bucket_entity_data on axolotl/fish buckets 0e22fdd1e Fix custom direct BlockState being not correctly set in DamageSource f2182ed47 SPIGOT-7659: TropicalFishBucketMeta should use BUCKET_ENTITY_DATA 2a6207fe1 PR-1393: Improve field rename handling and centralize conversion between bukkit and string more c024a5039 SPIGOT-7650: Add DamageSource for EntityDeathEvent and PlayerDeathEvent 741b84480 PR-1390: Improve internal handling of damage sources 0364df4e1 SPIGOT-7657: Error when loading angry entities
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 af5c6893859530f65724869d18b6677e6f556dc2..18a73cc12615ecc7e61e8f96e6d8a3aa2ffe6e1f 100644
|
|
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
@@ -2141,6 +2141,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 d6a0e7eb9ee643fa42e1f568eb76041ddd43871e..9b0cabd9fdcaab31f291894e370a7cc2d8e24825 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
|
@@ -309,6 +309,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);
|
|
@@ -390,6 +391,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
|
|
}
|
|
|
|
@@ -3100,5 +3102,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) {
|