diff --git a/src/main/java/baritone/Baritone.java b/src/main/java/baritone/Baritone.java index 2a88ed21..bd678dd8 100755 --- a/src/main/java/baritone/Baritone.java +++ b/src/main/java/baritone/Baritone.java @@ -17,9 +17,9 @@ package baritone; +import baritone.api.event.GameEventHandler; import baritone.behavior.Behavior; import baritone.behavior.impl.*; -import baritone.api.event.GameEventHandler; import baritone.utils.InputOverrideHandler; import net.minecraft.client.Minecraft; @@ -79,6 +79,7 @@ public enum Baritone { registerBehavior(MemoryBehavior.INSTANCE); registerBehavior(LocationTrackingBehavior.INSTANCE); registerBehavior(FollowBehavior.INSTANCE); + registerBehavior(MineBehavior.INSTANCE); } this.dir = new File(Minecraft.getMinecraft().gameDir, "baritone"); if (!Files.exists(dir.toPath())) { diff --git a/src/main/java/baritone/behavior/impl/FollowBehavior.java b/src/main/java/baritone/behavior/impl/FollowBehavior.java index 7ac54c32..55ec5539 100644 --- a/src/main/java/baritone/behavior/impl/FollowBehavior.java +++ b/src/main/java/baritone/behavior/impl/FollowBehavior.java @@ -23,6 +23,11 @@ import baritone.pathing.goals.GoalNear; import net.minecraft.entity.Entity; import net.minecraft.util.math.BlockPos; +/** + * Follow an entity + * + * @author leijurv + */ public class FollowBehavior extends Behavior { public static final FollowBehavior INSTANCE = new FollowBehavior(); diff --git a/src/main/java/baritone/behavior/impl/MineBehavior.java b/src/main/java/baritone/behavior/impl/MineBehavior.java index 01dd4137..e59058a8 100644 --- a/src/main/java/baritone/behavior/impl/MineBehavior.java +++ b/src/main/java/baritone/behavior/impl/MineBehavior.java @@ -1,4 +1,86 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Baritone. If not, see . + */ + package baritone.behavior.impl; -public class MineBehavior { +import baritone.api.event.events.TickEvent; +import baritone.behavior.Behavior; +import baritone.chunk.ChunkPacker; +import baritone.chunk.WorldProvider; +import baritone.pathing.goals.Goal; +import baritone.pathing.goals.GoalComposite; +import baritone.pathing.goals.GoalTwoBlocks; +import baritone.utils.BlockStateInterface; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.chunk.EmptyChunk; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Mine blocks of a certain type + * + * @author leijurv + */ +public class MineBehavior extends Behavior { + public static final MineBehavior INSTANCE = new MineBehavior(); + + private MineBehavior() { + } + + String mining; + + @Override + public void onTick(TickEvent event) { + if (event.getType() == TickEvent.Type.OUT) { + return; + } + if (mining == null) { + return; + } + List locs = new ArrayList<>(WorldProvider.INSTANCE.getCurrentWorld().cache.getLocationsOf(mining, 1, 1)); + if (locs.isEmpty()) { + displayChatMessageRaw("No locations for " + mining + " known, cancelling"); + cancel(); + return; + } + BlockPos playerFeet = playerFeet(); + locs.sort(Comparator.comparingDouble(playerFeet::distanceSq)); + + // remove any that are within loaded chunks that aren't actually what we want + locs.removeAll(locs.stream() + .filter(pos -> !(world().getChunk(pos) instanceof EmptyChunk)) + .filter(pos -> !ChunkPacker.blockToString(BlockStateInterface.get(pos).getBlock()).equalsIgnoreCase(mining)) + .collect(Collectors.toList())); + if (locs.size() > 30) { + locs = locs.subList(0, 30); + } + PathingBehavior.INSTANCE.setGoal(new GoalComposite(locs.stream().map(GoalTwoBlocks::new).toArray(Goal[]::new))); + PathingBehavior.INSTANCE.path(); + } + + public void mine(String mining) { + this.mining = mining; + } + + public void cancel() { + PathingBehavior.INSTANCE.cancel(); + mine(null); + } } diff --git a/src/main/java/baritone/behavior/impl/PathingBehavior.java b/src/main/java/baritone/behavior/impl/PathingBehavior.java index 25eb89ef..4b5f1f43 100644 --- a/src/main/java/baritone/behavior/impl/PathingBehavior.java +++ b/src/main/java/baritone/behavior/impl/PathingBehavior.java @@ -197,18 +197,23 @@ public class PathingBehavior extends Behavior { AbstractNodeCostSearch.getCurrentlyRunning().ifPresent(AbstractNodeCostSearch::cancel); } - public void path() { + /** + * Start calculating a path if we aren't already + * + * @return true if this call started path calculation, false if it was already calculating or executing a path + */ + public boolean path() { synchronized (pathPlanLock) { if (current != null) { - displayChatMessageRaw("Currently executing a path. Please cancel it first."); - return; + return false; } synchronized (pathCalcLock) { if (isPathCalcInProgress) { - return; + return false; } dispatchPathEvent(PathEvent.CALC_STARTED); findPathInNewThread(pathStart(), true, Optional.empty()); + return true; } } } diff --git a/src/main/java/baritone/utils/ExampleBaritoneControl.java b/src/main/java/baritone/utils/ExampleBaritoneControl.java index fcab3334..542ea323 100644 --- a/src/main/java/baritone/utils/ExampleBaritoneControl.java +++ b/src/main/java/baritone/utils/ExampleBaritoneControl.java @@ -22,6 +22,7 @@ import baritone.Settings; import baritone.api.event.events.ChatEvent; import baritone.behavior.Behavior; import baritone.behavior.impl.FollowBehavior; +import baritone.behavior.impl.MineBehavior; import baritone.behavior.impl.PathingBehavior; import baritone.chunk.ChunkPacker; import baritone.chunk.Waypoint; @@ -36,10 +37,8 @@ import baritone.utils.pathing.BetterBlockPos; import net.minecraft.block.Block; import net.minecraft.entity.Entity; import net.minecraft.util.math.BlockPos; -import net.minecraft.world.chunk.EmptyChunk; import java.util.*; -import java.util.stream.Collectors; public class ExampleBaritoneControl extends Behavior { public static ExampleBaritoneControl INSTANCE = new ExampleBaritoneControl(); @@ -102,13 +101,16 @@ public class ExampleBaritoneControl extends Behavior { return; } if (msg.equals("path")) { - PathingBehavior.INSTANCE.path(); + if (!PathingBehavior.INSTANCE.path()) { + displayChatMessageRaw("Currently executing a path. Please cancel it first."); + } event.cancel(); return; } if (msg.toLowerCase().equals("cancel")) { PathingBehavior.INSTANCE.cancel(); FollowBehavior.INSTANCE.cancel(); + MineBehavior.INSTANCE.cancel(); event.cancel(); displayChatMessageRaw("ok canceled"); return; @@ -131,7 +133,9 @@ public class ExampleBaritoneControl extends Behavior { return false; } }); - PathingBehavior.INSTANCE.path(); + if (!PathingBehavior.INSTANCE.path()) { + displayChatMessageRaw("Currently executing a path. Please cancel it first."); + } event.cancel(); return; } @@ -174,27 +178,8 @@ public class ExampleBaritoneControl extends Behavior { } if (msg.toLowerCase().startsWith("mine")) { String blockType = msg.toLowerCase().substring(4).trim(); - List locs = new ArrayList<>(WorldProvider.INSTANCE.getCurrentWorld().cache.getLocationsOf(blockType, 1, 1)); - if (locs.isEmpty()) { - displayChatMessageRaw("No locations known"); - event.cancel(); - return; - } - BlockPos playerFeet = playerFeet(); - locs.sort(Comparator.comparingDouble(playerFeet::distanceSq)); - - // remove any that are within loaded chunks that aren't actually what we want - locs.removeAll(locs.stream() - .filter(pos -> !(world().getChunk(pos) instanceof EmptyChunk)) - .filter(pos -> !ChunkPacker.blockToString(BlockStateInterface.get(pos).getBlock()).equalsIgnoreCase(blockType)) - .collect(Collectors.toList())); - - if (locs.size() > 30) { - displayChatMessageRaw("Pathing to any of closest 30"); - locs = locs.subList(0, 30); - } - PathingBehavior.INSTANCE.setGoal(new GoalComposite(locs.stream().map(GoalTwoBlocks::new).toArray(Goal[]::new))); - PathingBehavior.INSTANCE.path(); + MineBehavior.INSTANCE.mine(blockType); + displayChatMessageRaw("Started mining blocks of type" + blockType); event.cancel(); return; } @@ -248,7 +233,9 @@ public class ExampleBaritoneControl extends Behavior { } Goal goal = new GoalBlock(waypoint.location); PathingBehavior.INSTANCE.setGoal(goal); - PathingBehavior.INSTANCE.path(); + if (!PathingBehavior.INSTANCE.path()) { + displayChatMessageRaw("Currently executing a path. Please cancel it first."); + } event.cancel(); return; }