Repository: PaperMC/Paper
File: paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java (Java)

Code before:
    @Override
    public @Nullable Item dropItem(final @NotNull EquipmentSlot slot, final int amount) {
        return dropItemRaw(this.inventory.getItem(slot), amount, false);
    }

    @Override
    public @Nullable Item dropItemRandomly(final int slot, final int amount) {
        if (slot < 0 || slot >= this.inventory.getSize()) {
            throw new IllegalArgumentException("Slot " + slot + " is not a valid inventory slot.");
        }

        return dropItemRaw(this.inventory.getItem(slot), amount, true);
    }

    @Override
    public @Nullable Item dropItemRandomly(final @NotNull EquipmentSlot slot, final int amount) {
        return dropItemRaw(this.inventory.getItem(slot), amount, true);
    }

    private @Nullable Item dropItemRaw(final ItemStack originalItemStack, final int amount, final boolean throwRandomly) {
        if (originalItemStack == null || originalItemStack.isEmpty() || amount <= 0) {
            return null;
        }

        final net.minecraft.world.item.ItemStack nmsItemStack = CraftItemStack.unwrap(originalItemStack);
        final net.minecraft.world.item.ItemStack dropContent = nmsItemStack.split(Math.min(originalItemStack.getAmount(), amount));

        final ItemEntity droppedEntity = this.getHandle().drop(dropContent, throwRandomly, true);
        if (droppedEntity == null) {
            return null;
        }

        return (Item) droppedEntity.getBukkitEntity();
    }

    @Override
    public float getExhaustion() {
        return this.getHandle().getFoodData().exhaustionLevel;
    }

    @Override
    public void setExhaustion(float value) {
        this.getHandle().getFoodData().exhaustionLevel = value;
    }

    @Override
    public float getSaturation() {
        return this.getHandle().getFoodData().saturationLevel;
    }

    @Override

Review comment (suggestion):
I don't think you need to do the Math.min. That should be part of the nmsItemStack.split now. Check the source of ItemStack#split

Code after:
    @Override
    @Nullable
    public Item dropItem(final @NotNull EquipmentSlot slot, final int amount, final boolean throwRandomly, final @Nullable Consumer<Item> entityOperation) {
        return internalDropItemFromInventory(this.inventory.getItem(slot), amount, throwRandomly, entityOperation);
    }

    @Nullable
    private Item internalDropItemFromInventory(final ItemStack originalItemStack, final int amount, final boolean throwRandomly, final @Nullable Consumer<Item> entityOperation) {
        if (originalItemStack == null || originalItemStack.isEmpty() || amount <= 0) return null;

        final net.minecraft.world.item.ItemStack nmsItemStack = CraftItemStack.unwrap(originalItemStack);
        final net.minecraft.world.item.ItemStack dropContent = nmsItemStack.split(amount);

        // This will return the itemstack back to its original amount in case events fail
        final ItemEntity droppedEntity = this.getHandle().drop(dropContent, throwRandomly, true, true, entityOperation);
        return droppedEntity == null ? null : (Item) droppedEntity.getBukkitEntity();
    }

    @Override
    @Nullable
    public Item dropItem(final @Nullable ItemStack itemStack, final boolean throwRandomly, final @Nullable Consumer<Item> entityOperation) {
        // This method implementation differs from the previous dropItem implementations, as it does not source
        // its itemstack from the players inventory. As such, we cannot reuse #internalDropItemFromInventory.
        Preconditions.checkArgument(itemStack != null, "Cannot drop a null itemstack");
        if (itemStack.isEmpty()) return null;

        final net.minecraft.world.item.ItemStack nmsItemStack = CraftItemStack.asNMSCopy(itemStack);

        // Do *not* call the event here, the item is not in the player inventory, they are not dropping it / do not need recovering logic (which would be a dupe).
        final ItemEntity droppedEntity = this.getHandle().drop(nmsItemStack, throwRandomly, true, false, entityOperation);
        return droppedEntity == null ? null : (Item) droppedEntity.getBukkitEntity();
    }

    @Override
    public float getExhaustion() {
        return this.getHandle().getFoodData().exhaustionLevel;
    }

    @Override
    public void setExhaustion(float value) {
        this.getHandle().getFoodData().exhaustionLevel = value;
    }

    @Override
    public float getSaturation() {
        return this.getHandle().getFoodData().saturationLevel;
    }

    @Override
    public void setSaturation(float value) {
        this.getHandle().getFoodData().saturationLevel = value;