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