Skip to content

Commit 80f6545

Browse files
committed
make sure to pick up dropped items while mining, fixes #170
1 parent c614d7e commit 80f6545

File tree

3 files changed

+141
-9
lines changed

3 files changed

+141
-9
lines changed

src/api/java/baritone/api/Settings.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@
2424

2525
import java.awt.*;
2626
import java.lang.reflect.Field;
27-
import java.util.List;
2827
import java.util.*;
28+
import java.util.List;
2929
import java.util.function.Consumer;
3030

3131
/**
@@ -376,6 +376,11 @@ public class Settings {
376376
*/
377377
public Setting<Integer> mineGoalUpdateInterval = new Setting<>(5);
378378

379+
/**
380+
* While mining, should it also consider dropped items of the correct type as a pathing destination (as well as ore blocks)?
381+
*/
382+
public Setting<Boolean> mineScanDroppedItems = new Setting<>(true);
383+
379384
/**
380385
* Cancel the current path if the goal has changed, and the path originally ended in the goal but doesn't anymore.
381386
* <p>

src/main/java/baritone/behavior/MineBehavior.java

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,13 @@
3030
import baritone.utils.BlockStateInterface;
3131
import baritone.utils.Helper;
3232
import net.minecraft.block.Block;
33+
import net.minecraft.entity.Entity;
34+
import net.minecraft.entity.item.EntityItem;
3335
import net.minecraft.init.Blocks;
3436
import net.minecraft.item.Item;
3537
import net.minecraft.item.ItemStack;
3638
import net.minecraft.util.math.BlockPos;
39+
import net.minecraft.world.World;
3740
import net.minecraft.world.chunk.EmptyChunk;
3841

3942
import java.util.*;
@@ -45,7 +48,7 @@
4548
* @author leijurv
4649
*/
4750
public final class MineBehavior extends Behavior implements IMineBehavior, Helper {
48-
51+
public static final int ORE_LOCATIONS_COUNT = 64;
4952
private List<Block> mining;
5053
private List<BlockPos> knownOreLocations;
5154
private BlockPos branchPoint;
@@ -91,7 +94,7 @@ private void updateGoal() {
9194
}
9295
List<BlockPos> locs = knownOreLocations;
9396
if (!locs.isEmpty()) {
94-
List<BlockPos> locs2 = prune(new ArrayList<>(locs), mining, 64);
97+
List<BlockPos> locs2 = prune(new ArrayList<>(locs), mining, ORE_LOCATIONS_COUNT, world());
9598
// 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
9699
baritone.getPathingBehavior().setGoalAndPath(new GoalComposite(locs2.stream().map(loc -> coalesce(loc, locs2)).toArray(Goal[]::new)));
97100
knownOreLocations = locs2;
@@ -127,7 +130,8 @@ private void rescan() {
127130
if (Baritone.settings().legitMine.get()) {
128131
return;
129132
}
130-
List<BlockPos> locs = searchWorld(mining, 64);
133+
List<BlockPos> locs = searchWorld(mining, ORE_LOCATIONS_COUNT, world());
134+
locs.addAll(droppedItemsScan(mining, world()));
131135
if (locs.isEmpty()) {
132136
logDebug("No locations for " + mining + " known, cancelling");
133137
mine(0, (String[]) null);
@@ -158,7 +162,30 @@ private static Goal coalesce(BlockPos loc, List<BlockPos> locs) {
158162
}
159163
}
160164

161-
public List<BlockPos> searchWorld(List<Block> mining, int max) {
165+
public static List<BlockPos> droppedItemsScan(List<Block> mining, World world) {
166+
if (!Baritone.settings().mineScanDroppedItems.get()) {
167+
return new ArrayList<>();
168+
}
169+
Set<Item> searchingFor = new HashSet<>();
170+
for (Block block : mining) {
171+
Item drop = block.getItemDropped(block.getDefaultState(), new Random(), 0);
172+
Item ore = Item.getItemFromBlock(block);
173+
searchingFor.add(drop);
174+
searchingFor.add(ore);
175+
}
176+
List<BlockPos> ret = new ArrayList<>();
177+
for (Entity entity : world.loadedEntityList) {
178+
if (entity instanceof EntityItem) {
179+
EntityItem ei = (EntityItem) entity;
180+
if (searchingFor.contains(ei.getItem().getItem())) {
181+
ret.add(entity.getPosition());
182+
}
183+
}
184+
}
185+
return ret;
186+
}
187+
188+
public static List<BlockPos> searchWorld(List<Block> mining, int max, World world) {
162189
List<BlockPos> locs = new ArrayList<>();
163190
List<Block> uninteresting = new ArrayList<>();
164191
//long b = System.currentTimeMillis();
@@ -178,7 +205,7 @@ public List<BlockPos> searchWorld(List<Block> mining, int max) {
178205
locs.addAll(WorldScanner.INSTANCE.scanChunkRadius(uninteresting, max, 10, 26));
179206
//System.out.println("Scan of loaded chunks took " + (System.currentTimeMillis() - before) + "ms");
180207
}
181-
return prune(locs, mining, max);
208+
return prune(locs, mining, max, world);
182209
}
183210

184211
public void addNearby() {
@@ -194,15 +221,16 @@ public void addNearby() {
194221
}
195222
}
196223
}
197-
knownOreLocations = prune(knownOreLocations, mining, 64);
224+
knownOreLocations = prune(knownOreLocations, mining, ORE_LOCATIONS_COUNT, world());
198225
}
199226

200-
public List<BlockPos> prune(List<BlockPos> locs2, List<Block> mining, int max) {
227+
public static List<BlockPos> prune(List<BlockPos> locs2, List<Block> mining, int max, World world) {
228+
List<BlockPos> dropped = droppedItemsScan(mining, world);
201229
List<BlockPos> locs = locs2
202230
.stream()
203231

204232
// remove any that are within loaded chunks that aren't actually what we want
205-
.filter(pos -> world().getChunk(pos) instanceof EmptyChunk || mining.contains(BlockStateInterface.get(pos).getBlock()))
233+
.filter(pos -> world.getChunk(pos) instanceof EmptyChunk || mining.contains(BlockStateInterface.get(pos).getBlock()) || dropped.contains(pos))
206234

207235
// remove any that are implausible to mine (encased in bedrock, or touching lava)
208236
.filter(MineBehavior::plausibleToBreak)
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/*
2+
* This file is part of Baritone.
3+
*
4+
* Baritone is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU Lesser General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* Baritone is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU Lesser General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU Lesser General Public License
15+
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
16+
*/
17+
18+
package baritone.process;
19+
20+
import baritone.Baritone;
21+
import baritone.api.pathing.goals.Goal;
22+
import baritone.api.pathing.goals.GoalComposite;
23+
import baritone.api.pathing.goals.GoalGetToBlock;
24+
import baritone.api.process.IGetToBlockProcess;
25+
import baritone.api.process.PathingCommand;
26+
import baritone.api.process.PathingCommandType;
27+
import baritone.utils.BaritoneProcessHelper;
28+
import net.minecraft.block.Block;
29+
import net.minecraft.util.math.BlockPos;
30+
31+
import java.util.Collections;
32+
import java.util.List;
33+
34+
public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBlockProcess {
35+
private Block gettingTo;
36+
private List<BlockPos> knownLocations;
37+
38+
private int tickCount = 0;
39+
40+
public GetToBlockProcess(Baritone baritone) {
41+
super(baritone, 2);
42+
}
43+
44+
@Override
45+
public void getToBlock(Block block) {
46+
gettingTo = block;
47+
rescan();
48+
}
49+
50+
@Override
51+
public boolean isActive() {
52+
return gettingTo != null;
53+
}
54+
55+
@Override
56+
public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) {
57+
if (knownLocations == null) {
58+
rescan();
59+
}
60+
if (knownLocations.isEmpty()) {
61+
logDirect("No known locations of " + gettingTo + ", canceling GetToBlock");
62+
if (isSafeToCancel) {
63+
onLostControl();
64+
}
65+
return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL);
66+
}
67+
if (calcFailed) {
68+
logDirect("Unable to find any path to " + gettingTo + ", canceling GetToBlock");
69+
if (isSafeToCancel) {
70+
onLostControl();
71+
}
72+
return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL);
73+
}
74+
int mineGoalUpdateInterval = Baritone.settings().mineGoalUpdateInterval.get();
75+
if (mineGoalUpdateInterval != 0 && tickCount++ % mineGoalUpdateInterval == 0) { // big brain
76+
Baritone.INSTANCE.getExecutor().execute(this::rescan);
77+
}
78+
Goal goal = new GoalComposite(knownLocations.stream().map(GoalGetToBlock::new).toArray(Goal[]::new));
79+
if (goal.isInGoal(playerFeet())) {
80+
onLostControl();
81+
}
82+
return new PathingCommand(goal, PathingCommandType.REVALIDATE_GOAL_AND_PATH);
83+
}
84+
85+
@Override
86+
public void onLostControl() {
87+
gettingTo = null;
88+
knownLocations = null;
89+
}
90+
91+
@Override
92+
public String displayName() {
93+
return "Get To Block " + gettingTo;
94+
}
95+
96+
private void rescan() {
97+
knownLocations = MineProcess.searchWorld(Collections.singletonList(gettingTo), 64, world());
98+
}
99+
}

0 commit comments

Comments
 (0)