diff --git a/patches/server/0224-Fix-raid-captains-not-giving-voluntary-exile-advance.patch b/patches/server/0224-Fix-raid-captains-not-giving-voluntary-exile-advance.patch new file mode 100644 index 000000000..bdcf09fe4 --- /dev/null +++ b/patches/server/0224-Fix-raid-captains-not-giving-voluntary-exile-advance.patch @@ -0,0 +1,77 @@ +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 + }