Paper icon indicating copy to clipboard operation
Paper copied to clipboard

Player#dropItem(ItemStack)

Open NonSwag opened this issue 1 year ago • 0 comments

Is your feature request related to a problem?

Currently, there is only a Player#dropItem(boolean) method to drop the held item of the player, so when dropping an item from the inventory from a player you have to implement the entire drop logic yourself or use nms

Describe the solution you'd like.

A Player#dropItem(ItemStack) method and maybe even a Player#dropItem(EquipmentSlot) method

Describe alternatives you've considered.

Using NMS or implementing dropping yourself

Other

My best attempt at implementing it myself (basically what vanilla does)

player.getInventory().remove(item);
var location = player.getEyeLocation().clone();
location.setY(location.getY() - 0.30000001192092896D);
player.getWorld().dropItem(location, item, drop -> {

    var random = ThreadLocalRandom.current();

    var f1 = Mth.sin(player.getPitch() * 0.017453292F);
    var f2 = Mth.cos(player.getPitch() * 0.017453292F);
    var f3 = Mth.sin(player.getYaw() * 0.017453292F);
    var f4 = Mth.cos(player.getYaw() * 0.017453292F);
    var f5 = random.nextFloat() * 6.2831855F;
    var f6 = 0.02F * random.nextFloat();

    var x = (double) (f4 * f2 * 0.3F) + Math.sin(f5) * (double) f6;
    var y = (double) -f1 * 0.3F + 0.1F + (random.nextFloat() - random.nextFloat()) * 0.1F;
    var z = (double) (-f3 * f2 * 0.3F) + Math.cos(f5) * (double) f6;
    drop.setVelocity(new Vector(z, y, x));

    drop.setThrower(player.getUniqueId());
    drop.setPickupDelay(40);
});

or with NMS

((CraftPlayer) player).getHandle().drop(((CraftItemStack) item).handle, false, true, true);

Additionally, to make it seem like the player dropped the item themselves, swing their main hand

player.swingMainHand();

NonSwag avatar Nov 24 '24 10:11 NonSwag