mojira.dev
MC-185264

Snow golem with NoAI set to 1b still generates snow layers

The bug

Snow golems with NoAI set to 1b still produce snow layers, as they're expected not to produce snow without AI.

Reproduce

/summon minecraft:snow_golem ~ ~ ~ {NoAI:1b}

Code analysis

Code analysis by @unknown can be found in this comment.

Related issues

Attachments

Comments

migrated
[media][media][media][media][media][media][media][media]
MMK21

Can't reproduce in 20w21a.

[media]

g2245820920

@Mish Rodic   Snow golem only produces snow in low temperature, change a biome or height would reproduce.

[media]
Avoma

Can confirm for 20w46a.

Avoma

Can confirm in 20w51a.

Avoma

Can confirm in 21w03a. Feel free to use the following command to reproduce this issue:

/summon minecraft:snow_golem ~ ~ ~ {NoAI:1b}
bugsbugsbugs

Confirmed for 21w08b

Avoma

Can confirm in 21w15a.

Avoma

Can confirm in 1.17.

Avoma

Can confirm in 1.17.1.

MMK21

Affects 1.18 (it looks like you need to be in the correct biome; height is no longer sufficient)

MMK21

Affects 1.18.1

Avoma

Here's a code analysis of this issue along with a fix.

Code Analysis:

The following is based on a decompiled version of Minecraft 1.19.2 using MCP-Reborn.

net.minecraft.world.entity.animal.SnowGolem.java

public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackMob {
   ...
   public void aiStep() {
      super.aiStep();
      if (!this.level.isClientSide) {
         int i = Mth.floor(this.getX());
         int j = Mth.floor(this.getY());
         int k = Mth.floor(this.getZ());
         BlockPos blockpos = new BlockPos(i, j, k);
         Biome biome = this.level.getBiome(blockpos);
         if (biome.shouldSnowGolemBurn(blockpos)) {
            this.hurt(DamageSource.ON_FIRE, 1.0F);
         }

         if (!this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
            return;
         }

         BlockState blockstate = Blocks.SNOW.defaultBlockState();

         for(int l = 0; l < 4; ++l) {
            i = Mth.floor(this.getX() + (double)((float)(l % 2 * 2 - 1) * 0.25F));
            j = Mth.floor(this.getY());
            k = Mth.floor(this.getZ() + (double)((float)(l / 2 % 2 * 2 - 1) * 0.25F));
            BlockPos blockpos1 = new BlockPos(i, j, k);
            if (this.level.getBlockState(blockpos1).isAir() && blockstate.canSurvive(this.level, blockpos1)) {
               this.level.setBlockAndUpdate(blockpos1, blockstate);
            }
         }
      }

   }
   ...

If we look at the above class, we can see that there are two checks that are carried out before allowing snow golems to place snow beneath them. One of them is to make sure the action is carried out server-side and not client-side and the other is to check if the desired location of placement for the snow is air. The game doesn't check the value of the snow golem's "NoAI" NBT tag before allowing it to place snow beneath itself, therefore resulting in this problem occurring.

Fix:

Simply altering the appropriate existing "if" statement within this piece of code to check the value of the snow golem's "NoAI" NBT tag before allowing it to place snow beneath itself will resolve this problem.

Current "if" statement:

if (this.level.getBlockState(blockpos1).isAir() && blockstate.canSurvive(this.level, blockpos1)

Fixed "if" statement:

if (this.level.getBlockState(blockpos1).isAir() && blockstate.canSurvive(this.level, blockpos1) && !this.isNoAi())
Avoma

Can confirm in 1.18.2 and 22w13a.

Avoma

Can confirm in 1.19.2.

Avoma

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]

g2245820920

(Unassigned)

Confirmed

Mob behaviour

snow_golem

1.15.2, 20w21a, 20w22a, 1.16.1, 20w28a, ..., 22w13a, 1.19.2, 1.19.4, 23w16a, 1.20.1

Retrieved