avoidances
This commit is contained in:
parent
1a6c0cd4d9
commit
36cfcbbbe3
@ -37,8 +37,7 @@ import baritone.pathing.path.CutoffPath;
|
|||||||
import baritone.pathing.path.PathExecutor;
|
import baritone.pathing.path.PathExecutor;
|
||||||
import baritone.utils.Helper;
|
import baritone.utils.Helper;
|
||||||
import baritone.utils.PathRenderer;
|
import baritone.utils.PathRenderer;
|
||||||
import baritone.utils.pathing.AvoidanceHelper;
|
import baritone.utils.pathing.Favoring;
|
||||||
import it.unimi.dsi.fastutil.longs.Long2DoubleOpenHashMap;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.chunk.EmptyChunk;
|
import net.minecraft.world.chunk.EmptyChunk;
|
||||||
|
|
||||||
@ -504,13 +503,8 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
transformed = new GoalXZ(pos.getX(), pos.getZ());
|
transformed = new GoalXZ(pos.getX(), pos.getZ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Long2DoubleOpenHashMap favoredPositions = new Long2DoubleOpenHashMap();
|
Favoring favoring = new Favoring(context.getBaritone().getPlayerContext(), previous);
|
||||||
double coeff = Baritone.settings().backtrackCostFavoringCoefficient.get();
|
return new AStarPathFinder(start.getX(), start.getY(), start.getZ(), transformed, favoring, context);
|
||||||
if (coeff != 1D && previous != null) {
|
|
||||||
previous.positions().forEach(pos -> favoredPositions.put(BetterBlockPos.longHash(pos), coeff));
|
|
||||||
}
|
|
||||||
AvoidanceHelper.INSTANCE.apply(favoredPositions, context.getBaritone().getPlayerContext());
|
|
||||||
return new AStarPathFinder(start.getX(), start.getY(), start.getZ(), transformed, favoredPositions, context);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -27,8 +27,8 @@ import baritone.pathing.movement.CalculationContext;
|
|||||||
import baritone.pathing.movement.Moves;
|
import baritone.pathing.movement.Moves;
|
||||||
import baritone.utils.Helper;
|
import baritone.utils.Helper;
|
||||||
import baritone.utils.pathing.BetterWorldBorder;
|
import baritone.utils.pathing.BetterWorldBorder;
|
||||||
|
import baritone.utils.pathing.Favoring;
|
||||||
import baritone.utils.pathing.MutableMoveResult;
|
import baritone.utils.pathing.MutableMoveResult;
|
||||||
import it.unimi.dsi.fastutil.longs.Long2DoubleOpenHashMap;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@ -39,12 +39,12 @@ import java.util.Optional;
|
|||||||
*/
|
*/
|
||||||
public final class AStarPathFinder extends AbstractNodeCostSearch implements Helper {
|
public final class AStarPathFinder extends AbstractNodeCostSearch implements Helper {
|
||||||
|
|
||||||
private final Long2DoubleOpenHashMap favoredPositions;
|
private final Favoring favoring;
|
||||||
private final CalculationContext calcContext;
|
private final CalculationContext calcContext;
|
||||||
|
|
||||||
public AStarPathFinder(int startX, int startY, int startZ, Goal goal, Long2DoubleOpenHashMap favoredPositions, CalculationContext context) {
|
public AStarPathFinder(int startX, int startY, int startZ, Goal goal, Favoring favoring, CalculationContext context) {
|
||||||
super(startX, startY, startZ, goal, context);
|
super(startX, startY, startZ, goal, context);
|
||||||
this.favoredPositions = favoredPositions;
|
this.favoring = favoring;
|
||||||
this.calcContext = context;
|
this.calcContext = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,8 +63,7 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
|
|||||||
bestSoFar[i] = startNode;
|
bestSoFar[i] = startNode;
|
||||||
}
|
}
|
||||||
MutableMoveResult res = new MutableMoveResult();
|
MutableMoveResult res = new MutableMoveResult();
|
||||||
Long2DoubleOpenHashMap favored = favoredPositions;
|
Favoring favored = favoring;
|
||||||
favored.defaultReturnValue(1.0D);
|
|
||||||
BetterWorldBorder worldBorder = new BetterWorldBorder(calcContext.world().getWorldBorder());
|
BetterWorldBorder worldBorder = new BetterWorldBorder(calcContext.world().getWorldBorder());
|
||||||
long startTime = System.nanoTime() / 1000000L;
|
long startTime = System.nanoTime() / 1000000L;
|
||||||
boolean slowPath = Baritone.settings().slowPath.get();
|
boolean slowPath = Baritone.settings().slowPath.get();
|
||||||
@ -97,6 +96,7 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
|
|||||||
mostRecentConsidered = currentNode;
|
mostRecentConsidered = currentNode;
|
||||||
numNodes++;
|
numNodes++;
|
||||||
if (goal.isInGoal(currentNode.x, currentNode.y, currentNode.z)) {
|
if (goal.isInGoal(currentNode.x, currentNode.y, currentNode.z)) {
|
||||||
|
favored.printStats();
|
||||||
logDebug("Took " + (System.nanoTime() / 1000000L - startTime) + "ms, " + numMovementsConsidered + " movements considered");
|
logDebug("Took " + (System.nanoTime() / 1000000L - startTime) + "ms, " + numMovementsConsidered + " movements considered");
|
||||||
return Optional.of(new Path(startNode, currentNode, numNodes, goal, calcContext));
|
return Optional.of(new Path(startNode, currentNode, numNodes, goal, calcContext));
|
||||||
}
|
}
|
||||||
@ -137,10 +137,9 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
|
|||||||
throw new IllegalStateException(moves + " " + res.y + " " + (currentNode.y + moves.yOffset));
|
throw new IllegalStateException(moves + " " + res.y + " " + (currentNode.y + moves.yOffset));
|
||||||
}
|
}
|
||||||
long hashCode = BetterBlockPos.longHash(res.x, res.y, res.z);
|
long hashCode = BetterBlockPos.longHash(res.x, res.y, res.z);
|
||||||
favored.get(hashCode);
|
|
||||||
if (favoring) {
|
if (favoring) {
|
||||||
// see issue #18
|
// see issue #18
|
||||||
actionCost *= favored.get(hashCode);
|
actionCost *= favored.calculate(res.x, res.y, res.z, hashCode);
|
||||||
}
|
}
|
||||||
PathNode neighbor = getNodeAtPosition(res.x, res.y, res.z, hashCode);
|
PathNode neighbor = getNodeAtPosition(res.x, res.y, res.z, hashCode);
|
||||||
double tentativeCost = currentNode.cost + actionCost;
|
double tentativeCost = currentNode.cost + actionCost;
|
||||||
@ -178,6 +177,7 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
favored.printStats();
|
||||||
if (cancelRequested) {
|
if (cancelRequested) {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
@ -24,32 +24,61 @@ import it.unimi.dsi.fastutil.longs.Long2DoubleOpenHashMap;
|
|||||||
import net.minecraft.entity.monster.EntityMob;
|
import net.minecraft.entity.monster.EntityMob;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
public enum AvoidanceHelper {
|
import java.util.ArrayList;
|
||||||
INSTANCE;
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public void apply(Long2DoubleOpenHashMap map, IPlayerContext ctx) {
|
public class Avoidance {
|
||||||
if (!Baritone.settings().avoidance.get()) {
|
public final int centerX;
|
||||||
return;
|
public final int centerY;
|
||||||
|
public final int centerZ;
|
||||||
|
public final double coefficient;
|
||||||
|
public final int radius;
|
||||||
|
public final int radiusSq;
|
||||||
|
|
||||||
|
public Avoidance(BlockPos center, double coefficient, int radius) {
|
||||||
|
this(center.getX(), center.getY(), center.getZ(), coefficient, radius);
|
||||||
}
|
}
|
||||||
long start = System.currentTimeMillis();
|
|
||||||
|
public Avoidance(int centerX, int centerY, int centerZ, double coefficient, int radius) {
|
||||||
|
this.centerX = centerX;
|
||||||
|
this.centerY = centerY;
|
||||||
|
this.centerZ = centerZ;
|
||||||
|
this.coefficient = coefficient;
|
||||||
|
this.radius = radius;
|
||||||
|
this.radiusSq = radius * radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double coefficient(int x, int y, int z) {
|
||||||
|
int xDiff = x - centerX;
|
||||||
|
int yDiff = y - centerY;
|
||||||
|
int zDiff = z - centerZ;
|
||||||
|
return xDiff * xDiff + yDiff * yDiff + zDiff * zDiff <= radiusSq ? coefficient : 1.0D;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<Avoidance> create(IPlayerContext ctx) {
|
||||||
|
if (!Baritone.settings().avoidance.get()) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
List<Avoidance> res = new ArrayList<>();
|
||||||
double mobSpawnerCoeff = Baritone.settings().mobSpawnerAvoidanceCoefficient.get();
|
double mobSpawnerCoeff = Baritone.settings().mobSpawnerAvoidanceCoefficient.get();
|
||||||
double mobCoeff = Baritone.settings().mobAvoidanceCoefficient.get();
|
double mobCoeff = Baritone.settings().mobAvoidanceCoefficient.get();
|
||||||
if (mobSpawnerCoeff != 1.0D) {
|
if (mobSpawnerCoeff != 1.0D) {
|
||||||
ctx.worldData().getCachedWorld().getLocationsOf("mob_spawner", 1, ctx.playerFeet().x, ctx.playerFeet().z, 2).forEach(mobspawner -> sphere(mobspawner, Baritone.settings().mobSpawnerAvoidanceRadius.get(), map, mobSpawnerCoeff));
|
ctx.worldData().getCachedWorld().getLocationsOf("mob_spawner", 1, ctx.playerFeet().x, ctx.playerFeet().z, 2).forEach(mobspawner -> res.add(new Avoidance(mobspawner, mobSpawnerCoeff, Baritone.settings().mobSpawnerAvoidanceRadius.get())));
|
||||||
}
|
}
|
||||||
if (mobCoeff != 1.0D) {
|
if (mobCoeff != 1.0D) {
|
||||||
ctx.world().loadedEntityList.stream().filter(entity -> entity instanceof EntityMob).forEach(entity -> sphere(new BlockPos(entity), Baritone.settings().mobAvoidanceRadius.get(), map, mobCoeff));
|
ctx.world().loadedEntityList.stream().filter(entity -> entity instanceof EntityMob).forEach(entity -> res.add(new Avoidance(new BlockPos(entity), mobCoeff, Baritone.settings().mobAvoidanceRadius.get())));
|
||||||
}
|
}
|
||||||
long end = System.currentTimeMillis();
|
return res;
|
||||||
System.out.println("Took " + (end - start) + "ms to generate avoidance of " + map.size() + " blocks");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sphere(BlockPos center, int radius, Long2DoubleOpenHashMap map, double coeff) {
|
public void applySpherical(Long2DoubleOpenHashMap map) {
|
||||||
for (int x = -radius; x <= radius; x++) {
|
for (int x = -radius; x <= radius; x++) {
|
||||||
for (int y = -radius; y <= radius; y++) {
|
for (int y = -radius; y <= radius; y++) {
|
||||||
for (int z = -radius; z <= radius; z++) {
|
for (int z = -radius; z <= radius; z++) {
|
||||||
if (x * x + y * y + z * z <= radius * radius) {
|
if (x * x + y * y + z * z <= radius * radius) {
|
||||||
map.put(BetterBlockPos.longHash(center.getX() + x, center.getY() + y, center.getZ() + z), coeff);
|
long hash = BetterBlockPos.longHash(centerX + x, centerY + y, centerZ + z);
|
||||||
|
map.put(hash, map.get(hash) * coefficient);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
100
src/main/java/baritone/utils/pathing/Favoring.java
Normal file
100
src/main/java/baritone/utils/pathing/Favoring.java
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Baritone.
|
||||||
|
*
|
||||||
|
* Baritone is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Baritone is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package baritone.utils.pathing;
|
||||||
|
|
||||||
|
import baritone.Baritone;
|
||||||
|
import baritone.api.pathing.calc.IPath;
|
||||||
|
import baritone.api.utils.BetterBlockPos;
|
||||||
|
import baritone.api.utils.IPlayerContext;
|
||||||
|
import it.unimi.dsi.fastutil.longs.Long2DoubleOpenHashMap;
|
||||||
|
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class Favoring {
|
||||||
|
private final LongOpenHashSet backtrackFavored = new LongOpenHashSet();
|
||||||
|
private final double backtrackCoefficient;
|
||||||
|
|
||||||
|
private final List<Avoidance> avoidances;
|
||||||
|
|
||||||
|
private final Long2DoubleOpenHashMap favorings = new Long2DoubleOpenHashMap();
|
||||||
|
|
||||||
|
private long mapMethodNano = 0;
|
||||||
|
private long hybridMethodNano = 0;
|
||||||
|
|
||||||
|
|
||||||
|
public Favoring(IPlayerContext ctx, IPath previous) {
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
backtrackCoefficient = Baritone.settings().backtrackCostFavoringCoefficient.get();
|
||||||
|
if (backtrackCoefficient != 1D && previous != null) {
|
||||||
|
previous.positions().forEach(pos -> backtrackFavored.add(BetterBlockPos.longHash(pos)));
|
||||||
|
}
|
||||||
|
|
||||||
|
avoidances = Avoidance.create(ctx);
|
||||||
|
long end = System.currentTimeMillis();
|
||||||
|
System.out.println("Hybrid method init took " + (end - start) + "ms");
|
||||||
|
|
||||||
|
favorings.defaultReturnValue(1.0D);
|
||||||
|
backtrackFavored.forEach(l -> favorings.put((long) l, backtrackCoefficient));
|
||||||
|
for (Avoidance avoid : avoidances) {
|
||||||
|
avoid.applySpherical(favorings);
|
||||||
|
}
|
||||||
|
long end2 = System.currentTimeMillis();
|
||||||
|
System.out.println("Map method init took " + (end2 - end) + "ms");
|
||||||
|
System.out.println("Size: " + favorings.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void printStats() {
|
||||||
|
System.out.println("Map method nanos: " + mapMethodNano);
|
||||||
|
System.out.println("Hybrid method nano: " + hybridMethodNano);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return backtrackFavored.isEmpty() && favorings.isEmpty() && avoidances.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public double calculate(int x, int y, int z, long hash) {
|
||||||
|
long start = System.nanoTime();
|
||||||
|
double result = calculateMap(x, y, z, hash);
|
||||||
|
long mid = System.nanoTime();
|
||||||
|
double result2 = calculateHybrid(x, y, z, hash);
|
||||||
|
long end = System.nanoTime();
|
||||||
|
mapMethodNano += mid - start;
|
||||||
|
hybridMethodNano += end - mid;
|
||||||
|
if (result != result2) {
|
||||||
|
System.out.println("NO MATCH " + result + " " + result2);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public double calculateMap(int x, int y, int z, long hash) {
|
||||||
|
return favorings.get(hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
public double calculateHybrid(int x, int y, int z, long hash) {
|
||||||
|
double result = 1.0D;
|
||||||
|
if (backtrackFavored.contains(hash)) {
|
||||||
|
result *= backtrackCoefficient;
|
||||||
|
}
|
||||||
|
for (Avoidance avoid : avoidances) {
|
||||||
|
result *= avoid.coefficient(x, y, z);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user