Uploaded image for project: 'Minecraft: Java Edition'
  1. Minecraft: Java Edition
  2. MC-279079

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

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • None
    • 1.21.4
    • None
    • Confirmed
    • Commands
    • Low
    • Platform

      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.

            Unassigned Unassigned
            YocyCraft Han Hengrui
            Votes:
            2 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              CHK: