The Bug:
Zombie villagers can be cured again while already in the conversion process.
Steps to Reproduce:
Obtain a golden apple, a splash potion of weakness, and summon a zombie villager.
Begin the conversion process of the zombie villager by splashing it with weakness and giving it a golden apple.
Attempt to cure the zombie villager again while it's already in the conversion process.
Take note as to whether or not zombie villagers can be cured again while already in the conversion process.
Observed Behavior:
Zombie villagers can be cured again while already in the conversion process.
Expected Behavior:
Zombie villagers would not be able to be cured again while already in the conversion process.
Code Analysis:
Code analysis by @Avoma can be found below.
The following is based on a decompiled version of Minecraft 1.19.2 using MCP-Reborn.
net.minecraft.world.entity.monster.ZombieVillager.java
public class ZombieVillager extends Zombie implements VillagerDataHolder {
...
public InteractionResult mobInteract(Player player, InteractionHand interactionHand) {
ItemStack itemstack = player.getItemInHand(interactionHand);
if (itemstack.is(Items.GOLDEN_APPLE)) {
if (this.hasEffect(MobEffects.WEAKNESS)) {
if (!player.getAbilities().instabuild) {
itemstack.shrink(1);
}
if (!this.level.isClientSide) {
this.startConverting(player.getUUID(), this.random.nextInt(2401) + 3600);
}
return InteractionResult.SUCCESS;
} else {
return InteractionResult.CONSUME;
}
} else {
return super.mobInteract(player, interactionHand);
}
}
...
If we look at the above class, we can see that there are three necessary checks that are carried out before allowing a zombie villager to be cured. One of these is to check if the player is holding a golden apple at the time of the interaction; the next is to check if the zombie villager has the weakness effect, and the final one is to make sure that the action is carried out server-side and not client-side. The game doesn't check if the zombie villager is already in the process of being converted before allowing its conversion process to begin again, therefore resulting in this problem occurring.
Fix:
Simply altering the appropriate existing "if" statement within this piece of code to check if the zombie villager is currently converting before allowing its conversion process to begin again, will resolve this problem. We can achieve this through the use of the isConverting()
boolean.
Current "if" statement:
if (this.hasEffect(MobEffects.WEAKNESS))
Fixed "if" statement:
if (this.hasEffect(MobEffects.WEAKNESS) && !this.isConverting())
Linked issues
is duplicated by 2
Attachments
Comments 12
The best place to add that check would be in the same if as the weakness check; then it will try to consume the golden apple instead, like when it has no weakness, without having to write more additional code.
Following on from my code analysis, I've double-checked my proposed fix and I can confidently confirm that it's fully functioning and works as expected, so I've attached two screenshots to this report, one of which shows the current code and the other that shows the fixed code. I feel this information may be quite insightful hence my reasoning for providing it. 🙂
[media][media]I can confirm this behavior in 1.19.2. Also, if it's cool, would it be okay if I could take ownership of this ticket since the reporter has been inactive for over two years? I'm willing to keep it up-to-date. 🙂
Please check if this is still an issue for you in 1.16 Release Candidate 1 or later.