Merge branch 'master' into failure-cutoff

This commit is contained in:
Leijurv 2018-11-23 09:59:23 -08:00
commit f05613147e
No known key found for this signature in database
GPG Key ID: 44A3EA646EADAC6A
15 changed files with 211 additions and 103 deletions

View File

@ -21,9 +21,9 @@ import baritone.api.Settings;
import baritone.api.pathing.goals.Goal; import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.movement.IMovement; import baritone.api.pathing.movement.IMovement;
import baritone.api.utils.BetterBlockPos; import baritone.api.utils.BetterBlockPos;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World; import net.minecraft.world.World;
import java.util.HashSet;
import java.util.List; import java.util.List;
/** /**
@ -153,9 +153,10 @@ public interface IPath {
if (path.size() != movements.size() + 1) { if (path.size() != movements.size() + 1) {
throw new IllegalStateException("Size of path array is unexpected"); throw new IllegalStateException("Size of path array is unexpected");
} }
HashSet<BetterBlockPos> seenSoFar = new HashSet<>();
for (int i = 0; i < path.size() - 1; i++) { for (int i = 0; i < path.size() - 1; i++) {
BlockPos src = path.get(i); BetterBlockPos src = path.get(i);
BlockPos dest = path.get(i + 1); BetterBlockPos dest = path.get(i + 1);
IMovement movement = movements.get(i); IMovement movement = movements.get(i);
if (!src.equals(movement.getSrc())) { if (!src.equals(movement.getSrc())) {
throw new IllegalStateException("Path source is not equal to the movement source"); throw new IllegalStateException("Path source is not equal to the movement source");
@ -163,6 +164,10 @@ public interface IPath {
if (!dest.equals(movement.getDest())) { if (!dest.equals(movement.getDest())) {
throw new IllegalStateException("Path destination is not equal to the movement destination"); throw new IllegalStateException("Path destination is not equal to the movement destination");
} }
if (seenSoFar.contains(src)) {
throw new IllegalStateException("Path doubles back on itself, making a loop");
}
seenSoFar.add(src);
} }
} }
} }

View File

@ -0,0 +1,39 @@
/*
* 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.launch.mixins;
import baritone.utils.accessor.IChunkProviderClient;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import net.minecraft.client.multiplayer.ChunkProviderClient;
import net.minecraft.world.chunk.Chunk;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@Mixin(ChunkProviderClient.class)
public class MixinChunkProviderClient implements IChunkProviderClient {
@Shadow
@Final
private Long2ObjectMap<Chunk> loadedChunks;
@Override
public Long2ObjectMap<Chunk> loadedChunks() {
return this.loadedChunks;
}
}

View File

@ -10,6 +10,7 @@
"client": [ "client": [
"MixinAnvilChunkLoader", "MixinAnvilChunkLoader",
"MixinBlockPos", "MixinBlockPos",
"MixinChunkProviderClient",
"MixinChunkProviderServer", "MixinChunkProviderServer",
"MixinEntity", "MixinEntity",
"MixinEntityLivingBase", "MixinEntityLivingBase",

View File

@ -129,7 +129,7 @@ class Path extends PathBase {
private Movement runBackwards(BetterBlockPos src, BetterBlockPos dest, double cost) { private Movement runBackwards(BetterBlockPos src, BetterBlockPos dest, double cost) {
for (Moves moves : Moves.values()) { for (Moves moves : Moves.values()) {
Movement move = moves.apply0(context.getBaritone(), src); Movement move = moves.apply0(context, src);
if (move.getDest().equals(dest)) { if (move.getDest().equals(dest)) {
// have to calculate the cost at calculation time so we can accurately judge whether a cost increase happened between cached calculation and real execution // have to calculate the cost at calculation time so we can accurately judge whether a cost increase happened between cached calculation and real execution
move.override(cost); move.override(cost);

View File

@ -86,7 +86,7 @@ public interface MovementHelper extends ActionCosts, Helper {
// so the only remaining dynamic isPassables are snow and trapdoor // so the only remaining dynamic isPassables are snow and trapdoor
// if they're cached as a top block, we don't know their metadata // if they're cached as a top block, we don't know their metadata
// default to true (mostly because it would otherwise make long distance pathing through snowy biomes impossible) // default to true (mostly because it would otherwise make long distance pathing through snowy biomes impossible)
if (bsi.getWorld().getChunk(x >> 4, z >> 4) instanceof EmptyChunk) { if (!bsi.worldContainsLoadedChunk(x, z)) {
return true; return true;
} }
if (snow) { if (snow) {
@ -274,7 +274,7 @@ public interface MovementHelper extends ActionCosts, Helper {
// if assumeWalkOnWater is off, we can only walk on water if there is water above it // if assumeWalkOnWater is off, we can only walk on water if there is water above it
return isWater(up) ^ Baritone.settings().assumeWalkOnWater.get(); return isWater(up) ^ Baritone.settings().assumeWalkOnWater.get();
} }
if (block instanceof BlockGlass || block instanceof BlockStainedGlass) { if (block == Blocks.GLASS || block == Blocks.STAINED_GLASS) {
return true; return true;
} }
if (block instanceof BlockSlab) { if (block instanceof BlockSlab) {

View File

@ -17,7 +17,6 @@
package baritone.pathing.movement; package baritone.pathing.movement;
import baritone.api.IBaritone;
import baritone.api.utils.BetterBlockPos; import baritone.api.utils.BetterBlockPos;
import baritone.pathing.movement.movements.*; import baritone.pathing.movement.movements.*;
import baritone.utils.pathing.MutableMoveResult; import baritone.utils.pathing.MutableMoveResult;
@ -31,8 +30,8 @@ import net.minecraft.util.EnumFacing;
public enum Moves { public enum Moves {
DOWNWARD(0, -1, 0) { DOWNWARD(0, -1, 0) {
@Override @Override
public Movement apply0(IBaritone baritone, BetterBlockPos src) { public Movement apply0(CalculationContext context, BetterBlockPos src) {
return new MovementDownward(baritone, src, src.down()); return new MovementDownward(context.getBaritone(), src, src.down());
} }
@Override @Override
@ -43,8 +42,8 @@ public enum Moves {
PILLAR(0, +1, 0) { PILLAR(0, +1, 0) {
@Override @Override
public Movement apply0(IBaritone baritone, BetterBlockPos src) { public Movement apply0(CalculationContext context, BetterBlockPos src) {
return new MovementPillar(baritone, src, src.up()); return new MovementPillar(context.getBaritone(), src, src.up());
} }
@Override @Override
@ -55,8 +54,8 @@ public enum Moves {
TRAVERSE_NORTH(0, 0, -1) { TRAVERSE_NORTH(0, 0, -1) {
@Override @Override
public Movement apply0(IBaritone baritone, BetterBlockPos src) { public Movement apply0(CalculationContext context, BetterBlockPos src) {
return new MovementTraverse(baritone, src, src.north()); return new MovementTraverse(context.getBaritone(), src, src.north());
} }
@Override @Override
@ -67,8 +66,8 @@ public enum Moves {
TRAVERSE_SOUTH(0, 0, +1) { TRAVERSE_SOUTH(0, 0, +1) {
@Override @Override
public Movement apply0(IBaritone baritone, BetterBlockPos src) { public Movement apply0(CalculationContext context, BetterBlockPos src) {
return new MovementTraverse(baritone, src, src.south()); return new MovementTraverse(context.getBaritone(), src, src.south());
} }
@Override @Override
@ -79,8 +78,8 @@ public enum Moves {
TRAVERSE_EAST(+1, 0, 0) { TRAVERSE_EAST(+1, 0, 0) {
@Override @Override
public Movement apply0(IBaritone baritone, BetterBlockPos src) { public Movement apply0(CalculationContext context, BetterBlockPos src) {
return new MovementTraverse(baritone, src, src.east()); return new MovementTraverse(context.getBaritone(), src, src.east());
} }
@Override @Override
@ -91,8 +90,8 @@ public enum Moves {
TRAVERSE_WEST(-1, 0, 0) { TRAVERSE_WEST(-1, 0, 0) {
@Override @Override
public Movement apply0(IBaritone baritone, BetterBlockPos src) { public Movement apply0(CalculationContext context, BetterBlockPos src) {
return new MovementTraverse(baritone, src, src.west()); return new MovementTraverse(context.getBaritone(), src, src.west());
} }
@Override @Override
@ -103,8 +102,8 @@ public enum Moves {
ASCEND_NORTH(0, +1, -1) { ASCEND_NORTH(0, +1, -1) {
@Override @Override
public Movement apply0(IBaritone baritone, BetterBlockPos src) { public Movement apply0(CalculationContext context, BetterBlockPos src) {
return new MovementAscend(baritone, src, new BetterBlockPos(src.x, src.y + 1, src.z - 1)); return new MovementAscend(context.getBaritone(), src, new BetterBlockPos(src.x, src.y + 1, src.z - 1));
} }
@Override @Override
@ -115,8 +114,8 @@ public enum Moves {
ASCEND_SOUTH(0, +1, +1) { ASCEND_SOUTH(0, +1, +1) {
@Override @Override
public Movement apply0(IBaritone baritone, BetterBlockPos src) { public Movement apply0(CalculationContext context, BetterBlockPos src) {
return new MovementAscend(baritone, src, new BetterBlockPos(src.x, src.y + 1, src.z + 1)); return new MovementAscend(context.getBaritone(), src, new BetterBlockPos(src.x, src.y + 1, src.z + 1));
} }
@Override @Override
@ -127,8 +126,8 @@ public enum Moves {
ASCEND_EAST(+1, +1, 0) { ASCEND_EAST(+1, +1, 0) {
@Override @Override
public Movement apply0(IBaritone baritone, BetterBlockPos src) { public Movement apply0(CalculationContext context, BetterBlockPos src) {
return new MovementAscend(baritone, src, new BetterBlockPos(src.x + 1, src.y + 1, src.z)); return new MovementAscend(context.getBaritone(), src, new BetterBlockPos(src.x + 1, src.y + 1, src.z));
} }
@Override @Override
@ -139,8 +138,8 @@ public enum Moves {
ASCEND_WEST(-1, +1, 0) { ASCEND_WEST(-1, +1, 0) {
@Override @Override
public Movement apply0(IBaritone baritone, BetterBlockPos src) { public Movement apply0(CalculationContext context, BetterBlockPos src) {
return new MovementAscend(baritone, src, new BetterBlockPos(src.x - 1, src.y + 1, src.z)); return new MovementAscend(context.getBaritone(), src, new BetterBlockPos(src.x - 1, src.y + 1, src.z));
} }
@Override @Override
@ -151,13 +150,13 @@ public enum Moves {
DESCEND_EAST(+1, -1, 0, false, true) { DESCEND_EAST(+1, -1, 0, false, true) {
@Override @Override
public Movement apply0(IBaritone baritone, BetterBlockPos src) { public Movement apply0(CalculationContext context, BetterBlockPos src) {
MutableMoveResult res = new MutableMoveResult(); MutableMoveResult res = new MutableMoveResult();
apply(new CalculationContext(baritone), src.x, src.y, src.z, res); apply(context, src.x, src.y, src.z, res);
if (res.y == src.y - 1) { if (res.y == src.y - 1) {
return new MovementDescend(baritone, src, new BetterBlockPos(res.x, res.y, res.z)); return new MovementDescend(context.getBaritone(), src, new BetterBlockPos(res.x, res.y, res.z));
} else { } else {
return new MovementFall(baritone, src, new BetterBlockPos(res.x, res.y, res.z)); return new MovementFall(context.getBaritone(), src, new BetterBlockPos(res.x, res.y, res.z));
} }
} }
@ -169,13 +168,13 @@ public enum Moves {
DESCEND_WEST(-1, -1, 0, false, true) { DESCEND_WEST(-1, -1, 0, false, true) {
@Override @Override
public Movement apply0(IBaritone baritone, BetterBlockPos src) { public Movement apply0(CalculationContext context, BetterBlockPos src) {
MutableMoveResult res = new MutableMoveResult(); MutableMoveResult res = new MutableMoveResult();
apply(new CalculationContext(baritone), src.x, src.y, src.z, res); apply(context, src.x, src.y, src.z, res);
if (res.y == src.y - 1) { if (res.y == src.y - 1) {
return new MovementDescend(baritone, src, new BetterBlockPos(res.x, res.y, res.z)); return new MovementDescend(context.getBaritone(), src, new BetterBlockPos(res.x, res.y, res.z));
} else { } else {
return new MovementFall(baritone, src, new BetterBlockPos(res.x, res.y, res.z)); return new MovementFall(context.getBaritone(), src, new BetterBlockPos(res.x, res.y, res.z));
} }
} }
@ -187,13 +186,13 @@ public enum Moves {
DESCEND_NORTH(0, -1, -1, false, true) { DESCEND_NORTH(0, -1, -1, false, true) {
@Override @Override
public Movement apply0(IBaritone baritone, BetterBlockPos src) { public Movement apply0(CalculationContext context, BetterBlockPos src) {
MutableMoveResult res = new MutableMoveResult(); MutableMoveResult res = new MutableMoveResult();
apply(new CalculationContext(baritone), src.x, src.y, src.z, res); apply(context, src.x, src.y, src.z, res);
if (res.y == src.y - 1) { if (res.y == src.y - 1) {
return new MovementDescend(baritone, src, new BetterBlockPos(res.x, res.y, res.z)); return new MovementDescend(context.getBaritone(), src, new BetterBlockPos(res.x, res.y, res.z));
} else { } else {
return new MovementFall(baritone, src, new BetterBlockPos(res.x, res.y, res.z)); return new MovementFall(context.getBaritone(), src, new BetterBlockPos(res.x, res.y, res.z));
} }
} }
@ -205,13 +204,13 @@ public enum Moves {
DESCEND_SOUTH(0, -1, +1, false, true) { DESCEND_SOUTH(0, -1, +1, false, true) {
@Override @Override
public Movement apply0(IBaritone baritone, BetterBlockPos src) { public Movement apply0(CalculationContext context, BetterBlockPos src) {
MutableMoveResult res = new MutableMoveResult(); MutableMoveResult res = new MutableMoveResult();
apply(new CalculationContext(baritone), src.x, src.y, src.z, res); apply(context, src.x, src.y, src.z, res);
if (res.y == src.y - 1) { if (res.y == src.y - 1) {
return new MovementDescend(baritone, src, new BetterBlockPos(res.x, res.y, res.z)); return new MovementDescend(context.getBaritone(), src, new BetterBlockPos(res.x, res.y, res.z));
} else { } else {
return new MovementFall(baritone, src, new BetterBlockPos(res.x, res.y, res.z)); return new MovementFall(context.getBaritone(), src, new BetterBlockPos(res.x, res.y, res.z));
} }
} }
@ -223,8 +222,8 @@ public enum Moves {
DIAGONAL_NORTHEAST(+1, 0, -1) { DIAGONAL_NORTHEAST(+1, 0, -1) {
@Override @Override
public Movement apply0(IBaritone baritone, BetterBlockPos src) { public Movement apply0(CalculationContext context, BetterBlockPos src) {
return new MovementDiagonal(baritone, src, EnumFacing.NORTH, EnumFacing.EAST); return new MovementDiagonal(context.getBaritone(), src, EnumFacing.NORTH, EnumFacing.EAST);
} }
@Override @Override
@ -235,8 +234,8 @@ public enum Moves {
DIAGONAL_NORTHWEST(-1, 0, -1) { DIAGONAL_NORTHWEST(-1, 0, -1) {
@Override @Override
public Movement apply0(IBaritone baritone, BetterBlockPos src) { public Movement apply0(CalculationContext context, BetterBlockPos src) {
return new MovementDiagonal(baritone, src, EnumFacing.NORTH, EnumFacing.WEST); return new MovementDiagonal(context.getBaritone(), src, EnumFacing.NORTH, EnumFacing.WEST);
} }
@Override @Override
@ -247,8 +246,8 @@ public enum Moves {
DIAGONAL_SOUTHEAST(+1, 0, +1) { DIAGONAL_SOUTHEAST(+1, 0, +1) {
@Override @Override
public Movement apply0(IBaritone baritone, BetterBlockPos src) { public Movement apply0(CalculationContext context, BetterBlockPos src) {
return new MovementDiagonal(baritone, src, EnumFacing.SOUTH, EnumFacing.EAST); return new MovementDiagonal(context.getBaritone(), src, EnumFacing.SOUTH, EnumFacing.EAST);
} }
@Override @Override
@ -259,8 +258,8 @@ public enum Moves {
DIAGONAL_SOUTHWEST(-1, 0, +1) { DIAGONAL_SOUTHWEST(-1, 0, +1) {
@Override @Override
public Movement apply0(IBaritone baritone, BetterBlockPos src) { public Movement apply0(CalculationContext context, BetterBlockPos src) {
return new MovementDiagonal(baritone, src, EnumFacing.SOUTH, EnumFacing.WEST); return new MovementDiagonal(context.getBaritone(), src, EnumFacing.SOUTH, EnumFacing.WEST);
} }
@Override @Override
@ -271,8 +270,8 @@ public enum Moves {
PARKOUR_NORTH(0, 0, -4, true, false) { PARKOUR_NORTH(0, 0, -4, true, false) {
@Override @Override
public Movement apply0(IBaritone baritone, BetterBlockPos src) { public Movement apply0(CalculationContext context, BetterBlockPos src) {
return MovementParkour.cost(baritone, src, EnumFacing.NORTH); return MovementParkour.cost(context, src, EnumFacing.NORTH);
} }
@Override @Override
@ -283,8 +282,8 @@ public enum Moves {
PARKOUR_SOUTH(0, 0, +4, true, false) { PARKOUR_SOUTH(0, 0, +4, true, false) {
@Override @Override
public Movement apply0(IBaritone baritone, BetterBlockPos src) { public Movement apply0(CalculationContext context, BetterBlockPos src) {
return MovementParkour.cost(baritone, src, EnumFacing.SOUTH); return MovementParkour.cost(context, src, EnumFacing.SOUTH);
} }
@Override @Override
@ -295,8 +294,8 @@ public enum Moves {
PARKOUR_EAST(+4, 0, 0, true, false) { PARKOUR_EAST(+4, 0, 0, true, false) {
@Override @Override
public Movement apply0(IBaritone baritone, BetterBlockPos src) { public Movement apply0(CalculationContext context, BetterBlockPos src) {
return MovementParkour.cost(baritone, src, EnumFacing.EAST); return MovementParkour.cost(context, src, EnumFacing.EAST);
} }
@Override @Override
@ -307,8 +306,8 @@ public enum Moves {
PARKOUR_WEST(-4, 0, 0, true, false) { PARKOUR_WEST(-4, 0, 0, true, false) {
@Override @Override
public Movement apply0(IBaritone baritone, BetterBlockPos src) { public Movement apply0(CalculationContext context, BetterBlockPos src) {
return MovementParkour.cost(baritone, src, EnumFacing.WEST); return MovementParkour.cost(context, src, EnumFacing.WEST);
} }
@Override @Override
@ -336,7 +335,7 @@ public enum Moves {
this(x, y, z, false, false); this(x, y, z, false, false);
} }
public abstract Movement apply0(IBaritone baritone, BetterBlockPos src); public abstract Movement apply0(CalculationContext context, BetterBlockPos src);
public void apply(CalculationContext context, int x, int y, int z, MutableMoveResult result) { public void apply(CalculationContext context, int x, int y, int z, MutableMoveResult result) {
if (dynamicXZ || dynamicY) { if (dynamicXZ || dynamicY) {

View File

@ -211,6 +211,10 @@ public class MovementAscend extends Movement {
return state; return state;
} }
if (ctx.playerFeet().equals(src.up())) {
return state; // no need to hit space if we're already jumping
}
if (headBonkClear()) { if (headBonkClear()) {
return state.setInput(Input.JUMP, true); return state.setInput(Input.JUMP, true);
} }

View File

@ -33,6 +33,7 @@ import baritone.utils.BlockStateInterface;
import baritone.utils.Helper; import baritone.utils.Helper;
import baritone.utils.pathing.MutableMoveResult; import baritone.utils.pathing.MutableMoveResult;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockStairs;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks; import net.minecraft.init.Blocks;
import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumFacing;
@ -56,11 +57,11 @@ public class MovementParkour extends Movement {
this.dist = dist; this.dist = dist;
} }
public static MovementParkour cost(IBaritone baritone, BetterBlockPos src, EnumFacing direction) { public static MovementParkour cost(CalculationContext context, BetterBlockPos src, EnumFacing direction) {
MutableMoveResult res = new MutableMoveResult(); MutableMoveResult res = new MutableMoveResult();
cost(new CalculationContext(baritone), src.x, src.y, src.z, direction, res); cost(context, src.x, src.y, src.z, direction, res);
int dist = Math.abs(res.x - src.x) + Math.abs(res.z - src.z); int dist = Math.abs(res.x - src.x) + Math.abs(res.z - src.z);
return new MovementParkour(baritone, src, dist, direction); return new MovementParkour(context.getBaritone(), src, dist, direction);
} }
public static void cost(CalculationContext context, int x, int y, int z, EnumFacing dir, MutableMoveResult res) { public static void cost(CalculationContext context, int x, int y, int z, EnumFacing dir, MutableMoveResult res) {
@ -68,7 +69,7 @@ public class MovementParkour extends Movement {
return; return;
} }
IBlockState standingOn = context.get(x, y - 1, z); IBlockState standingOn = context.get(x, y - 1, z);
if (standingOn.getBlock() == Blocks.VINE || standingOn.getBlock() == Blocks.LADDER || MovementHelper.isBottomSlab(standingOn)) { if (standingOn.getBlock() == Blocks.VINE || standingOn.getBlock() == Blocks.LADDER || standingOn.getBlock() instanceof BlockStairs || MovementHelper.isBottomSlab(standingOn)) {
return; return;
} }
int xDiff = dir.getXOffset(); int xDiff = dir.getXOffset();

View File

@ -458,7 +458,7 @@ public class PathExecutor implements IPathExecutor, Helper {
if (next == null) { if (next == null) {
return cutIfTooLong(); return cutIfTooLong();
} }
return SplicedPath.trySplice(path, next.path).map(path -> { return SplicedPath.trySplice(path, next.path, false).map(path -> {
if (!path.getDest().equals(next.getPath().getDest())) { if (!path.getDest().equals(next.getPath().getDest())) {
throw new IllegalStateException(); throw new IllegalStateException();
} }

View File

@ -62,7 +62,7 @@ public class SplicedPath extends PathBase {
return numNodes; return numNodes;
} }
public static Optional<SplicedPath> trySplice(IPath first, IPath second) { public static Optional<SplicedPath> trySplice(IPath first, IPath second, boolean allowOverlapCutoff) {
if (second == null || first == null) { if (second == null || first == null) {
return Optional.empty(); return Optional.empty();
} }
@ -72,18 +72,31 @@ public class SplicedPath extends PathBase {
if (!first.getDest().equals(second.getSrc())) { if (!first.getDest().equals(second.getSrc())) {
return Optional.empty(); return Optional.empty();
} }
HashSet<BetterBlockPos> a = new HashSet<>(first.positions()); HashSet<BetterBlockPos> secondPos = new HashSet<>(second.positions());
for (int i = 1; i < second.length(); i++) { int firstPositionInSecond = -1;
if (a.contains(second.positions().get(i))) { for (int i = 0; i < first.length() - 1; i++) { // overlap in the very last element is fine (and required) so only go up to first.length() - 1
if (secondPos.contains(first.positions().get(i))) {
firstPositionInSecond = i;
}
}
if (firstPositionInSecond != -1) {
if (!allowOverlapCutoff) {
return Optional.empty(); return Optional.empty();
} }
} else {
firstPositionInSecond = first.length() - 1;
}
int positionInSecond = second.positions().indexOf(first.positions().get(firstPositionInSecond));
if (!allowOverlapCutoff && positionInSecond != 0) {
throw new IllegalStateException();
} }
List<BetterBlockPos> positions = new ArrayList<>(); List<BetterBlockPos> positions = new ArrayList<>();
List<IMovement> movements = new ArrayList<>(); List<IMovement> movements = new ArrayList<>();
positions.addAll(first.positions()); positions.addAll(first.positions().subList(0, firstPositionInSecond + 1));
positions.addAll(second.positions().subList(1, second.length())); movements.addAll(first.movements().subList(0, firstPositionInSecond));
movements.addAll(first.movements());
movements.addAll(second.movements()); positions.addAll(second.positions().subList(positionInSecond + 1, second.length()));
movements.addAll(second.movements().subList(positionInSecond, second.length() - 1));
return Optional.of(new SplicedPath(positions, movements, first.getNumNodesConsidered() + second.getNumNodesConsidered(), first.getGoal())); return Optional.of(new SplicedPath(positions, movements, first.getNumNodesConsidered() + second.getNumNodesConsidered(), first.getGoal()));
} }
} }

View File

@ -24,6 +24,7 @@ import baritone.api.pathing.goals.GoalGetToBlock;
import baritone.api.process.IGetToBlockProcess; import baritone.api.process.IGetToBlockProcess;
import baritone.api.process.PathingCommand; import baritone.api.process.PathingCommand;
import baritone.api.process.PathingCommandType; import baritone.api.process.PathingCommandType;
import baritone.pathing.movement.CalculationContext;
import baritone.utils.BaritoneProcessHelper; import baritone.utils.BaritoneProcessHelper;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
@ -46,7 +47,7 @@ public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBl
public void getToBlock(Block block) { public void getToBlock(Block block) {
gettingTo = block; gettingTo = block;
knownLocations = null; knownLocations = null;
rescan(new ArrayList<>()); rescan(new ArrayList<>(), new CalculationContext(baritone));
} }
@Override @Override
@ -57,7 +58,7 @@ public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBl
@Override @Override
public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) {
if (knownLocations == null) { if (knownLocations == null) {
rescan(new ArrayList<>()); rescan(new ArrayList<>(), new CalculationContext(baritone));
} }
if (knownLocations.isEmpty()) { if (knownLocations.isEmpty()) {
logDirect("No known locations of " + gettingTo + ", canceling GetToBlock"); logDirect("No known locations of " + gettingTo + ", canceling GetToBlock");
@ -76,7 +77,8 @@ public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBl
int mineGoalUpdateInterval = Baritone.settings().mineGoalUpdateInterval.get(); int mineGoalUpdateInterval = Baritone.settings().mineGoalUpdateInterval.get();
if (mineGoalUpdateInterval != 0 && tickCount++ % mineGoalUpdateInterval == 0) { // big brain if (mineGoalUpdateInterval != 0 && tickCount++ % mineGoalUpdateInterval == 0) { // big brain
List<BlockPos> current = new ArrayList<>(knownLocations); List<BlockPos> current = new ArrayList<>(knownLocations);
Baritone.getExecutor().execute(() -> rescan(current)); CalculationContext context = new CalculationContext(baritone);
Baritone.getExecutor().execute(() -> rescan(current, context));
} }
Goal goal = new GoalComposite(knownLocations.stream().map(GoalGetToBlock::new).toArray(Goal[]::new)); Goal goal = new GoalComposite(knownLocations.stream().map(GoalGetToBlock::new).toArray(Goal[]::new));
if (goal.isInGoal(ctx.playerFeet())) { if (goal.isInGoal(ctx.playerFeet())) {
@ -96,7 +98,7 @@ public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBl
return "Get To Block " + gettingTo; return "Get To Block " + gettingTo;
} }
private void rescan(List<BlockPos> known) { private void rescan(List<BlockPos> known, CalculationContext context) {
knownLocations = MineProcess.searchWorld(ctx, Collections.singletonList(gettingTo), 64, known); knownLocations = MineProcess.searchWorld(context, Collections.singletonList(gettingTo), 64, known);
} }
} }

View File

@ -27,6 +27,7 @@ import baritone.api.utils.RotationUtils;
import baritone.cache.CachedChunk; import baritone.cache.CachedChunk;
import baritone.cache.ChunkPacker; import baritone.cache.ChunkPacker;
import baritone.cache.WorldScanner; import baritone.cache.WorldScanner;
import baritone.pathing.movement.CalculationContext;
import baritone.pathing.movement.MovementHelper; import baritone.pathing.movement.MovementHelper;
import baritone.utils.BaritoneProcessHelper; import baritone.utils.BaritoneProcessHelper;
import baritone.utils.BlockStateInterface; import baritone.utils.BlockStateInterface;
@ -88,7 +89,8 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
int mineGoalUpdateInterval = Baritone.settings().mineGoalUpdateInterval.get(); int mineGoalUpdateInterval = Baritone.settings().mineGoalUpdateInterval.get();
if (mineGoalUpdateInterval != 0 && tickCount++ % mineGoalUpdateInterval == 0) { // big brain if (mineGoalUpdateInterval != 0 && tickCount++ % mineGoalUpdateInterval == 0) { // big brain
List<BlockPos> curr = new ArrayList<>(knownOreLocations); List<BlockPos> curr = new ArrayList<>(knownOreLocations);
Baritone.getExecutor().execute(() -> rescan(curr)); CalculationContext context = new CalculationContext(baritone);
Baritone.getExecutor().execute(() -> rescan(curr, context));
} }
if (Baritone.settings().legitMine.get()) { if (Baritone.settings().legitMine.get()) {
addNearby(); addNearby();
@ -116,7 +118,7 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
private Goal updateGoal() { private Goal updateGoal() {
List<BlockPos> locs = knownOreLocations; List<BlockPos> locs = knownOreLocations;
if (!locs.isEmpty()) { if (!locs.isEmpty()) {
List<BlockPos> locs2 = prune(ctx, new ArrayList<>(locs), mining, ORE_LOCATIONS_COUNT); List<BlockPos> locs2 = prune(new CalculationContext(baritone), new ArrayList<>(locs), mining, ORE_LOCATIONS_COUNT);
// can't reassign locs, gotta make a new var locs2, because we use it in a lambda right here, and variables you use in a lambda must be effectively final // can't reassign locs, gotta make a new var locs2, because we use it in a lambda right here, and variables you use in a lambda must be effectively final
Goal goal = new GoalComposite(locs2.stream().map(loc -> coalesce(ctx, loc, locs2)).toArray(Goal[]::new)); Goal goal = new GoalComposite(locs2.stream().map(loc -> coalesce(ctx, loc, locs2)).toArray(Goal[]::new));
knownOreLocations = locs2; knownOreLocations = locs2;
@ -151,14 +153,14 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
return branchPointRunaway; return branchPointRunaway;
} }
private void rescan(List<BlockPos> already) { private void rescan(List<BlockPos> already, CalculationContext context) {
if (mining == null) { if (mining == null) {
return; return;
} }
if (Baritone.settings().legitMine.get()) { if (Baritone.settings().legitMine.get()) {
return; return;
} }
List<BlockPos> locs = searchWorld(ctx, mining, ORE_LOCATIONS_COUNT, already); List<BlockPos> locs = searchWorld(context, mining, ORE_LOCATIONS_COUNT, already);
locs.addAll(droppedItemsScan(mining, ctx.world())); locs.addAll(droppedItemsScan(mining, ctx.world()));
if (locs.isEmpty()) { if (locs.isEmpty()) {
logDebug("No locations for " + mining + " known, cancelling"); logDebug("No locations for " + mining + " known, cancelling");
@ -205,13 +207,14 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
/*public static List<BlockPos> searchWorld(List<Block> mining, int max, World world) { /*public static List<BlockPos> searchWorld(List<Block> mining, int max, World world) {
}*/ }*/
public static List<BlockPos> searchWorld(IPlayerContext ctx, List<Block> mining, int max, List<BlockPos> alreadyKnown) { public static List<BlockPos> searchWorld(CalculationContext ctx, List<Block> mining, int max, List<BlockPos> alreadyKnown) {
IPlayerContext ipc;
List<BlockPos> locs = new ArrayList<>(); List<BlockPos> locs = new ArrayList<>();
List<Block> uninteresting = new ArrayList<>(); List<Block> uninteresting = new ArrayList<>();
//long b = System.currentTimeMillis(); //long b = System.currentTimeMillis();
for (Block m : mining) { for (Block m : mining) {
if (CachedChunk.BLOCKS_TO_KEEP_TRACK_OF.contains(m)) { if (CachedChunk.BLOCKS_TO_KEEP_TRACK_OF.contains(m)) {
locs.addAll(ctx.worldData().getCachedWorld().getLocationsOf(ChunkPacker.blockToString(m), 1, ctx.playerFeet().getX(), ctx.playerFeet().getZ(), 1)); locs.addAll(ctx.worldData().getCachedWorld().getLocationsOf(ChunkPacker.blockToString(m), 1, ctx.getBaritone().getPlayerContext().playerFeet().getX(), ctx.getBaritone().getPlayerContext().playerFeet().getZ(), 1));
} else { } else {
uninteresting.add(m); uninteresting.add(m);
} }
@ -222,7 +225,7 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
} }
if (!uninteresting.isEmpty()) { if (!uninteresting.isEmpty()) {
//long before = System.currentTimeMillis(); //long before = System.currentTimeMillis();
locs.addAll(WorldScanner.INSTANCE.scanChunkRadius(ctx, uninteresting, max, 10, 26)); locs.addAll(WorldScanner.INSTANCE.scanChunkRadius(ctx.getBaritone().getPlayerContext(), uninteresting, max, 10, 26));
//System.out.println("Scan of loaded chunks took " + (System.currentTimeMillis() - before) + "ms"); //System.out.println("Scan of loaded chunks took " + (System.currentTimeMillis() - before) + "ms");
} }
locs.addAll(alreadyKnown); locs.addAll(alreadyKnown);
@ -246,22 +249,22 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
} }
} }
} }
knownOreLocations = prune(ctx, knownOreLocations, mining, ORE_LOCATIONS_COUNT); knownOreLocations = prune(new CalculationContext(baritone), knownOreLocations, mining, ORE_LOCATIONS_COUNT);
} }
public static List<BlockPos> prune(IPlayerContext ctx, List<BlockPos> locs2, List<Block> mining, int max) { public static List<BlockPos> prune(CalculationContext ctx, List<BlockPos> locs2, List<Block> mining, int max) {
List<BlockPos> dropped = droppedItemsScan(mining, ctx.world()); List<BlockPos> dropped = droppedItemsScan(mining, ctx.world());
List<BlockPos> locs = locs2 List<BlockPos> locs = locs2
.stream() .stream()
.distinct() .distinct()
// remove any that are within loaded chunks that aren't actually what we want // remove any that are within loaded chunks that aren't actually what we want
.filter(pos -> ctx.world().getChunk(pos) instanceof EmptyChunk || mining.contains(BlockStateInterface.getBlock(ctx, pos)) || dropped.contains(pos)) .filter(pos -> ctx.world().getChunk(pos) instanceof EmptyChunk || mining.contains(ctx.getBlock(pos.getX(), pos.getY(), pos.getZ())) || dropped.contains(pos))
// remove any that are implausible to mine (encased in bedrock, or touching lava) // remove any that are implausible to mine (encased in bedrock, or touching lava)
.filter(pos -> MineProcess.plausibleToBreak(ctx, pos)) .filter(pos -> MineProcess.plausibleToBreak(ctx.bsi(), pos))
.sorted(Comparator.comparingDouble(ctx.playerFeet()::distanceSq)) .sorted(Comparator.comparingDouble(ctx.getBaritone().getPlayerContext().playerFeet()::distanceSq))
.collect(Collectors.toList()); .collect(Collectors.toList());
if (locs.size() > max) { if (locs.size() > max) {
@ -270,12 +273,13 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
return locs; return locs;
} }
public static boolean plausibleToBreak(IPlayerContext ctx, BlockPos pos) { public static boolean plausibleToBreak(BlockStateInterface bsi, BlockPos pos) {
if (MovementHelper.avoidBreaking(new BlockStateInterface(ctx), pos.getX(), pos.getY(), pos.getZ(), BlockStateInterface.get(ctx, pos))) { if (MovementHelper.avoidBreaking(bsi, pos.getX(), pos.getY(), pos.getZ(), bsi.get0(pos))) {
return false; return false;
} }
// bedrock above and below makes it implausible, otherwise we're good // bedrock above and below makes it implausible, otherwise we're good
return !(BlockStateInterface.getBlock(ctx, pos.up()) == Blocks.BEDROCK && BlockStateInterface.getBlock(ctx, pos.down()) == Blocks.BEDROCK); return !(bsi.get0(pos.up()).getBlock() == Blocks.BEDROCK && bsi.get0(pos.down()).getBlock() == Blocks.BEDROCK);
} }
@Override @Override
@ -290,6 +294,8 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
this.knownOreLocations = new ArrayList<>(); this.knownOreLocations = new ArrayList<>();
this.branchPoint = null; this.branchPoint = null;
this.branchPointRunaway = null; this.branchPointRunaway = null;
rescan(new ArrayList<>()); if (mining != null) {
rescan(new ArrayList<>(), new CalculationContext(baritone));
}
} }
} }

