mirror of
https://github.com/Winds-Studio/Leaf.git
synced 2025-12-19 15:09:25 +00:00
1. Wet the drys 2. Dry the wets 3. Wet the drys 4. Dry the wets 5. Wet the drys 6. Now dust the wets
843 lines
48 KiB
Diff
843 lines
48 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: peaches94 <peachescu94@gmail.com>
|
|
Date: Sun, 26 Jun 2022 16:51:37 -0500
|
|
Subject: [PATCH] Petal: Async Pathfinding
|
|
|
|
Fixed & Updated by KaiijuMC
|
|
Original license: GPLv3
|
|
Original project: https://github.com/KaiijuMC/Kaiiju
|
|
|
|
Original license: GPLv3
|
|
Original project: https://github.com/Bloom-host/Petal
|
|
|
|
Co-authored-by: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com>
|
|
Co-authored-by: Taiyou06 <kaandindar21@gmail.com>
|
|
Co-authored-by: Altiami <yoshimo.kristin@gmail.com>
|
|
|
|
This patch was ported downstream from the Petal fork.
|
|
|
|
Makes most pathfinding-related work happen asynchronously
|
|
|
|
diff --git a/net/minecraft/world/entity/Mob.java b/net/minecraft/world/entity/Mob.java
|
|
index 14d9dceacc82cc6c085dab8f52e59a318dd8cae5..8b3dfb1385a2252a4aaead5558c0ffbd5c204971 100644
|
|
--- a/net/minecraft/world/entity/Mob.java
|
|
+++ b/net/minecraft/world/entity/Mob.java
|
|
@@ -255,6 +255,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
|
|
@Nullable
|
|
@Override
|
|
public LivingEntity getTarget() {
|
|
+ //if (Thread.currentThread().getName().contains("petal-async-pathfinding-thread")) return this.target; // Kaiiju - Don't reset target when async pathfinding! // Leaf - Don't need this
|
|
return this.target;
|
|
}
|
|
|
|
diff --git a/net/minecraft/world/entity/ai/behavior/AcquirePoi.java b/net/minecraft/world/entity/ai/behavior/AcquirePoi.java
|
|
index 7f0975f8bd6d5f8ca28f503f93c8cb5c42557420..eb71f045d3e8698a8a9e9f51176c2884f71a034c 100644
|
|
--- a/net/minecraft/world/entity/ai/behavior/AcquirePoi.java
|
|
+++ b/net/minecraft/world/entity/ai/behavior/AcquirePoi.java
|
|
@@ -102,21 +102,20 @@ public class AcquirePoi {
|
|
}
|
|
}
|
|
// Paper end - optimise POI access
|
|
- Path path = findPathToPois(mob, set);
|
|
- if (path != null && path.canReach()) {
|
|
- BlockPos target = path.getTarget();
|
|
- poiManager.getType(target).ifPresent(holder -> {
|
|
- poiManager.take(acquirablePois, (holder1, blockPos) -> blockPos.equals(target), target, 1);
|
|
- memoryAccessor.set(GlobalPos.of(level.dimension(), target));
|
|
- entityEventId.ifPresent(id -> level.broadcastEntityEvent(mob, id));
|
|
- map.clear();
|
|
- DebugPackets.sendPoiTicketCountPacket(level, target);
|
|
+ // Kaiiju start - petal - Async path processing
|
|
+ if (org.dreeam.leaf.config.modules.async.AsyncPathfinding.enabled) {
|
|
+ // await on path async
|
|
+ Path possiblePath = findPathToPois(mob, set);
|
|
+
|
|
+ // wait on the path to be processed
|
|
+ org.dreeam.leaf.async.path.AsyncPathProcessor.awaitProcessing(possiblePath, path -> {
|
|
+ processPath(acquirablePois, entityEventId, (Long2ObjectMap<JitteredLinearRetry>) map, memoryAccessor, level, mob, time, poiManager, set, path);
|
|
});
|
|
} else {
|
|
- for (Pair<Holder<PoiType>, BlockPos> pair : set) {
|
|
- map.computeIfAbsent(pair.getSecond().asLong(), l -> new AcquirePoi.JitteredLinearRetry(level.random, time));
|
|
- }
|
|
- }
|
|
+ // Kaiiju end
|
|
+ Path path = findPathToPois(mob, set);
|
|
+ processPath(acquirablePois, entityEventId, (Long2ObjectMap<JitteredLinearRetry>) map, memoryAccessor, level, mob, time, poiManager, set, path);
|
|
+ } // Kaiiju - Async path processing
|
|
|
|
return true;
|
|
}
|
|
@@ -128,6 +127,34 @@ public class AcquirePoi {
|
|
: BehaviorBuilder.create(instance -> instance.group(instance.absent(existingAbsentMemory)).apply(instance, memoryAccessor -> oneShot));
|
|
}
|
|
|
|
+ // Leaf start - Kaiiju - Async path processing
|
|
+ private static void processPath(Predicate<Holder<PoiType>> acquirablePois,
|
|
+ Optional<Byte> entityEventId,
|
|
+ Long2ObjectMap<JitteredLinearRetry> map,
|
|
+ net.minecraft.world.entity.ai.behavior.declarative.MemoryAccessor<com.mojang.datafixers.kinds.Const.Mu<com.mojang.datafixers.util.Unit>, GlobalPos> memoryAccessor,
|
|
+ ServerLevel level,
|
|
+ PathfinderMob mob,
|
|
+ long time,
|
|
+ PoiManager poiManager,
|
|
+ Set<Pair<Holder<PoiType>, BlockPos>> set,
|
|
+ Path path) {
|
|
+ if (path != null && path.canReach()) {
|
|
+ BlockPos target = path.getTarget();
|
|
+ poiManager.getType(target).ifPresent(holder -> {
|
|
+ poiManager.take(acquirablePois, (holder1, blockPos) -> blockPos.equals(target), target, 1);
|
|
+ memoryAccessor.set(GlobalPos.of(level.dimension(), target));
|
|
+ entityEventId.ifPresent(id -> level.broadcastEntityEvent(mob, id));
|
|
+ map.clear();
|
|
+ DebugPackets.sendPoiTicketCountPacket(level, target);
|
|
+ });
|
|
+ } else {
|
|
+ for (Pair<Holder<PoiType>, BlockPos> pair : set) {
|
|
+ map.computeIfAbsent(pair.getSecond().asLong(), l -> new JitteredLinearRetry(level.random, time));
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ // Leaf end - Kaiiju - Async path processing
|
|
+
|
|
@Nullable
|
|
public static Path findPathToPois(Mob mob, Set<Pair<Holder<PoiType>, BlockPos>> poiPositions) {
|
|
if (poiPositions.isEmpty()) {
|
|
diff --git a/net/minecraft/world/entity/ai/behavior/MoveToTargetSink.java b/net/minecraft/world/entity/ai/behavior/MoveToTargetSink.java
|
|
index 621ba76784f2b92790eca62be4d0688834335ab6..e2e1532d2ffb709e347db42b1b5b6cae5e7e9700 100644
|
|
--- a/net/minecraft/world/entity/ai/behavior/MoveToTargetSink.java
|
|
+++ b/net/minecraft/world/entity/ai/behavior/MoveToTargetSink.java
|
|
@@ -21,6 +21,7 @@ public class MoveToTargetSink extends Behavior<Mob> {
|
|
private int remainingCooldown;
|
|
@Nullable
|
|
private Path path;
|
|
+ private boolean finishedProcessing; // Kaiiju - petal - track when path is processed
|
|
@Nullable
|
|
private BlockPos lastTargetPos;
|
|
private float speedModifier;
|
|
@@ -53,9 +54,10 @@ public class MoveToTargetSink extends Behavior<Mob> {
|
|
Brain<?> brain = owner.getBrain();
|
|
WalkTarget walkTarget = brain.getMemory(MemoryModuleType.WALK_TARGET).get();
|
|
boolean flag = this.reachedTarget(owner, walkTarget);
|
|
- if (!flag && this.tryComputePath(owner, walkTarget, level.getGameTime())) {
|
|
+ if (!org.dreeam.leaf.config.modules.async.AsyncPathfinding.enabled && !flag && this.tryComputePath(owner, walkTarget, level.getGameTime())) { // Kaiiju - petal - async path processing means we can't know if the path is reachable here
|
|
this.lastTargetPos = walkTarget.getTarget().currentBlockPosition();
|
|
return true;
|
|
+ } else if (org.dreeam.leaf.config.modules.async.AsyncPathfinding.enabled && !flag) { return true; // Kaiiju - async pathfinding
|
|
} else {
|
|
brain.eraseMemory(MemoryModuleType.WALK_TARGET);
|
|
if (flag) {
|
|
@@ -69,6 +71,7 @@ public class MoveToTargetSink extends Behavior<Mob> {
|
|
|
|
@Override
|
|
protected boolean canStillUse(ServerLevel level, Mob entity, long gameTime) {
|
|
+ if (org.dreeam.leaf.config.modules.async.AsyncPathfinding.enabled && !this.finishedProcessing) return true; // Kaiiju - petal - wait for processing
|
|
if (this.path != null && this.lastTargetPos != null) {
|
|
Optional<WalkTarget> memory = entity.getBrain().getMemory(MemoryModuleType.WALK_TARGET);
|
|
boolean flag = memory.map(MoveToTargetSink::isWalkTargetSpectator).orElse(false);
|
|
@@ -95,12 +98,68 @@ public class MoveToTargetSink extends Behavior<Mob> {
|
|
|
|
@Override
|
|
protected void start(ServerLevel level, Mob entity, long gameTime) {
|
|
+ // Kaiiju start - petal - start processing
|
|
+ if (org.dreeam.leaf.config.modules.async.AsyncPathfinding.enabled) {
|
|
+ Brain<?> brain = entity.getBrain();
|
|
+ WalkTarget walkTarget = brain.getMemory(MemoryModuleType.WALK_TARGET).get();
|
|
+
|
|
+ this.finishedProcessing = false;
|
|
+ this.lastTargetPos = walkTarget.getTarget().currentBlockPosition();
|
|
+ this.path = this.computePath(entity, walkTarget);
|
|
+ return;
|
|
+ }
|
|
+ // Kaiiju end
|
|
entity.getBrain().setMemory(MemoryModuleType.PATH, this.path);
|
|
entity.getNavigation().moveTo(this.path, (double)this.speedModifier);
|
|
}
|
|
|
|
@Override
|
|
protected void tick(ServerLevel level, Mob owner, long gameTime) {
|
|
+ // Kaiiju start - petal - Async path processing
|
|
+ if (org.dreeam.leaf.config.modules.async.AsyncPathfinding.enabled) {
|
|
+ if (this.path != null && !this.path.isProcessed()) return; // wait for processing
|
|
+
|
|
+ if (!this.finishedProcessing) {
|
|
+ this.finishedProcessing = true;
|
|
+
|
|
+ Brain<?> brain = owner.getBrain();
|
|
+ boolean canReach = this.path != null && this.path.canReach();
|
|
+ if (canReach) {
|
|
+ brain.eraseMemory(MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE);
|
|
+ } else if (!brain.hasMemoryValue(MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE)) {
|
|
+ brain.setMemory(MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE, gameTime);
|
|
+ }
|
|
+
|
|
+ if (!canReach) {
|
|
+ Optional<WalkTarget> walkTarget = brain.getMemory(MemoryModuleType.WALK_TARGET);
|
|
+
|
|
+ if (!walkTarget.isPresent()) return;
|
|
+
|
|
+ BlockPos blockPos = walkTarget.get().getTarget().currentBlockPosition();
|
|
+ Vec3 vec3 = DefaultRandomPos.getPosTowards((PathfinderMob) owner, 10, 7, Vec3.atBottomCenterOf(blockPos), (float) Math.PI / 2F);
|
|
+ if (vec3 != null) {
|
|
+ // try recalculating the path using a random position
|
|
+ this.path = owner.getNavigation().createPath(vec3.x, vec3.y, vec3.z, 0);
|
|
+ this.finishedProcessing = false;
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ owner.getBrain().setMemory(MemoryModuleType.PATH, this.path);
|
|
+ owner.getNavigation().moveTo(this.path, this.speedModifier);
|
|
+ }
|
|
+
|
|
+ Path path = owner.getNavigation().getPath();
|
|
+ Brain<?> brain = owner.getBrain();
|
|
+
|
|
+ if (path != null && this.lastTargetPos != null && brain.hasMemoryValue(MemoryModuleType.WALK_TARGET)) {
|
|
+ WalkTarget walkTarget = brain.getMemory(MemoryModuleType.WALK_TARGET).get(); // we know isPresent = true
|
|
+ if (walkTarget.getTarget().currentBlockPosition().distSqr(this.lastTargetPos) > 4.0D) {
|
|
+ this.start(level, owner, gameTime);
|
|
+ }
|
|
+ }
|
|
+ } else {
|
|
+ // Kaiiju end
|
|
Path path = owner.getNavigation().getPath();
|
|
Brain<?> brain = owner.getBrain();
|
|
if (this.path != path) {
|
|
@@ -115,7 +174,23 @@ public class MoveToTargetSink extends Behavior<Mob> {
|
|
this.start(level, owner, gameTime);
|
|
}
|
|
}
|
|
+ } // Kaiiju - async path processing
|
|
+ }
|
|
+
|
|
+ // Kaiiju start - petal - Async path processing
|
|
+ @Nullable
|
|
+ private Path computePath(Mob entity, WalkTarget walkTarget) {
|
|
+ BlockPos blockPos = walkTarget.getTarget().currentBlockPosition();
|
|
+ // don't pathfind outside region
|
|
+ //if (!io.papermc.paper.util.TickThread.isTickThreadFor((ServerLevel) entity.level(), blockPos)) return null; // Leaf - Don't need this
|
|
+ this.speedModifier = walkTarget.getSpeedModifier();
|
|
+ Brain<?> brain = entity.getBrain();
|
|
+ if (this.reachedTarget(entity, walkTarget)) {
|
|
+ brain.eraseMemory(MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE);
|
|
+ }
|
|
+ return entity.getNavigation().createPath(blockPos, 0);
|
|
}
|
|
+ // Kaiiju end
|
|
|
|
private boolean tryComputePath(Mob mob, WalkTarget target, long time) {
|
|
BlockPos blockPos = target.getTarget().currentBlockPosition();
|
|
diff --git a/net/minecraft/world/entity/ai/behavior/SetClosestHomeAsWalkTarget.java b/net/minecraft/world/entity/ai/behavior/SetClosestHomeAsWalkTarget.java
|
|
index 4f9f3367b1ca3903df03a80fa2b01a3d24e6e77d..51413df5cd61b3ff59c6c6c3ec69d6732ab07d83 100644
|
|
--- a/net/minecraft/world/entity/ai/behavior/SetClosestHomeAsWalkTarget.java
|
|
+++ b/net/minecraft/world/entity/ai/behavior/SetClosestHomeAsWalkTarget.java
|
|
@@ -60,17 +60,20 @@ public class SetClosestHomeAsWalkTarget {
|
|
poi -> poi.is(PoiTypes.HOME), predicate, mob.blockPosition(), 48, PoiManager.Occupancy.ANY
|
|
)
|
|
.collect(Collectors.toSet());
|
|
+ // Kaiiju start - petal - Async path processing
|
|
+ if (org.dreeam.leaf.config.modules.async.AsyncPathfinding.enabled) {
|
|
+ // await on path async
|
|
+ Path possiblePath = AcquirePoi.findPathToPois(mob, set);
|
|
+
|
|
+ // wait on the path to be processed
|
|
+ org.dreeam.leaf.async.path.AsyncPathProcessor.awaitProcessing(possiblePath, path -> {
|
|
+ processPath(speedModifier, map, mutableLong, walkTarget, level, poiManager, mutableInt, path);
|
|
+ });
|
|
+ } else {
|
|
+ // Kaiiju end
|
|
Path path = AcquirePoi.findPathToPois(mob, set);
|
|
- if (path != null && path.canReach()) {
|
|
- BlockPos target = path.getTarget();
|
|
- Optional<Holder<PoiType>> type = poiManager.getType(target);
|
|
- if (type.isPresent()) {
|
|
- walkTarget.set(new WalkTarget(target, speedModifier, 1));
|
|
- DebugPackets.sendPoiTicketCountPacket(level, target);
|
|
- }
|
|
- } else if (mutableInt.getValue() < 5) {
|
|
- map.long2LongEntrySet().removeIf(entry -> entry.getLongValue() < mutableLong.getValue());
|
|
- }
|
|
+ processPath(speedModifier, map, mutableLong, walkTarget, level, poiManager, mutableInt, path);
|
|
+ } // Kaiiju - async path processing
|
|
|
|
return true;
|
|
} else {
|
|
@@ -81,4 +84,26 @@ public class SetClosestHomeAsWalkTarget {
|
|
)
|
|
);
|
|
}
|
|
+
|
|
+ // Leaf start - Kaiiju - petal - Async path processing
|
|
+ private static void processPath(float speedModifier,
|
|
+ Long2LongMap map,
|
|
+ MutableLong mutableLong,
|
|
+ net.minecraft.world.entity.ai.behavior.declarative.MemoryAccessor<com.mojang.datafixers.kinds.Const.Mu<com.mojang.datafixers.util.Unit>, WalkTarget> walkTarget,
|
|
+ net.minecraft.server.level.ServerLevel level,
|
|
+ PoiManager poiManager,
|
|
+ MutableInt mutableInt,
|
|
+ @org.jetbrains.annotations.Nullable Path path) {
|
|
+ if (path != null && path.canReach()) {
|
|
+ BlockPos target = path.getTarget();
|
|
+ Optional<Holder<PoiType>> type = poiManager.getType(target);
|
|
+ if (type.isPresent()) {
|
|
+ walkTarget.set(new WalkTarget(target, speedModifier, 1));
|
|
+ DebugPackets.sendPoiTicketCountPacket(level, target);
|
|
+ }
|
|
+ } else if (mutableInt.getValue() < 5) {
|
|
+ map.long2LongEntrySet().removeIf(entry -> entry.getLongValue() < mutableLong.getValue());
|
|
+ }
|
|
+ }
|
|
+ // Leaf end - Kaiiju - petal - Async path processing
|
|
}
|
|
diff --git a/net/minecraft/world/entity/ai/goal/DoorInteractGoal.java b/net/minecraft/world/entity/ai/goal/DoorInteractGoal.java
|
|
index d8f532c5e68ff4dff933556c4f981e9474c044e6..95733482a647935e1e7f81fa71a0e99ea52e9a9b 100644
|
|
--- a/net/minecraft/world/entity/ai/goal/DoorInteractGoal.java
|
|
+++ b/net/minecraft/world/entity/ai/goal/DoorInteractGoal.java
|
|
@@ -56,7 +56,7 @@ public abstract class DoorInteractGoal extends Goal {
|
|
} else {
|
|
GroundPathNavigation groundPathNavigation = (GroundPathNavigation)this.mob.getNavigation();
|
|
Path path = groundPathNavigation.getPath();
|
|
- if (path != null && !path.isDone()) {
|
|
+ if (path != null && path.isProcessed() && !path.isDone()) { // Kaiiju - async pathfinding - ensure path is processed
|
|
for (int i = 0; i < Math.min(path.getNextNodeIndex() + 2, path.getNodeCount()); i++) {
|
|
Node node = path.getNode(i);
|
|
this.doorPos = new BlockPos(node.x, node.y + 1, node.z);
|
|
diff --git a/net/minecraft/world/entity/ai/navigation/AmphibiousPathNavigation.java b/net/minecraft/world/entity/ai/navigation/AmphibiousPathNavigation.java
|
|
index 66a02fe7594522ef391d67e09856bf3f70fe597d..55e4e6542ac05d89b8d062c546de85b29fb0099f 100644
|
|
--- a/net/minecraft/world/entity/ai/navigation/AmphibiousPathNavigation.java
|
|
+++ b/net/minecraft/world/entity/ai/navigation/AmphibiousPathNavigation.java
|
|
@@ -12,9 +12,25 @@ public class AmphibiousPathNavigation extends PathNavigation {
|
|
super(mob, level);
|
|
}
|
|
|
|
+ // Kaiiju start - petal - async path processing
|
|
+ private static final org.dreeam.leaf.async.path.NodeEvaluatorGenerator nodeEvaluatorGenerator = (org.dreeam.leaf.async.path.NodeEvaluatorFeatures nodeEvaluatorFeatures) -> {
|
|
+ AmphibiousNodeEvaluator nodeEvaluator = new AmphibiousNodeEvaluator(false);
|
|
+ nodeEvaluator.setCanPassDoors(nodeEvaluatorFeatures.canPassDoors());
|
|
+ nodeEvaluator.setCanFloat(nodeEvaluatorFeatures.canFloat());
|
|
+ nodeEvaluator.setCanWalkOverFences(nodeEvaluatorFeatures.canWalkOverFences());
|
|
+ nodeEvaluator.setCanOpenDoors(nodeEvaluatorFeatures.canOpenDoors());
|
|
+ return nodeEvaluator;
|
|
+ };
|
|
+ // Kaiiju end
|
|
+
|
|
@Override
|
|
protected PathFinder createPathFinder(int maxVisitedNodes) {
|
|
this.nodeEvaluator = new AmphibiousNodeEvaluator(false);
|
|
+ // Kaiiju start - petal - async path processing
|
|
+ if (org.dreeam.leaf.config.modules.async.AsyncPathfinding.enabled) {
|
|
+ return new PathFinder(this.nodeEvaluator, maxVisitedNodes, nodeEvaluatorGenerator);
|
|
+ }
|
|
+ // Kaiiju end
|
|
return new PathFinder(this.nodeEvaluator, maxVisitedNodes);
|
|
}
|
|
|
|
diff --git a/net/minecraft/world/entity/ai/navigation/FlyingPathNavigation.java b/net/minecraft/world/entity/ai/navigation/FlyingPathNavigation.java
|
|
index 71ea68b56b3069bdf8e47931156b6ef49ea8ce5d..5de4c1138c7092ff8240fcb30cd64ff1f4d12088 100644
|
|
--- a/net/minecraft/world/entity/ai/navigation/FlyingPathNavigation.java
|
|
+++ b/net/minecraft/world/entity/ai/navigation/FlyingPathNavigation.java
|
|
@@ -16,9 +16,25 @@ public class FlyingPathNavigation extends PathNavigation {
|
|
super(mob, level);
|
|
}
|
|
|
|
+ // Kaiiju start - petal - async path processing
|
|
+ private static final org.dreeam.leaf.async.path.NodeEvaluatorGenerator nodeEvaluatorGenerator = (org.dreeam.leaf.async.path.NodeEvaluatorFeatures nodeEvaluatorFeatures) -> {
|
|
+ FlyNodeEvaluator nodeEvaluator = new FlyNodeEvaluator();
|
|
+ nodeEvaluator.setCanPassDoors(nodeEvaluatorFeatures.canPassDoors());
|
|
+ nodeEvaluator.setCanFloat(nodeEvaluatorFeatures.canFloat());
|
|
+ nodeEvaluator.setCanWalkOverFences(nodeEvaluatorFeatures.canWalkOverFences());
|
|
+ nodeEvaluator.setCanOpenDoors(nodeEvaluatorFeatures.canOpenDoors());
|
|
+ return nodeEvaluator;
|
|
+ };
|
|
+ // Kaiiju end
|
|
+
|
|
@Override
|
|
protected PathFinder createPathFinder(int maxVisitedNodes) {
|
|
this.nodeEvaluator = new FlyNodeEvaluator();
|
|
+ // Kaiiju start - petal - async path processing
|
|
+ if (org.dreeam.leaf.config.modules.async.AsyncPathfinding.enabled) {
|
|
+ return new PathFinder(this.nodeEvaluator, maxVisitedNodes, nodeEvaluatorGenerator);
|
|
+ }
|
|
+ // Kaiiju end
|
|
return new PathFinder(this.nodeEvaluator, maxVisitedNodes);
|
|
}
|
|
|
|
@@ -48,6 +64,7 @@ public class FlyingPathNavigation extends PathNavigation {
|
|
if (this.hasDelayedRecomputation) {
|
|
this.recomputePath();
|
|
}
|
|
+ if (this.path != null && !this.path.isProcessed()) return; // Kaiiju - petal - async path processing
|
|
|
|
if (!this.isDone()) {
|
|
if (this.canUpdatePath()) {
|
|
diff --git a/net/minecraft/world/entity/ai/navigation/GroundPathNavigation.java b/net/minecraft/world/entity/ai/navigation/GroundPathNavigation.java
|
|
index 045cfafb3afe8271d60852ae3c7cdcb039b44d4f..3f55b00e2f8924a8450df8a3f9812a4ae2983df3 100644
|
|
--- a/net/minecraft/world/entity/ai/navigation/GroundPathNavigation.java
|
|
+++ b/net/minecraft/world/entity/ai/navigation/GroundPathNavigation.java
|
|
@@ -24,9 +24,25 @@ public class GroundPathNavigation extends PathNavigation {
|
|
super(mob, level);
|
|
}
|
|
|
|
+ // Kaiiju start - petal - async path processing
|
|
+ protected static final org.dreeam.leaf.async.path.NodeEvaluatorGenerator nodeEvaluatorGenerator = (org.dreeam.leaf.async.path.NodeEvaluatorFeatures nodeEvaluatorFeatures) -> {
|
|
+ WalkNodeEvaluator nodeEvaluator = new WalkNodeEvaluator();
|
|
+ nodeEvaluator.setCanPassDoors(nodeEvaluatorFeatures.canPassDoors());
|
|
+ nodeEvaluator.setCanFloat(nodeEvaluatorFeatures.canFloat());
|
|
+ nodeEvaluator.setCanWalkOverFences(nodeEvaluatorFeatures.canWalkOverFences());
|
|
+ nodeEvaluator.setCanOpenDoors(nodeEvaluatorFeatures.canOpenDoors());
|
|
+ return nodeEvaluator;
|
|
+ };
|
|
+ // Kaiiju end
|
|
+
|
|
@Override
|
|
protected PathFinder createPathFinder(int maxVisitedNodes) {
|
|
this.nodeEvaluator = new WalkNodeEvaluator();
|
|
+ // Kaiiju start - petal - async path processing
|
|
+ if (org.dreeam.leaf.config.modules.async.AsyncPathfinding.enabled) {
|
|
+ return new PathFinder(this.nodeEvaluator, maxVisitedNodes, nodeEvaluatorGenerator);
|
|
+ }
|
|
+ // Kaiiju end
|
|
return new PathFinder(this.nodeEvaluator, maxVisitedNodes);
|
|
}
|
|
|
|
diff --git a/net/minecraft/world/entity/ai/navigation/PathNavigation.java b/net/minecraft/world/entity/ai/navigation/PathNavigation.java
|
|
index 6c8fb611943aee8cabc471c63166f9b44ef14826..25ef9b67eee01c6df466031c5dbc728b1a754ab2 100644
|
|
--- a/net/minecraft/world/entity/ai/navigation/PathNavigation.java
|
|
+++ b/net/minecraft/world/entity/ai/navigation/PathNavigation.java
|
|
@@ -167,6 +167,10 @@ public abstract class PathNavigation {
|
|
return null;
|
|
} else if (!this.canUpdatePath()) {
|
|
return null;
|
|
+ // Kaiiju start - petal - catch early if it's still processing these positions let it keep processing
|
|
+ } else if (this.path instanceof org.dreeam.leaf.async.path.AsyncPath asyncPath && !asyncPath.isProcessed() && asyncPath.hasSameProcessingPositions(targets)) {
|
|
+ return this.path;
|
|
+ // Kaiiju end
|
|
} else if (this.path != null && !this.path.isDone() && targets.contains(this.targetPos)) {
|
|
return this.path;
|
|
} else {
|
|
@@ -191,11 +195,29 @@ public abstract class PathNavigation {
|
|
int i = (int)(followRange + regionOffset);
|
|
PathNavigationRegion pathNavigationRegion = new PathNavigationRegion(this.level, blockPos.offset(-i, -i, -i), blockPos.offset(i, i, i));
|
|
Path path = this.pathFinder.findPath(pathNavigationRegion, this.mob, targets, followRange, accuracy, this.maxVisitedNodesMultiplier);
|
|
+ // Kaiiju start - petal - async path processing
|
|
+ if (org.dreeam.leaf.config.modules.async.AsyncPathfinding.enabled) {
|
|
+ // assign early a target position. most calls will only have 1 position
|
|
+ if (!targets.isEmpty()) this.targetPos = targets.iterator().next();
|
|
+
|
|
+ org.dreeam.leaf.async.path.AsyncPathProcessor.awaitProcessing(path, processedPath -> {
|
|
+ // check that processing didn't take so long that we calculated a new path
|
|
+ if (processedPath != this.path) return;
|
|
+
|
|
+ if (processedPath != null && processedPath.getTarget() != null) {
|
|
+ this.targetPos = processedPath.getTarget();
|
|
+ this.reachRange = accuracy;
|
|
+ this.resetStuckTimeout();
|
|
+ }
|
|
+ });
|
|
+ } else {
|
|
+ // Kaiiju end
|
|
if (path != null && path.getTarget() != null) {
|
|
this.targetPos = path.getTarget();
|
|
this.reachRange = accuracy;
|
|
this.resetStuckTimeout();
|
|
}
|
|
+ } // Kaiiju - async path processing
|
|
|
|
return path;
|
|
}
|
|
@@ -246,8 +268,8 @@ public abstract class PathNavigation {
|
|
if (this.isDone()) {
|
|
return false;
|
|
} else {
|
|
- this.trimPath();
|
|
- if (this.path.getNodeCount() <= 0) {
|
|
+ if (path.isProcessed()) this.trimPath(); // Kaiiju - petal - only trim if processed
|
|
+ if (path.isProcessed() && this.path.getNodeCount() <= 0) { // Kaiiju - petal - only check node count if processed
|
|
return false;
|
|
} else {
|
|
this.speedModifier = speed;
|
|
@@ -270,6 +292,7 @@ public abstract class PathNavigation {
|
|
if (this.hasDelayedRecomputation) {
|
|
this.recomputePath();
|
|
}
|
|
+ if (this.path != null && !this.path.isProcessed()) return; // Kaiiju - petal - skip pathfinding if we're still processing
|
|
|
|
if (!this.isDone()) {
|
|
if (this.canUpdatePath()) {
|
|
@@ -299,6 +322,7 @@ public abstract class PathNavigation {
|
|
}
|
|
|
|
protected void followThePath() {
|
|
+ if (!this.path.isProcessed()) return; // Kaiiju - petal - skip if not processed
|
|
Vec3 tempMobPos = this.getTempMobPos();
|
|
this.maxDistanceToWaypoint = this.mob.getBbWidth() > 0.75F ? this.mob.getBbWidth() / 2.0F : 0.75F - this.mob.getBbWidth() / 2.0F;
|
|
Vec3i nextNodePos = this.path.getNextNodePos();
|
|
@@ -455,7 +479,7 @@ public abstract class PathNavigation {
|
|
public boolean shouldRecomputePath(BlockPos pos) {
|
|
if (this.hasDelayedRecomputation) {
|
|
return false;
|
|
- } else if (this.path != null && !this.path.isDone() && this.path.getNodeCount() != 0) {
|
|
+ } else if (this.path != null && this.path.isProcessed() && !this.path.isDone() && this.path.getNodeCount() != 0) { // Kaiiju - petal - Skip if not processed
|
|
Node endNode = this.path.getEndNode();
|
|
Vec3 vec3 = new Vec3((endNode.x + this.mob.getX()) / 2.0, (endNode.y + this.mob.getY()) / 2.0, (endNode.z + this.mob.getZ()) / 2.0);
|
|
return pos.closerToCenterThan(vec3, this.path.getNodeCount() - this.path.getNextNodeIndex());
|
|
diff --git a/net/minecraft/world/entity/ai/navigation/WaterBoundPathNavigation.java b/net/minecraft/world/entity/ai/navigation/WaterBoundPathNavigation.java
|
|
index 2979846853898d78a2df19df2287da16dbe4ae71..1289a6e85f3fdb9187323343b6c20e17b6a7e296 100644
|
|
--- a/net/minecraft/world/entity/ai/navigation/WaterBoundPathNavigation.java
|
|
+++ b/net/minecraft/world/entity/ai/navigation/WaterBoundPathNavigation.java
|
|
@@ -15,11 +15,27 @@ public class WaterBoundPathNavigation extends PathNavigation {
|
|
super(mob, level);
|
|
}
|
|
|
|
+ // Kaiiju start - petal - async path processing
|
|
+ private static final org.dreeam.leaf.async.path.NodeEvaluatorGenerator nodeEvaluatorGenerator = (org.dreeam.leaf.async.path.NodeEvaluatorFeatures nodeEvaluatorFeatures) -> {
|
|
+ SwimNodeEvaluator nodeEvaluator = new SwimNodeEvaluator(nodeEvaluatorFeatures.allowBreaching());
|
|
+ nodeEvaluator.setCanPassDoors(nodeEvaluatorFeatures.canPassDoors());
|
|
+ nodeEvaluator.setCanFloat(nodeEvaluatorFeatures.canFloat());
|
|
+ nodeEvaluator.setCanWalkOverFences(nodeEvaluatorFeatures.canWalkOverFences());
|
|
+ nodeEvaluator.setCanOpenDoors(nodeEvaluatorFeatures.canOpenDoors());
|
|
+ return nodeEvaluator;
|
|
+ };
|
|
+ // Kaiiju end
|
|
+
|
|
@Override
|
|
protected PathFinder createPathFinder(int maxVisitedNodes) {
|
|
this.allowBreaching = this.mob.getType() == EntityType.DOLPHIN;
|
|
this.nodeEvaluator = new SwimNodeEvaluator(this.allowBreaching);
|
|
this.nodeEvaluator.setCanPassDoors(false);
|
|
+ // Kaiiju start - async path processing
|
|
+ if (org.dreeam.leaf.config.modules.async.AsyncPathfinding.enabled) {
|
|
+ return new PathFinder(this.nodeEvaluator, maxVisitedNodes, nodeEvaluatorGenerator);
|
|
+ }
|
|
+ // Kaiiju end
|
|
return new PathFinder(this.nodeEvaluator, maxVisitedNodes);
|
|
}
|
|
|
|
diff --git a/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java b/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java
|
|
index 1f96fd5085bacb4c584576c7cb9f51e7898e9b03..8819717c5307a90abc493cf801b4e795c13b3460 100644
|
|
--- a/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java
|
|
+++ b/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java
|
|
@@ -57,17 +57,32 @@ public class NearestBedSensor extends Sensor<Mob> {
|
|
java.util.List<Pair<Holder<PoiType>, BlockPos>> poiposes = new java.util.ArrayList<>();
|
|
// don't ask me why it's unbounded. ask mojang.
|
|
io.papermc.paper.util.PoiAccess.findAnyPoiPositions(poiManager, type -> type.is(PoiTypes.HOME), predicate, entity.blockPosition(), level.purpurConfig.villagerNearestBedSensorSearchRadius, PoiManager.Occupancy.ANY, false, Integer.MAX_VALUE, poiposes); // Purpur - Configurable villager search radius
|
|
- Path path = AcquirePoi.findPathToPois(entity, new java.util.HashSet<>(poiposes));
|
|
- // Paper end - optimise POI access
|
|
- if (path != null && path.canReach()) {
|
|
- BlockPos target = path.getTarget();
|
|
- Optional<Holder<PoiType>> type = poiManager.getType(target);
|
|
- if (type.isPresent()) {
|
|
- entity.getBrain().setMemory(MemoryModuleType.NEAREST_BED, target);
|
|
- }
|
|
- } else if (this.triedCount < 5) {
|
|
- this.batchCache.long2LongEntrySet().removeIf(entry -> entry.getLongValue() < this.lastUpdate);
|
|
+ // Kaiiju start - await on async path processing
|
|
+ if (org.dreeam.leaf.config.modules.async.AsyncPathfinding.enabled) {
|
|
+ Path possiblePath = AcquirePoi.findPathToPois(entity, new java.util.HashSet<>(poiposes));
|
|
+ org.dreeam.leaf.async.path.AsyncPathProcessor.awaitProcessing(possiblePath, path -> {
|
|
+ processPath(entity, poiManager, path);
|
|
+ });
|
|
+ } else {
|
|
+ // Kaiiju end
|
|
+ Path path = AcquirePoi.findPathToPois(entity, new java.util.HashSet<>(poiposes));
|
|
+ // Paper end - optimise POI access
|
|
+ processPath(entity, poiManager, path);
|
|
+ } // Kaiiju - async path processing
|
|
+ }
|
|
+ }
|
|
+
|
|
+ // Leaf start - Kaiiju - await on async path processing
|
|
+ private void processPath(Mob entity, PoiManager poiManager, @org.jetbrains.annotations.Nullable Path path) {
|
|
+ if (path != null && path.canReach()) {
|
|
+ BlockPos target = path.getTarget();
|
|
+ Optional<Holder<PoiType>> type = poiManager.getType(target);
|
|
+ if (type.isPresent()) {
|
|
+ entity.getBrain().setMemory(MemoryModuleType.NEAREST_BED, target);
|
|
}
|
|
+ } else if (this.triedCount < 5) {
|
|
+ this.batchCache.long2LongEntrySet().removeIf(entry -> entry.getLongValue() < this.lastUpdate);
|
|
}
|
|
}
|
|
+ // Leaf end - Kaiiju - await on async path processing
|
|
}
|
|
diff --git a/net/minecraft/world/entity/animal/Bee.java b/net/minecraft/world/entity/animal/Bee.java
|
|
index d5727999eb67ff30dbf47865d59452483338e170..6fffa2e98e54ab015762417af8507d11c164e765 100644
|
|
--- a/net/minecraft/world/entity/animal/Bee.java
|
|
+++ b/net/minecraft/world/entity/animal/Bee.java
|
|
@@ -936,7 +936,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
|
|
} else {
|
|
Bee.this.pathfindRandomlyTowards(Bee.this.hivePos);
|
|
}
|
|
- } else {
|
|
+ } else if (navigation.getPath() != null && navigation.getPath().isProcessed()) { // Kaiiju - petal - check processing
|
|
boolean flag = this.pathfindDirectlyTowards(Bee.this.hivePos);
|
|
if (!flag) {
|
|
this.dropAndBlacklistHive();
|
|
@@ -990,7 +990,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
|
|
return true;
|
|
} else {
|
|
Path path = Bee.this.navigation.getPath();
|
|
- return path != null && path.getTarget().equals(pos) && path.canReach() && path.isDone();
|
|
+ return path != null && path.isProcessed() && path.getTarget().equals(pos) && path.canReach() && path.isDone(); // Kaiiju - petal - ensure path is processed
|
|
}
|
|
}
|
|
}
|
|
diff --git a/net/minecraft/world/entity/animal/frog/Frog.java b/net/minecraft/world/entity/animal/frog/Frog.java
|
|
index e5ec23c413e0d7da6f6b9c43925a7aa247946895..6e5cb137b3aa91321528d00a1433009cb9a0e656 100644
|
|
--- a/net/minecraft/world/entity/animal/frog/Frog.java
|
|
+++ b/net/minecraft/world/entity/animal/frog/Frog.java
|
|
@@ -479,9 +479,25 @@ public class Frog extends Animal implements VariantHolder<Holder<FrogVariant>> {
|
|
return pathType != PathType.WATER_BORDER && super.canCutCorner(pathType);
|
|
}
|
|
|
|
+ // Kaiiju start - petal - async path processing
|
|
+ private static final org.dreeam.leaf.async.path.NodeEvaluatorGenerator nodeEvaluatorGenerator = (org.dreeam.leaf.async.path.NodeEvaluatorFeatures nodeEvaluatorFeatures) -> {
|
|
+ Frog.FrogNodeEvaluator nodeEvaluator = new Frog.FrogNodeEvaluator(true);
|
|
+ nodeEvaluator.setCanPassDoors(nodeEvaluatorFeatures.canPassDoors());
|
|
+ nodeEvaluator.setCanFloat(nodeEvaluatorFeatures.canFloat());
|
|
+ nodeEvaluator.setCanWalkOverFences(nodeEvaluatorFeatures.canWalkOverFences());
|
|
+ nodeEvaluator.setCanOpenDoors(nodeEvaluatorFeatures.canOpenDoors());
|
|
+ return nodeEvaluator;
|
|
+ };
|
|
+ // Kaiiju end
|
|
+
|
|
@Override
|
|
protected PathFinder createPathFinder(int maxVisitedNodes) {
|
|
this.nodeEvaluator = new Frog.FrogNodeEvaluator(true);
|
|
+ // Kaiiju start - petal - async path processing
|
|
+ if (org.dreeam.leaf.config.modules.async.AsyncPathfinding.enabled) {
|
|
+ return new PathFinder(this.nodeEvaluator, maxVisitedNodes, nodeEvaluatorGenerator);
|
|
+ }
|
|
+ // Kaiiju end
|
|
return new PathFinder(this.nodeEvaluator, maxVisitedNodes);
|
|
}
|
|
}
|
|
diff --git a/net/minecraft/world/entity/monster/Drowned.java b/net/minecraft/world/entity/monster/Drowned.java
|
|
index 6c73245b8d04f194e72165aa0000ca79a95db59d..f5e6673ff2bd3029585b9ffea10df5d549f1cdd6 100644
|
|
--- a/net/minecraft/world/entity/monster/Drowned.java
|
|
+++ b/net/minecraft/world/entity/monster/Drowned.java
|
|
@@ -313,7 +313,7 @@ public class Drowned extends Zombie implements RangedAttackMob {
|
|
|
|
protected boolean closeToNextPos() {
|
|
Path path = this.getNavigation().getPath();
|
|
- if (path != null) {
|
|
+ if (path != null && path.isProcessed()) { // Kaiiju - petal - ensure path is processed
|
|
BlockPos target = path.getTarget();
|
|
if (target != null) {
|
|
double d = this.distanceToSqr(target.getX(), target.getY(), target.getZ());
|
|
diff --git a/net/minecraft/world/entity/monster/Strider.java b/net/minecraft/world/entity/monster/Strider.java
|
|
index 241526239bdbd5d9276f85e7fca46a7051f46a25..ae4ee948971e931e4fdc4ec2187f5182195c626c 100644
|
|
--- a/net/minecraft/world/entity/monster/Strider.java
|
|
+++ b/net/minecraft/world/entity/monster/Strider.java
|
|
@@ -579,9 +579,25 @@ public class Strider extends Animal implements ItemSteerable, Saddleable {
|
|
super(strider, level);
|
|
}
|
|
|
|
+ // Kaiiju start - petal - async path processing
|
|
+ private static final org.dreeam.leaf.async.path.NodeEvaluatorGenerator nodeEvaluatorGenerator = (org.dreeam.leaf.async.path.NodeEvaluatorFeatures nodeEvaluatorFeatures) -> {
|
|
+ WalkNodeEvaluator nodeEvaluator = new WalkNodeEvaluator();
|
|
+ nodeEvaluator.setCanPassDoors(nodeEvaluatorFeatures.canPassDoors());
|
|
+ nodeEvaluator.setCanFloat(nodeEvaluatorFeatures.canFloat());
|
|
+ nodeEvaluator.setCanWalkOverFences(nodeEvaluatorFeatures.canWalkOverFences());
|
|
+ nodeEvaluator.setCanOpenDoors(nodeEvaluatorFeatures.canOpenDoors());
|
|
+ return nodeEvaluator;
|
|
+ };
|
|
+ // Kaiiju end
|
|
+
|
|
@Override
|
|
protected PathFinder createPathFinder(int maxVisitedNodes) {
|
|
this.nodeEvaluator = new WalkNodeEvaluator();
|
|
+ // Kaiiju start - async path processing
|
|
+ if (org.dreeam.leaf.config.modules.async.AsyncPathfinding.enabled) {
|
|
+ return new PathFinder(this.nodeEvaluator, maxVisitedNodes, nodeEvaluatorGenerator);
|
|
+ }
|
|
+ // Kaiiju end
|
|
return new PathFinder(this.nodeEvaluator, maxVisitedNodes);
|
|
}
|
|
|
|
diff --git a/net/minecraft/world/entity/monster/warden/Warden.java b/net/minecraft/world/entity/monster/warden/Warden.java
|
|
index 26f3fe1c80b0d87b96076432f35fe4f95f92ce13..3a43790fb91e778f4fc0730aecd0dde4a6d301c8 100644
|
|
--- a/net/minecraft/world/entity/monster/warden/Warden.java
|
|
+++ b/net/minecraft/world/entity/monster/warden/Warden.java
|
|
@@ -599,6 +599,16 @@ public class Warden extends Monster implements VibrationSystem {
|
|
@Override
|
|
protected PathFinder createPathFinder(int maxVisitedNodes) {
|
|
this.nodeEvaluator = new WalkNodeEvaluator();
|
|
+ // Kaiiju start - petal - async path processing
|
|
+ if (org.dreeam.leaf.config.modules.async.AsyncPathfinding.enabled) {
|
|
+ return new PathFinder(this.nodeEvaluator, maxVisitedNodes, GroundPathNavigation.nodeEvaluatorGenerator) {
|
|
+ @Override
|
|
+ protected float distance(Node first, Node second) {
|
|
+ return first.distanceToXZ(second);
|
|
+ }
|
|
+ };
|
|
+ }
|
|
+ // Kaiiju end
|
|
return new PathFinder(this.nodeEvaluator, maxVisitedNodes) {
|
|
@Override
|
|
protected float distance(Node first, Node second) {
|
|
diff --git a/net/minecraft/world/level/block/ShulkerBoxBlock.java b/net/minecraft/world/level/block/ShulkerBoxBlock.java
|
|
index cdf835ff107bc1eadde706d69384e687626fce70..31066accd82da2b8b36d9a9d8676dc887af31fed 100644
|
|
--- a/net/minecraft/world/level/block/ShulkerBoxBlock.java
|
|
+++ b/net/minecraft/world/level/block/ShulkerBoxBlock.java
|
|
@@ -217,9 +217,16 @@ public class ShulkerBoxBlock extends BaseEntityBlock {
|
|
|
|
@Override
|
|
protected VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) {
|
|
+ //if (Thread.currentThread().getName().contains("petal-async-pathfinding-thread")) return Shapes.block(); // Kaiiju - async pathfinding - we cannot get block entities // Leaf - Don't need this
|
|
return level.getBlockEntity(pos) instanceof ShulkerBoxBlockEntity shulkerBoxBlockEntity
|
|
? Shapes.create(shulkerBoxBlockEntity.getBoundingBox(state))
|
|
: Shapes.block();
|
|
+ // Kaiiju start - async pathfinding - workaround // Leaf - Don't need this
|
|
+ /*
|
|
+ } catch (NullPointerException e) {
|
|
+ return Shapes.block();
|
|
+ }
|
|
+ */
|
|
}
|
|
|
|
@Override
|
|
diff --git a/net/minecraft/world/level/pathfinder/Path.java b/net/minecraft/world/level/pathfinder/Path.java
|
|
index d6d3c8f5e5dd4a8cab0d3fcc131c3a59f06130c6..add5b8b98e4d09617cbd4e7dd2710dc50781613a 100644
|
|
--- a/net/minecraft/world/level/pathfinder/Path.java
|
|
+++ b/net/minecraft/world/level/pathfinder/Path.java
|
|
@@ -26,6 +26,17 @@ public class Path {
|
|
this.reached = reached;
|
|
}
|
|
|
|
+ // Kaiiju start - petal - async path processing
|
|
+ /**
|
|
+ * checks if the path is completely processed in the case of it being computed async
|
|
+ *
|
|
+ * @return true if the path is processed
|
|
+ */
|
|
+ public boolean isProcessed() {
|
|
+ return true;
|
|
+ }
|
|
+ // Kaiiju end
|
|
+
|
|
public void advance() {
|
|
this.nextNodeIndex++;
|
|
}
|
|
@@ -99,6 +110,7 @@ public class Path {
|
|
}
|
|
|
|
public boolean sameAs(@Nullable Path pathentity) {
|
|
+ if (pathentity == this) return true; // Kaiiju - petal - short circuit
|
|
if (pathentity == null) {
|
|
return false;
|
|
} else if (pathentity.nodes.size() != this.nodes.size()) {
|
|
diff --git a/net/minecraft/world/level/pathfinder/PathFinder.java b/net/minecraft/world/level/pathfinder/PathFinder.java
|
|
index c2baadcdceb1df6a881d6f73aa4eb4dd264bcdfe..61912c67611ded5a8f34e0c55d3d3017f144f970 100644
|
|
--- a/net/minecraft/world/level/pathfinder/PathFinder.java
|
|
+++ b/net/minecraft/world/level/pathfinder/PathFinder.java
|
|
@@ -22,10 +22,18 @@ public class PathFinder {
|
|
public final NodeEvaluator nodeEvaluator;
|
|
private static final boolean DEBUG = false;
|
|
private final BinaryHeap openSet = new BinaryHeap();
|
|
+ private final @Nullable org.dreeam.leaf.async.path.NodeEvaluatorGenerator nodeEvaluatorGenerator; // Kaiiju - petal - we use this later to generate an evaluator
|
|
|
|
- public PathFinder(NodeEvaluator nodeEvaluator, int maxVisitedNodes) {
|
|
+ public PathFinder(NodeEvaluator nodeEvaluator, int maxVisitedNodes, @Nullable org.dreeam.leaf.async.path.NodeEvaluatorGenerator nodeEvaluatorGenerator) { // Kaiiju - petal - add nodeEvaluatorGenerator
|
|
this.nodeEvaluator = nodeEvaluator;
|
|
this.maxVisitedNodes = maxVisitedNodes;
|
|
+ // Kaiiju start - petal - support nodeEvaluatorgenerators
|
|
+ this.nodeEvaluatorGenerator = nodeEvaluatorGenerator;
|
|
+ }
|
|
+
|
|
+ public PathFinder(NodeEvaluator nodeEvaluator, int maxVisitedNodes) {
|
|
+ this(nodeEvaluator, maxVisitedNodes, null);
|
|
+ // Kaiiju end
|
|
}
|
|
|
|
public void setMaxVisitedNodes(int maxVisitedNodes) {
|
|
@@ -34,26 +42,63 @@ public class PathFinder {
|
|
|
|
@Nullable
|
|
public Path findPath(PathNavigationRegion region, Mob mob, Set<BlockPos> targetPositions, float maxRange, int accuracy, float searchDepthMultiplier) {
|
|
- this.openSet.clear();
|
|
- this.nodeEvaluator.prepare(region, mob);
|
|
- Node start = this.nodeEvaluator.getStart();
|
|
+ if (!org.dreeam.leaf.config.modules.async.AsyncPathfinding.enabled)
|
|
+ this.openSet.clear(); // Kaiiju - petal - it's always cleared in processPath
|
|
+ // Kaiiju start - petal - use a generated evaluator if we have one otherwise run sync
|
|
+ NodeEvaluator nodeEvaluator = this.nodeEvaluatorGenerator == null
|
|
+ ? this.nodeEvaluator
|
|
+ : org.dreeam.leaf.async.path.NodeEvaluatorCache.takeNodeEvaluator(this.nodeEvaluatorGenerator, this.nodeEvaluator);
|
|
+ nodeEvaluator.prepare(region, mob);
|
|
+ Node start = nodeEvaluator.getStart();
|
|
+ // Kaiiju end
|
|
if (start == null) {
|
|
+ org.dreeam.leaf.async.path.NodeEvaluatorCache.removeNodeEvaluator(nodeEvaluator); // Kaiiju - petal - handle nodeEvaluatorGenerator
|
|
return null;
|
|
} else {
|
|
// Paper start - Perf: remove streams and optimize collection
|
|
List<Map.Entry<Target, BlockPos>> map = Lists.newArrayList();
|
|
for (BlockPos pos : targetPositions) {
|
|
- map.add(new java.util.AbstractMap.SimpleEntry<>(this.nodeEvaluator.getTarget(pos.getX(), pos.getY(), pos.getZ()), pos));
|
|
+ map.add(new java.util.AbstractMap.SimpleEntry<>(nodeEvaluator.getTarget(pos.getX(), pos.getY(), pos.getZ()), pos)); // Kaiiju - petal - handle nodeEvaluatorGenerator
|
|
}
|
|
// Paper end - Perf: remove streams and optimize collection
|
|
- Path path = this.findPath(start, map, maxRange, accuracy, searchDepthMultiplier);
|
|
- this.nodeEvaluator.done();
|
|
- return path;
|
|
+ // Kaiiju start - petal - async path processing
|
|
+ if (this.nodeEvaluatorGenerator == null) {
|
|
+ // run sync :(
|
|
+ org.dreeam.leaf.async.path.NodeEvaluatorCache.removeNodeEvaluator(nodeEvaluator);
|
|
+ return this.findPath(start, map, maxRange, accuracy, searchDepthMultiplier);
|
|
+ }
|
|
+
|
|
+ return new org.dreeam.leaf.async.path.AsyncPath(Lists.newArrayList(), targetPositions, () -> {
|
|
+ try {
|
|
+ return this.processPath(nodeEvaluator, start, map, maxRange, accuracy, searchDepthMultiplier);
|
|
+ } catch (Exception e) {
|
|
+ e.printStackTrace();
|
|
+ return null;
|
|
+ } finally {
|
|
+ nodeEvaluator.done();
|
|
+ org.dreeam.leaf.async.path.NodeEvaluatorCache.returnNodeEvaluator(nodeEvaluator);
|
|
+ }
|
|
+ });
|
|
+ // Kaiiju end
|
|
}
|
|
}
|
|
|
|
@Nullable
|
|
private Path findPath(Node node, List<Map.Entry<Target, BlockPos>> positions, float maxRange, int accuracy, float searchDepthMultiplier) { // Paper - optimize collection
|
|
+ // Kaiiju start - petal - split pathfinding into the original sync method for compat and processing for delaying
|
|
+ try {
|
|
+ return this.processPath(this.nodeEvaluator, node, positions, maxRange, accuracy, searchDepthMultiplier);
|
|
+ } catch (Exception e) {
|
|
+ e.printStackTrace();
|
|
+ return null;
|
|
+ } finally {
|
|
+ this.nodeEvaluator.done();
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private synchronized @org.jetbrains.annotations.NotNull Path processPath(NodeEvaluator nodeEvaluator, Node node, List<Map.Entry<Target, BlockPos>> positions, float maxRange, int accuracy, float searchDepthMultiplier) { // sync to only use the caching functions in this class on a single thread
|
|
+ org.apache.commons.lang3.Validate.isTrue(!positions.isEmpty()); // ensure that we have at least one position, which means we'll always return a path
|
|
+ // Kaiiju end
|
|
// Set<Target> set = targetPositions.keySet(); // Paper
|
|
node.g = 0.0F;
|
|
node.h = this.getBestH(node, positions); // Paper - optimize collection
|
|
@@ -89,7 +134,7 @@ public class PathFinder {
|
|
}
|
|
|
|
if (!(node1.distanceTo(node) >= maxRange)) {
|
|
- int neighbors = this.nodeEvaluator.getNeighbors(this.neighbors, node1);
|
|
+ int neighbors = nodeEvaluator.getNeighbors(this.neighbors, node1); // Kaiiju - petal - use provided nodeEvaluator
|
|
|
|
for (int i2 = 0; i2 < neighbors; i2++) {
|
|
Node node2 = this.neighbors[i2];
|
|
@@ -123,6 +168,7 @@ public class PathFinder {
|
|
best = path;
|
|
}
|
|
}
|
|
+ //noinspection ConstantConditions // Kaiiju - petal - ignore this warning, we know that the above loop always runs at least once since positions is not empty
|
|
return best;
|
|
// Paper end - Perf: remove streams and optimize collection
|
|
}
|