mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-28 15:30:19 +01:00
4d20922b79
* Updated Upstream (Bukkit/CraftBukkit/Spigot) 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: e86f4dc4 PR-1041: Improve getPlayer(String) docs to clarify it matches the name 9738f005 Fix spawner API documentation 69ebd9fd PR-1034: Add TrialSpawnerSpawnEvent 23cffd9c PR-973: Improve spawner API and add API for Trial Spawners 8bf19163 PR-1038: Clarify HumanEntity#openInventory(InventoryView) JavaDoc 1ff76351 SPIGOT-7732, SPIGOT-7786: Add freezing damage modifier 02161cb4 PR-1034: Add CreatureSpawnEvent.SpawnReason#TRIAL_SPAWNER f9cb6f34 SPIGOT-7777: All entity potion effects are removed on death 25d548eb PR-1031: Expose Creeper igniter ccbf0915 SPIGOT-7770: Reserve spaces in shaped recipes for blank ingredients 17f7097c Clarify ambiguity around what is API 71714f0c Remove note from InventoryView JavaDoc aaf49731 PR-1030: Deprecate more unused methods in UnsafeValues 3a9dc689 SPIGOT-7771: Material.getDefaultAttributes always returns an empty map CraftBukkit Changes: c3ceeb6f7 SPIGOT-7814: Call PlayerShearEntityEvent for Bogged 97b1e4f58 Fix wolf armor not dropping from use of shears fd2ef563a SPIGOT-7812: Revert "SPIGOT-7809: Restore shield/banner conversion for base colours" f672c351b SPIGOT-7811: Enchantments are applied on sweeping attack even if damage event is cancelled cfe29350b SPIGOT-7808: Fix implementation of Enchantment#getName() for bad name return 19335f69e SPIGOT-7809: Restore shield/banner conversion for base colours ae4f5a0be SPIGOT-7805: Fix jukebox deserialization 62e3b73a4 SPIGOT-7804: Fix written book serialization aac911d26 SPIGOT-7800, SPIGOT-7801: Keep vanilla behaviour for items dropped on player death 13ece474f PR-1429: Implement TrialSpawnerSpawnEvent bf13e9113 PR-1354: Improve spawner API and add API for Trial Spawners 515fe49e1 Increase outdated build delay 9cd5a19a0 SPIGOT-7794: Cancelling InventoryItemMoveEvent destroys items ce40c7b14 SPIGOT-7796: Kickplayer newlines not working 5167256ff SPIGOT-7795: Fix damage/stats ignore the invulnerable damage time f993563ee Improve cross-world teleportation handling ab29122cf PR-1433: HumanEntity#openInventory(InventoryView) should only support views belonging to the player 764a541c5 SPIGOT-7732: Issue with the "hurt()" method of EntityLiving and invulnerable time 820084b5f SPIGOT-7791: Skull BlockState with null profile causes NullPointerException 5e46f1c82 SPIGOT-7785: Teleporting a player at the right moment can mess up vanilla teleportation cbd95a6b3 SPIGOT-7772: Include hidden / non-sampled players in player count 3153debc5 SPIGOT-7790: Server crashes after bee nest is forced to update e77bb26bb SPIGOT-7788: The healing power of friendship advancement is never granted ee3d7258a SPIGOT-7789: Fix NPE in CraftMetaFirework applyToItem 2889b3a11 PR-1429: Add CreatureSpawnEvent.SpawnReason#TRIAL_SPAWNER cdd05bc7f SPIGOT-7777: Speed attribute stays after death; missing EntityPotionEffectEvent call d0e6af2d4 PR-1428: Expose Creeper igniter d01c70e93 PR-1425: Fix bytecode transformation taking care of class-to-interface compatibility. b2b08f68c SPIGOT-7770: Fix certain shaped recipes not registering 3f8e4161f PR-1426: Deprecate more unused methods in UnsafeValues 2c9dd879e SPIGOT-7771: Material.getDefaultAttributes always returns an empty map Spigot Changes: 491f3675 Rebuild patches 0a642bd7 Rebuild patches 8897571b Rebuild patches cb8cf80c Fix newlines in custom restart message 1aabe506 Rebuild patches
410 lines
23 KiB
Diff
410 lines
23 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
|
Date: Tue, 18 May 2021 12:32:02 -0700
|
|
Subject: [PATCH] Add drops to shear events
|
|
|
|
|
|
diff --git a/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java
|
|
index f32f8d5cb22feb885a53d3b56c04ad4219d2bafa..44b79a7c2f8b95a484d1999fa2167ce588f7985b 100644
|
|
--- a/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java
|
|
+++ b/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java
|
|
@@ -103,11 +103,14 @@ public class ShearsDispenseItemBehavior extends OptionalDispenseItemBehavior {
|
|
if (entityliving instanceof Shearable ishearable) {
|
|
if (ishearable.readyForShearing()) {
|
|
// CraftBukkit start
|
|
- if (CraftEventFactory.callBlockShearEntityEvent(entityliving, bukkitBlock, craftItem).isCancelled()) {
|
|
+ // Paper start - Add drops to shear events
|
|
+ org.bukkit.event.block.BlockShearEntityEvent event = CraftEventFactory.callBlockShearEntityEvent(entityliving, bukkitBlock, craftItem, ishearable.generateDefaultDrops());
|
|
+ if (event.isCancelled()) {
|
|
+ // Paper end - Add drops to shear events
|
|
continue;
|
|
}
|
|
// CraftBukkit end
|
|
- ishearable.shear(SoundSource.BLOCKS);
|
|
+ ishearable.shear(SoundSource.BLOCKS, CraftItemStack.asNMSCopy(event.getDrops())); // Paper - Add drops to shear events
|
|
worldserver.gameEvent((Entity) null, (Holder) 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..2ee48ac3b665db2b02bcb1a30ec972d43a3725b0 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 {
|
|
+ default void shear(SoundSource soundCategory, java.util.List<net.minecraft.world.item.ItemStack> drops) { this.shear(soundCategory); } // Paper - Add drops to shear events
|
|
void shear(SoundSource shearedSoundCategory);
|
|
|
|
boolean readyForShearing();
|
|
+ // Paper start - custom shear drops; ensure all implementing entities override this
|
|
+ default java.util.List<net.minecraft.world.item.ItemStack> generateDefaultDrops() {
|
|
+ return java.util.Collections.emptyList();
|
|
+ }
|
|
+ // Paper end - custom shear drops
|
|
}
|
|
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 aa125e3043b120935aaa015803f065f99eb8d050..0c21959f57ae88fcd0a4d6dc911c1ce347c96528 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java
|
|
@@ -123,11 +123,18 @@ public class MushroomCow extends Cow implements Shearable, VariantHolder<Mushroo
|
|
return InteractionResult.sidedSuccess(this.level().isClientSide);
|
|
} else if (itemstack.is(Items.SHEARS) && this.readyForShearing()) {
|
|
// CraftBukkit start
|
|
- if (!CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand)) {
|
|
- return InteractionResult.PASS;
|
|
+ // Paper start - custom shear drops
|
|
+ java.util.List<ItemStack> drops = this.generateDefaultDrops();
|
|
+ org.bukkit.event.player.PlayerShearEntityEvent event = CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand, drops);
|
|
+ if (event != null) {
|
|
+ if (event.isCancelled()) {
|
|
+ return InteractionResult.PASS;
|
|
+ }
|
|
+ drops = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getDrops());
|
|
}
|
|
+ // Paper end - custom shear drops
|
|
// CraftBukkit end
|
|
- this.shear(SoundSource.PLAYERS);
|
|
+ this.shear(SoundSource.PLAYERS, drops); // Paper - custom shear drops
|
|
this.gameEvent(GameEvent.SHEAR, player);
|
|
if (!this.level().isClientSide) {
|
|
itemstack.hurtAndBreak(1, player, getSlotForHand(hand));
|
|
@@ -164,6 +171,22 @@ public class MushroomCow extends Cow implements Shearable, VariantHolder<Mushroo
|
|
|
|
@Override
|
|
public void shear(SoundSource shearedSoundCategory) {
|
|
+ // Paper start - custom shear drops
|
|
+ this.shear(shearedSoundCategory, this.generateDefaultDrops());
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public java.util.List<ItemStack> generateDefaultDrops() {
|
|
+ java.util.List<ItemStack> dropEntities = new java.util.ArrayList<>(5);
|
|
+ for (int i = 0; i < 5; ++i) {
|
|
+ dropEntities.add(new ItemStack(this.getVariant().getBlockState().getBlock()));
|
|
+ }
|
|
+ return dropEntities;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void shear(SoundSource shearedSoundCategory, java.util.List<ItemStack> drops) { // If drops is null, need to generate drops
|
|
+ // Paper end - custom shear drops
|
|
this.level().playSound((Player) null, (Entity) this, SoundEvents.MOOSHROOM_SHEAR, shearedSoundCategory, 1.0F, 1.0F);
|
|
if (!this.level().isClientSide()) {
|
|
Cow entitycow = (Cow) EntityType.COW.create(this.level());
|
|
@@ -193,17 +216,12 @@ public class MushroomCow extends Cow implements Shearable, VariantHolder<Mushroo
|
|
this.discard(EntityRemoveEvent.Cause.TRANSFORMATION); // CraftBukkit - from above and add Bukkit remove cause
|
|
// CraftBukkit end
|
|
|
|
- for (int i = 0; i < 5; ++i) {
|
|
- // CraftBukkit start
|
|
- ItemEntity entityitem = new ItemEntity(this.level(), this.getX(), this.getY(1.0D), this.getZ(), new ItemStack(this.getVariant().blockState.getBlock()));
|
|
- EntityDropItemEvent event = new EntityDropItemEvent(this.getBukkitEntity(), (org.bukkit.entity.Item) entityitem.getBukkitEntity());
|
|
- Bukkit.getPluginManager().callEvent(event);
|
|
- if (event.isCancelled()) {
|
|
- continue;
|
|
- }
|
|
- this.level().addFreshEntity(entityitem);
|
|
- // CraftBukkit end
|
|
+ // Paper start - custom shear drops; moved drop generation to separate method
|
|
+ for (final ItemStack drop : drops) {
|
|
+ ItemEntity entityitem = new ItemEntity(this.level(), this.getX(), this.getY(1.0D), this.getZ(), drop);
|
|
+ this.spawnAtLocation(entityitem);
|
|
}
|
|
+ // Paper end - custom shear drops
|
|
}
|
|
}
|
|
|
|
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 6b26af41423110bd982eb8c0eea0cba5e9fdc633..38ac2759894660be1ee7ba59b0bd1270158e9232 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/animal/Sheep.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/animal/Sheep.java
|
|
@@ -256,11 +256,18 @@ public class Sheep extends Animal implements Shearable {
|
|
if (itemstack.is(Items.SHEARS)) {
|
|
if (!this.level().isClientSide && this.readyForShearing()) {
|
|
// CraftBukkit start
|
|
- if (!CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand)) {
|
|
- return InteractionResult.PASS;
|
|
+ // Paper start - custom shear drops
|
|
+ java.util.List<ItemStack> drops = this.generateDefaultDrops();
|
|
+ org.bukkit.event.player.PlayerShearEntityEvent event = CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand, drops);
|
|
+ if (event != null) {
|
|
+ if (event.isCancelled()) {
|
|
+ return InteractionResult.PASS;
|
|
+ }
|
|
+ drops = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getDrops());
|
|
}
|
|
+ // Paper end - custom shear drops
|
|
// CraftBukkit end
|
|
- this.shear(SoundSource.PLAYERS);
|
|
+ this.shear(SoundSource.PLAYERS, drops); // Paper
|
|
this.gameEvent(GameEvent.SHEAR, player);
|
|
itemstack.hurtAndBreak(1, player, getSlotForHand(hand));
|
|
return InteractionResult.SUCCESS;
|
|
@@ -274,13 +281,30 @@ public class Sheep extends Animal implements Shearable {
|
|
|
|
@Override
|
|
public void shear(SoundSource shearedSoundCategory) {
|
|
+ // Paper start - custom shear drops
|
|
+ this.shear(shearedSoundCategory, this.generateDefaultDrops());
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public java.util.List<ItemStack> generateDefaultDrops() {
|
|
+ int count = 1 + this.random.nextInt(3);
|
|
+ java.util.List<ItemStack> dropEntities = new java.util.ArrayList<>(count);
|
|
+ for (int j = 0; j < count; ++j) {
|
|
+ dropEntities.add(new ItemStack(Sheep.ITEM_BY_DYE.get(this.getColor())));
|
|
+ }
|
|
+ return dropEntities;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void shear(SoundSource shearedSoundCategory, java.util.List<ItemStack> drops) {
|
|
+ // Paper end - custom shear drops
|
|
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);
|
|
|
|
- for (int j = 0; j < i; ++j) {
|
|
+ for (final ItemStack drop : drops) { // Paper - custom shear drops (moved drop generation to separate method)
|
|
this.forceDrops = true; // CraftBukkit
|
|
- ItemEntity entityitem = this.spawnAtLocation((ItemLike) Sheep.ITEM_BY_DYE.get(this.getColor()), 1);
|
|
+ ItemEntity entityitem = this.spawnAtLocation(drop, 1); // Paper - custom shear drops
|
|
this.forceDrops = false; // CraftBukkit
|
|
|
|
if (entityitem != null) {
|
|
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 2de1a2f666da9db1832907e1651dbff948e37252..5c2ed3c39c8eb850f3be1e2ea5b5a7ea266e16d1 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java
|
|
@@ -146,11 +146,18 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM
|
|
|
|
if (itemstack.is(Items.SHEARS) && this.readyForShearing()) {
|
|
// CraftBukkit start
|
|
- if (!CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand)) {
|
|
- return InteractionResult.PASS;
|
|
+ // Paper start - custom shear drops
|
|
+ java.util.List<ItemStack> drops = this.generateDefaultDrops();
|
|
+ org.bukkit.event.player.PlayerShearEntityEvent event = CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand, drops);
|
|
+ if (event != null) {
|
|
+ if (event.isCancelled()) {
|
|
+ return InteractionResult.PASS;
|
|
+ }
|
|
+ drops = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getDrops());
|
|
}
|
|
+ // Paper end - custom shear drops
|
|
// CraftBukkit end
|
|
- this.shear(SoundSource.PLAYERS);
|
|
+ this.shear(SoundSource.PLAYERS, drops); // Paper
|
|
this.gameEvent(GameEvent.SHEAR, player);
|
|
if (!this.level().isClientSide) {
|
|
itemstack.hurtAndBreak(1, player, getSlotForHand(hand));
|
|
@@ -164,12 +171,28 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM
|
|
|
|
@Override
|
|
public void shear(SoundSource shearedSoundCategory) {
|
|
+ // Paper start - custom shear drops
|
|
+ this.shear(shearedSoundCategory, this.generateDefaultDrops());
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public java.util.List<ItemStack> generateDefaultDrops() {
|
|
+ return java.util.Collections.singletonList(new ItemStack(Items.CARVED_PUMPKIN));
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void shear(SoundSource shearedSoundCategory, java.util.List<ItemStack> drops) {
|
|
+ // Paper end - custom shear drops
|
|
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
|
|
- this.spawnAtLocation(new ItemStack(Items.CARVED_PUMPKIN), this.getEyeHeight());
|
|
- this.forceDrops = false; // CraftBukkit
|
|
+ // Paper start - custom shear drops (moved drop generation to separate method)
|
|
+ for (final ItemStack drop : drops) {
|
|
+ this.forceDrops = true;
|
|
+ this.spawnAtLocation(drop, this.getEyeHeight());
|
|
+ this.forceDrops = false;
|
|
+ }
|
|
+ // Paper end - custom shear drops
|
|
}
|
|
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/world/entity/monster/Bogged.java b/src/main/java/net/minecraft/world/entity/monster/Bogged.java
|
|
index dc6230458e09f7555eee7f6a567ff60ad454666b..9d50b9ac8084f3db1844cc7ad1ce9153614ff9d9 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/monster/Bogged.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/monster/Bogged.java
|
|
@@ -80,12 +80,19 @@ public class Bogged extends AbstractSkeleton implements Shearable {
|
|
|
|
if (itemstack.is(Items.SHEARS) && this.readyForShearing()) {
|
|
// CraftBukkit start
|
|
- if (!org.bukkit.craftbukkit.event.CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand)) {
|
|
- this.getEntityData().markDirty(Bogged.DATA_SHEARED); // CraftBukkit - mark dirty to restore sheared state to clients
|
|
- return InteractionResult.PASS;
|
|
+ // Paper start - expose drops in event
|
|
+ java.util.List<net.minecraft.world.item.ItemStack> drops = generateDefaultDrops();
|
|
+ final org.bukkit.event.player.PlayerShearEntityEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand, drops);
|
|
+ if (event != null) {
|
|
+ if (event.isCancelled()) {
|
|
+ if (player instanceof final net.minecraft.server.level.ServerPlayer serverPlayer) this.resendPossiblyDesyncedDataValues(java.util.List.of(Bogged.DATA_SHEARED), serverPlayer);
|
|
+ return InteractionResult.PASS;
|
|
+ }
|
|
+ drops = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getDrops());
|
|
+ // Paper end - expose drops in event
|
|
}
|
|
// CraftBukkit end
|
|
- this.shear(SoundSource.PLAYERS);
|
|
+ this.shear(SoundSource.PLAYERS, drops); // Paper - expose drops in event
|
|
this.gameEvent(GameEvent.SHEAR, player);
|
|
if (!this.level().isClientSide) {
|
|
itemstack.hurtAndBreak(1, player, getSlotForHand(hand));
|
|
@@ -140,12 +147,31 @@ public class Bogged extends AbstractSkeleton implements Shearable {
|
|
|
|
@Override
|
|
public void shear(SoundSource shearedSoundCategory) {
|
|
+ // Paper start - shear drop API
|
|
+ this.shear(shearedSoundCategory, generateDefaultDrops());
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void shear(SoundSource shearedSoundCategory, java.util.List<net.minecraft.world.item.ItemStack> drops) {
|
|
+ // Paper end - shear drop API
|
|
this.level().playSound((Player) null, (Entity) this, SoundEvents.BOGGED_SHEAR, shearedSoundCategory, 1.0F, 1.0F);
|
|
- this.spawnShearedMushrooms();
|
|
+ this.spawnDrops(drops); // Paper - shear drop API
|
|
this.setSheared(true);
|
|
}
|
|
|
|
private void spawnShearedMushrooms() {
|
|
+ // Paper start - shear drops API
|
|
+ this.spawnDrops(generateDefaultDrops()); // Only here for people calling spawnSheardMushrooms. Not used otherwise.
|
|
+ }
|
|
+ private void spawnDrops(java.util.List<net.minecraft.world.item.ItemStack> drops) {
|
|
+ drops.forEach(stack -> {
|
|
+ this.forceDrops = true;
|
|
+ this.spawnAtLocation(stack, this.getBbHeight());
|
|
+ this.forceDrops = false;
|
|
+ });
|
|
+ }
|
|
+ private void generateShearedMushrooms(java.util.function.Consumer<ItemStack> stackConsumer) {
|
|
+ // Paper end - shear drops API
|
|
Level world = this.level();
|
|
|
|
if (world instanceof ServerLevel worldserver) {
|
|
@@ -156,12 +182,21 @@ public class Bogged extends AbstractSkeleton implements Shearable {
|
|
while (objectlistiterator.hasNext()) {
|
|
ItemStack itemstack = (ItemStack) objectlistiterator.next();
|
|
|
|
- this.spawnAtLocation(itemstack, this.getBbHeight());
|
|
+ stackConsumer.accept(itemstack); // Paper
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
+ // Paper start - shear drops API
|
|
+ @Override
|
|
+ public java.util.List<ItemStack> generateDefaultDrops() {
|
|
+ final java.util.List<ItemStack> drops = new java.util.ArrayList<>();
|
|
+ this.generateShearedMushrooms(drops::add);
|
|
+ return drops;
|
|
+ }
|
|
+ // Paper end - shear drops API
|
|
+
|
|
@Override
|
|
public boolean readyForShearing() {
|
|
return !this.isSheared() && this.isAlive();
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
|
index 1d958323eccd4cf5e369e99e32d2f1dec0959591..56869e0d001d984c6b73f5a92c60508e2366eb61 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
|
@@ -1673,20 +1673,20 @@ public class CraftEventFactory {
|
|
player.level().getCraftServer().getPluginManager().callEvent(event);
|
|
}
|
|
|
|
- public static BlockShearEntityEvent callBlockShearEntityEvent(Entity animal, org.bukkit.block.Block dispenser, CraftItemStack is) {
|
|
- BlockShearEntityEvent bse = new BlockShearEntityEvent(dispenser, animal.getBukkitEntity(), is);
|
|
+ public static BlockShearEntityEvent callBlockShearEntityEvent(Entity animal, org.bukkit.block.Block dispenser, CraftItemStack is, List<ItemStack> drops) { // Paper - custom shear drops
|
|
+ BlockShearEntityEvent bse = new BlockShearEntityEvent(dispenser, animal.getBukkitEntity(), is, Lists.transform(drops, CraftItemStack::asCraftMirror)); // Paper - custom shear drops
|
|
Bukkit.getPluginManager().callEvent(bse);
|
|
return bse;
|
|
}
|
|
|
|
- public static boolean handlePlayerShearEntityEvent(net.minecraft.world.entity.player.Player player, Entity sheared, ItemStack shears, InteractionHand hand) {
|
|
+ public static PlayerShearEntityEvent handlePlayerShearEntityEvent(net.minecraft.world.entity.player.Player player, Entity sheared, ItemStack shears, InteractionHand hand, List<ItemStack> drops) { // Paper - custom shear drops
|
|
if (!(player instanceof ServerPlayer)) {
|
|
- return true;
|
|
+ return null; // Paper - custom shear drops
|
|
}
|
|
|
|
- PlayerShearEntityEvent event = new PlayerShearEntityEvent((Player) player.getBukkitEntity(), sheared.getBukkitEntity(), CraftItemStack.asCraftMirror(shears), (hand == InteractionHand.OFF_HAND ? EquipmentSlot.OFF_HAND : EquipmentSlot.HAND));
|
|
+ PlayerShearEntityEvent event = new PlayerShearEntityEvent((Player) player.getBukkitEntity(), sheared.getBukkitEntity(), CraftItemStack.asCraftMirror(shears), (hand == InteractionHand.OFF_HAND ? EquipmentSlot.OFF_HAND : EquipmentSlot.HAND), Lists.transform(drops, CraftItemStack::asCraftMirror)); // Paper - custom shear drops
|
|
Bukkit.getPluginManager().callEvent(event);
|
|
- return !event.isCancelled();
|
|
+ return event; // Paper - custom shear drops
|
|
}
|
|
|
|
public static Cancellable handleStatisticsIncrease(net.minecraft.world.entity.player.Player entityHuman, net.minecraft.stats.Stat<?> statistic, int current, int newValue) {
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
|
index 41c0cfc88f2ec48c1bb8ac10a78f89bf1f2f2319..62b5ba0cafd3a09229648b1205679148b476edcc 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
|
@@ -68,6 +68,16 @@ public final class CraftItemStack extends ItemStack {
|
|
return stack;
|
|
}
|
|
|
|
+ // Paper start
|
|
+ public static java.util.List<net.minecraft.world.item.ItemStack> asNMSCopy(java.util.List<? extends ItemStack> originals) {
|
|
+ final java.util.List<net.minecraft.world.item.ItemStack> items = new java.util.ArrayList<>(originals.size());
|
|
+ for (final ItemStack original : originals) {
|
|
+ items.add(asNMSCopy(original));
|
|
+ }
|
|
+ return items;
|
|
+ }
|
|
+ // Paper end
|
|
+
|
|
public static net.minecraft.world.item.ItemStack copyNMSStack(net.minecraft.world.item.ItemStack original, int amount) {
|
|
net.minecraft.world.item.ItemStack stack = original.copy();
|
|
stack.setCount(amount);
|
|
diff --git a/src/test/java/io/papermc/paper/entity/ShearableDropsTest.java b/src/test/java/io/papermc/paper/entity/ShearableDropsTest.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..e612515f7709dbe5d1fa5751337cdc34fce10a98
|
|
--- /dev/null
|
|
+++ b/src/test/java/io/papermc/paper/entity/ShearableDropsTest.java
|
|
@@ -0,0 +1,34 @@
|
|
+package io.papermc.paper.entity;
|
|
+
|
|
+import io.github.classgraph.ClassGraph;
|
|
+import io.github.classgraph.ClassInfo;
|
|
+import io.github.classgraph.MethodInfoList;
|
|
+import io.github.classgraph.ScanResult;
|
|
+import java.util.ArrayList;
|
|
+import net.minecraft.world.entity.Shearable;
|
|
+import org.bukkit.support.AbstractTestingBase;
|
|
+import org.junit.jupiter.params.ParameterizedTest;
|
|
+import org.junit.jupiter.params.provider.MethodSource;
|
|
+
|
|
+import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
+
|
|
+class ShearableDropsTest extends AbstractTestingBase {
|
|
+
|
|
+ static Iterable<ClassInfo> parameters() {
|
|
+ try (ScanResult scanResult = new ClassGraph()
|
|
+ .enableClassInfo()
|
|
+ .enableMethodInfo()
|
|
+ .whitelistPackages("net.minecraft")
|
|
+ .scan()
|
|
+ ) {
|
|
+ return new ArrayList<>(scanResult.getClassesImplementing(Shearable.class.getName()));
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @ParameterizedTest
|
|
+ @MethodSource("parameters")
|
|
+ void checkShearableDropOverrides(final ClassInfo classInfo) {
|
|
+ final MethodInfoList generateDefaultDrops = classInfo.getDeclaredMethodInfo("generateDefaultDrops");
|
|
+ assertEquals(1, generateDefaultDrops.size(), classInfo.getName() + " doesn't implement Shearable#generateDefaultDrops");
|
|
+ }
|
|
+}
|