diff --git a/patches/server/0253-Shears-can-have-looting-enchantment.patch b/patches/server/0253-Shears-can-have-looting-enchantment.patch new file mode 100644 index 000000000..31920e331 --- /dev/null +++ b/patches/server/0253-Shears-can-have-looting-enchantment.patch @@ -0,0 +1,179 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: BillyGalbreath +Date: Mon, 3 Jan 2022 00:06:51 -0600 +Subject: [PATCH] Shears can have looting enchantment + + +diff --git a/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java +index c861505325efecfb53069ce44c14bc20fb851c59..405884a6ab983eed56554eeba6d6acd483b13374 100644 +--- a/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java ++++ b/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java +@@ -106,7 +106,7 @@ public class ShearsDispenseItemBehavior extends OptionalDispenseItemBehavior { + continue; + } + // CraftBukkit end +- ishearable.shear(SoundSource.BLOCKS); ++ ishearable.shear(SoundSource.BLOCKS, net.minecraft.world.item.enchantment.EnchantmentHelper.getItemEnchantmentLevel(net.minecraft.world.item.enchantment.Enchantments.MOB_LOOTING, CraftItemStack.asNMSCopy(craftItem))); // Purpur + worldserver.gameEvent((Entity) null, GameEvent.SHEAR, blockposition); + return true; + } +diff --git a/src/main/java/net/minecraft/world/entity/Shearable.java b/src/main/java/net/minecraft/world/entity/Shearable.java +index 5e8cc5cfac8888628c6d513148f41be09ca65a2c..a089fc61ec09be6b7490375489178dc6ba5a644b 100644 +--- a/src/main/java/net/minecraft/world/entity/Shearable.java ++++ b/src/main/java/net/minecraft/world/entity/Shearable.java +@@ -3,7 +3,13 @@ package net.minecraft.world.entity; + import net.minecraft.sounds.SoundSource; + + public interface Shearable { +- void shear(SoundSource shearedSoundCategory); ++ // Purpur start ++ default void shear(SoundSource shearedSoundCategory) { ++ shear(shearedSoundCategory, 0); ++ } ++ ++ void shear(SoundSource shearedSoundCategory, int looting); ++ // Purpur end + + boolean readyForShearing(); + } +diff --git a/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java b/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java +index 16b4b6a382db7c81eb19771a4fa0cc3ae73c3645..6fc17adcfd300796579badc5af3ce2e8c1baf928 100644 +--- a/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java ++++ b/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java +@@ -161,7 +161,7 @@ public class MushroomCow extends Cow implements Shearable { + return tryRide(player, hand); // Purpur + } + // CraftBukkit end +- this.shear(SoundSource.PLAYERS); ++ this.shear(SoundSource.PLAYERS, net.minecraft.world.item.enchantment.EnchantmentHelper.getMobLooting(player)); // Purpur + this.gameEvent(GameEvent.SHEAR, (Entity) player); + if (!this.level.isClientSide) { + itemstack.hurtAndBreak(1, player, (entityhuman1) -> { +@@ -204,7 +204,7 @@ public class MushroomCow extends Cow implements Shearable { + } + + @Override +- public void shear(SoundSource shearedSoundCategory) { ++ public void shear(SoundSource shearedSoundCategory, int looting) { // Purpur + this.level.playSound((Player) null, (Entity) this, SoundEvents.MOOSHROOM_SHEAR, shearedSoundCategory, 1.0F, 1.0F); + if (!this.level.isClientSide()) { + ((ServerLevel) this.level).sendParticles(ParticleTypes.EXPLOSION, this.getX(), this.getY(0.5D), this.getZ(), 1, 0.0D, 0.0D, 0.0D, 0.0D); +@@ -239,7 +239,7 @@ public class MushroomCow extends Cow implements Shearable { + this.discard(); // CraftBukkit - from above + // CraftBukkit end + +- for (int i = 0; i < 5; ++i) { ++ for (int i = 0; i < 5 + (org.purpurmc.purpur.PurpurConfig.allowShearsLooting ? looting : 0); ++i) { // Purpur + // CraftBukkit start + ItemEntity entityitem = new ItemEntity(this.level, this.getX(), this.getY(1.0D), this.getZ(), new ItemStack(this.getMushroomType().blockState.getBlock())); + EntityDropItemEvent event = new EntityDropItemEvent(this.getBukkitEntity(), (org.bukkit.entity.Item) entityitem.getBukkitEntity()); +diff --git a/src/main/java/net/minecraft/world/entity/animal/Sheep.java b/src/main/java/net/minecraft/world/entity/animal/Sheep.java +index 3e72abd93bc5b9f97c2bd62702273d63b43cc245..6c044f123c0cdcdaec93b6761a117493c4a5bbe8 100644 +--- a/src/main/java/net/minecraft/world/entity/animal/Sheep.java ++++ b/src/main/java/net/minecraft/world/entity/animal/Sheep.java +@@ -266,7 +266,7 @@ public class Sheep extends Animal implements Shearable { + return InteractionResult.PASS; + } + // CraftBukkit end +- this.shear(SoundSource.PLAYERS); ++ this.shear(SoundSource.PLAYERS, net.minecraft.world.item.enchantment.EnchantmentHelper.getMobLooting(player)); // Purpur + this.gameEvent(GameEvent.SHEAR, (Entity) player); + itemstack.hurtAndBreak(1, player, (entityhuman1) -> { + entityhuman1.broadcastBreakEvent(hand); +@@ -281,10 +281,11 @@ public class Sheep extends Animal implements Shearable { + } + + @Override +- public void shear(SoundSource shearedSoundCategory) { ++ public void shear(SoundSource shearedSoundCategory, int looting) { // Purpur + this.level.playSound((Player) null, (Entity) this, SoundEvents.SHEEP_SHEAR, shearedSoundCategory, 1.0F, 1.0F); + this.setSheared(true); + int i = 1 + this.random.nextInt(3); ++ if (org.purpurmc.purpur.PurpurConfig.allowShearsLooting) i += looting; // Purpur + + for (int j = 0; j < i; ++j) { + this.forceDrops = true; // CraftBukkit +diff --git a/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java b/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java +index d60cb629586e6eccfcd79b1b2e4da119550497f3..465bd5c7401ec29d0c43d9add3b072542a2c7923 100644 +--- a/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java ++++ b/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java +@@ -195,7 +195,7 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM + return tryRide(player, hand); // Purpur + } + // CraftBukkit end +- this.shear(SoundSource.PLAYERS); ++ this.shear(SoundSource.PLAYERS, net.minecraft.world.item.enchantment.EnchantmentHelper.getMobLooting(player)); // Purpur + this.gameEvent(GameEvent.SHEAR, (Entity) player); + if (!this.level.isClientSide) { + itemstack.hurtAndBreak(1, player, (entityhuman1) -> { +@@ -218,12 +218,13 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM + } + + @Override +- public void shear(SoundSource shearedSoundCategory) { ++ public void shear(SoundSource shearedSoundCategory, int looting) { // Purpur + this.level.playSound((Player) null, (Entity) this, SoundEvents.SNOW_GOLEM_SHEAR, shearedSoundCategory, 1.0F, 1.0F); + if (!this.level.isClientSide()) { + this.setPumpkin(false); + this.forceDrops = true; // CraftBukkit + if (level.purpurConfig.snowGolemDropsPumpkin) // Purpur ++ for (int i = 0; i < 1 + (org.purpurmc.purpur.PurpurConfig.allowShearsLooting ? looting : 0); i++) // Purpur + this.spawnAtLocation(new ItemStack(Items.CARVED_PUMPKIN), 1.7F); + this.forceDrops = false; // CraftBukkit + } +diff --git a/src/main/java/net/minecraft/world/item/enchantment/EnchantmentCategory.java b/src/main/java/net/minecraft/world/item/enchantment/EnchantmentCategory.java +index d6417c1e77ac8823e18a179dc9f61757a1f339ad..90f3db3401d5b5ea5b9456f21d7f9bff0e48d364 100644 +--- a/src/main/java/net/minecraft/world/item/enchantment/EnchantmentCategory.java ++++ b/src/main/java/net/minecraft/world/item/enchantment/EnchantmentCategory.java +@@ -104,6 +104,12 @@ public enum EnchantmentCategory { + public boolean canEnchant(Item item) { + return item instanceof BowItem || item instanceof CrossbowItem; + } ++ }, ++ SHEARS { ++ @Override ++ public boolean canEnchant(Item item) { ++ return item instanceof net.minecraft.world.item.ShearsItem; ++ } + // Purpur end + }; + +diff --git a/src/main/java/net/minecraft/world/item/enchantment/LootBonusEnchantment.java b/src/main/java/net/minecraft/world/item/enchantment/LootBonusEnchantment.java +index 6b8a1535086aae7e4e3229d05615fb903188f507..2c3d984cef5e589b72c5509c1eea1422865aa69c 100644 +--- a/src/main/java/net/minecraft/world/item/enchantment/LootBonusEnchantment.java ++++ b/src/main/java/net/minecraft/world/item/enchantment/LootBonusEnchantment.java +@@ -7,6 +7,14 @@ public class LootBonusEnchantment extends Enchantment { + super(weight, type, slotTypes); + } + ++ // Purpur start ++ @Override ++ public boolean canEnchant(net.minecraft.world.item.ItemStack stack) { ++ // we have to cheat the system because this class is loaded before purpur's config is loaded ++ return (org.purpurmc.purpur.PurpurConfig.allowShearsLooting ? EnchantmentCategory.SHEARS : this.category).canEnchant(stack.getItem()); ++ } ++ // Purpur end ++ + @Override + public int getMinCost(int level) { + return 15 + (level - 1) * 9; +diff --git a/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/src/main/java/org/purpurmc/purpur/PurpurConfig.java +index 6eb138a83460e049f711c67055fe6db4ff812e8c..f19e6c9af8cd559ba5a1492b0d579bf6182f342a 100644 +--- a/src/main/java/org/purpurmc/purpur/PurpurConfig.java ++++ b/src/main/java/org/purpurmc/purpur/PurpurConfig.java +@@ -340,6 +340,7 @@ public class PurpurConfig { + + public static boolean allowInfinityMending = false; + public static boolean allowCrossbowInfinity = false; ++ public static boolean allowShearsLooting = false; + public static boolean allowUnsafeEnchants = false; + private static void enchantmentSettings() { + if (version < 5) { +@@ -349,6 +350,7 @@ public class PurpurConfig { + } + allowInfinityMending = getBoolean("settings.enchantment.allow-infinity-and-mending-together", allowInfinityMending); + allowCrossbowInfinity = getBoolean("settings.enchantment.allow-infinity-on-crossbow", allowCrossbowInfinity); ++ allowShearsLooting = getBoolean("settings.enchantment.allow-looting-on-shears", allowShearsLooting); + allowUnsafeEnchants = getBoolean("settings.enchantment.allow-unsafe-enchants", allowUnsafeEnchants); + } +