mirror of
https://github.com/PurpurMC/Purpur.git
synced 2026-02-19 17:37:42 +01:00
210 lines
9.4 KiB
Diff
210 lines
9.4 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: BillyGalbreath <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/EntityInsentient.java b/src/main/java/net/minecraft/world/entity/EntityInsentient.java
|
|
index d96630a64f132eecf5cb4c80302cf9dd6176ad7c..b4afd71340a0c7e1b6aa2e3f01a6a4fc998f3f16 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/EntityInsentient.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/EntityInsentient.java
|
|
@@ -106,9 +106,9 @@ public abstract class EntityInsentient extends EntityLiving {
|
|
public PathfinderGoalSelector targetSelector;
|
|
private EntityLiving goalTarget;
|
|
private final EntitySenses bo;
|
|
- private final NonNullList<ItemStack> bp;
|
|
+ private final NonNullList<ItemStack> bp; public List<ItemStack> getHandEquipment() { return this.bp; } // Purpur - OBFHELPER
|
|
public final float[] dropChanceHand;
|
|
- private final NonNullList<ItemStack> bq;
|
|
+ private final NonNullList<ItemStack> bq; public List<ItemStack> getArmorEquipment() { return this.bq; } // Purpur - OBFHELPER
|
|
public final float[] dropChanceArmor;
|
|
// private boolean canPickUpLoot; // CraftBukkit - moved up to EntityLiving
|
|
public boolean persistent;
|
|
@@ -1004,6 +1004,41 @@ public abstract class EntityInsentient extends EntityLiving {
|
|
}
|
|
}
|
|
|
|
+ // 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.getHandEquipment()) {
|
|
+ handItems.add(item.cloneItemStack());
|
|
+ }
|
|
+ list.add(handItems);
|
|
+ List<ItemStack> armorItems = new java.util.ArrayList<>();
|
|
+ for (ItemStack item : this.getArmorEquipment()) {
|
|
+ armorItems.add(item.cloneItemStack());
|
|
+ }
|
|
+ list.add(armorItems);
|
|
+ return list;
|
|
+ }
|
|
+
|
|
+ public void restoreEquipment(List<List<ItemStack>> list) {
|
|
+ this.getHandEquipment().clear();
|
|
+ List<ItemStack> handItems = list.get(0);
|
|
+ for (int i = 0; i < handItems.size(); i++) {
|
|
+ this.getHandEquipment().set(i, handItems.get(1));
|
|
+ }
|
|
+ this.getArmorEquipment().clear();
|
|
+ List<ItemStack> armorItems = list.get(1);
|
|
+ for (int i = 0; i < armorItems.size(); i++) {
|
|
+ this.getArmorEquipment().set(i, armorItems.get(i));
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public void clearEquipment() {
|
|
+ this.getHandEquipment().clear();
|
|
+ this.getArmorEquipment().clear();
|
|
+ }
|
|
+ // Purpur end
|
|
+
|
|
@Override
|
|
public void setSlot(EnumItemSlot enumitemslot, ItemStack itemstack) {
|
|
switch (enumitemslot.a()) {
|
|
diff --git a/src/main/java/net/minecraft/world/entity/EntityLiving.java b/src/main/java/net/minecraft/world/entity/EntityLiving.java
|
|
index 57660a67003dff6a5515912fe07e79fac1fb9e37..4c527cd68da13633b424e666d693f82dc2a3fc25 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/EntityLiving.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/EntityLiving.java
|
|
@@ -1557,10 +1557,13 @@ public abstract class EntityLiving extends Entity {
|
|
}
|
|
|
|
// Paper start
|
|
+ List<List<ItemStack>> equipmentSnapshotBefore = this.cloneEquipment(); // Purpur
|
|
org.bukkit.event.entity.EntityDeathEvent deathEvent = this.d(damagesource);
|
|
if (deathEvent == null || !deathEvent.isCancelled()) {
|
|
if (this.getKillCount() >= 0 && entityliving != null) {
|
|
+ this.restoreEquipment(equipmentSnapshotBefore); // Purpur
|
|
entityliving.runKillTrigger(this, this.getKillCount(), damagesource);
|
|
+ this.clearEquipment(); // Purpur
|
|
}
|
|
if (this.isSleeping()) {
|
|
this.entityWakeup();
|
|
@@ -2258,6 +2261,12 @@ public abstract class EntityLiving extends Entity {
|
|
|
|
public abstract ItemStack getEquipment(EnumItemSlot enumitemslot);
|
|
|
|
+ // Purpur start
|
|
+ public abstract List<List<ItemStack>> cloneEquipment();
|
|
+ public abstract void restoreEquipment(List<List<ItemStack>> list);
|
|
+ public abstract void clearEquipment();
|
|
+ // Purpur end
|
|
+
|
|
// CraftBukkit start
|
|
public void setSlot(EnumItemSlot enumitemslot, ItemStack itemstack, boolean silent) {
|
|
this.setSlot(enumitemslot, itemstack);
|
|
diff --git a/src/main/java/net/minecraft/world/entity/decoration/EntityArmorStand.java b/src/main/java/net/minecraft/world/entity/decoration/EntityArmorStand.java
|
|
index ddc1c3383cdc32fa832485f3922c74185731557a..e28a2d983ae7b83f435c9dea606a92e2fbd3391a 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/decoration/EntityArmorStand.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/decoration/EntityArmorStand.java
|
|
@@ -171,6 +171,41 @@ public class EntityArmorStand extends EntityLiving {
|
|
}
|
|
}
|
|
|
|
+ // 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.cloneItemStack());
|
|
+ }
|
|
+ list.add(handItems);
|
|
+ List<ItemStack> armorItems = new java.util.ArrayList<>();
|
|
+ for (ItemStack item : this.armorItems) {
|
|
+ armorItems.add(item.cloneItemStack());
|
|
+ }
|
|
+ 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 void setSlot(EnumItemSlot enumitemslot, ItemStack itemstack) {
|
|
// CraftBukkit start
|
|
diff --git a/src/main/java/net/minecraft/world/entity/player/EntityHuman.java b/src/main/java/net/minecraft/world/entity/player/EntityHuman.java
|
|
index 24285b1b2264939fdfa6f7d6311772fa67be8680..383b4cacc8c9f4fd5d2a83f683e5174ea5025f61 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/player/EntityHuman.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/player/EntityHuman.java
|
|
@@ -1886,6 +1886,52 @@ public abstract class EntityHuman extends EntityLiving {
|
|
return enumitemslot == EnumItemSlot.MAINHAND ? this.inventory.getItemInHand() : (enumitemslot == EnumItemSlot.OFFHAND ? (ItemStack) this.inventory.extraSlots.get(0) : (enumitemslot.a() == EnumItemSlot.Function.ARMOR ? (ItemStack) this.inventory.armor.get(enumitemslot.b()) : ItemStack.b));
|
|
}
|
|
|
|
+ // 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.cloneItemStack());
|
|
+ }
|
|
+ list.add(invItems);
|
|
+ List<ItemStack> armorItems = new java.util.ArrayList<>();
|
|
+ for (ItemStack item : this.inventory.armor) {
|
|
+ armorItems.add(item.cloneItemStack());
|
|
+ }
|
|
+ list.add(armorItems);
|
|
+ List<ItemStack> extraItems = new java.util.ArrayList<>();
|
|
+ for (ItemStack item : this.inventory.extraSlots) {
|
|
+ extraItems.add(item.cloneItemStack());
|
|
+ }
|
|
+ list.add(extraItems);
|
|
+ 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.extraSlots.clear();
|
|
+ List<ItemStack> extraItems = list.get(2);
|
|
+ for (int i = 0; i < extraItems.size(); i++) {
|
|
+ this.inventory.extraSlots.set(i, extraItems.get(1));
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public void clearEquipment() {
|
|
+ this.inventory.items.clear();
|
|
+ this.inventory.armor.clear();
|
|
+ this.inventory.extraSlots.clear();
|
|
+ }
|
|
+ // Purpur end
|
|
+
|
|
@Override
|
|
public void setSlot(EnumItemSlot enumitemslot, ItemStack itemstack) {
|
|
// CraftBukkit start
|