make sure to pick up dropped items while mining, fixes #170
This commit is contained in:
@@ -24,8 +24,8 @@ import net.minecraft.util.text.ITextComponent;
|
||||
|
||||
import java.awt.*;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
@@ -376,6 +376,11 @@ public class Settings {
|
||||
*/
|
||||
public Setting<Integer> mineGoalUpdateInterval = new Setting<>(5);
|
||||
|
||||
/**
|
||||
* While mining, should it also consider dropped items of the correct type as a pathing destination (as well as ore blocks)?
|
||||
*/
|
||||
public Setting<Boolean> mineScanDroppedItems = new Setting<>(true);
|
||||
|
||||
/**
|
||||
* Cancel the current path if the goal has changed, and the path originally ended in the goal but doesn't anymore.
|
||||
* <p>
|
||||
|
||||
@@ -30,10 +30,13 @@ import baritone.pathing.movement.MovementHelper;
|
||||
import baritone.utils.BlockStateInterface;
|
||||
import baritone.utils.Helper;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.item.EntityItem;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.chunk.EmptyChunk;
|
||||
|
||||
import java.util.*;
|
||||
@@ -45,7 +48,7 @@ import java.util.stream.Collectors;
|
||||
* @author leijurv
|
||||
*/
|
||||
public final class MineBehavior extends Behavior implements IMineBehavior, Helper {
|
||||
|
||||
public static final int ORE_LOCATIONS_COUNT = 64;
|
||||
private List<Block> mining;
|
||||
private List<BlockPos> knownOreLocations;
|
||||
private BlockPos branchPoint;
|
||||
@@ -91,7 +94,7 @@ public final class MineBehavior extends Behavior implements IMineBehavior, Helpe
|
||||
}
|
||||
List<BlockPos> locs = knownOreLocations;
|
||||
if (!locs.isEmpty()) {
|
||||
List<BlockPos> locs2 = prune(new ArrayList<>(locs), mining, 64);
|
||||
List<BlockPos> locs2 = prune(new ArrayList<>(locs), mining, ORE_LOCATIONS_COUNT, world());
|
||||
// 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
|
||||
baritone.getPathingBehavior().setGoalAndPath(new GoalComposite(locs2.stream().map(loc -> coalesce(loc, locs2)).toArray(Goal[]::new)));
|
||||
knownOreLocations = locs2;
|
||||
@@ -127,7 +130,8 @@ public final class MineBehavior extends Behavior implements IMineBehavior, Helpe
|
||||
if (Baritone.settings().legitMine.get()) {
|
||||
return;
|
||||
}
|
||||
List<BlockPos> locs = searchWorld(mining, 64);
|
||||
List<BlockPos> locs = searchWorld(mining, ORE_LOCATIONS_COUNT, world());
|
||||
locs.addAll(droppedItemsScan(mining, world()));
|
||||
if (locs.isEmpty()) {
|
||||
logDebug("No locations for " + mining + " known, cancelling");
|
||||
mine(0, (String[]) null);
|
||||
@@ -158,7 +162,30 @@ public final class MineBehavior extends Behavior implements IMineBehavior, Helpe
|
||||
}
|
||||
}
|
||||
|
||||
public List<BlockPos> searchWorld(List<Block> mining, int max) {
|
||||
public static List<BlockPos> droppedItemsScan(List<Block> mining, World world) {
|
||||
if (!Baritone.settings().mineScanDroppedItems.get()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
Set<Item> searchingFor = new HashSet<>();
|
||||
for (Block block : mining) {
|
||||
Item drop = block.getItemDropped(block.getDefaultState(), new Random(), 0);
|
||||
Item ore = Item.getItemFromBlock(block);
|
||||
searchingFor.add(drop);
|
||||
searchingFor.add(ore);
|
||||
}
|
||||
List<BlockPos> ret = new ArrayList<>();
|
||||
for (Entity entity : world.loadedEntityList) {
|
||||
if (entity instanceof EntityItem) {
|
||||
EntityItem ei = (EntityItem) entity;
|
||||
if (searchingFor.contains(ei.getItem().getItem())) {
|
||||
ret.add(entity.getPosition());
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static List<BlockPos> searchWorld(List<Block> mining, int max, World world) {
|
||||
List<BlockPos> locs = new ArrayList<>();
|
||||
List<Block> uninteresting = new ArrayList<>();
|
||||
//long b = System.currentTimeMillis();
|
||||
@@ -178,7 +205,7 @@ public final class MineBehavior extends Behavior implements IMineBehavior, Helpe
|
||||
locs.addAll(WorldScanner.INSTANCE.scanChunkRadius(uninteresting, max, 10, 26));
|
||||
//System.out.println("Scan of loaded chunks took " + (System.currentTimeMillis() - before) + "ms");
|
||||
}
|
||||
return prune(locs, mining, max);
|
||||
return prune(locs, mining, max, world);
|
||||
}
|
||||
|
||||
public void addNearby() {
|
||||
@@ -194,15 +221,16 @@ public final class MineBehavior extends Behavior implements IMineBehavior, Helpe
|
||||
}
|
||||
}
|
||||
}
|
||||
knownOreLocations = prune(knownOreLocations, mining, 64);
|
||||
knownOreLocations = prune(knownOreLocations, mining, ORE_LOCATIONS_COUNT, world());
|
||||
}
|
||||
|
||||
public List<BlockPos> prune(List<BlockPos> locs2, List<Block> mining, int max) {
|
||||
public static List<BlockPos> prune(List<BlockPos> locs2, List<Block> mining, int max, World world) {
|
||||
List<BlockPos> dropped = droppedItemsScan(mining, world);
|
||||
List<BlockPos> locs = locs2
|
||||
.stream()
|
||||
|
||||
// remove any that are within loaded chunks that aren't actually what we want
|
||||
.filter(pos -> world().getChunk(pos) instanceof EmptyChunk || mining.contains(BlockStateInterface.get(pos).getBlock()))
|
||||
.filter(pos -> world.getChunk(pos) instanceof EmptyChunk || mining.contains(BlockStateInterface.get(pos).getBlock()) || dropped.contains(pos))
|
||||
|
||||
// remove any that are implausible to mine (encased in bedrock, or touching lava)
|
||||
.filter(MineBehavior::plausibleToBreak)
|
||||
|
||||
99
src/main/java/baritone/process/GetToBlockProcess.java
Normal file
99
src/main/java/baritone/process/GetToBlockProcess.java
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* 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.process;
|
||||
|
||||
import baritone.Baritone;
|
||||
import baritone.api.pathing.goals.Goal;
|
||||
import baritone.api.pathing.goals.GoalComposite;
|
||||
import baritone.api.pathing.goals.GoalGetToBlock;
|
||||
import baritone.api.process.IGetToBlockProcess;
|
||||
import baritone.api.process.PathingCommand;
|
||||
import baritone.api.process.PathingCommandType;
|
||||
import baritone.utils.BaritoneProcessHelper;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBlockProcess {
|
||||
private Block gettingTo;
|
||||
private List<BlockPos> knownLocations;
|
||||
|
||||
private int tickCount = 0;
|
||||
|
||||
public GetToBlockProcess(Baritone baritone) {
|
||||
super(baritone, 2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getToBlock(Block block) {
|
||||
gettingTo = block;
|
||||
rescan();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
return gettingTo != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) {
|
||||
if (knownLocations == null) {
|
||||
rescan();
|
||||
}
|
||||
if (knownLocations.isEmpty()) {
|
||||
logDirect("No known locations of " + gettingTo + ", canceling GetToBlock");
|
||||
if (isSafeToCancel) {
|
||||
onLostControl();
|
||||
}
|
||||
return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL);
|
||||
}
|
||||
if (calcFailed) {
|
||||
logDirect("Unable to find any path to " + gettingTo + ", canceling GetToBlock");
|
||||
if (isSafeToCancel) {
|
||||
onLostControl();
|
||||
}
|
||||
return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL);
|
||||
}
|
||||
int mineGoalUpdateInterval = Baritone.settings().mineGoalUpdateInterval.get();
|
||||
if (mineGoalUpdateInterval != 0 && tickCount++ % mineGoalUpdateInterval == 0) { // big brain
|
||||
Baritone.INSTANCE.getExecutor().execute(this::rescan);
|
||||
}
|
||||
Goal goal = new GoalComposite(knownLocations.stream().map(GoalGetToBlock::new).toArray(Goal[]::new));
|
||||
if (goal.isInGoal(playerFeet())) {
|
||||
onLostControl();
|
||||
}
|
||||
return new PathingCommand(goal, PathingCommandType.REVALIDATE_GOAL_AND_PATH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLostControl() {
|
||||
gettingTo = null;
|
||||
knownLocations = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String displayName() {
|
||||
return "Get To Block " + gettingTo;
|
||||
}
|
||||
|
||||
private void rescan() {
|
||||
knownLocations = MineProcess.searchWorld(Collections.singletonList(gettingTo), 64, world());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user