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
is duplicated by9
Created Issue:
Activating the piston next to the last-placed end crystal while re-summoning the ender dragon generates incorrect end portal blocks
This bug actually affects 1.18.2 and even some earlier versions
Please refer to the attached screenshotHow 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 explosion happens, place a piston beside one of the end crystals with its head facing upwards, and activate it before the ender dragon appears
- Notice that after finishing the resummoning process, two end portal blocks appear on the opposite side of the piston
Activating the piston next to the last-placed end crystal while re-summoning the ender dragongenerates incorrectend portal blocksActivating the piston next to the last-placed end crystal while re-summoning the ender dragon incorrectly generates end portal blocks
This bug actually affects 1.18.2 and even some earlier versions
Please refer to the attached screenshotHow 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 explosion happens, place a piston beside one of the end crystals with its head facing upwards, and activate it before the ender dragon appears
- Notice that after finishing the resummoning process, two end portal blocks appear
on the opposite side of the pistonThis bug actually affects 1.18.2 and even some earlier versions
Please refer to the attached screenshotHow 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 explosion happens, place a piston beside one of the end crystals with its head facing upwards, and activate it before the ender dragon appears
- Notice that after finishing the resummoning process, two end portal blocks appear incorrectly
relates to
This bug actually affects 1.18.2 and even some earlier versions
Please refer to the attached screenshotHow 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 explosion happens, place a piston beside one of the end crystals with its head facing upwards, and activate it before the ender dragon appears
- Notice that after finishing the resummoning process, two end portal blocks appear incorrectly
Code Analysis
Huge thanks to Nickid and his video
1. After activating the end crystal, the
This bug actually affects 1.18.2 and even some earlier versions
Please refer to the attached screenshotHow 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 explosion happens, place a piston beside one of the end crystals with its head facing upwards, and activate it before the ender dragon appears
- Notice that after finishing the resummoning process, two end portal blocks appear incorrectly
Code Analysis
Huge thanks to Nickid and his video
1. After activating the end crystal, the
![]()
This bug actually affects 1.18.2 and even some earlier versions
Please refer to the attached screenshotHow 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 explosion happens, place a piston beside one of the end crystals with its head facing upwards, and activate it before the ender dragon appears
- Notice that after finishing the resummoning process, two end portal blocks appear incorrectly
CodeAnalysis
Huge thanks to Nickid and his video
1. After activating the end crystal, the
![]()
This bug actually affects 1.18.2 and even some earlier versions
Please refer to the attached screenshotsHow 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 explosion happens, place a piston beside one of the end crystals with its head facing upwards, and activate it before the ender dragon appears
- Notice that after finishing the resummoning process, two end portal blocks appear incorrectly
Source code analysis
Huge thanks to Nickid and his videoAs shown in the following code, after activating the end crystal, the explosion range would be calculated first, marking some blocks in the exit portal as candidates for being exploded
Then the explosion would also kill other end crystals, making the
This bug actually affects 1.18.2 and even some earlier versions
Please refer to the attached screenshotsHow 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 explosion happens, place a piston beside one of the end crystals with its head facing upwards, and activate it before the ender dragon appears
- Notice that after finishing the resummoning process, two end portal blocks appear incorrectly
Source code analysis
Huge thanks to Nickid and his videoAs shown in the following code, after activating the end crystal, the explosion range would be calculated first, marking some blocks in the exit portal as candidates for being exploded
Then the explosion would also kill other end crystals, making the
This bug actually affects 1.18.2 and even some earlier versions
Please refer to the attached screenshotsHow 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 explosion happens, place a piston beside one of the end crystals with its head facing upwards, and activate it before the ender dragon appears
- Notice that after finishing the resummoning process, two end portal blocks appear incorrectly
Source code analysis
Huge thanks to Nickid and his videoAs shown in the following code as in the behavior definition java file of end crystals, after activating the end crystal, the explosion range would be calculated first, marking some blocks in the exit portal as candidates for being exploded
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, preventing the dragon to respawn. 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 just been placed (but not necessarily all of them)
This bug actually affects 1.18.2 and even some earlier versions
Please refer to the attached screenshotsHow 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 explosion happens, place a piston beside one of the end crystals with its head facing upwards, and activate it before the ender dragon appears
- Notice that after finishing the resummoning process, two end portal blocks appear incorrectly
Source code analysis
Huge thanks to Nickid and his video
As shown in the following code as in the behavior definition java file of end crystals, after activatingtheend crystal, the explosion range would be calculated first, marking some blocks in the exit portal as candidates for being explodedpublic 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, preventing the dragon to respawn. 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
justbeen placed(butnotnecessarily all of them)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 explosion happens, place a piston beside one of the end crystals with its head facing upwards, and activate it before the ender dragon appears
- Notice that after finishing the resummoning process, two end portal blocks appear incorrectly
Source code analysis
Huge thanks to Nickid and his videoAs shown in the following code as in the behavior definition java file of 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
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, preventing the dragon to respawn. 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 markings remain
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
explosionhappens, place a piston beside one of the end crystalswith its head facing upwards,and activateit before the ender dragon appears- Notice that after finishing the resummoning process, two end portal blocks appear incorrectly
Source code analysis
Huge thanks to Nickid and his videoAs shown in the following code as in the behavior definition java file of 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
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, preventing the dragon to respawn. 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 mark
ingsremainThis 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
Huge thanks to Nickid and his videoAs shown in the following code as in the behavior definition java file of 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, preventing the dragon to respawn. 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 mark remain
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
Huge thanks to Nickid and his videoAs shown in the following code as in the behavior definition java file of 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, preventing the dragon to respawn. 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 mark remain
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 is being deobfuscated and decompiled using the official obfuscation map, but still did not do a good job of restoring the local variable table. Apologies for the inconvenienceHuge thanks to Nickid and his video
As shown in the following code as in the behavior definition java file of 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, preventing the dragon to respawn. 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 mark remain
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 is being deobfuscated and decompiled using the official obfuscation map, but still did not do a good job of restoring the local variable table. Apologies for the inconvenienceHuge thanks to Nickid and his video
As shown in the following code as in the behavior definition java file of 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, preventing the dragon to respawn. 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
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 codeis being deobfuscated and decompiled using the official obfuscation map, but still did notdo a good jobof restoring the local variable table. Apologies for the inconvenienceHuge thanks to Nickid and his video
As shown in the following code as in the behavior definition java file of 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, prevent
ingthe dragon to respawn.The portal blocks would also be placed by this functionpublic 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
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 inconvenienceHuge 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
relates to
is duplicated by
is duplicated by
Activating the piston next to the last-placed end crystal while re-summoning the ender dragon incorrectly generatesendportalblocksWhen the ender dragon respawn sequence is cancelled because one of the end crystals was destroyed by an explosion, an incomplete exit portal is generated
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, twoend portal blocks appearincorrectlySource 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 inconvenienceHuge 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
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
- Cancel the respawn sequence by running the following:
/execute positioned 2 63 2 run summon tnt
- 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 inconvenienceHuge 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
This bug actually affects 1.18.2 and even some earlier versionsPlease 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
- Cancel the respawn sequence by running the following:
/execute positioned 2 63 2 run summon tnt
- 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 inconvenienceHuge 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
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:
/execute positioned 2 63 2 run summon tnt
- 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 inconvenienceHuge 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
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:
/execute positioned 2 63 2 run summon tnt
- 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 inconvenienceHuge 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
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:
/execute positioned 2 63 2 run summon tnt
- 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
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:
/execute positioned 2 63 2 run summon tnt
- 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
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
Thank you for your report!
We're actually already tracking this issue in MC-259670, so this ticket is being resolved and linked as a duplicate.
If you would like to add a vote or any additional information to the main ticket it would be appreciated.
Please be sure to use the search feature before creating a ticket to see if the issue has already been reported.
Quick Links:
📓 Bug Tracker Guidelines – 🛠 Community Support – 📧 Mojang Support – ✍️ Feedback and Suggestions – 💬 Mojira Discord
We're resolving and linking this ticket forward as a duplicate of MC-259670, as that ticket contains more detailed information and has already been triaged by Mojang.
Thank you for your report!
We're resolving and linking this ticket forward as a duplicate of MC-259670, as that ticket contains more detailed information and/or has already been triaged by Mojang.
If you would like to add a vote and any extra information to the main ticket it would be appreciated.
Quick Links:
📓 Bug Tracker Guidelines – 💬 Community Support – 📧 Mojang Support
📓 Project Summary – ✍️ Feedback and Suggestions – 📖 Game Wiki
– I am a bot. This action was performed automatically! The ticket was resolved by one of our moderators, and I left this message to give more information to you.
Thank you for your report!
We're resolving and linking this ticket forward as a duplicate of MC-259670, as that ticket contains more detailed information and/or has already been triaged by Mojang.
If you would like to add a vote and any extra information to the main ticket it would be appreciated.
Quick Links:
📓 Bug Tracker Guidelines – 💬 Community Support – 📧 Mojang Support
📓 Project Summary – ✍️ Feedback and Suggestions – 📖 Game Wiki
– I am a bot. This action was performed automatically! The ticket was resolved by one of our moderators, and I left this message to give more information to you.
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.
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.
Confirmed in 1.21.3