From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: BillyGalbreath Date: Fri, 28 May 2021 12:24:45 -0500 Subject: [PATCH] Fix raid captains not giving voluntary exile advancement This fixes PaperMC/Paper#3729 where killing a raid captain does not give the voluntary exile advancement. The problem is 2 fold on Paper's end. Firstly, Paper changes logical order revolving around making the EntityDeathEvent cancellable. Reordering this logic has ended up with raid captains unsetting the banner on their head _before_ the criterion triggers for the advancement leaving the criterion to believe a regular pillager has been killed, not a captain. Secondly, Paper sets itemstacks to count of 0 too early in an attempt to reduce the amount of dupes caused by leaking them through various gameplay mechanics. This means the banner on their head get converted to air before the criterion triggers leaving the criterion to believe a regular pillager has been killed. This fixes both issues by storing a copy of the banner in a new field that is set back to the head slot just before the criterion triggers and then removed again right after the criterion is finished running. diff --git a/src/main/java/net/minecraft/world/entity/EntityLiving.java b/src/main/java/net/minecraft/world/entity/EntityLiving.java index 6b65b17d6b100adacd628d08a24a68164d2bb9aa..6acef38b805b35e1f2ae9e6f4d2f387a5050d0f7 100644 --- a/src/main/java/net/minecraft/world/entity/EntityLiving.java +++ b/src/main/java/net/minecraft/world/entity/EntityLiving.java @@ -1563,7 +1563,9 @@ public abstract class EntityLiving extends Entity { org.bukkit.event.entity.EntityDeathEvent deathEvent = this.d(damagesource); if (deathEvent == null || !deathEvent.isCancelled()) { if (this.getKillCount() >= 0 && entityliving != null) { + this.fixHead(); // Purpur entityliving.runKillTrigger(this, this.getKillCount(), damagesource); + this.fixHead(); // Purpur } if (this.isSleeping()) { this.entityWakeup(); @@ -3902,4 +3904,6 @@ public abstract class EntityLiving extends Entity { this.shieldBlockingDelay = shieldBlockingDelay; } // Paper end + + public void fixHead() {} // Purpur } diff --git a/src/main/java/net/minecraft/world/entity/raid/EntityRaider.java b/src/main/java/net/minecraft/world/entity/raid/EntityRaider.java index 8eec32af12c69e1963dcd304a25ec4811b2f1f5a..d0cf1eca6f077673aa353e92ef9732f0fe5d0b54 100644 --- a/src/main/java/net/minecraft/world/entity/raid/EntityRaider.java +++ b/src/main/java/net/minecraft/world/entity/raid/EntityRaider.java @@ -152,6 +152,10 @@ public abstract class EntityRaider extends EntityMonsterPatrolling { } if (!itemstack.isEmpty() && ItemStack.matches(itemstack, Raid.s()) && entityhuman != null) { + // Purpur start + this.fixHead = itemstack.cloneItemStack(); + this.fixHead.setCount(1); + // Purpur end MobEffect mobeffect = entityhuman.getEffect(MobEffects.BAD_OMEN); byte b0 = 1; int i; @@ -564,4 +568,18 @@ public abstract class EntityRaider extends EntityMonsterPatrolling { } } + + // Purpur start + private ItemStack fixHead = null; + + @Override + public void fixHead() { + if (this.fixHead != null) { + setSlot(EnumItemSlot.HEAD, this.fixHead); + this.fixHead = null; + } else { + setSlot(EnumItemSlot.HEAD, ItemStack.NULL_ITEM); + } + } + // Purpur end }