mojira.dev
MC-259670

When the ender dragon respawn sequence is cancelled because one of the end crystals was destroyed by an explosion, an incomplete exit portal is generated

When an explosion destroys (at least one of) the end crystals used to resummon the dragon, an incomplete exit portal is generated.

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

  • Cancel the respawn sequence by running the following:

/summon minecraft:tnt 2 63 2
  • Notice that only one end portal block has appeared, in the corner opposite where you summoned the TNT

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

Linked issues

Attachments

Comments 6

Relates to MC-252472.

I didn't have a code analysis, but I think the positions of the portal blocks have to be hardcoded instead of relating to crystals.

TiredRedstoner

Can confirm in 23w05a.

I can't reproduce this with pistons in 1.21-pre2, since they seem to consistently push the crystals rather than destroying them, but I do get a partial portal when the sequence is cancelled because an external explosion destroys one or more of the crystals,

Requesting ownership (at least temporarily) so I can rewrite this.

Minecraft386882

Confirmed in 1.21.3

KK899

clamlol

(Unassigned)

Confirmed

Platform

Normal

Block states

end-crystal, ender-dragon, ender-dragon-respawn, piston

Minecraft 15w44a, Minecraft 15w44b, Minecraft 15w46a, Minecraft 15w49b, Minecraft 15w51b, ..., 23w17a, 23w33a, 1.21 Pre-Release 2, 24w44a, 1.21.3

Retrieved