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 #11689

Open
wants to merge 8 commits into
base: master
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
111 changes: 111 additions & 0 deletions patches/api/0501-Extend-HumanEntity-dropItem-API.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Strokkur24 <strokkur24@gmail.com>
Date: Sat, 30 Nov 2024 11:54:38 +0100
Subject: [PATCH] Extend HumanEntity#dropItem API


diff --git a/src/main/java/org/bukkit/entity/HumanEntity.java b/src/main/java/org/bukkit/entity/HumanEntity.java
index 488604ba1a516b477693877c74712e4a45624a8b..59f4f0a51cb47c40dd154b8139634ac07351cef2 100644
--- a/src/main/java/org/bukkit/entity/HumanEntity.java
+++ b/src/main/java/org/bukkit/entity/HumanEntity.java
@@ -706,6 +706,100 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder
*/
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, boolean persistThrower)}
+ * with the first {@link ItemStack} occurrence in the inventory
+ *
+ * @param itemStack The ItemStack to drop from their inventory
+ * @param persistThrower Whether the resulting {@link Item} should have its thrower set to this {@link HumanEntity}
+ * @return The dropped item, or null if the action was unsuccessful
+ */
+ public @Nullable Item dropItem(final @NotNull ItemStack itemStack, final boolean persistThrower);
+
+ /**
+ * Makes the entity drop an item from their inventory based on the specified ItemStack.
+ * <br>
+ * This method calls {@link HumanEntity#dropItem(int slot, boolean persistThrower, boolean throwRandomly)}
+ * with the first {@link ItemStack} occurrence in the inventory
+ *
+ * @param itemStack The ItemStack to drop
+ * @param persistThrower Whether the resulting {@link Item} should have its thrower set to this {@link HumanEntity}
+ * @param throwRandomly Whether the item should disperse randomly
+ * @return The dropped item, or null if the action was unsuccessful
+ */
+ public @Nullable Item dropItem(final @NotNull ItemStack itemStack, final boolean persistThrower, 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
+ */
+ 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 persistThrower Whether the resulting {@link Item} should have its thrower set to this {@link HumanEntity}
+ * @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 boolean persistThrower);
+
+ /**
+ * Makes the entity drop an item from their inventory based on the slot.
+ *
+ * @param slot The slot to drop
+ * @param persistThrower Whether the resulting {@link Item} should have its thrower set to this {@link HumanEntity}
+ * @param throwRandomly Whether the item should disperse randomly
+ * @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
+ */
+ public @Nullable Item dropItem(final int slot, final boolean persistThrower, 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 persistThrower Whether the resulting {@link Item} should have its thrower set to this {@link HumanEntity}
+ * @return The dropped item entity, or null if the action was unsuccessful
+ */
+ public @Nullable Item dropItem(final @NotNull org.bukkit.inventory.EquipmentSlot slot, final boolean persistThrower);
+
+ /**
+ * Makes the entity drop an item from their inventory based on the equipment slot.
+ *
+ * @param slot The equipment slot to drop
+ * @param persistThrower Whether the resulting {@link Item} should have its thrower set to this {@link HumanEntity}
+ * @param throwRandomly Whether the item should disperse randomly
+ * @return The dropped item entity, or null if the action was unsuccessful
+ */
+ public @Nullable Item dropItem(final @NotNull org.bukkit.inventory.EquipmentSlot slot, final boolean persistThrower, final boolean throwRandomly);
+ // Paper end
+
/**
* Gets the players current exhaustion level.
* <p>
95 changes: 95 additions & 0 deletions patches/server/1073-Extend-HumanEntity-dropItem-API.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Strokkur24 <strokkur24@gmail.com>
Date: Sat, 30 Nov 2024 11:54:38 +0100
Subject: [PATCH] Extend HumanEntity#dropItem API


diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
index e345cdbfab44a0f5da80d738798dbb4424b7ab5c..6c7142decc6114c1ae216e69e352d2e08485a631 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
@@ -801,6 +801,84 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
// Paper end - Fix HumanEntity#drop not updating the client inv
}

+ // Paper start - Extend HumanEntity#dropItem API
+ @Override
+ public @org.jetbrains.annotations.Nullable org.bukkit.entity.Item dropItem(final @org.jetbrains.annotations.NotNull ItemStack itemStack) {
+ return this.dropItem(itemStack, false, false);
+ }
+
+ @Override
+ public @org.jetbrains.annotations.Nullable org.bukkit.entity.Item dropItem(final @org.jetbrains.annotations.NotNull ItemStack itemStack, final boolean persistThrower) {
+ return this.dropItem(itemStack, persistThrower, false);
+ }
+
+ @Override
+ public @org.jetbrains.annotations.Nullable org.bukkit.entity.Item dropItem(final @org.jetbrains.annotations.NotNull ItemStack itemStack, final boolean persistThrower, final boolean throwRandomly) {
+ final int slot = this.inventory.first(itemStack);
+ if (slot == -1) {
+ return null;
+ }
+
+ return this.dropItem(slot, persistThrower, throwRandomly);
+ }
+
+ @Override
+ public @org.jetbrains.annotations.Nullable org.bukkit.entity.Item dropItem(final int slot) {
+ return this.dropItem(slot, false, false);
+ }
+
+ @Override
+ public @org.jetbrains.annotations.Nullable org.bukkit.entity.Item dropItem(final int slot, final boolean persistThrower) {
+ return this.dropItem(slot, persistThrower, false);
+ }
+
+ @Override
+ public @org.jetbrains.annotations.Nullable org.bukkit.entity.Item dropItem(final int slot, final boolean persistThrower, 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, persistThrower, throwRandomly);
+
+ this.inventory.setItem(slot, null);
+ return itemEntity;
+ }
+
+ @Override
+ public @org.jetbrains.annotations.Nullable org.bukkit.entity.Item dropItem(final @org.jetbrains.annotations.NotNull org.bukkit.inventory.EquipmentSlot slot) {
+ return dropItem(slot, false, false);
+ }
+
+ @Override
+ public @org.jetbrains.annotations.Nullable org.bukkit.entity.Item dropItem(final @org.jetbrains.annotations.NotNull org.bukkit.inventory.EquipmentSlot slot, final boolean persistThrower) {
+ return dropItem(slot, persistThrower, false);
+ }
+
+ @Override
+ public @org.jetbrains.annotations.Nullable org.bukkit.entity.Item dropItem(final @org.jetbrains.annotations.NotNull org.bukkit.inventory.EquipmentSlot slot, final boolean persistThrower, final boolean throwRandomly) {
+ final ItemStack stack = this.inventory.getItem(slot);
+ final org.bukkit.entity.Item itemEntity = dropItemRaw(stack, persistThrower, throwRandomly);
+
+ this.inventory.setItem(slot, null);
+ return itemEntity;
+ }
+
+ private org.bukkit.entity.Item dropItemRaw(final ItemStack is, final boolean persistThrower, 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, persistThrower);
+ if (droppedEntity == null) {
+ return null;
+ }
+
+ return (org.bukkit.entity.Item) droppedEntity.getBukkitEntity();
+ }
+ // Paper end
+
@Override
public float getExhaustion() {
return this.getHandle().getFoodData().exhaustionLevel;