start on legitMine

This commit is contained in:
leijurv 2018-10-25 21:21:42 -07:00 committed by Leijurv
parent a0b1cb2993
commit 55091154c4
No known key found for this signature in database
GPG Key ID: 44A3EA646EADAC6A
3 changed files with 93 additions and 20 deletions

View File

@ -24,8 +24,8 @@ import net.minecraft.util.text.ITextComponent;
import java.awt.*; import java.awt.*;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.*;
import java.util.List; import java.util.List;
import java.util.*;
import java.util.function.Consumer; import java.util.function.Consumer;
/** /**
@ -396,6 +396,18 @@ public class Settings {
*/ */
public Setting<Integer> axisHeight = new Setting<>(120); public Setting<Integer> axisHeight = new Setting<>(120);
/**
* Allow MineBehavior to use X-Ray to see where the ores are. Turn this option off to force it to mine "legit"
* where it will only mine an ore once it can actually see it, so it won't do or know anything that a normal player
* couldn't. If you don't want it to look like you're X-Raying, turn this off
*/
public Setting<Boolean> legitMine = new Setting<>(false);
/**
* What Y level to go to for legit strip mining
*/
public Setting<Integer> legitMineYLevel = new Setting<>(11);
/** /**
* When mining block of a certain type, try to mine two at once instead of one. * When mining block of a certain type, try to mine two at once instead of one.
* If the block above is also a goal block, set GoalBlock instead of GoalTwoBlocks * If the block above is also a goal block, set GoalBlock instead of GoalTwoBlocks

View File

@ -20,14 +20,13 @@ package baritone.behavior;
import baritone.Baritone; import baritone.Baritone;
import baritone.api.behavior.IMineBehavior; import baritone.api.behavior.IMineBehavior;
import baritone.api.event.events.TickEvent; import baritone.api.event.events.TickEvent;
import baritone.api.pathing.goals.Goal; import baritone.api.pathing.goals.*;
import baritone.api.pathing.goals.GoalBlock; import baritone.api.utils.RotationUtils;
import baritone.api.pathing.goals.GoalComposite;
import baritone.api.pathing.goals.GoalTwoBlocks;
import baritone.cache.CachedChunk; import baritone.cache.CachedChunk;
import baritone.cache.ChunkPacker; import baritone.cache.ChunkPacker;
import baritone.cache.WorldProvider; import baritone.cache.WorldProvider;
import baritone.cache.WorldScanner; import baritone.cache.WorldScanner;
import baritone.pathing.movement.MovementHelper;
import baritone.utils.BlockStateInterface; import baritone.utils.BlockStateInterface;
import baritone.utils.Helper; import baritone.utils.Helper;
import net.minecraft.block.Block; import net.minecraft.block.Block;
@ -51,6 +50,7 @@ public final class MineBehavior extends Behavior implements IMineBehavior, Helpe
private List<Block> mining; private List<Block> mining;
private List<BlockPos> knownOreLocations; private List<BlockPos> knownOreLocations;
private BlockPos branchPoint;
private int desiredQuantity; private int desiredQuantity;
private MineBehavior() {} private MineBehavior() {}
@ -80,6 +80,9 @@ public final class MineBehavior extends Behavior implements IMineBehavior, Helpe
Baritone.INSTANCE.getExecutor().execute(this::rescan); Baritone.INSTANCE.getExecutor().execute(this::rescan);
} }
} }
if (Baritone.settings().legitMine.get()) {
addNearby();
}
updateGoal(); updateGoal();
PathingBehavior.INSTANCE.revalidateGoal(); PathingBehavior.INSTANCE.revalidateGoal();
} }
@ -90,17 +93,42 @@ public final class MineBehavior extends Behavior implements IMineBehavior, Helpe
} }
List<BlockPos> locs = knownOreLocations; List<BlockPos> locs = knownOreLocations;
if (!locs.isEmpty()) { if (!locs.isEmpty()) {
locs = prune(new ArrayList<>(locs), mining, 64); List<BlockPos> locs2 = prune(new ArrayList<>(locs), mining, 64);
PathingBehavior.INSTANCE.setGoal(coalesce(locs)); // 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
PathingBehavior.INSTANCE.path(); PathingBehavior.INSTANCE.setGoalAndPath(new GoalComposite(locs2.stream().map(loc -> coalesce(loc, locs2)).toArray(Goal[]::new)));
knownOreLocations = locs; knownOreLocations = locs;
return;
} }
// we don't know any ore locations at the moment
if (!Baritone.settings().legitMine.get()) {
return;
}
// only in non-Xray mode (aka legit mode) do we do this
if (branchPoint == null) {
int y = Baritone.settings().legitMineYLevel.get();
if (!PathingBehavior.INSTANCE.isPathing() && playerFeet().y == y) {
// cool, path is over and we are at desired y
branchPoint = playerFeet();
} else {
PathingBehavior.INSTANCE.setGoalAndPath(new GoalYLevel(y));
return;
}
}
if (playerFeet().equals(branchPoint)) {
// TODO mine 1x1 shafts to either side
branchPoint = branchPoint.north(10);
}
PathingBehavior.INSTANCE.setGoalAndPath(new GoalBlock(branchPoint));
} }
private void rescan() { private void rescan() {
if (mining == null) { if (mining == null) {
return; return;
} }
if (Baritone.settings().legitMine.get()) {
return;
}
List<BlockPos> locs = xrayFor(mining, 64); List<BlockPos> locs = xrayFor(mining, 64);
if (locs.isEmpty()) { if (locs.isEmpty()) {
logDebug("No locations for " + mining + " known, cancelling"); logDebug("No locations for " + mining + " known, cancelling");
@ -132,10 +160,6 @@ public final class MineBehavior extends Behavior implements IMineBehavior, Helpe
} }
} }
public GoalComposite coalesce(List<BlockPos> locs) {
return new GoalComposite(locs.stream().map(loc -> coalesce(loc, locs)).toArray(Goal[]::new));
}
public List<BlockPos> xrayFor(List<Block> mining, int max) { public List<BlockPos> xrayFor(List<Block> mining, int max) {
List<BlockPos> locs = new ArrayList<>(); List<BlockPos> locs = new ArrayList<>();
List<Block> uninteresting = new ArrayList<>(); List<Block> uninteresting = new ArrayList<>();
@ -159,26 +183,57 @@ public final class MineBehavior extends Behavior implements IMineBehavior, Helpe
return prune(locs, mining, max); return prune(locs, mining, max);
} }
public List<BlockPos> prune(List<BlockPos> locs, List<Block> mining, int max) { public void addNearby() {
BlockPos playerFeet = MineBehavior.INSTANCE.playerFeet(); BlockPos playerFeet = playerFeet();
locs.sort(Comparator.comparingDouble(playerFeet::distanceSq)); int searchDist = 4;//why four? idk
for (int x = playerFeet.getX() - searchDist; x <= playerFeet.getX() + searchDist; x++) {
for (int y = playerFeet.getY() - searchDist; y <= playerFeet.getY() + searchDist; y++) {
for (int z = playerFeet.getZ() - searchDist; z <= playerFeet.getZ() + searchDist; z++) {
BlockPos pos = new BlockPos(x, y, z);
if (mining.contains(BlockStateInterface.getBlock(pos))) {
if (RotationUtils.reachable(player(), pos).isPresent()) {//crucial to only add blocks we can see because otherwise this is an x-ray and it'll get caught
knownOreLocations.add(pos);
}
}
}
}
}
knownOreLocations = prune(knownOreLocations, mining, 64);
}
public static List<BlockPos> prune(List<BlockPos> locs2, List<Block> mining, int max) {
List<BlockPos> locs = locs2
.stream()
// remove any that are within loaded chunks that aren't actually what we want
.filter(pos -> MineBehavior.INSTANCE.world().getChunk(pos) instanceof EmptyChunk || mining.contains(BlockStateInterface.get(pos).getBlock()))
// remove any that are implausible to mine (encased in bedrock, or touching lava)
.filter(MineBehavior::plausibleToBreak)
.sorted(Comparator.comparingDouble(Helper.HELPER.playerFeet()::distanceSq))
.collect(Collectors.toList());
// remove any that are within loaded chunks that aren't actually what we want
locs.removeAll(locs.stream()
.filter(pos -> !(MineBehavior.INSTANCE.world().getChunk(pos) instanceof EmptyChunk))
.filter(pos -> !mining.contains(BlockStateInterface.get(pos).getBlock()))
.collect(Collectors.toList()));
if (locs.size() > max) { if (locs.size() > max) {
return locs.subList(0, max); return locs.subList(0, max);
} }
return locs; return locs;
} }
public static boolean plausibleToBreak(BlockPos pos) {
if (MovementHelper.avoidBreaking(pos.getX(), pos.getY(), pos.getZ(), BlockStateInterface.get(pos))) {
return false;
}
// bedrock above and below makes it implausible, otherwise we're good
return !(BlockStateInterface.getBlock(pos.up()) == Blocks.BEDROCK && BlockStateInterface.getBlock(pos.down()) == Blocks.BEDROCK);
}
@Override @Override
public void mine(int quantity, String... blocks) { public void mine(int quantity, String... blocks) {
this.mining = blocks == null || blocks.length == 0 ? null : Arrays.stream(blocks).map(ChunkPacker::stringToBlock).collect(Collectors.toList()); this.mining = blocks == null || blocks.length == 0 ? null : Arrays.stream(blocks).map(ChunkPacker::stringToBlock).collect(Collectors.toList());
this.desiredQuantity = quantity; this.desiredQuantity = quantity;
this.knownOreLocations = new ArrayList<>(); this.knownOreLocations = new ArrayList<>();
this.branchPoint = null;
rescan(); rescan();
updateGoal(); updateGoal();
} }
@ -188,6 +243,7 @@ public final class MineBehavior extends Behavior implements IMineBehavior, Helpe
this.mining = blocks == null || blocks.length == 0 ? null : Arrays.asList(blocks); this.mining = blocks == null || blocks.length == 0 ? null : Arrays.asList(blocks);
this.desiredQuantity = quantity; this.desiredQuantity = quantity;
this.knownOreLocations = new ArrayList<>(); this.knownOreLocations = new ArrayList<>();
this.branchPoint = null;
rescan(); rescan();
updateGoal(); updateGoal();
} }

View File

@ -201,6 +201,11 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
this.goal = goal; this.goal = goal;
} }
public boolean setGoalAndPath(Goal goal) {
setGoal(goal);
return path();
}
@Override @Override
public Goal getGoal() { public Goal getGoal() {
return goal; return goal;