Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend HumanEntity#dropItem API #11810

Open
wants to merge 18 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
270 changes: 270 additions & 0 deletions paper-api/src/main/java/org/bukkit/entity/HumanEntity.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

import java.util.Collection;
import java.util.Set;
import java.util.function.Consumer;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.InventoryView;
Expand Down Expand Up @@ -703,9 +705,277 @@ default void openSign(@NotNull org.bukkit.block.Sign sign) {
*
* @param dropAll True to drop entire stack, false to drop 1 of the stack
* @return True if item was dropped successfully
* @deprecated You should instead use {@link #dropItem(EquipmentSlot, int)} or {@link #dropItems(EquipmentSlot)} with a {@link EquipmentSlot#HAND} parameter.
*/
@Deprecated(since = "1.21.4")
public boolean dropItem(boolean dropAll);

/**
* Makes the player drop an item from their inventory based on the inventory slot.
*
* @param slot The slot to drop
* @param amount The number of items to drop from this slot. Values below one always return null
* @param entityOperation The function to be run before adding the entity into the world
* @return The dropped item entity, or null if the action was unsuccessful
* @throws IllegalArgumentException If the slot is negative or bigger than the player's inventory
*/
@Nullable
public Item dropItem(int slot, int amount, @Nullable Consumer<Item> entityOperation);

/**
* Makes the player drop an item from their inventory based on the inventory slot.
*
* @param slot The slot to drop
* @param amount The number of items to drop from this slot. Values below one always return null
* @return The dropped item entity, or null if the action was unsuccessful
* @throws IllegalArgumentException If the slot is negative or bigger than the player's inventory
*/
@Nullable
public default Item dropItem(int slot, int amount) {
return this.dropItem(slot, amount, null);
}

/**
* Makes the player drop an item from their inventory based on the equipment slot.
*
* @param slot The equipment slot to drop
* @param amount The amount of items to drop from this equipment slot. Values below one always return null
* @param entityOperation The function to be run before adding the entity into the world
* @return The dropped item entity, or null if the action was unsuccessful
*/
@Nullable
public Item dropItem(@NotNull EquipmentSlot slot, int amount, @Nullable Consumer<Item> entityOperation);

/**
* Makes the player drop an item from their inventory based on the equipment slot.
*
* @param slot The equipment slot to drop
* @param amount The amount of items to drop from this equipment slot. Values below one always return null
* @return The dropped item entity, or null if the action was unsuccessful
*/
@Nullable
public default Item dropItem(@NotNull EquipmentSlot slot, int amount) {
return this.dropItem(slot, amount, null);
}

/**
* Makes the entity drop an item from their inventory based on the inventory slot.
* Instead of the item entity being dropped where the player is currently looking, this method makes it drop in
* a random direction, similar to how items are dropped after a player's death.
*
* @param slot The slot to drop
* @param amount The number of items to drop from this slot. Values below one always return null
* @param entityOperation The function to be run before adding the entity into the world
* @return The dropped item entity, or null if the action was unsuccessful
* @throws IllegalArgumentException If the slot is negative or bigger than the player's inventory
*/
@Nullable
public Item dropItemRandomly(int slot, int amount, @Nullable Consumer<Item> entityOperation);

/**
* Makes the player drop an item from their inventory based on the inventory slot.
* Instead of the item entity being dropped where the player is currently looking, this method makes it drop in
* a random direction, similar to how items are dropped after a player's death.
*
* @param slot The slot to drop
* @param amount The number of items to drop from this slot. Values below one always return null
* @return The dropped item entity, or null if the action was unsuccessful
* @throws IllegalArgumentException If the slot is negative or bigger than the player's inventory
*/
@Nullable
public default Item dropItemRandomly(int slot, int amount) {
return this.dropItemRandomly(slot, amount, null);
}

/**
* Makes the player drop an item from their inventory based on the equipment slot.
* Instead of the item entity being dropped where the player is currently looking, this method makes it drop in
* a random direction, similar to how items are dropped after a player's death.
*
* @param slot The equipment slot to drop
* @param amount The amount of items to drop from this equipment slot. Values below one always return null
* @param entityOperation The function to be run before adding the entity into the world
* @return The dropped item entity, or null if the action was unsuccessful
*/
@Nullable
public Item dropItemRandomly(@NotNull EquipmentSlot slot, int amount, @Nullable Consumer<Item> entityOperation);

/**
* Makes the player drop an item from their inventory based on the equipment slot.
* Instead of the item entity being dropped where the player is currently looking, this method makes it drop in
* a random direction, similar to how items are dropped after a player's death.
*
* @param slot The equipment slot to drop
* @param amount The amount of items to drop from this equipment slot. Values below one always return null
* @return The dropped item entity, or null if the action was unsuccessful
*/
@Nullable
public default Item dropItemRandomly(@NotNull EquipmentSlot slot, int amount) {
return this.dropItemRandomly(slot, amount, null);
}

/**
* Makes the player drop all items from their inventory based on the slot.
*
* @param slot The equipment slot to drop
* @param entityOperation The function to be run before adding the entity into the world
* @return The dropped item entity, or null if the action was unsuccessful
*/
@Nullable
public default Item dropItems(int slot, @Nullable Consumer<Item> entityOperation) {
return this.dropItem(slot, Integer.MAX_VALUE, entityOperation);
}

/**
* Makes the player drop all items from their inventory based on the inventory slot.
*
* @param slot The equipment slot to drop
* @return The dropped item entity, or null if the action was unsuccessful
*/
@Nullable
public default Item dropItems(int slot) {
return this.dropItems(slot, null);
}

/**
* Makes the player drop all items from their inventory based on the equipment slot.
*
* @param slot The equipment slot to drop
* @param entityOperation The function to be run before adding the entity into the world
* @return The dropped item entity, or null if the action was unsuccessful
*/
@Nullable
public default Item dropItems(@NotNull EquipmentSlot slot, @Nullable Consumer<Item> entityOperation) {
return this.dropItem(slot, Integer.MAX_VALUE, entityOperation);
}

/**
* Makes the player drop all items from their inventory based on the equipment slot.
*
* @param slot The equipment slot to drop
* @return The dropped item entity, or null if the action was unsuccessful
*/
@Nullable
public default Item dropItems(@NotNull EquipmentSlot slot) {
return this.dropItems(slot, null);
}

/**
* Makes the player drop all items from their inventory based on the inventory slot.
* Instead of the item entity being dropped where the player is currently looking, this method makes it drop in
* a random direction, similar to how items are dropped after a player's death.
*
* @param slot The equipment slot to drop
* @param entityOperation The function to be run before adding the entity into the world
* @return The dropped item entity, or null if the action was unsuccessful
*/
@Nullable
public default Item dropItemsRandomly(int slot, @Nullable Consumer<Item> entityOperation) {
return this.dropItem(slot, Integer.MAX_VALUE, entityOperation);
}

/**
* Makes the player drop all items from their inventory based on the inventory slot.
* Instead of the item entity being dropped where the player is currently looking, this method makes it drop in
* a random direction, similar to how items are dropped after a player's death.
*
* @param slot The slot to drop
* @return The dropped item entity, or null if the action was unsuccessful
*/
@Nullable
public default Item dropItemsRandomly(int slot) {
return this.dropItemsRandomly(slot, null);
}

/**
* Makes the player drop all items from their inventory based on the equipment slot.
* Instead of the item entity being dropped where the player is currently looking, this method makes it drop in
* a random direction, similar to how items are dropped after a player's death.
*
* @param slot The equipment slot to drop
* @param entityOperation The function to be run before adding the entity into the world
* @return The dropped item entity, or null if the action was unsuccessful
*/
@Nullable
public default Item dropItemsRandomly(@NotNull EquipmentSlot slot, @Nullable Consumer<Item> entityOperation) {
return this.dropItemRandomly(slot, Integer.MAX_VALUE, entityOperation);
}

/**
* Makes the player drop all items from their inventory based on the equipment slot.
* Instead of the item entity being dropped where the player is currently looking, this method makes it drop in
* a random direction, similar to how items are dropped after a player's death.
*
* @param slot The equipment slot to drop
* @return The dropped item entity, or null if the action was unsuccessful
*/
@Nullable
public default Item dropItemsRandomly(@NotNull EquipmentSlot slot) {
return this.dropItemsRandomly(slot, null);
}

/**
* Makes the player drop any arbitrary {@link ItemStack}, independently of whether the player actually
* has that item in their inventory.
* This method modifies neither the item nor the player's inventory.
* Item removal has to be handled by the method caller.
*
* @param itemStack The item to drop
* @param entityOperation The function to be run before adding the entity into the world
* @return The dropped item entity, or null if the action was unsuccessful
*/
@Nullable
public Item dropItem(@Nullable ItemStack itemStack, @Nullable Consumer<Item> entityOperation);

/**
* Makes the player drop any arbitrary {@link ItemStack}, independently of whether the player actually
* has that item in their inventory.
* This method modifies neither the item nor the player's inventory.
* Item removal has to be handled by the method caller.
*
* @param itemStack The item to drop
* @return The dropped item entity, or null if the action was unsuccessful
*/
@Nullable
public default Item dropItem(@Nullable ItemStack itemStack) {
return this.dropItem(itemStack, null);
}

/**
* Makes the player drop any arbitrary {@link ItemStack}, independently of whether the player actually
* has that item in their inventory.
* This method modifies neither the item nor the player's inventory.
* Item removal has to be handled by the method caller.
* <p>
* Instead of the item entity being dropped where the player is currently looking, this method makes it drop in
* a random direction, similar to how items are dropped after a player's death.
* </p>
*
* @param itemStack The item to drop
* @param entityOperation The function to be run before adding the entity into the world
* @return The dropped item entity, or null if the action was unsuccessful
*/
@Nullable
public Item dropItemRandomly(@Nullable ItemStack itemStack, @Nullable Consumer<Item> entityOperation);

/**
* Makes the player drop any arbitrary {@link ItemStack}, independently of whether the player actually
* has that item in their inventory.
* This method modifies neither the item nor the player's inventory.
* Item removal has to be handled by the method caller.
* <p>
* Instead of the item entity being dropped where the player is currently looking, this method makes it drop in
* a random direction, similar to how items are dropped after a player's death.
* </p>
*
* @param itemStack The item to drop
* @return The dropped item entity, or null if the action was unsuccessful
*/
@Nullable
public default Item dropItemRandomly(@Nullable ItemStack itemStack) {
return this.dropItemRandomly(itemStack, null);
}

Strokkur424 marked this conversation as resolved.
Show resolved Hide resolved
/**
* Gets the players current exhaustion level.
* <p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1342,12 +1342,19 @@
}

public SectionPos getLastSectionPos() {
@@ -1930,21 +_,54 @@
@@ -1930,21 +_,66 @@
}

@Override
- public ItemEntity drop(ItemStack droppedItem, boolean dropAround, boolean traceItem) {
+ public ItemEntity drop(ItemStack droppedItem, boolean dropAround, boolean traceItem, boolean callEvent) { // CraftBukkit - SPIGOT-2942: Add boolean to call event
+ // Paper start - Extend HumanEntity#dropItem API
+ return this.drop(droppedItem, dropAround, traceItem, callEvent, null);
+ }
+
+ @Override
+ public ItemEntity drop(ItemStack droppedItem, boolean dropAround, boolean traceItem, boolean callEvent, @Nullable java.util.function.Consumer<org.bukkit.entity.Item> entityOperation) {
+ // Paper end - Extend HumanEntity#dropItem API
ItemEntity itemEntity = this.createItemStackToDrop(droppedItem, dropAround, traceItem);
if (itemEntity == null) {
return null;
Expand Down Expand Up @@ -1376,6 +1383,11 @@
+ return null;
+ }
+ }
+ // Paper start - Extend HumanEntity#dropItem API
+ if (entityOperation != null) {
+ entityOperation.accept((org.bukkit.entity.Item) itemEntity.getBukkitEntity());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might make sense to apply it before PlayerDropItemEvent?

+ }
+ // Paper end - Extend HumanEntity#dropItem API
+ // CraftBukkit end
this.level().addFreshEntity(itemEntity);
ItemStack item = itemEntity.getItem();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@
this.removeEntitiesOnShoulder();
}
}
@@ -717,6 +_,13 @@
@@ -717,6 +_,20 @@

@Nullable
public ItemEntity drop(ItemStack droppedItem, boolean dropAround, boolean includeThrowerName) {
Expand All @@ -123,6 +123,13 @@
+ @Nullable
+ public ItemEntity drop(ItemStack droppedItem, boolean dropAround, boolean includeThrowerName, boolean callEvent) {
+ // CraftBukkit end
+ // Paper start - Extend HumanEntity#dropItem API
+ return this.drop(droppedItem, dropAround, includeThrowerName, callEvent, null);
+ }
+
+ @Nullable
+ public ItemEntity drop(ItemStack droppedItem, boolean dropAround, boolean includeThrowerName, boolean callEvent, @Nullable java.util.function.Consumer<org.bukkit.entity.Item> entityOperation) {
+ // Paper end - Extend HumanEntity#dropItem API
if (!droppedItem.isEmpty() && this.level().isClientSide) {
this.swing(InteractionHand.MAIN_HAND);
}
Expand Down
Loading