I've used this setup for reproducing MC-311510, MC-311511, MC-311513 and MC-311514, however the fact that this works at all may be a bug in and of itself.
To reproduce: /effect give @s minecraft:mining_fatigue 1 86 then try punching some slime blocks, honey blocks or basic plants
Expected results: since these have zero hardness, they would break instantly regardless of circumstances.
Actual results: in this bizarre edge case, they suddenly become indestructible
Linked issues
is duplicated by 3
Attachments
Comments 3
Some analysis:
As the fix for MC-279819, the speed multipliers for Mining Fatigue are no longer from a lookup table, and are instead calculated directly from the exponential formula.
// net.minecraft.world.entity.player.Player at 26.3-rc-2
public float getDestroySpeed(BlockState state) {
float speed = this.inventory.getSelectedItem().getDestroySpeed(state);
if (speed > 1.0f) {
speed += (float)this.getAttributeValue(Attributes.MINING_EFFICIENCY);
}
if (MobEffectUtil.hasDigSpeed(this)) {
speed *= 1.0f + (float)(MobEffectUtil.getDigSpeedAmplification(this) + 1) * 0.2f;
}
// This is the part in question
if (this.hasEffect(MobEffects.MINING_FATIGUE)) {
int amplifier = this.getEffect(MobEffects.MINING_FATIGUE).getAmplifier();
float scale = (float)Math.pow(0.3, amplifier + 1);
speed *= scale;
}
speed *= (float)this.getAttributeValue(Attributes.BLOCK_BREAK_SPEED);
if (this.isEyeInFluid(FluidTags.WATER)) {
speed *= (float)this.getAttribute(Attributes.SUBMERGED_MINING_SPEED).getValue();
}
if (!this.onGround()) {
speed /= 5.0f;
}
return speed;
}And pow(0.3, 87) underflows to zero when cast to single-precision. Thus the mining speed calculated turns out to be zero under Mining Fatigue 87 or higher.
Well, this speed is not used directly, and is instead used to calculate the mining progress per tick:
// net.minecraft.world.level.block.state.BlockBehaviour at 26.3-rc-2
protected float getDestroyProgress(BlockState state, Player player, BlockGetter level, BlockPos pos) {
float destroySpeed = state.getDestroySpeed(level, pos);
if (destroySpeed == -1.0f) {
return 0.0f;
}
int modifier = player.hasCorrectToolForDrops(state) ? 30 : 100;
return player.getDestroySpeed(state) / destroySpeed / (float)modifier;
}destroySpeed here is just the block hardness. Evidently having both the mining speed and the hardness set to zero incurs Bad Things (a.k.a. NaN), and there seems to be no guarding against either of them being zero (although I haven’t thoroughly scanned the code, so I may be wrong). This is probably why the insta-breakable blocks are now unbreakable.
Thank you for helping us improve Minecraft! We saved your files: