From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Mon, 11 Jul 2022 11:56:41 -0700
Subject: [PATCH] Fix a bunch of vanilla bugs

https://bugs.mojang.com/browse/MC-253884
  show raid entity event to all tracking players

https://bugs.mojang.com/browse/MC-253721
  wrong msg for opping multiple players

https://bugs.mojang.com/browse/MC-248588
  respect mob griefing gamerule for draining water cauldrons

https://bugs.mojang.com/browse/MC-244739
  play goat eating sound for last item in stack

https://bugs.mojang.com/browse/MC-243057
  ignore furnace fuel slot in recipe book click

https://bugs.mojang.com/browse/MC-147659
  Some witch huts spawn the incorrect cat
  Note: Marked as Won't Fix, makes 0 sense

https://bugs.mojang.com/browse/MC-179072
  Creepers do not defuse when switching from Survival to Creative/Spectator

https://bugs.mojang.com/browse/MC-191591
https://bugs.mojang.com/browse/MC-258360
  Fix items equipped on AbstractHorse losing NBT

https://bugs.mojang.com/browse/MC-121048
  by: MelnCat <melncatuwu@gmail.com>
  This moves the setHealth call to below the recordDamage call to prevent
  recordDamage from clearing the CombatTracker, since recordDamage will
  clear the CombatTracker if the entity is dead. This fixes death messages
  such as the "doomed to fall" messages.

https://bugs.mojang.com/browse/MC-257875
  by: Jake Potrebic <jake.m.potrebic@gmail.com>
  Fixes server not consuming fire charges when igniting a creeper

Co-authored-by: William Blake Galbreath <blake.galbreath@gmail.com>
Co-authored-by: MelnCat <melncatuwu@gmail.com>

diff --git a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java
index c0c31a5d356d0754b478d84f0cef87fc84c4fea1..3c2ed8e7cf54ab5e32df713010b948d568aab9b0 100644
--- a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java
+++ b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java
@@ -347,7 +347,7 @@ public interface DispenseItemBehavior {
                         }
                     }
                     // CraftBukkit end
-                    ((Saddleable) list.get(0)).equipSaddle(SoundSource.BLOCKS);
+                    ((Saddleable) list.get(0)).equipSaddle(SoundSource.BLOCKS, CraftItemStack.asNMSCopy(event.getItem())); // Paper - Fix saddles losing nbt data - MC-191591
                     // itemstack.shrink(1); // CraftBukkit - handled above
                     this.setSuccess(true);
                     return stack;
diff --git a/src/main/java/net/minecraft/server/commands/DeOpCommands.java b/src/main/java/net/minecraft/server/commands/DeOpCommands.java
index cca2618d90306eed9894c5fa7b6ed96b68210688..10769c60bd53438d44fbc6192667acdf4cc95594 100644
--- a/src/main/java/net/minecraft/server/commands/DeOpCommands.java
+++ b/src/main/java/net/minecraft/server/commands/DeOpCommands.java
@@ -33,7 +33,7 @@ public class DeOpCommands {
             if (playerList.isOp(gameProfile)) {
                 playerList.deop(gameProfile);
                 ++i;
-                source.sendSuccess(Component.translatable("commands.deop.success", targets.iterator().next().getName()), true);
+                source.sendSuccess(Component.translatable("commands.deop.success", gameProfile.getName()), true); // Paper - fixes MC-253721
             }
         }
 
diff --git a/src/main/java/net/minecraft/server/commands/OpCommand.java b/src/main/java/net/minecraft/server/commands/OpCommand.java
index 43e77cef0fce75f59aeb05e161668bebb8fca229..ef50fbf8cb3f008827850b5ed33422007be09bd2 100644
--- a/src/main/java/net/minecraft/server/commands/OpCommand.java
+++ b/src/main/java/net/minecraft/server/commands/OpCommand.java
@@ -38,7 +38,7 @@ public class OpCommand {
             if (!playerList.isOp(gameProfile)) {
                 playerList.op(gameProfile);
                 ++i;
-                source.sendSuccess(Component.translatable("commands.op.success", targets.iterator().next().getName()), true);
+                source.sendSuccess(Component.translatable("commands.op.success", gameProfile.getName()), true); // Paper - fixes MC-253721
             }
         }
 
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index 6d682a78c6fe4cbf44cd20449cfe89d530e1d28c..cd57fde197f622e5315c4a63936a9b66f5f05916 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -2207,8 +2207,10 @@ public abstract class LivingEntity extends Entity {
                 // CraftBukkit end
                 float f3 = this.getHealth();
 
-                this.setHealth(f3 - f);
+                // Paper start - MC-121048
                 this.getCombatTracker().recordDamage(damagesource, f3, f);
+                this.setHealth(f3 - f);
+                // Paper end
                 // CraftBukkit start
                 if (!human) {
                     this.setAbsorptionAmount(this.getAbsorptionAmount() - f);
diff --git a/src/main/java/net/minecraft/world/entity/Saddleable.java b/src/main/java/net/minecraft/world/entity/Saddleable.java
index effe4c4fb37fe13aece70cdef4966047d4719af9..7152674d3f3fb98198585cb5ece2bb88877345f9 100644
--- a/src/main/java/net/minecraft/world/entity/Saddleable.java
+++ b/src/main/java/net/minecraft/world/entity/Saddleable.java
@@ -9,6 +9,11 @@ public interface Saddleable {
     boolean isSaddleable();
 
     void equipSaddle(@Nullable SoundSource sound);
+    // Paper start - Fix saddles losing nbt data - MC-191591
+    default void equipSaddle(final @Nullable SoundSource sound, final @Nullable net.minecraft.world.item.ItemStack stack) {
+        this.equipSaddle(sound);
+    }
+    // Paper end
 
     default SoundEvent getSaddleSoundEvent() {
         return SoundEvents.HORSE_SADDLE;
diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/SwellGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/SwellGoal.java
index 19540fd4a7f992888fadb6501d0c8a5a7e71fcf6..e241ae250f4f04a17ef2c583d00b065a4ca56a4c 100644
--- a/src/main/java/net/minecraft/world/entity/ai/goal/SwellGoal.java
+++ b/src/main/java/net/minecraft/world/entity/ai/goal/SwellGoal.java
@@ -21,6 +21,13 @@ public class SwellGoal extends Goal {
         return this.creeper.getSwellDir() > 0 || livingEntity != null && this.creeper.distanceToSqr(livingEntity) < 9.0D;
     }
 
+    // Paper start - Fix MC-179072
+    @Override
+    public boolean canContinueToUse() {
+        return !net.minecraft.world.entity.EntitySelector.NO_CREATIVE_OR_SPECTATOR.test(this.creeper.getTarget()) && canUse();
+    }
+    // Paper end
+
     @Override
     public void start() {
         this.creeper.getNavigation().stop();
diff --git a/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java b/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java
index 0b0377fa1483e4fcb31456af6c7e1749bd8af484..e9f7c08ae3ea9c578971b1ede88788572c20e277 100644
--- a/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java
+++ b/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java
@@ -236,9 +236,10 @@ public class Goat extends Animal {
             player.setItemInHand(hand, itemstack1);
             return InteractionResult.sidedSuccess(this.level.isClientSide);
         } else {
+            boolean isFood = this.isFood(itemstack); // Paper - track before stack is possibly decreased to 0 (Fixes MC-244739)
             InteractionResult enuminteractionresult = super.mobInteract(player, hand);
 
-            if (enuminteractionresult.consumesAction() && this.isFood(itemstack)) {
+            if (enuminteractionresult.consumesAction() && isFood) { // Paper
                 this.level.playSound((Player) null, (Entity) this, this.getEatingSound(itemstack), SoundSource.NEUTRAL, 1.0F, Mth.randomBetween(this.level.random, 0.8F, 1.2F));
             }
 
diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java b/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java
index 821b88d0c32f946af9af1c2e211b38446fab4ecb..72d660cd2ade39335024897cffb8b8a151a7cb71 100644
--- a/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java
+++ b/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java
@@ -221,7 +221,13 @@ public abstract class AbstractHorse extends Animal implements ContainerListener,
 
     @Override
     public void equipSaddle(@Nullable SoundSource sound) {
-        this.inventory.setItem(0, new ItemStack(Items.SADDLE));
+        // Paper start - Fix saddles losing nbt data - MC-191591
+        this.equipSaddle(sound, null);
+    }
+    @Override
+    public void equipSaddle(@Nullable SoundSource sound, @Nullable ItemStack stack) {
+        this.inventory.setItem(0, stack != null ? stack : new ItemStack(Items.SADDLE));
+        // Paper end
         if (sound != null) {
             this.level.playSound((Player) null, (Entity) this, this.getSaddleSoundEvent(), sound, 0.5F, 1.0F);
         }
@@ -230,7 +236,7 @@ public abstract class AbstractHorse extends Animal implements ContainerListener,
 
     public void equipArmor(Player player, ItemStack stack) {
         if (this.isArmor(stack)) {
-            this.inventory.setItem(1, new ItemStack(stack.getItem()));
+            this.inventory.setItem(1, stack.copyWithCount(1)); // Paper - fix equipping items with nbt - MC-258360, MC-191591
             if (!player.getAbilities().instabuild) {
                 stack.shrink(1);
             }
diff --git a/src/main/java/net/minecraft/world/entity/monster/Creeper.java b/src/main/java/net/minecraft/world/entity/monster/Creeper.java
index 805e267090285d625dbeb75b06f8c5ad141a75a4..338161d2eb15d9264027961b71678b8d2f020fd8 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Creeper.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Creeper.java
@@ -247,9 +247,15 @@ public class Creeper extends Monster implements PowerableMob {
             this.level.playSound(player, this.getX(), this.getY(), this.getZ(), soundeffect, this.getSoundSource(), 1.0F, this.random.nextFloat() * 0.4F + 0.8F);
             if (!this.level.isClientSide) {
                 this.ignite();
+                if (itemstack.isDamageableItem()) { // Paper - only call hurtAndBreak for a damageable item - MC-257875
                 itemstack.hurtAndBreak(1, player, (entityhuman1) -> {
                     entityhuman1.broadcastBreakEvent(hand);
                 });
+                // Paper start - just consume the item - MC-257875
+                } else if (!player.getAbilities().instabuild) {
+                    itemstack.shrink(1);
+                }
+                // Paper end
             }
 
             return InteractionResult.sidedSuccess(this.level.isClientSide);
diff --git a/src/main/java/net/minecraft/world/entity/npc/CatSpawner.java b/src/main/java/net/minecraft/world/entity/npc/CatSpawner.java
index f174094febfdfdc309f1b50877be60bae8a98156..5f407535298a31a34cfe114dd863fd6a9b977707 100644
--- a/src/main/java/net/minecraft/world/entity/npc/CatSpawner.java
+++ b/src/main/java/net/minecraft/world/entity/npc/CatSpawner.java
@@ -87,8 +87,8 @@ public class CatSpawner implements CustomSpawner {
         if (cat == null) {
             return 0;
         } else {
+            cat.moveTo(pos, 0.0F, 0.0F); // Paper - move up - Fix MC-147659
             cat.finalizeSpawn(world, world.getCurrentDifficultyAt(pos), MobSpawnType.NATURAL, (SpawnGroupData)null, (CompoundTag)null);
-            cat.moveTo(pos, 0.0F, 0.0F);
             world.addFreshEntityWithPassengers(cat);
             return 1;
         }
diff --git a/src/main/java/net/minecraft/world/entity/raid/Raids.java b/src/main/java/net/minecraft/world/entity/raid/Raids.java
index fa8fcdfea51a35e4a482d3d7b18159099da62706..feb89eb69994bdd1d2f95d2b9992e69251b2bee7 100644
--- a/src/main/java/net/minecraft/world/entity/raid/Raids.java
+++ b/src/main/java/net/minecraft/world/entity/raid/Raids.java
@@ -125,7 +125,7 @@ public class Raids extends SavedData {
                     // CraftBukkit end
                 } else {
                     player.removeEffect(MobEffects.BAD_OMEN);
-                    player.connection.send(new ClientboundEntityEventPacket(player, (byte) 43));
+                    this.level.broadcastEntityEvent(player, net.minecraft.world.entity.EntityEvent.BAD_OMEN_TRIGGERED /* (byte) 43 */); // Paper - Fix MC-253884
                 }
 
                 if (flag) {
@@ -140,7 +140,7 @@ public class Raids extends SavedData {
                     }
                     // CraftBukkit end
                     raid.absorbBadOmen(player);
-                    player.connection.send(new ClientboundEntityEventPacket(player, (byte) 43));
+                    this.level.broadcastEntityEvent(player, net.minecraft.world.entity.EntityEvent.BAD_OMEN_TRIGGERED /* (byte) 43 */); // Paper - Fix MC-253884
                     if (!raid.hasFirstWaveSpawned()) {
                         player.awardStat(Stats.RAID_TRIGGER);
                         CriteriaTriggers.BAD_OMEN.trigger(player);
diff --git a/src/main/java/net/minecraft/world/item/SaddleItem.java b/src/main/java/net/minecraft/world/item/SaddleItem.java
index c35375e15c0368fec12d37a4b82668b51d9fe9ff..0c975875f1f2d0236d42a291486a7e78e1702802 100644
--- a/src/main/java/net/minecraft/world/item/SaddleItem.java
+++ b/src/main/java/net/minecraft/world/item/SaddleItem.java
@@ -18,7 +18,7 @@ public class SaddleItem extends Item {
         if (entity instanceof Saddleable saddleable && entity.isAlive()) {
             if (!saddleable.isSaddled() && saddleable.isSaddleable()) {
                 if (!user.level.isClientSide) {
-                    saddleable.equipSaddle(SoundSource.NEUTRAL);
+                    saddleable.equipSaddle(SoundSource.NEUTRAL, stack.copyWithCount(1)); // Paper - Fix saddles losing nbt data - MC-191591
                     entity.level.gameEvent(entity, GameEvent.EQUIP, entity.position());
                     stack.shrink(1);
                 }
diff --git a/src/main/java/net/minecraft/world/level/block/LayeredCauldronBlock.java b/src/main/java/net/minecraft/world/level/block/LayeredCauldronBlock.java
index a223959f766ac41aff7aeff80606f5e7c37ebf49..1a90860bc39afb8bade96a5c6c40861dbb68c21e 100644
--- a/src/main/java/net/minecraft/world/level/block/LayeredCauldronBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/LayeredCauldronBlock.java
@@ -63,7 +63,7 @@ public class LayeredCauldronBlock extends AbstractCauldronBlock {
         if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
         if (!world.isClientSide && entity.isOnFire() && this.isEntityInsideContent(state, pos, entity)) {
             // CraftBukkit start
-            if (entity.mayInteract(world, pos)) {
+            if ((entity instanceof net.minecraft.world.entity.player.Player || world.getGameRules().getBoolean(net.minecraft.world.level.GameRules.RULE_MOBGRIEFING)) && entity.mayInteract(world, pos)) { // Paper - Fixes MC-248588
                 if (!this.handleEntityOnFireInsideWithEvent(state, world, pos, entity)) { // Paper - fix powdered snow cauldron extinguishing entities
                     return;
                 }
diff --git a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
index 1e2af7d3a6d2ad0a298d2f6ac2d8110354282988..cac2768fe520b591990c7bc943ae7e95f49efb31 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
@@ -663,13 +663,10 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit
 
     @Override
     public void fillStackedContents(StackedContents finder) {
-        Iterator iterator = this.items.iterator();
-
-        while (iterator.hasNext()) {
-            ItemStack itemstack = (ItemStack) iterator.next();
-
-            finder.accountStack(itemstack);
-        }
+        // Paper start - don't account fuel stack (fixes MC-243057)
+        finder.accountStack(this.items.get(SLOT_INPUT));
+        finder.accountStack(this.items.get(SLOT_RESULT));
+        // Paper end
 
     }
 }
