Do crystal-portal proximity check before entity lookup (#9611)

This commit is contained in:
Martijn 2023-08-26 22:23:31 +02:00 committed by GitHub
parent 0e622c79fa
commit 0c0a480d82
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 75 additions and 0 deletions

View File

@ -0,0 +1,75 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Martijn Muijsers <martijnmuijsers@live.nl>
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<EndCrystal> list = Lists.newArrayList();
BlockPos blockposition1 = blockposition.above(1);
Iterator iterator = Direction.Plane.HORIZONTAL.iterator();