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 1 commit
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
101 changes: 101 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 @@ -706,6 +706,107 @@ default void openSign(@NotNull org.bukkit.block.Sign sign) {
*/
public boolean dropItem(boolean dropAll);

// Paper start - Extend HumanEntity#dropItem API
/**
* Makes the entity drop an item from their inventory.
* <br>
* This method calls {@link HumanEntity#dropItem(int slot)}
* with the first {@link ItemStack} occurrence in the inventory
*
* @param itemStack The ItemStack to drop
* @return The dropped item, or null if the action was unsuccessful
*/
public @Nullable Item dropItem(final @NotNull ItemStack itemStack);

/**
* Makes the entity drop an item from their inventory.
* <br>
* This method calls {@link HumanEntity#dropItem(int slot, java.util.UUID thrower)}
* with the first {@link ItemStack} occurrence in the inventory
*
* @param itemStack The ItemStack to drop from their inventory
* @param thrower The {@link java.util.UUID} to set the resulting {@link Item}'s thrower to
* @return The dropped item, or null if the action was unsuccessful
*/
public @Nullable Item dropItem(final @NotNull ItemStack itemStack, final @Nullable java.util.UUID thrower);

/**
* Makes the entity drop an item from their inventory based on the specified ItemStack.
* <br>
* This method calls {@link HumanEntity#dropItem(int slot, java.util.UUID thrower, boolean throwRandomly)}
* with the first {@link ItemStack} occurrence in the inventory
*
* @param itemStack The ItemStack to drop
* @param thrower The {@link java.util.UUID} to set the resulting {@link Item}'s thrower to
* @param throwRandomly Whether the item should disperse randomly.
* This means that instead of the item being dropped where the player is currently looking,
* it instead throws it in any direction, similar to how items drop after a player's death.
* @return The dropped item, or null if the action was unsuccessful
*/
public @Nullable Item dropItem(final @NotNull ItemStack itemStack, final @Nullable java.util.UUID thrower, final boolean throwRandomly);

/**
* Makes the entity drop an item from their inventory based on the slot.
*
* @param slot The slot to drop
* @return The dropped item, or null if the action was unsuccessful
* @throws IndexOutOfBoundsException If the slot is negative or bigger than the player's inventory
Strokkur424 marked this conversation as resolved.
Show resolved Hide resolved
*/
public @Nullable Item dropItem(final int slot);

/**
* Makes the entity drop an item from their inventory based on the slot.
*
* @param slot The slot to drop
* @param thrower The {@link java.util.UUID} to set the resulting {@link Item}'s thrower to
* @return The dropped item, or null if the action was unsuccessful
* @throws IndexOutOfBoundsException If the slot is negative or bigger than the player's inventory
*/
public @Nullable Item dropItem(final int slot, final @Nullable java.util.UUID thrower);

/**
* Makes the entity drop an item from their inventory based on the slot.
*
* @param slot The slot to drop
* @param thrower The {@link java.util.UUID} to set the resulting {@link Item}'s thrower to
* @param throwRandomly Whether the item should disperse randomly.
* This means that instead of the item being dropped where the player is currently looking,
* it instead throws it in any direction, similar to how items drop after a player's death.
* @return The dropped item entity, or null if the action was unsuccessful
* @throws IndexOutOfBoundsException If the slot is negative or bigger than the player's inventory
Strokkur424 marked this conversation as resolved.
Show resolved Hide resolved
*/
public @Nullable Item dropItem(final int slot, final @Nullable java.util.UUID thrower, final boolean throwRandomly);

/**
* Makes the entity drop an item from their inventory based on the {@link org.bukkit.inventory.EquipmentSlot}
*
* @param slot The equipment slot to drop
* @return The dropped item entity, or null if the action was unsuccessful
*/
public @Nullable Item dropItem(final @NotNull org.bukkit.inventory.EquipmentSlot slot);

/**
* Makes the entity drop an item from their inventory based on the {@link org.bukkit.inventory.EquipmentSlot}
*
* @param slot The equipment slot to drop
* @param thrower The {@link java.util.UUID} to set the resulting {@link Item}'s thrower to
* @return The dropped item entity, or null if the action was unsuccessful
*/
public @Nullable Item dropItem(final @NotNull org.bukkit.inventory.EquipmentSlot slot, final @Nullable java.util.UUID thrower);

/**
* Makes the player drop an item from their inventory based on the equipment slot.
*
* @param slot The equipment slot to drop
* @param thrower The {@link java.util.UUID} to set the resulting {@link Item}'s thrower to
* @param throwRandomly Whether the item should disperse randomly.
* This means that instead of the item being dropped where the player is currently looking,
* it instead throws it in any direction, similar to how items drop after a player's death.
* @return The dropped item entity, or null if the action was unsuccessful
*/
public @Nullable Item dropItem(final @NotNull org.bukkit.inventory.EquipmentSlot slot, final @Nullable java.util.UUID thrower, final boolean throwRandomly);
// Paper end

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 @@ -66,6 +66,8 @@
import org.bukkit.permissions.PermissionAttachment;
import org.bukkit.permissions.PermissionAttachmentInfo;
import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.NotNull; // Paper - Extend HumanEntity#dropItem API
import org.jetbrains.annotations.Nullable; // Paper - Extend HumanEntity#dropItem API

public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
private CraftInventoryPlayer inventory;
Expand Down Expand Up @@ -801,6 +803,86 @@ public boolean dropItem(boolean dropAll) {
// Paper end - Fix HumanEntity#drop not updating the client inv
}

// Paper start - Extend HumanEntity#dropItem API
@Override
public @Nullable org.bukkit.entity.Item dropItem(final @NotNull ItemStack itemStack) {
return this.dropItem(itemStack, null, false);
}

@Override
public @Nullable org.bukkit.entity.Item dropItem(final @NotNull ItemStack itemStack, final @Nullable java.util.UUID thrower) {
return this.dropItem(itemStack, thrower, false);
}

@Override
public @Nullable org.bukkit.entity.Item dropItem(final @NotNull ItemStack itemStack, final @Nullable java.util.UUID thrower, final boolean throwRandomly) {
final int slot = this.inventory.first(itemStack);
if (slot == -1) {
return null;
}

return this.dropItem(slot, thrower, throwRandomly);
}

@Override
public @Nullable org.bukkit.entity.Item dropItem(final int slot) {
return this.dropItem(slot, null, false);
}

@Override
public @Nullable org.bukkit.entity.Item dropItem(final int slot, final @Nullable java.util.UUID thrower) {
return this.dropItem(slot, thrower, false);
}

@Override
public @Nullable org.bukkit.entity.Item dropItem(final int slot, final @Nullable java.util.UUID thrower, final boolean throwRandomly) {
// Make sure the slot is in bounds
if (slot < 0 || this.inventory.getSize() <= slot) {
Strokkur424 marked this conversation as resolved.
Show resolved Hide resolved
throw new IndexOutOfBoundsException("Slot " + slot + " out of range for inventory of size " + this.inventory.getSize());
}

final ItemStack stack = this.inventory.getItem(slot);
final org.bukkit.entity.Item itemEntity = dropItemRaw(stack, thrower, throwRandomly);

this.inventory.setItem(slot, null);
return itemEntity;
}

@Override
public @Nullable org.bukkit.entity.Item dropItem(final @NotNull org.bukkit.inventory.EquipmentSlot slot) {
return dropItem(slot, null, false);
}

@Override
public @Nullable org.bukkit.entity.Item dropItem(final @NotNull org.bukkit.inventory.EquipmentSlot slot, final @Nullable java.util.UUID thrower) {
return dropItem(slot, thrower, false);
}

@Override
public @Nullable org.bukkit.entity.Item dropItem(final @NotNull org.bukkit.inventory.EquipmentSlot slot, final @Nullable java.util.UUID thrower, final boolean throwRandomly) {
final ItemStack stack = this.inventory.getItem(slot);
final org.bukkit.entity.Item itemEntity = dropItemRaw(stack, thrower, throwRandomly);

this.inventory.setItem(slot, null);
return itemEntity;
}

private org.bukkit.entity.Item dropItemRaw(final ItemStack is, final @Nullable java.util.UUID thrower, final boolean throwRandomly) {
if (is == null || is.getType() == Material.AIR) {
Strokkur424 marked this conversation as resolved.
Show resolved Hide resolved
return null;
}

final net.minecraft.world.entity.item.ItemEntity droppedEntity = this.getHandle().drop(CraftItemStack.asNMSCopy(is), throwRandomly);
if (droppedEntity == null) {
return null;
}

droppedEntity.thrower = thrower;
return (org.bukkit.entity.Item) droppedEntity.getBukkitEntity();
}
// Paper end


Strokkur424 marked this conversation as resolved.
Show resolved Hide resolved
@Override
public float getExhaustion() {
return this.getHandle().getFoodData().exhaustionLevel;
Expand Down