From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Aikar Date: Wed, 27 Mar 2019 23:01:33 -0400 Subject: [PATCH] PlayerDeathEvent#getItemsToKeep Exposes a mutable array on items a player should keep on death Example Usage: https://gist.github.com/aikar/5bb202de6057a051a950ce1f29feb0b4 == AT == public net.minecraft.world.entity.player.Inventory compartments diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java index 647cec024d90014a6928d3889f6d1b24d5a4a4de..2bc6228057e01bf197e8b6e58ae6389f2d19ffe5 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java @@ -896,6 +896,46 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { }); } + // Paper start - PlayerDeathEvent#getItemsToKeep + private static void processKeep(org.bukkit.event.entity.PlayerDeathEvent event, NonNullList inv) { + List itemsToKeep = event.getItemsToKeep(); + if (inv == null) { + // remainder of items left in toKeep - plugin added stuff on death that wasn't in the initial loot? + if (!itemsToKeep.isEmpty()) { + for (org.bukkit.inventory.ItemStack itemStack : itemsToKeep) { + event.getEntity().getInventory().addItem(itemStack); + } + } + + return; + } + + for (int i = 0; i < inv.size(); ++i) { + ItemStack item = inv.get(i); + if (EnchantmentHelper.has(item, EnchantmentEffectComponents.PREVENT_EQUIPMENT_DROP) || itemsToKeep.isEmpty() || item.isEmpty()) { + inv.set(i, ItemStack.EMPTY); + continue; + } + + final org.bukkit.inventory.ItemStack bukkitStack = item.getBukkitStack(); + boolean keep = false; + final Iterator iterator = itemsToKeep.iterator(); + while (iterator.hasNext()) { + final org.bukkit.inventory.ItemStack itemStack = iterator.next(); + if (bukkitStack.equals(itemStack)) { + iterator.remove(); + keep = true; + break; + } + } + + if (!keep) { + inv.set(i, ItemStack.EMPTY); + } + } + } + // Paper end - PlayerDeathEvent#getItemsToKeep + @Override public void die(DamageSource damageSource) { // this.gameEvent(GameEvent.ENTITY_DIE); // Paper - move below event cancellation check @@ -980,7 +1020,12 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { this.dropExperience(damageSource.getEntity()); // we clean the player's inventory after the EntityDeathEvent is called so plugins can get the exact state of the inventory. if (!event.getKeepInventory()) { - this.getInventory().clearContent(); + // Paper start - PlayerDeathEvent#getItemsToKeep + for (NonNullList inv : this.getInventory().compartments) { + processKeep(event, inv); + } + processKeep(event, null); + // Paper end - PlayerDeathEvent#getItemsToKeep } this.setCamera(this); // Remove spectated target