mojira.dev
MC-279079

Command `/setblock <pos> minecraft:air destroy` has inconsistent behavior when replacing infested blocks and beehives

When you run command

/setblock <pos> minecraft:air destroy

to replace an infested stone, a silverfish will be spawned. However, if this command replaced a beehive with bee inside, no bee could be spawned.

Code Analysis

Infested blocks use spawnAfterBreak method to spawn silverfish:

@Override
protected void spawnAfterBreak(BlockState state, ServerLevel level, BlockPos pos, ItemStack stack, boolean dropExperience) {
    super.spawnAfterBreak(state, level, pos, stack, dropExperience);
    if (level.getGameRules().getBoolean(GameRules.RULE_DOBLOCKDROPS) && !EnchantmentHelper.hasTag(stack, EnchantmentTags.PREVENTS_INFESTED_SPAWNS)) {
        this.spawnInfestation(level, pos);
    }
}

However beehives use playerDestroy method to spawn bees when destroyed by player, and use getDrops to spawn bees when destroyed by explosion:

@Override
public void playerDestroy(Level level, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity te, ItemStack stack) {
    super.playerDestroy(level, player, pos, state, te, stack);
    if (!level.isClientSide && te instanceof BeehiveBlockEntity beehiveblockentity) {
        if (!EnchantmentHelper.hasTag(stack, EnchantmentTags.PREVENTS_BEE_SPAWNS_WHEN_MINING)) {
            beehiveblockentity.emptyAllLivingFromHive(player, state, BeehiveBlockEntity.BeeReleaseStatus.EMERGENCY);
            level.updateNeighbourForOutputSignal(pos, this);
            this.angerNearbyBees(level, pos);
        }

        CriteriaTriggers.BEE_NEST_DESTROYED.trigger((ServerPlayer)player, state, stack, beehiveblockentity.getOccupantCount());
    }
}

@Override
protected List<ItemStack> getDrops(BlockState state, LootParams.Builder params) {
    Entity entity = params.getOptionalParameter(LootContextParams.THIS_ENTITY);
    if (entity instanceof PrimedTnt
        || entity instanceof Creeper
        || entity instanceof WitherSkull
        || entity instanceof WitherBoss
        || entity instanceof MinecartTNT) {
        BlockEntity blockentity = params.getOptionalParameter(LootContextParams.BLOCK_ENTITY);
        if (blockentity instanceof BeehiveBlockEntity beehiveblockentity) {
            beehiveblockentity.emptyAllLivingFromHive(null, state, BeehiveBlockEntity.BeeReleaseStatus.EMERGENCY);
        }
    }

    return super.getDrops(state, params);
}

These two behaviors make beehive only spawn bees when destroyed by player or explosive entities. To solve this bug they should be unified in spawnAfterBreak method.

Comments 0

No comments.

YocyCraft

(Unassigned)

Confirmed

Platform

Low

Commands

1.21.4

Retrieved