Files
Purpur/patches/server/0208-Fix-advancement-triggers-on-entity-death.patch
William Blake Galbreath 444413bba6 Updated Upstream (Paper)
Upstream has released updates that appear to apply and compile correctly

Paper Changes:
5059ada Move log message for named entity deaths into correct location (#6105)
b5be382 Add methods to ProtoWorld for working with BlockStates (#5929)
144e5f7 Add option for logging named entity deaths (#6107)
4aef035 [ci skip] Use Java toolchain for run tasks (#6108)
dafc064 Fix MobEffectArgument#getEffect reobf
648f607 Route sign run_command click events through normal chat logic (#6109)
351a2c3 Drop no longer needed patch (#6115)
bb44da8 Fix cancelling EntityPickupItemEvent for villagers (#6091)
2021-07-07 14:51:18 -05:00

198 lines
8.3 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Fri, 28 May 2021 12:24:45 -0500
Subject: [PATCH] Fix advancement triggers on entity death
This fixes PaperMC/Paper#3729 and PaperMC/Paper#4252
Paper changes logical order revolving around making the EntityDeathEvent
cancellable. Reordering this logic has ended up with entity equipment being
cleared _before_ advancement criteria can run, causing things like killing
raid captains not giving the voluntary exile advancement.
This fixes the issue by storing a copy of the equipment in a new field just
before doing the death event logic where the equipment is cleared and then
restoring it back to the entity just before the criterion triggers run and
then finally clearing the equipment again right after the criterion is done.
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index 124cee713c3a808bd9c52f105a38ce71b6c9b423..7da1a70667c7537f2367660285d5ee80e9b6b67d 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -1661,10 +1661,13 @@ public abstract class LivingEntity extends Entity {
}
// Paper start
+ List<List<ItemStack>> equipmentSnapshotBefore = this.cloneEquipment(); // Purpur
org.bukkit.event.entity.EntityDeathEvent deathEvent = this.dropAllDeathLoot(source);
if (deathEvent == null || !deathEvent.isCancelled()) {
if (this.deathScore >= 0 && entityliving != null) {
+ this.restoreEquipment(equipmentSnapshotBefore); // Purpur
entityliving.awardKillScore(this, this.deathScore, source);
+ this.clearEquipment(); // Purpur
}
if (this.isSleeping()) {
@@ -2534,6 +2537,12 @@ public abstract class LivingEntity extends Entity {
@Override
public abstract void setItemSlot(EquipmentSlot slot, ItemStack stack);
+ // Purpur start
+ public abstract List<List<ItemStack>> cloneEquipment();
+ public abstract void restoreEquipment(List<List<ItemStack>> list);
+ public abstract void clearEquipment();
+ // Purpur end
+
protected void verifyEquippedItem(ItemStack stack) {
CompoundTag nbttagcompound = stack.getTag();
diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java
index ab55aa6f5717d191d0afb2da357178b294bad40e..ad5197e5f814c02e81c52b2acb2e8554f746a28c 100644
--- a/src/main/java/net/minecraft/world/entity/Mob.java
+++ b/src/main/java/net/minecraft/world/entity/Mob.java
@@ -1020,6 +1020,41 @@ public abstract class Mob extends LivingEntity {
}
+ // Purpur start
+ public List<List<ItemStack>> cloneEquipment() {
+ List<List<ItemStack>> list = new java.util.ArrayList<>();
+ List<ItemStack> handItems = new java.util.ArrayList<>();
+ for (ItemStack item : this.handItems) {
+ handItems.add(item.copy());
+ }
+ list.add(handItems);
+ List<ItemStack> armorItems = new java.util.ArrayList<>();
+ for (ItemStack item : this.armorItems) {
+ armorItems.add(item.copy());
+ }
+ list.add(armorItems);
+ return list;
+ }
+
+ public void restoreEquipment(List<List<ItemStack>> list) {
+ this.handItems.clear();
+ List<ItemStack> handItems = list.get(0);
+ for (int i = 0; i < handItems.size(); i++) {
+ this.handItems.set(i, handItems.get(1));
+ }
+ this.armorItems.clear();
+ List<ItemStack> armorItems = list.get(1);
+ for (int i = 0; i < armorItems.size(); i++) {
+ this.armorItems.set(i, armorItems.get(i));
+ }
+ }
+
+ public void clearEquipment() {
+ this.handItems.clear();
+ this.armorItems.clear();
+ }
+ // Purpur end
+
@Override
protected void dropCustomDeathLoot(DamageSource source, int lootingMultiplier, boolean allowDrops) {
super.dropCustomDeathLoot(source, lootingMultiplier, allowDrops);
diff --git a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
index c9a44a4765f43b9c0247ed1005f4c13469bdee95..6d08c8c31a32ea38f06410fbaddf19b95bec7c6f 100644
--- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
+++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
@@ -205,6 +205,41 @@ public class ArmorStand extends LivingEntity {
this.noTickEquipmentDirty = true; // Paper - Allow equipment to be updated even when tick disabled
}
+ // Purpur start
+ public List<List<ItemStack>> cloneEquipment() {
+ List<List<ItemStack>> list = new java.util.ArrayList<>();
+ List<ItemStack> handItems = new java.util.ArrayList<>();
+ for (ItemStack item : this.handItems) {
+ handItems.add(item.copy());
+ }
+ list.add(handItems);
+ List<ItemStack> armorItems = new java.util.ArrayList<>();
+ for (ItemStack item : this.armorItems) {
+ armorItems.add(item.copy());
+ }
+ list.add(armorItems);
+ return list;
+ }
+
+ public void restoreEquipment(List<List<ItemStack>> list) {
+ this.handItems.clear();
+ List<ItemStack> handItems = list.get(0);
+ for (int i = 0; i < handItems.size(); i++) {
+ this.handItems.set(i, handItems.get(1));
+ }
+ this.armorItems.clear();
+ List<ItemStack> armorItems = list.get(1);
+ for (int i = 0; i < armorItems.size(); i++) {
+ this.armorItems.set(i, armorItems.get(1));
+ }
+ }
+
+ public void clearEquipment() {
+ this.handItems.clear();
+ this.armorItems.clear();
+ }
+ // Purpur end
+
@Override
public boolean canTakeItem(ItemStack stack) {
net.minecraft.world.entity.EquipmentSlot enumitemslot = Mob.getEquipmentSlotForItem(stack);
diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java
index 5963b407d936e930a370677113ba947d2c2a198d..b60e38add38ac58d01f419dcb1b07a9b79bf1cb8 100644
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
@@ -1989,6 +1989,52 @@ public abstract class Player extends LivingEntity {
}
+ // Purpur start
+ public List<List<ItemStack>> cloneEquipment() {
+ List<List<ItemStack>> list = new java.util.ArrayList<>();
+ List<ItemStack> invItems = new java.util.ArrayList<>();
+ for (ItemStack item : this.inventory.items) {
+ invItems.add(item.copy());
+ }
+ list.add(invItems);
+ List<ItemStack> armorItems = new java.util.ArrayList<>();
+ for (ItemStack item : this.inventory.armor) {
+ armorItems.add(item.copy());
+ }
+ list.add(armorItems);
+ List<ItemStack> offhandItems = new java.util.ArrayList<>();
+ for (ItemStack item : this.inventory.offhand) {
+ offhandItems.add(item.copy());
+ }
+ list.add(offhandItems);
+ return list;
+ }
+
+ public void restoreEquipment(List<List<ItemStack>> list) {
+ this.inventory.items.clear();
+ List<ItemStack> invItems = list.get(0);
+ for (int i = 0; i < invItems.size(); i++) {
+ this.inventory.items.set(i, invItems.get(1));
+ }
+ this.inventory.armor.clear();
+ List<ItemStack> armorItems = list.get(1);
+ for (int i = 0; i < armorItems.size(); i++) {
+ this.inventory.armor.set(i, armorItems.get(1));
+ }
+ this.inventory.offhand.clear();
+ List<ItemStack> offhandItems = list.get(2);
+ for (int i = 0; i < offhandItems.size(); i++) {
+ this.inventory.offhand.set(i, offhandItems.get(1));
+ }
+ }
+
+ public void clearEquipment() {
+ this.inventory.items.clear();
+ this.inventory.armor.clear();
+ this.inventory.offhand.clear();
+ }
+ // Purpur end
+
public boolean addItem(ItemStack stack) {
this.equipEventAndSound(stack);
return this.inventory.add(stack);