diff --git a/src/api/java/baritone/api/command/datatypes/ItemById.java b/src/api/java/baritone/api/command/datatypes/ItemById.java
new file mode 100644
index 000000000..eb4f230b4
--- /dev/null
+++ b/src/api/java/baritone/api/command/datatypes/ItemById.java
@@ -0,0 +1,53 @@
+/*
+ * 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 .
+ */
+
+package baritone.api.command.datatypes;
+
+import baritone.api.command.exception.CommandException;
+import baritone.api.command.helpers.TabCompleteHelper;
+import net.minecraft.core.registries.BuiltInRegistries;
+import net.minecraft.resources.ResourceLocation;
+import net.minecraft.world.item.Item;
+
+import java.util.stream.Stream;
+
+public enum ItemById implements IDatatypeFor- {
+ INSTANCE;
+
+ @Override
+ public Item get(IDatatypeContext ctx) throws CommandException {
+ ResourceLocation id = new ResourceLocation(ctx.getConsumer().getString());
+ Item item;
+ if ((item = BuiltInRegistries.ITEM.getOptional(id).orElse(null)) == null) {
+ throw new IllegalArgumentException("No item found by that id");
+ }
+ return item;
+ }
+
+ @Override
+ public Stream tabComplete(IDatatypeContext ctx) throws CommandException {
+ return new TabCompleteHelper()
+ .append(
+ BuiltInRegistries.BLOCK.keySet()
+ .stream()
+ .map(ResourceLocation::toString)
+ )
+ .filterPrefixNamespaced(ctx.getConsumer().getString())
+ .sortAlphabetically()
+ .stream();
+ }
+}
diff --git a/src/api/java/baritone/api/process/IFollowProcess.java b/src/api/java/baritone/api/process/IFollowProcess.java
index 6f7f0a239..e3ed73006 100644
--- a/src/api/java/baritone/api/process/IFollowProcess.java
+++ b/src/api/java/baritone/api/process/IFollowProcess.java
@@ -17,9 +17,11 @@
package baritone.api.process;
+import net.minecraft.world.entity.Entity;
+import net.minecraft.world.item.ItemStack;
+
import java.util.List;
import java.util.function.Predicate;
-import net.minecraft.world.entity.Entity;
/**
* @author Brady
@@ -34,6 +36,13 @@ public interface IFollowProcess extends IBaritoneProcess {
*/
void follow(Predicate filter);
+ /**
+ * Try to pick up any items matching this predicate
+ *
+ * @param filter the predicate
+ */
+ void pickup(Predicate filter);
+
/**
* @return The entities that are currently being followed. null if not currently following, empty if nothing matches the predicate
*/
diff --git a/src/main/java/baritone/command/defaults/DefaultCommands.java b/src/main/java/baritone/command/defaults/DefaultCommands.java
index c810d07c1..5228a7ae1 100644
--- a/src/main/java/baritone/command/defaults/DefaultCommands.java
+++ b/src/main/java/baritone/command/defaults/DefaultCommands.java
@@ -53,6 +53,7 @@ public final class DefaultCommands {
new RenderCommand(baritone),
new FarmCommand(baritone),
new FollowCommand(baritone),
+ new PickupCommand(baritone),
new ExploreFilterCommand(baritone),
new ReloadAllCommand(baritone),
new SaveAllCommand(baritone),
diff --git a/src/main/java/baritone/command/defaults/PickupCommand.java b/src/main/java/baritone/command/defaults/PickupCommand.java
new file mode 100644
index 000000000..e1e7014b0
--- /dev/null
+++ b/src/main/java/baritone/command/defaults/PickupCommand.java
@@ -0,0 +1,83 @@
+/*
+ * 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 .
+ */
+
+package baritone.command.defaults;
+
+import baritone.api.IBaritone;
+import baritone.api.command.Command;
+import baritone.api.command.argument.IArgConsumer;
+import baritone.api.command.datatypes.ItemById;
+import baritone.api.command.exception.CommandException;
+import baritone.api.command.helpers.TabCompleteHelper;
+import net.minecraft.core.registries.BuiltInRegistries;
+import net.minecraft.resources.ResourceLocation;
+import net.minecraft.world.item.Item;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Stream;
+
+public class PickupCommand extends Command {
+
+ public PickupCommand(IBaritone baritone) {
+ super(baritone, "pickup");
+ }
+
+ @Override
+ public void execute(String label, IArgConsumer args) throws CommandException {
+ Set
- collecting = new HashSet<>();
+ while (args.hasAny()) {
+ Item item = args.getDatatypeFor(ItemById.INSTANCE);
+ collecting.add(item);
+ }
+ if (collecting.isEmpty()) {
+ baritone.getFollowProcess().pickup(stack -> true);
+ logDirect("Picking up all items");
+ } else {
+ baritone.getFollowProcess().pickup(stack -> collecting.contains(stack.getItem()));
+ logDirect("Picking up these items:");
+ collecting.stream().map(BuiltInRegistries.ITEM::getKey).map(ResourceLocation::toString).forEach(this::logDirect);
+ }
+ }
+
+ @Override
+ public Stream tabComplete(String label, IArgConsumer args) throws CommandException {
+ while (args.has(2)) {
+ if (args.peekDatatypeOrNull(ItemById.INSTANCE) == null) {
+ return Stream.empty();
+ }
+ args.get();
+ }
+ return args.tabCompleteDatatype(ItemById.INSTANCE);
+ }
+
+ @Override
+ public String getShortDesc() {
+ return "Pickup items";
+ }
+
+ @Override
+ public List getLongDesc() {
+ return Arrays.asList(
+ "Usage:",
+ "> pickup - Pickup anything",
+ "> pickup <...> - Pickup certain items"
+ );
+ }
+}
diff --git a/src/main/java/baritone/process/FollowProcess.java b/src/main/java/baritone/process/FollowProcess.java
index 49cd5f0b8..0be7a4e80 100644
--- a/src/main/java/baritone/process/FollowProcess.java
+++ b/src/main/java/baritone/process/FollowProcess.java
@@ -19,6 +19,7 @@ package baritone.process;
import baritone.Baritone;
import baritone.api.pathing.goals.Goal;
+import baritone.api.pathing.goals.GoalBlock;
import baritone.api.pathing.goals.GoalComposite;
import baritone.api.pathing.goals.GoalNear;
import baritone.api.pathing.goals.GoalXZ;
@@ -27,11 +28,14 @@ import baritone.api.process.PathingCommand;
import baritone.api.process.PathingCommandType;
import baritone.api.utils.BetterBlockPos;
import baritone.utils.BaritoneProcessHelper;
+import net.minecraft.core.BlockPos;
+import net.minecraft.world.entity.Entity;
+import net.minecraft.world.entity.item.ItemEntity;
+import net.minecraft.world.item.ItemStack;
+
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
-import net.minecraft.core.BlockPos;
-import net.minecraft.world.entity.Entity;
/**
* Follow an entity
@@ -42,6 +46,7 @@ public final class FollowProcess extends BaritoneProcessHelper implements IFollo
private Predicate filter;
private List cache;
+ private boolean into; // walk straight into the target, regardless of settings
public FollowProcess(Baritone baritone) {
super(baritone);
@@ -56,12 +61,15 @@ public final class FollowProcess extends BaritoneProcessHelper implements IFollo
private Goal towards(Entity following) {
BlockPos pos;
- if (Baritone.settings().followOffsetDistance.value == 0) {
+ if (Baritone.settings().followOffsetDistance.value == 0 || into) {
pos = following.blockPosition();
} else {
GoalXZ g = GoalXZ.fromDirection(following.position(), Baritone.settings().followOffsetDirection.value, Baritone.settings().followOffsetDistance.value);
pos = new BetterBlockPos(g.getX(), following.position().y, g.getZ());
}
+ if (into) {
+ return new GoalBlock(pos);
+ }
return new GoalNear(pos, Baritone.settings().followRadius.value);
}
@@ -114,6 +122,13 @@ public final class FollowProcess extends BaritoneProcessHelper implements IFollo
@Override
public void follow(Predicate filter) {
this.filter = filter;
+ this.into = false;
+ }
+
+ @Override
+ public void pickup(Predicate filter) {
+ this.filter = e -> e instanceof ItemEntity && filter.test(((ItemEntity) e).getItem());
+ this.into = true;
}
@Override