diff --git a/patches/server/1029-Do-crystal-portal-proximity-check-before-entity-look.patch b/patches/server/1029-Do-crystal-portal-proximity-check-before-entity-look.patch new file mode 100644 index 0000000000..09f66decbf --- /dev/null +++ b/patches/server/1029-Do-crystal-portal-proximity-check-before-entity-look.patch @@ -0,0 +1,75 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martijn Muijsers +Date: Tue, 15 Aug 2023 21:04:55 +0200 +Subject: [PATCH] Do crystal-portal proximity check before entity lookup + +This adds a very cheap distance check when an end crystal is placed. + +Attempting to respawn the dragon, which involves looking up the end crystal +entities near the portal, every time an end crystal is placed, can be slow on +some servers that have players placing end crystals as a style of combat. + +The very cheap distance check prevents running the entity lookup every time. + +diff --git a/src/main/java/net/minecraft/world/item/EndCrystalItem.java b/src/main/java/net/minecraft/world/item/EndCrystalItem.java +index ca1edc083847b47bb450b291723aca778a5912dc..5a19875cbc603acea95193d969d2e1dc1e0bfd78 100644 +--- a/src/main/java/net/minecraft/world/item/EndCrystalItem.java ++++ b/src/main/java/net/minecraft/world/item/EndCrystalItem.java +@@ -29,7 +29,7 @@ public class EndCrystalItem extends Item { + if (!iblockdata.is(Blocks.OBSIDIAN) && !iblockdata.is(Blocks.BEDROCK)) { + return InteractionResult.FAIL; + } else { +- BlockPos blockposition1 = blockposition.above(); ++ BlockPos blockposition1 = blockposition.above(); final BlockPos aboveBlockPosition = blockposition1; // Paper - OBFHELPER + + if (!world.isEmptyBlock(blockposition1)) { + return InteractionResult.FAIL; +@@ -56,7 +56,7 @@ public class EndCrystalItem extends Item { + EndDragonFight enderdragonbattle = ((ServerLevel) world).getDragonFight(); + + if (enderdragonbattle != null) { +- enderdragonbattle.tryRespawn(); ++ enderdragonbattle.tryRespawn(aboveBlockPosition); // Paper - pass placed end crystal position to pre-check proximity to portal + } + } + +diff --git a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java +index 630971d7a87c12798672af9635535eaf80a3ec9c..5b333bef255d7ef61c99510837536920c6fb6e8c 100644 +--- a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java ++++ b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java +@@ -553,6 +553,12 @@ public class EndDragonFight { + } + + public boolean tryRespawn() { // CraftBukkit - return boolean ++ // Paper start - pass null (indicating no placed end crystal involved) by default ++ return this.tryRespawn(null); ++ } ++ ++ public boolean tryRespawn(@Nullable BlockPos placedEndCrystalPos) { // placedEndCrystalPos is null if the tryRespawn() call was not caused by a placed end crystal ++ // Paper end + if (this.dragonKilled && this.respawnStage == null) { + BlockPos blockposition = this.portalLocation; + +@@ -570,6 +576,22 @@ public class EndDragonFight { + blockposition = this.portalLocation; + } + ++ // Paper start - check placed end crystal to portal proximity before attempting to respawn dragon ++ if (placedEndCrystalPos != null) { ++ // The end crystal must be 0 or 1 higher than the portal origin ++ int dy = placedEndCrystalPos.getY() - blockposition.getY(); ++ if (dy != 0 && dy != 1) { ++ return false; ++ } ++ // The end crystal must be within a distance of 1 in one planar direction, and 3 in the other ++ int dx = placedEndCrystalPos.getX() - blockposition.getX(); ++ int dz = placedEndCrystalPos.getZ() - blockposition.getZ(); ++ if (!((dx >= -1 && dx <= 1 && dz >= -3 && dz <= 3) || (dx >= -3 && dx <= 3 && dz >= -1 && dz <= 1))) { ++ return false; ++ } ++ } ++ // Paper end ++ + List list = Lists.newArrayList(); + BlockPos blockposition1 = blockposition.above(1); + Iterator iterator = Direction.Plane.HORIZONTAL.iterator();