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

Activating the piston next to the last-placed end crystal while re-summoning the ender dragon incorrectly generates end portal blocks

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • None
    • Minecraft 15w44a, Minecraft 15w44b, Minecraft 15w46a, Minecraft 15w49b, Minecraft 15w51b, Minecraft 16w42a, Minecraft 1.13.1, 1.15.2, 20w18a, 20w19a, 1.16.5, 21w16a, 1.17.1, 1.18, 1.19.3 Release Candidate 3, 1.19.3, 23w05a, 1.19.4 Pre-release 1, 1.19.4 Pre-release 2, 1.19.4, 23w13a, 23w14a, 23w17a, 23w33a
    • Confirmed
    • Block states
    • Normal
    • Platform

      This bug actually affects 1.18.2 and even some earlier versions

      Please refer to the attached screenshot

      How to reproduce

      • Create a new world, go to the end dimension, and kill the ender dragon
      • Place four end crystals on the edges of the exit portal to resummon the ender dragon
      • After the respawning process happens, place a piston beside one of the end crystals and activate the latter before the ender dragon appears
      • Notice that after finishing the resummoning process, two end portal blocks appear incorrectly

      Source code analysis
      The following code was being deobfuscated and decompiled using the official obfuscation map, but still did not accomplish a good result in terms of restoring the local variable table. Apologies for the inconvenience

      Huge thanks to Nickid and his video

      As shown in the following code as in the behavior definition java file of the end crystals, after activating the end crystal using the piston, the explosion range would be calculated first, marking some blocks in the exit portal as candidates for being exploded

      However, the two positions with the end portal shown in the screenshot can never be marked, since they are being blocked by the bedrock pillar at the middle of the portal (in fact, any block with a very high blast resistance can also lead to the same result, such as obsidians as being featured in the video above)

         public boolean hurt(DamageSource var0, float var1) {
              if (this.isInvulnerableTo(var0)) {
                  return false;
              }
              if (var0.getEntity() instanceof EnderDragon) {
                  return false;
              }
              if (!this.isRemoved() && !this.level.isClientSide) {
                  this.remove(Entity.RemovalReason.KILLED);
                  if (!var0.isExplosion()) {
                      DamageSource var2 = var0.getEntity() != null ? DamageSource.explosion(this, var0.getEntity()) : null;
                      this.level.explode(this, var2, null, this.getX(), this.getY(), this.getZ(), 6.0f, false, Level.ExplosionInteraction.BLOCK);
                  }
                  this.onDestroyedBy(var0);
              }
              return true;
          }
      

      Then the explosion would also kill other end crystals, making the following tryRespawn() return, which prevents the dragon to respawn. Since the ender dragon match was not triggered, the portal blocks would also be placed by this function

         public void tryRespawn() {
              if (this.dragonKilled && this.respawnStage == null) {
                  BlockPos var0 = this.portalLocation;
                  if (var0 == null) {
                      LOGGER.debug("Tried to respawn, but need to find the portal first.");
                      BlockPattern.BlockPatternMatch var1 = this.findExitPortal();
                      if (var1 == null) {
                          LOGGER.debug("Couldn't find a portal, so we made one.");
                          this.spawnExitPortal(true);
                      } else {
                          LOGGER.debug("Found the exit portal & saved its location for next time.");
                      }
                      var0 = this.portalLocation;
                  }
                  ArrayList var2 = Lists.newArrayList();
                  BlockPos var3 = var0.above(1);
                  for (Direction var4 : Direction.Plane.HORIZONTAL) {
                      List<EndCrystal> var5 = this.level.getEntitiesOfClass(EndCrystal.class, new AABB(var3.relative(var4, 2)));
                      if (var5.isEmpty()) {
                          return;
                      }
                      var2.addAll(var5);
                  }
                  LOGGER.debug("Found all crystals, respawning dragon.");
                  this.respawnDragon(var2);
              }
          }
      

      Finally, the explosion of the activated end crystal occurs, destroying some of the end portal blocks that have been placed and marked earlier as to be exploded, but those who did not receive the explosion mark remain

            Unassigned Unassigned
            KK899 KK899
            Votes:
            9 Vote for this issue
            Watchers:
            12 Start watching this issue

              Created:
              Updated:
              CHK: