From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> Date: Thu, 31 Aug 2023 17:32:48 +0200 Subject: [PATCH] Fix silent equipment change for mobs diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java index 1e997c1758ed86dc563983317ceb17e626b8dba7..956d05e2ae59978ea9623ca0e167c0afe0b87306 100644 --- a/src/main/java/net/minecraft/world/entity/Mob.java +++ b/src/main/java/net/minecraft/world/entity/Mob.java @@ -1058,13 +1058,20 @@ public abstract class Mob extends LivingEntity implements Targeting { @Override public void setItemSlot(EquipmentSlot slot, ItemStack stack) { + // Paper start + setItemSlot(slot, stack, false); + } + + @Override + public void setItemSlot(EquipmentSlot slot, ItemStack stack, boolean silent) { + // Paper end this.verifyEquippedItem(stack); switch (slot.getType()) { case HAND: - this.onEquipItem(slot, (ItemStack) this.handItems.set(slot.getIndex(), stack), stack); + this.onEquipItem(slot, (ItemStack) this.handItems.set(slot.getIndex(), stack), stack, silent); // Paper break; case ARMOR: - this.onEquipItem(slot, (ItemStack) this.armorItems.set(slot.getIndex(), stack), stack); + this.onEquipItem(slot, (ItemStack) this.armorItems.set(slot.getIndex(), stack), stack, silent); // Paper } } diff --git a/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java b/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java index 8e9469fec42f7b6a132cf173f6f5a95777a29b3b..b319021b22c5dceba6199ed27814b2dcf47b8d50 100644 --- a/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java +++ b/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java @@ -250,8 +250,8 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo // Paper end @Override - public void setItemSlot(EquipmentSlot slot, ItemStack stack) { - super.setItemSlot(slot, stack); + public void setItemSlot(EquipmentSlot slot, ItemStack stack, boolean silent) { // Paper + super.setItemSlot(slot, stack, silent); // Paper if (!this.level().isClientSide) { this.reassessWeaponGoal(); } diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java index f2f93761985a78b563dd1eda57f9a08b1cc8893a..2354a0e5d15e9be633d9fe3a1a9feefe7b9b7782 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java @@ -1870,7 +1870,10 @@ public abstract class Level implements LevelAccessor, AutoCloseable { // Paper end - optimize redstone (Alternate Current) // Paper start - notify observers even if grow failed public void checkCapturedTreeStateForObserverNotify(final BlockPos pos, final CraftBlockState craftBlockState) { - if (craftBlockState.getPosition().getY() == pos.getY() && this.getBlockState(craftBlockState.getPosition()) == craftBlockState.getHandle()) { // notify observers if the block state is the same and the Y level equals the original y level (for mega trees) + // notify observers if the block state is the same and the Y level equals the original y level (for mega trees) + // blocks at the same Y level with the same state can be assumed to be saplings which trigger observers regardless of if the + // tree grew or not + if (craftBlockState.getPosition().getY() == pos.getY() && this.getBlockState(craftBlockState.getPosition()) == craftBlockState.getHandle()) { this.notifyAndUpdatePhysics(craftBlockState.getPosition(), null, craftBlockState.getHandle(), craftBlockState.getHandle(), craftBlockState.getHandle(), craftBlockState.getFlag(), 512); } } diff --git a/src/test/java/io/papermc/paper/entity/EntitySetItemSlotSilentOverrideTest.java b/src/test/java/io/papermc/paper/entity/EntitySetItemSlotSilentOverrideTest.java new file mode 100644 index 0000000000000000000000000000000000000000..81947843d1f2f7dc6f59d7b52f327d60b17d0dcc --- /dev/null +++ b/src/test/java/io/papermc/paper/entity/EntitySetItemSlotSilentOverrideTest.java @@ -0,0 +1,51 @@ +package io.papermc.paper.entity; + +import io.github.classgraph.ClassGraph; +import io.github.classgraph.ClassInfo; +import io.github.classgraph.MethodInfo; +import io.github.classgraph.MethodInfoList; +import io.github.classgraph.MethodParameterInfo; +import io.github.classgraph.ScanResult; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Stream; +import org.bukkit.support.AbstractTestingBase; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +import static org.junit.jupiter.api.Assertions.fail; + +public class EntitySetItemSlotSilentOverrideTest extends AbstractTestingBase { + + public static Stream parameters() { + final List classInfo = new ArrayList<>(); + try (ScanResult scanResult = new ClassGraph() + .enableClassInfo() + .enableMethodInfo() + .whitelistPackages("net.minecraft") + .scan() + ) { + for (final ClassInfo subclass : scanResult.getSubclasses("net.minecraft.world.entity.LivingEntity")) { + final MethodInfoList setItemSlot = subclass.getDeclaredMethodInfo("setItemSlot"); + if (!setItemSlot.isEmpty()) { + classInfo.add(subclass); + } + } + } + return classInfo.stream(); + } + + @ParameterizedTest + @MethodSource("parameters") + public void checkSetItemSlotSilentOverrides(ClassInfo overridesSetItemSlot) { + final MethodInfoList setItemSlot = overridesSetItemSlot.getDeclaredMethodInfo("setItemSlot"); + for (final MethodInfo methodInfo : setItemSlot) { + for (final MethodParameterInfo methodParameterInfo : methodInfo.getParameterInfo()) { + if ("boolean".equals(methodParameterInfo.getTypeDescriptor().toStringWithSimpleNames())) { + return; + } + } + } + fail(overridesSetItemSlot.getName() + " needs to override setItemSlot with the boolean silent parameter as well"); + } +}