View File

@ -21,10 +21,14 @@ import baritone.Baritone;
import baritone.api.utils.IPlayerContext; import baritone.api.utils.IPlayerContext;
import baritone.cache.CachedRegion; import baritone.cache.CachedRegion;
import baritone.cache.WorldData; import baritone.cache.WorldData;
import baritone.utils.accessor.IChunkProviderClient;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.init.Blocks; import net.minecraft.init.Blocks;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.Chunk;
@ -35,7 +39,7 @@ import net.minecraft.world.chunk.Chunk;
*/ */
public class BlockStateInterface { public class BlockStateInterface {
private final World world; private final Long2ObjectMap<Chunk> loadedChunks;
private final WorldData worldData; private final WorldData worldData;
private Chunk prev = null; private Chunk prev = null;
@ -49,11 +53,14 @@ public class BlockStateInterface {
public BlockStateInterface(World world, WorldData worldData) { public BlockStateInterface(World world, WorldData worldData) {
this.worldData = worldData; this.worldData = worldData;
this.world = world; this.loadedChunks = ((IChunkProviderClient) world.getChunkProvider()).loadedChunks();
if (!Minecraft.getMinecraft().isCallingFromMinecraftThread()) {
throw new IllegalStateException();
}
} }
public World getWorld() { public boolean worldContainsLoadedChunk(int blockX, int blockZ) {
return world; return loadedChunks.containsKey(ChunkPos.asLong(blockX >> 4, blockZ >> 4));
} }
public static Block getBlock(IPlayerContext ctx, BlockPos pos) { // won't be called from the pathing thread because the pathing thread doesn't make a single blockpos pog public static Block getBlock(IPlayerContext ctx, BlockPos pos) { // won't be called from the pathing thread because the pathing thread doesn't make a single blockpos pog
@ -66,6 +73,10 @@ public class BlockStateInterface {
// and toBreak and stuff fails when the movement is instantiated out of load range but it's not able to BlockStateInterface.get what it's going to walk on // and toBreak and stuff fails when the movement is instantiated out of load range but it's not able to BlockStateInterface.get what it's going to walk on
} }
public IBlockState get0(BlockPos pos) {
return get0(pos.getX(), pos.getY(), pos.getZ());
}
public IBlockState get0(int x, int y, int z) { // Mickey resigned public IBlockState get0(int x, int y, int z) { // Mickey resigned
// Invalid vertical position // Invalid vertical position
@ -84,8 +95,9 @@ public class BlockStateInterface {
if (cached != null && cached.x == x >> 4 && cached.z == z >> 4) { if (cached != null && cached.x == x >> 4 && cached.z == z >> 4) {
return cached.getBlockState(x, y, z); return cached.getBlockState(x, y, z);
} }
Chunk chunk = world.getChunk(x >> 4, z >> 4); Chunk chunk = loadedChunks.get(ChunkPos.asLong(x >> 4, z >> 4));
if (chunk.isLoaded()) {
if (chunk != null && chunk.isLoaded()) {
prev = chunk; prev = chunk;
return chunk.getBlockState(x, y, z); return chunk.getBlockState(x, y, z);
} }
@ -116,8 +128,8 @@ public class BlockStateInterface {
if (prevChunk != null && prevChunk.x == x >> 4 && prevChunk.z == z >> 4) { if (prevChunk != null && prevChunk.x == x >> 4 && prevChunk.z == z >> 4) {
return true; return true;
} }
prevChunk = world.getChunk(x >> 4, z >> 4); prevChunk = loadedChunks.get(ChunkPos.asLong(x >> 4, z >> 4));
if (prevChunk.isLoaded()) { if (prevChunk != null && prevChunk.isLoaded()) {
prev = prevChunk; prev = prevChunk;
return true; return true;
} }

View File

@ -28,6 +28,7 @@ import baritone.behavior.Behavior;
import baritone.behavior.PathingBehavior; import baritone.behavior.PathingBehavior;
import baritone.cache.ChunkPacker; import baritone.cache.ChunkPacker;
import baritone.cache.Waypoint; import baritone.cache.Waypoint;
import baritone.pathing.movement.CalculationContext;
import baritone.pathing.movement.Movement; import baritone.pathing.movement.Movement;
import baritone.pathing.movement.Moves; import baritone.pathing.movement.Moves;
import baritone.process.CustomGoalProcess; import baritone.process.CustomGoalProcess;
@ -446,7 +447,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
return true; return true;
} }
if (msg.equals("costs")) { if (msg.equals("costs")) {
List<Movement> moves = Stream.of(Moves.values()).map(x -> x.apply0(baritone, ctx.playerFeet())).collect(Collectors.toCollection(ArrayList::new)); List<Movement> moves = Stream.of(Moves.values()).map(x -> x.apply0(new CalculationContext(baritone), ctx.playerFeet())).collect(Collectors.toCollection(ArrayList::new));
while (moves.contains(null)) { while (moves.contains(null)) {
moves.remove(null); moves.remove(null);
} }

View File

@ -0,0 +1,25 @@
/*
* 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.accessor;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import net.minecraft.world.chunk.Chunk;
public interface IChunkProviderClient {
Long2ObjectMap<Chunk> loadedChunks();
}