9
0
mirror of https://github.com/LeavesMC/Leaves.git synced 2025-12-23 08:59:31 +00:00
Files
LeavesMC/patches/server/0069-Optimized-dragon-respawn.patch
2023-10-07 20:39:40 +08:00

146 lines
8.0 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: violetc <58360096+s-yh-china@users.noreply.github.com>
Date: Tue, 27 Jun 2023 13:22:34 +0800
Subject: [PATCH] Optimized dragon respawn
diff --git a/src/main/java/net/minecraft/world/level/block/state/pattern/BlockPattern.java b/src/main/java/net/minecraft/world/level/block/state/pattern/BlockPattern.java
index d0a047fd8849e9210dc9424325561f5a1b9998df..b665410788aa7c889dc214c2a97a9c29080b6001 100644
--- a/src/main/java/net/minecraft/world/level/block/state/pattern/BlockPattern.java
+++ b/src/main/java/net/minecraft/world/level/block/state/pattern/BlockPattern.java
@@ -60,7 +60,7 @@ public class BlockPattern {
}
@Nullable
- private BlockPattern.BlockPatternMatch matches(BlockPos frontTopLeft, Direction forwards, Direction up, LoadingCache<BlockPos, BlockInWorld> cache) {
+ public BlockPattern.BlockPatternMatch matches(BlockPos frontTopLeft, Direction forwards, Direction up, LoadingCache<BlockPos, BlockInWorld> cache) { // Leaves - private -> public
for(int i = 0; i < this.width; ++i) {
for(int j = 0; j < this.height; ++j) {
for(int k = 0; k < this.depth; ++k) {
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 c1ff2e15bc5da1a642872ac0fdcdc457e8abb063..467ddfbb53ef4bbe92ea7372f0654fc39d2a619d 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
@@ -45,6 +45,7 @@ import net.minecraft.world.entity.boss.enderdragon.phases.EnderDragonPhase;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.entity.BlockEntity;
+import net.minecraft.world.level.block.entity.TheEndGatewayBlockEntity;
import net.minecraft.world.level.block.entity.TheEndPortalBlockEntity;
import net.minecraft.world.level.block.state.pattern.BlockInWorld;
import net.minecraft.world.level.block.state.pattern.BlockPattern;
@@ -289,8 +290,67 @@ 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 (top.leavesmc.leaves.LeavesConfig.optimizedDragonRespawn) {
+ 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 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 = top.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 chunkcoordintpair = new ChunkPos(this.origin);
int i;
@@ -619,6 +679,11 @@ public class EndDragonFight {
}
public boolean respawnDragon(List<EndCrystal> list) { // CraftBukkit - return boolean
+ // Leaves - start optimizedDragonRespawn
+ cachePortalChunkIteratorX = -8;
+ cachePortalChunkIteratorZ = -8;
+ cachePortalOriginIteratorY = -1;
+ // Leaves - end optimizedDragonRespawn
if (this.dragonKilled && this.respawnStage == null) {
for (BlockPattern.BlockPatternMatch shapedetector_shapedetectorcollection = this.findExitPortal(); shapedetector_shapedetectorcollection != null; shapedetector_shapedetectorcollection = this.findExitPortal()) {
for (int i = 0; i < this.exitPortalPattern.getWidth(); ++i) {
diff --git a/src/main/java/top/leavesmc/leaves/util/BlockPatternHelper.java b/src/main/java/top/leavesmc/leaves/util/BlockPatternHelper.java
new file mode 100644
index 0000000000000000000000000000000000000000..cbe424356db5237c261320f0ad5ef5bcf2c70ed4
--- /dev/null
+++ b/src/main/java/top/leavesmc/leaves/util/BlockPatternHelper.java
@@ -0,0 +1,28 @@
+package top.leavesmc.leaves.util;
+
+import com.google.common.cache.LoadingCache;
+import net.minecraft.core.BlockPos;
+import net.minecraft.core.Direction;
+import net.minecraft.world.level.Level;
+import net.minecraft.world.level.block.state.pattern.BlockInWorld;
+import net.minecraft.world.level.block.state.pattern.BlockPattern;
+
+// Powered by Carpet-AMS-Addition(https://github.com/Minecraft-AMS/Carpet-AMS-Addition)
+public class BlockPatternHelper {
+ public static BlockPattern.BlockPatternMatch partialSearchAround(BlockPattern pattern, Level world, BlockPos pos) {
+ LoadingCache<BlockPos, BlockInWorld> loadingCache = BlockPattern.createLevelCache(world, false);
+ int i = Math.max(Math.max(pattern.getWidth(), pattern.getHeight()), pattern.getDepth());
+
+ for (BlockPos blockPos : BlockPos.betweenClosed(pos, pos.offset(i - 1, 0, i - 1))) {
+ for (Direction direction : Direction.values()) {
+ for (Direction direction2 : Direction.values()) {
+ BlockPattern.BlockPatternMatch result;
+ if (direction2 == direction || direction2 == direction.getOpposite() || (result = pattern.matches(blockPos, direction, direction2, loadingCache)) == null)
+ continue;
+ return result;
+ }
+ }
+ }
+ return null;
+ }
+}