Uploaded image for project: 'Minecraft: Java Edition'
  1. Minecraft: Java Edition
  2. MC-166984

Zombie villagers can be cured again while already in the conversion process

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • None
    • 1.14.4, 1.15 Pre-release 3, 1.16 Release Candidate 1, 1.16.2, 20w51a, 1.16.5, 1.17 Release Candidate 1, 1.17, 1.17.1, 21w38a, 1.18.1, 22w07a, 1.18.2, 22w16b, 1.19.2, 1.19.3, 1.19.4, 1.20, 1.20.1, 1.20.4, 23w51b, 1.20.6, 1.21, 1.21.3
    • Community Consensus
    • Mob behaviour

      The Bug:

      Zombie villagers can be cured again while already in the conversion process.

      Steps to Reproduce:

      1. Obtain a golden apple, a splash potion of weakness, and summon a zombie villager.
      2. Begin the conversion process of the zombie villager by splashing it with weakness and giving it a golden apple.
      3. Attempt to cure the zombie villager again while it's already in the conversion process.
      4. 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())

        1. MC-166984.mp4
          5.20 MB
          [Mod] Avoma
        2. MC-166984 - Current Code.png
          54 kB
          [Mod] Avoma
        3. MC-166984 - Fixed Code.png
          55 kB
          [Mod] Avoma

            Unassigned Unassigned
            Avoma [Mod] Avoma
            Votes:
            8 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              CHK: