9
0
mirror of https://github.com/Winds-Studio/Leaf.git synced 2025-12-25 18:09:17 +00:00

re-add:use BFS on getSlopeDistance

This commit is contained in:
Taiyou06
2025-03-19 19:40:46 +01:00
parent 84b5a4eb1c
commit 492f9de0c6
2 changed files with 116 additions and 1 deletions

View File

@@ -6,7 +6,6 @@ Subject: [PATCH] Remove streams on InsideBrownianWalk
This method is maninly visible when ton of villagers suddenly wants to sleep
Safe optimization, no need to provide any numbers.
diff --git a/net/minecraft/world/entity/ai/behavior/InsideBrownianWalk.java b/net/minecraft/world/entity/ai/behavior/InsideBrownianWalk.java
index cbde74f4b6d586a5f80cdd675573441636bf682d..3ac3059ce23d6291aa4e96ed5441159133d3e965 100644
--- a/net/minecraft/world/entity/ai/behavior/InsideBrownianWalk.java

View File

@@ -0,0 +1,116 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Taiyou06 <kaandindar21@gmail.com>
Date: Wed, 19 Mar 2025 18:41:56 +0100
Subject: [PATCH] Use BFS on getSlopeDistance
Uses Breadth First Search (BFS) to optimize getSlopeDistance
Paper: ~75ms
Leaf: ~48ms (-36%)
This should help drastically on the farms that use actively changing fluids.
diff --git a/net/minecraft/world/level/material/FlowingFluid.java b/net/minecraft/world/level/material/FlowingFluid.java
index 4c2c2efd5380ff1fa5ad7553b51babae20f516ae..618a8af8fe30c39bb8c93dcc324f4ae1c48e704e 100644
--- a/net/minecraft/world/level/material/FlowingFluid.java
+++ b/net/minecraft/world/level/material/FlowingFluid.java
@@ -8,6 +8,8 @@ import it.unimi.dsi.fastutil.shorts.Short2ObjectMap;
import it.unimi.dsi.fastutil.shorts.Short2ObjectOpenHashMap;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.Queue;
+
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.server.level.ServerLevel;
@@ -341,31 +343,72 @@ public abstract class FlowingFluid extends Fluid {
protected void beforeDestroyingBlock(LevelAccessor level, BlockPos pos, BlockState state, BlockPos source) { beforeDestroyingBlock(level, pos, state); } // Paper - Add BlockBreakBlockEvent
protected abstract void beforeDestroyingBlock(LevelAccessor level, BlockPos pos, BlockState state);
- protected int getSlopeDistance(LevelReader level, BlockPos pos, int depth, Direction direction, BlockState state, FlowingFluid.SpreadContext spreadContext) {
- int i = 1000;
+ protected int getSlopeDistance(LevelReader level, BlockPos startPos, int initialDepth, Direction excludedDirection, BlockState startState, FlowingFluid.SpreadContext spreadContext) {
+ it.unimi.dsi.fastutil.longs.LongSet visited = new it.unimi.dsi.fastutil.longs.LongOpenHashSet(512); // Pre-allocate capacity
+ java.util.Queue<FlowingFluid.SlopeDistanceNode> queue = new java.util.ArrayDeque<>(64); // Optimized initial capacity
- for (Direction direction1 : Direction.Plane.HORIZONTAL) {
- if (direction1 != direction) {
- BlockPos blockPos = pos.relative(direction1);
- BlockState blockState = spreadContext.getBlockStateIfLoaded(blockPos); // Paper - Prevent chunk loading from fluid flowing
- if (blockState == null) continue; // Paper - Prevent chunk loading from fluid flowing
- FluidState fluidState = blockState.getFluidState();
- if (this.canPassThrough(level, this.getFlowing(), pos, state, direction1, blockPos, blockState, fluidState)) {
- if (spreadContext.isHole(blockPos)) {
- return depth;
- }
+ for (Direction dir : Direction.Plane.HORIZONTAL) {
+ if (dir == excludedDirection) continue;
- if (depth < this.getSlopeFindDistance(level)) {
- int slopeDistance = this.getSlopeDistance(level, blockPos, depth + 1, direction1.getOpposite(), blockState, spreadContext);
- if (slopeDistance < i) {
- i = slopeDistance;
- }
- }
+ BlockPos neighborPos = startPos.relative(dir);
+ BlockState neighborState = spreadContext.getBlockStateIfLoaded(neighborPos);
+ if (neighborState == null) continue;
+
+ long visitKey = encodeSlopeNode(neighborPos, dir.getOpposite());
+ if (visited.add(visitKey)) {
+ queue.add(new FlowingFluid.SlopeDistanceNode(neighborPos, initialDepth + 1, dir.getOpposite(), neighborState));
+ }
+ }
+
+ int slopeFindDistance = this.getSlopeFindDistance(level);
+ int minDistance = 1000;
+
+ // Process the queue
+ while (!queue.isEmpty()) {
+ FlowingFluid.SlopeDistanceNode current = queue.poll();
+ if (current.depth >= slopeFindDistance) continue;
+
+ if (spreadContext.isHole(current.pos)) {
+ return current.depth;
+ }
+
+ for (Direction dir : Direction.Plane.HORIZONTAL) {
+ if (dir == current.excludedDir) continue;
+
+ BlockPos nextPos = current.pos.relative(dir);
+ BlockState nextState = spreadContext.getBlockStateIfLoaded(nextPos);
+ if (nextState == null) continue;
+
+ FluidState nextFluidState = nextState.getFluidState();
+ if (!this.canPassThrough(level, this.getFlowing(), current.pos, current.state, dir, nextPos, nextState, nextFluidState)) {
+ continue;
+ }
+
+ long visitKey = encodeSlopeNode(nextPos, dir.getOpposite());
+ if (visited.add(visitKey)) {
+ queue.add(new FlowingFluid.SlopeDistanceNode(nextPos, current.depth + 1, dir.getOpposite(), nextState));
}
}
}
- return i;
+ return minDistance; // Return fallback value
+ }
+
+ private static long encodeSlopeNode(BlockPos pos, Direction excludedDir) {
+ return ((long) pos.getX() & 0xFFFFFFFFL) << 32 | ((long) pos.getZ() & 0xFFFFFFFFL) << 4 | (excludedDir.ordinal() & 0x0F);}
+
+ private static class SlopeDistanceNode {
+ final BlockPos pos;
+ final int depth;
+ final Direction excludedDir;
+ final BlockState state;
+
+ SlopeDistanceNode(BlockPos pos, int depth, Direction excludedDir, BlockState state) {
+ this.pos = pos.immutable();
+ this.depth = depth;
+ this.excludedDir = excludedDir;
+ this.state = state;
+ }
}
boolean isWaterHole(BlockGetter level, BlockPos pos, BlockState state, BlockPos belowPos, BlockState belowState) {