Luminol-Core/luminol-server/minecraft-patches/features/0039-Leaves-Optimized-dragon-respawn.patch
2026-06-30 18:32:29 +08:00

108 lines
6.0 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
Date: Fri, 26 Sep 2025 15:53:06 +0800
Subject: [PATCH] Leaves: Optimized dragon respawn
Co-authored by: violetc <58360096+s-yh-china@users.noreply.github.com>
As part of: Leaves (https://github.com/LeavesMC/Leaves/blob/4ade1001e4dd19c47d95c27f0b12df3175697f29/leaves-server/minecraft-patches/features/0049-Optimized-dragon-respawn.patch)
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
diff --git a/net/minecraft/world/level/block/state/pattern/BlockPattern.java b/net/minecraft/world/level/block/state/pattern/BlockPattern.java
index f7bb979f08634a7e1b77c59040f59fb5e11aafa5..3cad7d6bca9af77bace18bfd7cc013ac22be4075 100644
--- a/net/minecraft/world/level/block/state/pattern/BlockPattern.java
+++ b/net/minecraft/world/level/block/state/pattern/BlockPattern.java
@@ -59,7 +59,7 @@ public class BlockPattern {
}
@Nullable
- private BlockPattern.BlockPatternMatch matches(BlockPos pos, Direction finger, Direction thumb, LoadingCache<BlockPos, BlockInWorld> cache) {
+ public BlockPattern.BlockPatternMatch matches(BlockPos pos, Direction finger, Direction thumb, LoadingCache<BlockPos, BlockInWorld> cache) { // Leaves - private -> public
for (int i = 0; i < this.width; i++) {
for (int i1 = 0; i1 < this.height; i1++) {
for (int i2 = 0; i2 < this.depth; i2++) {
diff --git a/net/minecraft/world/level/dimension/end/EndDragonFight.java b/net/minecraft/world/level/dimension/end/EndDragonFight.java
index 23072c9ced73311954863592b0458c9662a551aa..ad1d1c3e1204e40c813c44d9da7909ed123dcd4c 100644
--- a/net/minecraft/world/level/dimension/end/EndDragonFight.java
+++ b/net/minecraft/world/level/dimension/end/EndDragonFight.java
@@ -279,8 +279,68 @@ public class EndDragonFight {
return false;
}
+ // Leaves start - optimizedDragonRespawn
+ private int cachePortalChunkIteratorX = -8;
+ private int cachePortalChunkIteratorZ = -8;
+ private int cachePortalOriginIteratorY = -1;
+
@Nullable
public BlockPattern.BlockPatternMatch findExitPortal() {
+ if (me.earthme.luminol.config.modules.optimizations.OptimizedDragonRespawnConfig.optimizedRespawn) {
+ int i, j;
+ for (i = cachePortalChunkIteratorX; i <= 8; ++i) {
+ for (j = cachePortalChunkIteratorZ; j <= 8; ++j) {
+ LevelChunk worldChunk = this.level.getChunk(i, j);
+ for (BlockEntity blockEntity : worldChunk.getBlockEntities().values()) {
+ if (blockEntity instanceof net.minecraft.world.level.block.entity.TheEndGatewayBlockEntity) {
+ continue;
+ }
+ if (blockEntity instanceof TheEndPortalBlockEntity) {
+ BlockPattern.BlockPatternMatch blockPatternMatch = this.exitPortalPattern.find(this.level, blockEntity.getBlockPos());
+ if (blockPatternMatch != null) {
+ BlockPos blockPos = blockPatternMatch.getBlock(3, 3, 3).getPos();
+ if (this.portalLocation == null) {
+ this.portalLocation = blockPos;
+ }
+ //No need to judge whether optimizing option is open
+ cachePortalChunkIteratorX = i;
+ cachePortalChunkIteratorZ = j;
+ return blockPatternMatch;
+ }
+ }
+ }
+ }
+ }
+
+ if (this.needsStateScanning || this.portalLocation == null) {
+ if (cachePortalOriginIteratorY != -1) {
+ i = cachePortalOriginIteratorY;
+ } else {
+ i = this.level.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, EndPodiumFeature.getLocation(BlockPos.ZERO)).getY();
+ }
+ boolean notFirstSearch = false;
+ for (j = i; j >= 0; --j) {
+ BlockPattern.BlockPatternMatch result2 = null;
+ if (notFirstSearch) {
+ result2 = org.leavesmc.leaves.util.BlockPatternHelper.partialSearchAround(this.exitPortalPattern, this.level, new BlockPos(EndPodiumFeature.getLocation(BlockPos.ZERO).getY(), j, EndPodiumFeature.getLocation(BlockPos.ZERO).getZ()));
+ } else {
+ result2 = this.exitPortalPattern.find(this.level, new BlockPos(EndPodiumFeature.getLocation(BlockPos.ZERO).getX(), j, EndPodiumFeature.getLocation(BlockPos.ZERO).getZ()));
+ }
+ if (result2 != null) {
+ if (this.portalLocation == null) {
+ this.portalLocation = result2.getBlock(3, 3, 3).getPos();
+ }
+ cachePortalOriginIteratorY = j;
+ return result2;
+ }
+ notFirstSearch = true;
+ }
+ }
+
+ return null;
+ }
+ // Leaves end - optimizedDragonRespawn
+
ChunkPos chunkPos = new ChunkPos(this.origin);
for (int i = -8 + chunkPos.x; i <= 8 + chunkPos.x; i++) {
@@ -583,6 +643,11 @@ public class EndDragonFight {
}
public boolean respawnDragon(List<EndCrystal> crystals) { // CraftBukkit - return boolean
+ // Leaves - start optimizedDragonRespawn
+ cachePortalChunkIteratorX = -8;
+ cachePortalChunkIteratorZ = -8;
+ cachePortalOriginIteratorY = -1;
+ // Leaves - end optimizedDragonRespawn
if (this.dragonKilled && this.respawnStage == null) {
for (BlockPattern.BlockPatternMatch blockPatternMatch = this.findExitPortal(); blockPatternMatch != null; blockPatternMatch = this.findExitPortal()) {
for (int i = 0; i < this.exitPortalPattern.getWidth(); i++) {