From 2c1b5f78fc49dae41bec29d205c70a6355f74c5c Mon Sep 17 00:00:00 2001 From: Miles Holder Date: Thu, 9 Nov 2023 06:30:23 +1100 Subject: [PATCH] SPIGOT-7514, #1289: Add "Enchantment Roll" API to enchant items according to Minecraft mechanics --- .../net/minecraft/world/entity/Entity.patch | 9 +++++ .../inventory/CraftItemFactory.java | 39 +++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/nms-patches/net/minecraft/world/entity/Entity.patch b/nms-patches/net/minecraft/world/entity/Entity.patch index cd99fd620..6d4f25bfd 100644 --- a/nms-patches/net/minecraft/world/entity/Entity.patch +++ b/nms-patches/net/minecraft/world/entity/Entity.patch @@ -66,6 +66,15 @@ private static final Logger LOGGER = LogUtils.getLogger(); public static final String ID_TAG = "id"; public static final String PASSENGERS_TAG = "Passengers"; +@@ -189,7 +246,7 @@ + public double zOld; + private float maxUpStep; + public boolean noPhysics; +- protected final RandomSource random; ++ public final RandomSource random; + public int tickCount; + private int remainingFireTicks; + public boolean wasTouchingWater; @@ -241,6 +298,25 @@ public boolean hasVisualFire; @Nullable diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java index 5e53a822f..0096ad12d 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java @@ -6,15 +6,21 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException; import net.minecraft.commands.arguments.item.ArgumentParserItemStack; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.RandomSource; import net.minecraft.world.entity.EntityTypes; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemMonsterEgg; +import net.minecraft.world.item.enchantment.EnchantmentManager; import org.bukkit.Color; import org.bukkit.Material; +import org.bukkit.World; import org.bukkit.configuration.serialization.ConfigurationSerialization; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.entity.CraftEntity; import org.bukkit.craftbukkit.entity.CraftEntityType; import org.bukkit.craftbukkit.util.CraftLegacy; import org.bukkit.craftbukkit.util.CraftMagicNumbers; +import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.inventory.ItemFactory; import org.bukkit.inventory.ItemStack; @@ -23,6 +29,7 @@ import org.bukkit.inventory.meta.ItemMeta; public final class CraftItemFactory implements ItemFactory { static final Color DEFAULT_LEATHER_COLOR = Color.fromRGB(0xA06540); private static final CraftItemFactory instance; + private static final RandomSource randomSource = RandomSource.create(); static { instance = new CraftItemFactory(); @@ -457,4 +464,36 @@ public final class CraftItemFactory implements ItemFactory { return CraftMagicNumbers.getMaterial(nmsItem); } + + @Override + public ItemStack enchantItem(Entity entity, ItemStack itemStack, int level, boolean allowTreasures) { + Preconditions.checkArgument(entity != null, "The entity must not be null"); + + return enchantItem(((CraftEntity) entity).getHandle().random, itemStack, level, allowTreasures); + } + + @Override + public ItemStack enchantItem(final World world, final ItemStack itemStack, final int level, final boolean allowTreasures) { + Preconditions.checkArgument(world != null, "The world must not be null"); + + return enchantItem(((CraftWorld) world).getHandle().random, itemStack, level, allowTreasures); + } + + @Override + public ItemStack enchantItem(final ItemStack itemStack, final int level, final boolean allowTreasures) { + return enchantItem(randomSource, itemStack, level, allowTreasures); + } + + private static ItemStack enchantItem(RandomSource source, ItemStack itemStack, int level, boolean allowTreasures) { + Preconditions.checkArgument(itemStack != null, "ItemStack must not be null"); + Preconditions.checkArgument(!itemStack.getType().isAir(), "ItemStack must not be air"); + + if (!(itemStack instanceof CraftItemStack)) { + itemStack = CraftItemStack.asCraftCopy(itemStack); + } + + CraftItemStack craft = (CraftItemStack) itemStack; + EnchantmentManager.enchantItem(source, craft.handle, level, allowTreasures); + return craft; + } }