Paper/patches/unapplied/server/0284-PlayerDeathEvent-getItemsToKeep.patch
2024-10-22 19:28:57 +02:00

78 lines
3.4 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
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 ad2b8ea068469f2b0597c0e0436ad3c94dcb62ea..cba123f40d72ebd39305a76694be508510997d1e 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -897,6 +897,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<ItemStack> inv) {
+ List<org.bukkit.inventory.ItemStack> 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<org.bukkit.inventory.ItemStack> 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
@@ -981,7 +1021,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<ItemStack> inv : this.getInventory().compartments) {
+ processKeep(event, inv);
+ }
+ processKeep(event, null);
+ // Paper end - PlayerDeathEvent#getItemsToKeep
}
this.setCamera(this); // Remove spectated target