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.
Linked issues
Attachments
Comments 15
@Mish Rodic Snow golem only produces snow in low temperature, change a biome or height would reproduce.
[media]Can confirm in 21w03a. Feel free to use the following command to reproduce this issue:
/summon minecraft:snow_golem ~ ~ ~ {NoAI:1b}
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())
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]
Can't reproduce in 20w21a.
[media]