The Bug:
Dying snow golems can place snow beneath themselves.
Steps to Reproduce:
Summon a snow golem in a non-warm biome that has 1 health.
/summon minecraft:snow_golem ~ ~ ~ {Health:1f}Kill the snow golem with a knockback (sprint) attack.
Watch the blocks beneath the snow golem closely as it plays through its death animation.
Take note as to whether or not dying snow golems can place snow beneath themselves.
Observed Behavior:
Dying snow golems can place snow beneath themselves.
Expected Behavior:
Dying snow golems would not place snow beneath themselves as they are in the process of dying and are no longer alive.
Code Analysis:
Code analysis by @unknown can be found below.
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 if the snow golem is dying 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 if the snow golem is dying before allowing it to place snow beneath itself will resolve this problem. We can achieve this through the use of the isAlive() boolean.
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.isAlive())Linked issues
Attachments
Comments 2
Duplicate of MC-106291. Currently, it's ambiguous whether this issue is operating as intended and not deemed a bug, or if it is indeed a bug but simply won't be addressed, as these two tickets have distinct resolutions.
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. 🙂