Merge branch 'processes'

This commit is contained in:
Leijurv
2018-11-06 08:43:57 -08:00
46 changed files with 1207 additions and 567 deletions

View File

@@ -18,16 +18,24 @@
package baritone;
import baritone.api.BaritoneAPI;
import baritone.api.IBaritoneProvider;
import baritone.api.IBaritone;
import baritone.api.Settings;
import baritone.api.event.listener.IGameEventListener;
import baritone.behavior.*;
import baritone.behavior.Behavior;
import baritone.behavior.LookBehavior;
import baritone.behavior.MemoryBehavior;
import baritone.behavior.PathingBehavior;
import baritone.cache.WorldProvider;
import baritone.cache.WorldScanner;
import baritone.event.GameEventHandler;
import baritone.process.CustomGoalProcess;
import baritone.process.FollowProcess;
import baritone.process.GetToBlockProcess;
import baritone.process.MineProcess;
import baritone.utils.BaritoneAutoTest;
import baritone.utils.ExampleBaritoneControl;
import baritone.utils.InputOverrideHandler;
import baritone.utils.PathingControlManager;
import net.minecraft.client.Minecraft;
import java.io.File;
@@ -44,7 +52,7 @@ import java.util.concurrent.TimeUnit;
* @author Brady
* @since 7/31/2018 10:50 PM
*/
public enum Baritone implements IBaritoneProvider {
public enum Baritone implements IBaritone {
/**
* Singleton instance of this class
@@ -57,33 +65,33 @@ public enum Baritone implements IBaritoneProvider {
private boolean initialized;
private GameEventHandler gameEventHandler;
private InputOverrideHandler inputOverrideHandler;
private Settings settings;
private File dir;
private ThreadPoolExecutor threadPool;
private List<Behavior> behaviors;
private PathingBehavior pathingBehavior;
private LookBehavior lookBehavior;
private MemoryBehavior memoryBehavior;
private FollowBehavior followBehavior;
private MineBehavior mineBehavior;
private InputOverrideHandler inputOverrideHandler;
/**
* Whether or not Baritone is active
*/
private boolean active;
private FollowProcess followProcess;
private MineProcess mineProcess;
private GetToBlockProcess getToBlockProcess;
private CustomGoalProcess customGoalProcess;
private PathingControlManager pathingControlManager;
private static ThreadPoolExecutor threadPool = new ThreadPoolExecutor(4, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<>());
Baritone() {
this.gameEventHandler = new GameEventHandler();
this.gameEventHandler = new GameEventHandler(this);
}
public synchronized void init() {
if (initialized) {
return;
}
this.threadPool = new ThreadPoolExecutor(4, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<>());
this.inputOverrideHandler = new InputOverrideHandler();
// Acquire the "singleton" instance of the settings directly from the API
// We might want to change this...
@@ -95,10 +103,18 @@ public enum Baritone implements IBaritoneProvider {
pathingBehavior = new PathingBehavior(this);
lookBehavior = new LookBehavior(this);
memoryBehavior = new MemoryBehavior(this);
followBehavior = new FollowBehavior(this);
mineBehavior = new MineBehavior(this);
inputOverrideHandler = new InputOverrideHandler(this);
new ExampleBaritoneControl(this);
}
this.pathingControlManager = new PathingControlManager(this);
{
followProcess = new FollowProcess(this);
mineProcess = new MineProcess(this);
customGoalProcess = new CustomGoalProcess(this); // very high iq
getToBlockProcess = new GetToBlockProcess(this);
}
if (BaritoneAutoTest.ENABLE_AUTO_TEST) {
registerEventListener(BaritoneAutoTest.INSTANCE);
}
@@ -109,10 +125,13 @@ public enum Baritone implements IBaritoneProvider {
} catch (IOException ignored) {}
}
this.active = true;
this.initialized = true;
}
public PathingControlManager getPathingControlManager() {
return pathingControlManager;
}
public boolean isInitialized() {
return this.initialized;
}
@@ -129,7 +148,7 @@ public enum Baritone implements IBaritoneProvider {
return this.behaviors;
}
public Executor getExecutor() {
public static Executor getExecutor() {
return threadPool;
}
@@ -139,8 +158,18 @@ public enum Baritone implements IBaritoneProvider {
}
@Override
public FollowBehavior getFollowBehavior() {
return followBehavior;
public CustomGoalProcess getCustomGoalProcess() {
return customGoalProcess;
}
@Override
public GetToBlockProcess getGetToBlockProcess() { // very very high iq
return getToBlockProcess;
}
@Override
public FollowProcess getFollowProcess() {
return followProcess;
}
@Override
@@ -154,8 +183,8 @@ public enum Baritone implements IBaritoneProvider {
}
@Override
public MineBehavior getMineBehavior() {
return mineBehavior;
public MineProcess getMineProcess() {
return mineProcess;
}
@Override
@@ -178,10 +207,6 @@ public enum Baritone implements IBaritoneProvider {
this.gameEventHandler.registerEventListener(listener);
}
public boolean isActive() {
return this.active;
}
public Settings getSettings() {
return this.settings;
}
@@ -190,7 +215,7 @@ public enum Baritone implements IBaritoneProvider {
return Baritone.INSTANCE.settings; // yolo
}
public File getDir() {
return this.dir;
public static File getDir() {
return Baritone.INSTANCE.dir; // should be static I guess
}
}

View File

@@ -17,59 +17,17 @@
package baritone;
import baritone.api.IBaritone;
import baritone.api.IBaritoneProvider;
import baritone.api.behavior.*;
import baritone.api.cache.IWorldProvider;
import baritone.api.cache.IWorldScanner;
import baritone.api.event.listener.IGameEventListener;
import baritone.cache.WorldProvider;
import baritone.cache.WorldScanner;
import net.minecraft.client.entity.EntityPlayerSP;
/**
* todo fix this cancer
*
* @author Brady
* @since 9/29/2018
*/
public final class BaritoneProvider implements IBaritoneProvider {
@Override
public IFollowBehavior getFollowBehavior() {
return Baritone.INSTANCE.getFollowBehavior();
}
@Override
public ILookBehavior getLookBehavior() {
return Baritone.INSTANCE.getLookBehavior();
}
@Override
public IMemoryBehavior getMemoryBehavior() {
return Baritone.INSTANCE.getMemoryBehavior();
}
@Override
public IMineBehavior getMineBehavior() {
return Baritone.INSTANCE.getMineBehavior();
}
@Override
public IPathingBehavior getPathingBehavior() {
return Baritone.INSTANCE.getPathingBehavior();
}
@Override
public IWorldProvider getWorldProvider() {
return WorldProvider.INSTANCE;
}
@Override
public IWorldScanner getWorldScanner() {
return WorldScanner.INSTANCE;
}
@Override
public void registerEventListener(IGameEventListener listener) {
Baritone.INSTANCE.registerEventListener(listener);
public IBaritone getBaritoneForPlayer(EntityPlayerSP player) {
return Baritone.INSTANCE; // pwnage
}
}

View File

@@ -30,49 +30,8 @@ public class Behavior implements IBehavior {
public final Baritone baritone;
/**
* Whether or not this behavior is enabled
*/
private boolean enabled = true;
protected Behavior(Baritone baritone) {
this.baritone = baritone;
baritone.registerBehavior(this);
}
/**
* Toggles the enabled state of this {@link Behavior}.
*
* @return The new state.
*/
@Override
public final boolean toggle() {
return this.setEnabled(!this.isEnabled());
}
/**
* Sets the enabled state of this {@link Behavior}.
*
* @return The new state.
*/
@Override
public final boolean setEnabled(boolean enabled) {
if (enabled == this.enabled) {
return this.enabled;
}
if (this.enabled = enabled) {
this.onEnable();
} else {
this.onDisable();
}
return this.enabled;
}
/**
* @return Whether or not this {@link Behavior} is active.
*/
@Override
public final boolean isEnabled() {
return this.enabled;
}
}

View File

@@ -52,6 +52,10 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
private Goal goal;
private boolean safeToCancel;
private boolean pauseRequestedLastTick;
private boolean calcFailedLastTick;
private volatile boolean isPathCalcInProgress;
private final Object pathCalcLock = new Object();
@@ -72,8 +76,9 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
private void dispatchEvents() {
ArrayList<PathEvent> curr = new ArrayList<>();
toDispatch.drainTo(curr);
calcFailedLastTick = curr.contains(PathEvent.CALC_FAILED);
for (PathEvent event : curr) {
Baritone.INSTANCE.getGameEventHandler().onPathEvent(event);
baritone.getGameEventHandler().onPathEvent(event);
}
}
@@ -81,7 +86,8 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
public void onTick(TickEvent event) {
dispatchEvents();
if (event.getType() == TickEvent.Type.OUT) {
cancel();
secretInternalSegmentCancel();
baritone.getPathingControlManager().cancelEverything();
return;
}
tickPath();
@@ -89,10 +95,17 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
}
private void tickPath() {
baritone.getPathingControlManager().doTheThingWithTheStuff();
if (pauseRequestedLastTick && safeToCancel) {
pauseRequestedLastTick = false;
baritone.getInputOverrideHandler().clearAllKeys();
BlockBreakHelper.stopBreakingBlock();
return;
}
if (current == null) {
return;
}
boolean safe = current.onTick();
safeToCancel = current.onTick();
synchronized (pathPlanLock) {
if (current.failed() || current.finished()) {
current = null;
@@ -134,7 +147,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
return;
}
// at this point, we know current is in progress
if (safe && next != null && next.snipsnapifpossible()) {
if (safeToCancel && next != null && next.snipsnapifpossible()) {
// a movement just ended; jump directly onto the next path
logDebug("Splicing into planned next path early...");
queuePathEvent(PathEvent.SPLICING_ONTO_NEXT_EARLY);
@@ -191,14 +204,13 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
return Optional.of(current.getPath().ticksRemainingFrom(current.getPosition()));
}
@Override
public void setGoal(Goal goal) {
public void secretInternalSetGoal(Goal goal) {
this.goal = goal;
}
public boolean setGoalAndPath(Goal goal) {
setGoal(goal);
return path();
public boolean secretInternalSetGoalAndPath(Goal goal) {
secretInternalSetGoal(goal);
return secretInternalPath();
}
@Override
@@ -226,17 +238,49 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
return this.current != null;
}
public boolean isSafeToCancel() {
return current == null || safeToCancel;
}
public void requestPause() {
pauseRequestedLastTick = true;
}
public boolean cancelSegmentIfSafe() {
if (isSafeToCancel()) {
secretInternalSegmentCancel();
return true;
}
return false;
}
@Override
public void cancel() {
public boolean cancelEverything() {
boolean doIt = isSafeToCancel();
if (doIt) {
secretInternalSegmentCancel();
}
baritone.getPathingControlManager().cancelEverything();
return doIt;
}
public boolean calcFailedLastTick() { // NOT exposed on public api
return calcFailedLastTick;
}
// just cancel the current path
public void secretInternalSegmentCancel() {
queuePathEvent(PathEvent.CANCELED);
current = null;
next = null;
Baritone.INSTANCE.getInputOverrideHandler().clearAllKeys();
baritone.getInputOverrideHandler().clearAllKeys();
AbstractNodeCostSearch.getCurrentlyRunning().ifPresent(AbstractNodeCostSearch::cancel);
BlockBreakHelper.stopBreakingBlock();
}
public void forceCancel() { // NOT exposed on public api
cancelEverything();
secretInternalSegmentCancel();
isPathCalcInProgress = false;
}
@@ -245,8 +289,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
*
* @return true if this call started path calculation, false if it was already calculating or executing a path
*/
@Override
public boolean path() {
public boolean secretInternalPath() {
if (goal == null) {
return false;
}
@@ -327,7 +370,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
isPathCalcInProgress = true;
}
CalculationContext context = new CalculationContext(); // not safe to create on the other thread, it looks up a lot of stuff in minecraft
Baritone.INSTANCE.getExecutor().execute(() -> {
Baritone.getExecutor().execute(() -> {
if (talkAboutIt) {
logDebug("Starting to search for path from " + start + " to " + goal);
}
@@ -435,31 +478,8 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
}
}
public void revalidateGoal() {
if (!Baritone.settings().cancelOnGoalInvalidation.get()) {
return;
}
synchronized (pathPlanLock) {
if (current == null || goal == null) {
return;
}
Goal intended = current.getPath().getGoal();
BlockPos end = current.getPath().getDest();
if (intended.isInGoal(end) && !goal.isInGoal(end)) {
// this path used to end in the goal
// but the goal has changed, so there's no reason to continue...
cancel();
}
}
}
@Override
public void onRenderPass(RenderEvent event) {
PathRenderer.render(event, this);
}
@Override
public void onDisable() {
Baritone.INSTANCE.getInputOverrideHandler().clearAllKeys();
}
}

View File

@@ -67,8 +67,8 @@ public final class CachedWorld implements ICachedWorld, Helper {
System.out.println("Cached world directory: " + directory);
// Insert an invalid region element
cachedRegions.put(0, null);
Baritone.INSTANCE.getExecutor().execute(new PackerThread());
Baritone.INSTANCE.getExecutor().execute(() -> {
Baritone.getExecutor().execute(new PackerThread());
Baritone.getExecutor().execute(() -> {
try {
Thread.sleep(30000);
while (true) {

View File

@@ -42,9 +42,9 @@ public class Waypoint implements IWaypoint {
* Constructor called when a Waypoint is read from disk, adds the creationTimestamp
* as a parameter so that it is reserved after a waypoint is wrote to the disk.
*
* @param name The waypoint name
* @param tag The waypoint tag
* @param location The waypoint location
* @param name The waypoint name
* @param tag The waypoint tag
* @param location The waypoint location
* @param creationTimestamp When the waypoint was created
*/
Waypoint(String name, Tag tag, BlockPos location, long creationTimestamp) {

View File

@@ -43,7 +43,7 @@ public class WorldData implements IWorldData {
}
public void onClose() {
Baritone.INSTANCE.getExecutor().execute(() -> {
Baritone.getExecutor().execute(() -> {
System.out.println("Started saving the world in a new thread");
cache.save();
});

View File

@@ -74,8 +74,8 @@ public enum WorldProvider implements IWorldProvider, Helper {
} else {
//remote
directory = new File(Baritone.INSTANCE.getDir(), mc.getCurrentServerData().serverIP);
readme = Baritone.INSTANCE.getDir();
directory = new File(Baritone.getDir(), mc.getCurrentServerData().serverIP);
readme = Baritone.getDir();
}
// lol wtf is this baritone folder in my minecraft save?
try (FileOutputStream out = new FileOutputStream(new File(readme, "readme.txt"))) {

View File

@@ -21,16 +21,13 @@ import baritone.Baritone;
import baritone.api.event.events.*;
import baritone.api.event.events.type.EventState;
import baritone.api.event.listener.IGameEventListener;
import baritone.api.utils.interfaces.Toggleable;
import baritone.cache.WorldProvider;
import baritone.utils.BlockStateInterface;
import baritone.utils.Helper;
import baritone.utils.InputOverrideHandler;
import net.minecraft.client.settings.KeyBinding;
import net.minecraft.world.chunk.Chunk;
import org.lwjgl.input.Keyboard;
import java.util.ArrayList;
import java.util.List;
/**
* @author Brady
@@ -38,57 +35,32 @@ import java.util.ArrayList;
*/
public final class GameEventHandler implements IGameEventListener, Helper {
private final ArrayList<IGameEventListener> listeners = new ArrayList<>();
private final Baritone baritone;
private final List<IGameEventListener> listeners = new ArrayList<>();
public GameEventHandler(Baritone baritone) {
this.baritone = baritone;
}
@Override
public final void onTick(TickEvent event) {
listeners.forEach(l -> {
if (canDispatch(l)) {
l.onTick(event);
}
});
listeners.forEach(l -> l.onTick(event));
}
@Override
public final void onPlayerUpdate(PlayerUpdateEvent event) {
listeners.forEach(l -> {
if (canDispatch(l)) {
l.onPlayerUpdate(event);
}
});
listeners.forEach(l -> l.onPlayerUpdate(event));
}
@Override
public final void onProcessKeyBinds() {
InputOverrideHandler inputHandler = Baritone.INSTANCE.getInputOverrideHandler();
// Simulate the key being held down this tick
for (InputOverrideHandler.Input input : InputOverrideHandler.Input.values()) {
KeyBinding keyBinding = input.getKeyBinding();
if (inputHandler.isInputForcedDown(keyBinding) && !keyBinding.isKeyDown()) {
int keyCode = keyBinding.getKeyCode();
if (keyCode < Keyboard.KEYBOARD_SIZE) {
KeyBinding.onTick(keyCode < 0 ? keyCode + 100 : keyCode);
}
}
}
listeners.forEach(l -> {
if (canDispatch(l)) {
l.onProcessKeyBinds();
}
});
listeners.forEach(IGameEventListener::onProcessKeyBinds);
}
@Override
public final void onSendChatMessage(ChatEvent event) {
listeners.forEach(l -> {
if (canDispatch(l)) {
l.onSendChatMessage(event);
}
});
listeners.forEach(l -> l.onSendChatMessage(event));
}
@Override
@@ -114,20 +86,12 @@ public final class GameEventHandler implements IGameEventListener, Helper {
}
listeners.forEach(l -> {
if (canDispatch(l)) {
l.onChunkEvent(event);
}
});
listeners.forEach(l -> l.onChunkEvent(event));
}
@Override
public final void onRenderPass(RenderEvent event) {
listeners.forEach(l -> {
if (canDispatch(l)) {
l.onRenderPass(event);
}
});
listeners.forEach(l -> l.onRenderPass(event));
}
@Override
@@ -143,72 +107,41 @@ public final class GameEventHandler implements IGameEventListener, Helper {
}
}
listeners.forEach(l -> {
if (canDispatch(l)) {
l.onWorldEvent(event);
}
});
listeners.forEach(l -> l.onWorldEvent(event));
}
@Override
public final void onSendPacket(PacketEvent event) {
listeners.forEach(l -> {
if (canDispatch(l)) {
l.onSendPacket(event);
}
});
listeners.forEach(l -> l.onSendPacket(event));
}
@Override
public final void onReceivePacket(PacketEvent event) {
listeners.forEach(l -> {
if (canDispatch(l)) {
l.onReceivePacket(event);
}
});
listeners.forEach(l -> l.onReceivePacket(event));
}
@Override
public void onPlayerRotationMove(RotationMoveEvent event) {
listeners.forEach(l -> {
if (canDispatch(l)) {
l.onPlayerRotationMove(event);
}
});
listeners.forEach(l -> l.onPlayerRotationMove(event));
}
@Override
public void onBlockInteract(BlockInteractEvent event) {
listeners.forEach(l -> {
if (canDispatch(l)) {
l.onBlockInteract(event);
}
});
listeners.forEach(l -> l.onBlockInteract(event));
}
@Override
public void onPlayerDeath() {
listeners.forEach(l -> {
if (canDispatch(l)) {
l.onPlayerDeath();
}
});
listeners.forEach(IGameEventListener::onPlayerDeath);
}
@Override
public void onPathEvent(PathEvent event) {
listeners.forEach(l -> {
if (canDispatch(l)) {
l.onPathEvent(event);
}
});
listeners.forEach(l -> l.onPathEvent(event));
}
public final void registerEventListener(IGameEventListener listener) {
this.listeners.add(listener);
}
private boolean canDispatch(IGameEventListener listener) {
return !(listener instanceof Toggleable) || ((Toggleable) listener).isEnabled();
}
}

View File

@@ -24,14 +24,12 @@ import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.Rotation;
import baritone.api.utils.RotationUtils;
import baritone.api.utils.VecUtils;
import baritone.utils.BlockBreakHelper;
import baritone.utils.BlockStateInterface;
import baritone.utils.Helper;
import baritone.utils.InputOverrideHandler;
import net.minecraft.block.BlockLiquid;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.world.chunk.EmptyChunk;
import java.util.ArrayList;
@@ -115,52 +113,31 @@ public abstract class Movement implements IMovement, Helper, MovementHelper {
@Override
public MovementStatus update() {
player().capabilities.isFlying = false;
MovementState latestState = updateState(currentState);
currentState = updateState(currentState);
if (MovementHelper.isLiquid(playerFeet())) {
latestState.setInput(Input.JUMP, true);
currentState.setInput(Input.JUMP, true);
}
if (player().isEntityInsideOpaqueBlock()) {
latestState.setInput(Input.CLICK_LEFT, true);
currentState.setInput(Input.CLICK_LEFT, true);
}
// If the movement target has to force the new rotations, or we aren't using silent move, then force the rotations
latestState.getTarget().getRotation().ifPresent(rotation ->
currentState.getTarget().getRotation().ifPresent(rotation ->
Baritone.INSTANCE.getLookBehavior().updateTarget(
rotation,
latestState.getTarget().hasToForceRotations()));
currentState.getTarget().hasToForceRotations()));
// TODO: calculate movement inputs from latestState.getGoal().position
// latestState.getTarget().position.ifPresent(null); NULL CONSUMER REALLY SHOULDN'T BE THE FINAL THING YOU SHOULD REALLY REPLACE THIS WITH ALMOST ACTUALLY ANYTHING ELSE JUST PLEASE DON'T LEAVE IT AS IT IS THANK YOU KANYE
this.didBreakLastTick = false;
latestState.getInputStates().forEach((input, forced) -> {
if (Baritone.settings().leftClickWorkaround.get()) {
RayTraceResult trace = mc.objectMouseOver;
boolean isBlockTrace = trace != null && trace.typeOfHit == RayTraceResult.Type.BLOCK;
boolean isLeftClick = forced && input == Input.CLICK_LEFT;
// If we're forcing left click, we're in a gui screen, and we're looking
// at a block, break the block without a direct game input manipulation.
if (mc.currentScreen != null && isLeftClick && isBlockTrace) {
BlockBreakHelper.tryBreakBlock(trace.getBlockPos(), trace.sideHit);
this.didBreakLastTick = true;
return;
}
}
currentState.getInputStates().forEach((input, forced) -> {
Baritone.INSTANCE.getInputOverrideHandler().setInputForceState(input, forced);
});
latestState.getInputStates().replaceAll((input, forced) -> false);
if (!this.didBreakLastTick) {
BlockBreakHelper.stopBreakingBlock();
}
currentState = latestState;
currentState.getInputStates().replaceAll((input, forced) -> false);
// If the current status indicates a completed movement
if (currentState.getStatus().isComplete()) {
onFinish(latestState);
Baritone.INSTANCE.getInputOverrideHandler().clearAllKeys();
}
return currentState.getStatus();
@@ -218,20 +195,6 @@ public abstract class Movement implements IMovement, Helper, MovementHelper {
return dest;
}
/**
* Run cleanup on state finish and declare success.
*/
public void onFinish(MovementState state) {
state.getInputStates().replaceAll((input, forced) -> false);
state.getInputStates().forEach((input, forced) -> Baritone.INSTANCE.getInputOverrideHandler().setInputForceState(input, forced));
}
public void cancel() {
currentState.getInputStates().replaceAll((input, forced) -> false);
currentState.getInputStates().forEach((input, forced) -> Baritone.INSTANCE.getInputOverrideHandler().setInputForceState(input, forced));
currentState.setStatus(MovementStatus.CANCELED);
}
@Override
public void reset() {
currentState = new MovementState().setStatus(MovementStatus.PREPPING);

View File

@@ -0,0 +1,115 @@
/*
* 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.process.ICustomGoalProcess;
import baritone.api.process.PathingCommand;
import baritone.api.process.PathingCommandType;
import baritone.utils.BaritoneProcessHelper;
import java.util.Objects;
/**
* As set by ExampleBaritoneControl or something idk
*
* @author leijurv
*/
public class CustomGoalProcess extends BaritoneProcessHelper implements ICustomGoalProcess {
/**
* The current goal
*/
private Goal goal;
/**
* The current process state.
*
* @see State
*/
private State state;
public CustomGoalProcess(Baritone baritone) {
super(baritone, 3);
}
@Override
public void setGoal(Goal goal) {
this.goal = goal;
this.state = State.GOAL_SET;
}
@Override
public void path() {
this.state = State.PATH_REQUESTED;
}
@Override
public Goal getGoal() {
return this.goal;
}
@Override
public boolean isActive() {
return this.state != State.NONE;
}
@Override
public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) {
switch (this.state) {
case GOAL_SET:
if (!baritone.getPathingBehavior().isPathing() && Objects.equals(baritone.getPathingBehavior().getGoal(), this.goal)) {
this.state = State.NONE;
}
return new PathingCommand(this.goal, PathingCommandType.CANCEL_AND_SET_GOAL);
case PATH_REQUESTED:
PathingCommand ret = new PathingCommand(this.goal, PathingCommandType.SET_GOAL_AND_PATH);
this.state = State.EXECUTING;
return ret;
case EXECUTING:
if (calcFailed) {
onLostControl();
}
if (this.goal == null || this.goal.isInGoal(playerFeet())) {
onLostControl(); // we're there xd
}
return new PathingCommand(this.goal, PathingCommandType.SET_GOAL_AND_PATH);
default:
throw new IllegalStateException();
}
}
@Override
public void onLostControl() {
this.state = State.NONE;
this.goal = null;
}
@Override
public String displayName() {
return "Custom Goal " + this.goal;
}
protected enum State {
NONE,
GOAL_SET,
PATH_REQUESTED,
EXECUTING
}
}

View File

@@ -15,14 +15,15 @@
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.behavior;
package baritone.process;
import baritone.Baritone;
import baritone.api.behavior.IFollowBehavior;
import baritone.api.event.events.TickEvent;
import baritone.api.pathing.goals.GoalNear;
import baritone.api.pathing.goals.GoalXZ;
import baritone.utils.Helper;
import baritone.api.process.IFollowProcess;
import baritone.api.process.PathingCommand;
import baritone.api.process.PathingCommandType;
import baritone.utils.BaritoneProcessHelper;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.BlockPos;
@@ -31,23 +32,16 @@ import net.minecraft.util.math.BlockPos;
*
* @author leijurv
*/
public final class FollowBehavior extends Behavior implements IFollowBehavior, Helper {
public final class FollowProcess extends BaritoneProcessHelper implements IFollowProcess {
private Entity following;
public FollowBehavior(Baritone baritone) {
super(baritone);
public FollowProcess(Baritone baritone) {
super(baritone, 1);
}
@Override
public void onTick(TickEvent event) {
if (event.getType() == TickEvent.Type.OUT) {
following = null;
return;
}
if (following == null) {
return;
}
public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) {
// lol this is trashy but it works
BlockPos pos;
if (Baritone.settings().followOffsetDistance.get() == 0) {
@@ -56,9 +50,22 @@ public final class FollowBehavior extends Behavior implements IFollowBehavior, H
GoalXZ g = GoalXZ.fromDirection(following.getPositionVector(), Baritone.settings().followOffsetDirection.get(), Baritone.settings().followOffsetDistance.get());
pos = new BlockPos(g.getX(), following.posY, g.getZ());
}
baritone.getPathingBehavior().setGoal(new GoalNear(pos, Baritone.settings().followRadius.get()));
((PathingBehavior) baritone.getPathingBehavior()).revalidateGoal();
baritone.getPathingBehavior().path();
return new PathingCommand(new GoalNear(pos, Baritone.settings().followRadius.get()), PathingCommandType.FORCE_REVALIDATE_GOAL_AND_PATH);
}
@Override
public boolean isActive() {
return following != null;
}
@Override
public void onLostControl() {
following = null;
}
@Override
public String displayName() {
return "Follow " + following;
}
@Override
@@ -70,10 +77,4 @@ public final class FollowBehavior extends Behavior implements IFollowBehavior, H
public Entity following() {
return this.following;
}
@Override
public void cancel() {
baritone.getPathingBehavior().cancel();
follow(null);
}
}

View 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.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());
}
}

View File

@@ -15,25 +15,30 @@
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.behavior;
package baritone.process;
import baritone.Baritone;
import baritone.api.behavior.IMineBehavior;
import baritone.api.event.events.TickEvent;
import baritone.api.pathing.goals.*;
import baritone.api.process.IMineProcess;
import baritone.api.process.PathingCommand;
import baritone.api.process.PathingCommandType;
import baritone.api.utils.RotationUtils;
import baritone.cache.CachedChunk;
import baritone.cache.ChunkPacker;
import baritone.cache.WorldProvider;
import baritone.cache.WorldScanner;
import baritone.pathing.movement.MovementHelper;
import baritone.utils.BaritoneProcessHelper;
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.*;
@@ -44,26 +49,27 @@ import java.util.stream.Collectors;
*
* @author leijurv
*/
public final class MineBehavior extends Behavior implements IMineBehavior, Helper {
public final class MineProcess extends BaritoneProcessHelper implements IMineProcess {
private static final int ORE_LOCATIONS_COUNT = 64;
private List<Block> mining;
private List<BlockPos> knownOreLocations;
private BlockPos branchPoint;
private int desiredQuantity;
private int tickCount;
public MineBehavior(Baritone baritone) {
super(baritone);
public MineProcess(Baritone baritone) {
super(baritone, 0);
}
@Override
public void onTick(TickEvent event) {
if (event.getType() == TickEvent.Type.OUT) {
cancel();
return;
}
if (mining == null) {
return;
}
public boolean isActive() {
return mining != null;
}
@Override
public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) {
if (desiredQuantity > 0) {
Item item = mining.get(0).getItemDropped(mining.get(0).getDefaultState(), new Random(), 0);
int curr = player().inventory.mainInventory.stream().filter(stack -> item.equals(stack.getItem())).mapToInt(ItemStack::getCount).sum();
@@ -71,35 +77,53 @@ public final class MineBehavior extends Behavior implements IMineBehavior, Helpe
if (curr >= desiredQuantity) {
logDirect("Have " + curr + " " + item.getItemStackDisplayName(new ItemStack(item, 1)));
cancel();
return;
return null;
}
}
if (calcFailed) {
logDirect("Unable to find any path to " + mining + ", canceling Mine");
cancel();
return null;
}
int mineGoalUpdateInterval = Baritone.settings().mineGoalUpdateInterval.get();
if (mineGoalUpdateInterval != 0 && event.getCount() % mineGoalUpdateInterval == 0) {
Baritone.INSTANCE.getExecutor().execute(this::rescan);
if (mineGoalUpdateInterval != 0 && tickCount++ % mineGoalUpdateInterval == 0) { // big brain
baritone.getExecutor().execute(this::rescan);
}
if (Baritone.settings().legitMine.get()) {
addNearby();
}
updateGoal();
baritone.getPathingBehavior().revalidateGoal();
Goal goal = updateGoal();
if (goal == null) {
// none in range
// maybe say something in chat? (ahem impact)
cancel();
return null;
}
return new PathingCommand(goal, PathingCommandType.REVALIDATE_GOAL_AND_PATH);
}
private void updateGoal() {
if (mining == null) {
return;
}
@Override
public void onLostControl() {
mine(0, (Block[]) null);
}
@Override
public String displayName() {
return "Mine " + mining;
}
private Goal updateGoal() {
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)));
Goal goal = new GoalComposite(locs2.stream().map(loc -> coalesce(loc, locs2)).toArray(Goal[]::new));
knownOreLocations = locs2;
return;
return goal;
}
// we don't know any ore locations at the moment
if (!Baritone.settings().legitMine.get()) {
return;
return null;
}
// only in non-Xray mode (aka legit mode) do we do this
if (branchPoint == null) {
@@ -108,8 +132,7 @@ public final class MineBehavior extends Behavior implements IMineBehavior, Helpe
// cool, path is over and we are at desired y
branchPoint = playerFeet();
} else {
baritone.getPathingBehavior().setGoalAndPath(new GoalYLevel(y));
return;
return new GoalYLevel(y);
}
}
@@ -117,7 +140,7 @@ public final class MineBehavior extends Behavior implements IMineBehavior, Helpe
// TODO mine 1x1 shafts to either side
branchPoint = branchPoint.north(10);
}
baritone.getPathingBehavior().setGoalAndPath(new GoalBlock(branchPoint));
return new GoalBlock(branchPoint);
}
private void rescan() {
@@ -127,10 +150,11 @@ 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);
cancel();
return;
}
knownOreLocations = locs;
@@ -158,7 +182,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(new BlockPos(entity));
}
}
}
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 +225,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,18 +241,19 @@ 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)
.filter(MineProcess::plausibleToBreak)
.sorted(Comparator.comparingDouble(Helper.HELPER.playerFeet()::distanceSq))
.collect(Collectors.toList());
@@ -225,13 +273,8 @@ public final class MineBehavior extends Behavior implements IMineBehavior, Helpe
}
@Override
public void mine(int quantity, String... blocks) {
this.mining = blocks == null || blocks.length == 0 ? null : Arrays.stream(blocks).map(ChunkPacker::stringToBlock).collect(Collectors.toList());
this.desiredQuantity = quantity;
this.knownOreLocations = new ArrayList<>();
this.branchPoint = null;
rescan();
updateGoal();
public void mineByName(int quantity, String... blocks) {
mine(quantity, blocks == null || blocks.length == 0 ? null : Arrays.stream(blocks).map(ChunkPacker::stringToBlock).toArray(Block[]::new));
}
@Override
@@ -241,12 +284,5 @@ public final class MineBehavior extends Behavior implements IMineBehavior, Helpe
this.knownOreLocations = new ArrayList<>();
this.branchPoint = null;
rescan();
updateGoal();
}
@Override
public void cancel() {
mine(0, (String[]) null);
baritone.getPathingBehavior().cancel();
}
}

View File

@@ -105,8 +105,7 @@ public class BaritoneAutoTest implements AbstractGameEventListener, Helper {
}
// Setup Baritone's pathing goal and (if needed) begin pathing
Baritone.INSTANCE.getPathingBehavior().setGoal(GOAL);
Baritone.INSTANCE.getPathingBehavior().path();
Baritone.INSTANCE.getCustomGoalProcess().setGoalAndPath(GOAL);
// If we have reached our goal, print a message and safely close the game
if (GOAL.isInGoal(playerFeet())) {

View File

@@ -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 <https://www.gnu.org/licenses/>.
*/
package baritone.utils;
import baritone.Baritone;
import baritone.api.process.IBaritoneProcess;
public abstract class BaritoneProcessHelper implements IBaritoneProcess, Helper {
public static final double DEFAULT_PRIORITY = 0;
protected final Baritone baritone;
private final double priority;
public BaritoneProcessHelper(Baritone baritone) {
this(baritone, DEFAULT_PRIORITY);
}
public BaritoneProcessHelper(Baritone baritone, double priority) {
this.baritone = baritone;
this.priority = priority;
baritone.getPathingControlManager().registerProcess(this);
}
@Override
public Baritone associatedWith() {
return baritone;
}
@Override
public boolean isTemporary() {
return false;
}
@Override
public double priority() {
return priority;
}
}

View File

@@ -20,6 +20,7 @@ package baritone.utils;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
/**
* @author Brady
@@ -32,6 +33,7 @@ public final class BlockBreakHelper implements Helper {
* between attempts, then we re-initialize the breaking process.
*/
private static BlockPos lastBlock;
private static boolean didBreakLastTick;
private BlockBreakHelper() {}
@@ -48,7 +50,23 @@ public final class BlockBreakHelper implements Helper {
public static void stopBreakingBlock() {
if (mc.playerController != null) {
mc.playerController.resetBlockRemoving();
}
}
lastBlock = null;
}
public static boolean tick(boolean isLeftClick) {
RayTraceResult trace = mc.objectMouseOver;
boolean isBlockTrace = trace != null && trace.typeOfHit == RayTraceResult.Type.BLOCK;
// If we're forcing left click, we're in a gui screen, and we're looking
// at a block, break the block without a direct game input manipulation.
if (mc.currentScreen != null && isLeftClick && isBlockTrace) {
tryBreakBlock(trace.getBlockPos(), trace.sideHit);
didBreakLastTick = true;
} else if (didBreakLastTick) {
stopBreakingBlock();
didBreakLastTick = false;
}
return !didBreakLastTick && isLeftClick;
}
}

View File

@@ -33,6 +33,7 @@ import baritone.cache.WorldProvider;
import baritone.pathing.calc.AbstractNodeCostSearch;
import baritone.pathing.movement.Movement;
import baritone.pathing.movement.Moves;
import baritone.process.CustomGoalProcess;
import net.minecraft.block.Block;
import net.minecraft.client.multiplayer.ChunkProviderClient;
import net.minecraft.entity.Entity;
@@ -73,7 +74,6 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
"sethome - Sets \"home\"\n" +
"home - Paths towards \"home\" \n" +
"costs - (debug) all movement costs from current location\n" +
"pause - Toggle pause\n" +
"damn - Daniel ";
public ExampleBaritoneControl(Baritone baritone) {
@@ -100,6 +100,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
public boolean runCommand(String msg0) {
String msg = msg0.toLowerCase(Locale.US).trim(); // don't reassign the argument LOL
PathingBehavior pathingBehavior = baritone.getPathingBehavior();
CustomGoalProcess customGoalProcess = baritone.getCustomGoalProcess();
List<Settings.Setting<Boolean>> toggleable = Baritone.settings().getAllValuesByType(Boolean.class);
for (Settings.Setting<Boolean> setting : toggleable) {
if (msg.equalsIgnoreCase(setting.getName())) {
@@ -187,21 +188,19 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
logDirect("unable to parse integer " + ex);
return true;
}
pathingBehavior.setGoal(goal);
customGoalProcess.setGoal(goal);
logDirect("Goal: " + goal);
return true;
}
if (msg.equals("path")) {
if (!pathingBehavior.path()) {
if (pathingBehavior.getGoal() == null) {
logDirect("No goal.");
} else {
if (pathingBehavior.getGoal().isInGoal(playerFeet())) {
logDirect("Already in goal");
} else {
logDirect("Currently executing a path. Please cancel it first.");
}
}
if (pathingBehavior.getGoal() == null) {
logDirect("No goal.");
} else if (pathingBehavior.getGoal().isInGoal(playerFeet())) {
logDirect("Already in goal");
} else if (pathingBehavior.isPathing()) {
logDirect("Currently executing a path. Please cancel it first.");
} else {
customGoalProcess.setGoalAndPath(pathingBehavior.getGoal());
}
return true;
}
@@ -223,21 +222,16 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
return true;
}
if (msg.equals("axis")) {
pathingBehavior.setGoal(new GoalAxis());
pathingBehavior.path();
customGoalProcess.setGoalAndPath(new GoalAxis());
return true;
}
if (msg.equals("cancel") || msg.equals("stop")) {
baritone.getMineBehavior().cancel();
baritone.getFollowBehavior().cancel();
pathingBehavior.cancel();
pathingBehavior.cancelEverything();
logDirect("ok canceled");
return true;
}
if (msg.equals("forcecancel")) {
baritone.getMineBehavior().cancel();
baritone.getFollowBehavior().cancel();
pathingBehavior.cancel();
pathingBehavior.cancelEverything();
AbstractNodeCostSearch.forceCancel();
pathingBehavior.forceCancel();
logDirect("ok force canceled");
@@ -260,15 +254,12 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
logDirect("Inverting goal of player feet");
runAwayFrom = playerFeet();
}
pathingBehavior.setGoal(new GoalRunAway(1, runAwayFrom) {
customGoalProcess.setGoalAndPath(new GoalRunAway(1, runAwayFrom) {
@Override
public boolean isInGoal(int x, int y, int z) {
return false;
}
});
if (!pathingBehavior.path()) {
logDirect("Currently executing a path. Please cancel it first.");
}
return true;
}
if (msg.startsWith("follow")) {
@@ -288,7 +279,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
logDirect("Not found");
return true;
}
baritone.getFollowBehavior().follow(toFollow.get());
baritone.getFollowProcess().follow(toFollow.get());
logDirect("Following " + toFollow.get());
return true;
}
@@ -320,7 +311,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
int quantity = Integer.parseInt(blockTypes[1]);
Block block = ChunkPacker.stringToBlock(blockTypes[0]);
Objects.requireNonNull(block);
baritone.getMineBehavior().mine(quantity, block);
baritone.getMineProcess().mine(quantity, block);
logDirect("Will mine " + quantity + " " + blockTypes[0]);
return true;
} catch (NumberFormatException | ArrayIndexOutOfBoundsException | NullPointerException ex) {}
@@ -331,14 +322,14 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
}
}
baritone.getMineBehavior().mine(0, blockTypes);
baritone.getMineProcess().mineByName(0, blockTypes);
logDirect("Started mining blocks of type " + Arrays.toString(blockTypes));
return true;
}
if (msg.startsWith("thisway")) {
try {
Goal goal = GoalXZ.fromDirection(playerFeetAsVec(), player().rotationYaw, Double.parseDouble(msg.substring(7).trim()));
pathingBehavior.setGoal(goal);
customGoalProcess.setGoal(goal);
logDirect("Goal: " + goal);
} catch (NumberFormatException ex) {
logDirect("Error unable to parse '" + msg.substring(7).trim() + "' to a double.");
@@ -407,13 +398,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
return true;
}
} else {
List<BlockPos> locs = baritone.getMineBehavior().searchWorld(Collections.singletonList(block), 64);
if (locs.isEmpty()) {
logDirect("No locations for " + mining + " known, cancelling");
return true;
}
pathingBehavior.setGoal(new GoalComposite(locs.stream().map(GoalGetToBlock::new).toArray(Goal[]::new)));
pathingBehavior.path();
baritone.getGetToBlockProcess().getToBlock(block);
return true;
}
} else {
@@ -424,10 +409,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
}
}
Goal goal = new GoalBlock(waypoint.getLocation());
pathingBehavior.setGoal(goal);
if (!pathingBehavior.path() && !goal.isInGoal(playerFeet())) {
logDirect("Currently executing a path. Please cancel it first.");
}
customGoalProcess.setGoalAndPath(goal);
return true;
}
if (msg.equals("spawn") || msg.equals("bed")) {
@@ -437,10 +419,10 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
// for some reason the default spawnpoint is underground sometimes
Goal goal = new GoalXZ(spawnPoint.getX(), spawnPoint.getZ());
logDirect("spawn not saved, defaulting to world spawn. set goal to " + goal);
pathingBehavior.setGoal(goal);
customGoalProcess.setGoalAndPath(goal);
} else {
Goal goal = new GoalBlock(waypoint.getLocation());
pathingBehavior.setGoal(goal);
Goal goal = new GoalGetToBlock(waypoint.getLocation());
customGoalProcess.setGoalAndPath(goal);
logDirect("Set goal to most recent bed " + goal);
}
return true;
@@ -456,8 +438,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
logDirect("home not saved");
} else {
Goal goal = new GoalBlock(waypoint.getLocation());
pathingBehavior.setGoal(goal);
pathingBehavior.path();
customGoalProcess.setGoalAndPath(goal);
logDirect("Going to saved home " + goal);
}
return true;
@@ -479,11 +460,6 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
}
return true;
}
if (msg.equals("pause")) {
boolean enabled = pathingBehavior.toggle();
logDirect("Pathing Behavior has " + (enabled ? "resumed" : "paused") + ".");
return true;
}
if (msg.equals("damn")) {
logDirect("daniel");
}

View File

@@ -17,7 +17,11 @@
package baritone.utils;
import baritone.Baritone;
import baritone.api.event.events.TickEvent;
import baritone.behavior.Behavior;
import net.minecraft.client.settings.KeyBinding;
import org.lwjgl.input.Keyboard;
import java.util.HashMap;
import java.util.Map;
@@ -30,7 +34,11 @@ import java.util.Map;
* @author Brady
* @since 7/31/2018 11:20 PM
*/
public final class InputOverrideHandler implements Helper {
public final class InputOverrideHandler extends Behavior implements Helper {
public InputOverrideHandler(Baritone baritone) {
super(baritone);
}
/**
* Maps keybinds to whether or not we are forcing their state down.
@@ -61,6 +69,33 @@ public final class InputOverrideHandler implements Helper {
inputForceStateMap.put(input.getKeyBinding(), forced);
}
@Override
public final void onProcessKeyBinds() {
// Simulate the key being held down this tick
for (InputOverrideHandler.Input input : Input.values()) {
KeyBinding keyBinding = input.getKeyBinding();
if (isInputForcedDown(keyBinding) && !keyBinding.isKeyDown()) {
int keyCode = keyBinding.getKeyCode();
if (keyCode < Keyboard.KEYBOARD_SIZE) {
KeyBinding.onTick(keyCode < 0 ? keyCode + 100 : keyCode);
}
}
}
}
@Override
public final void onTick(TickEvent event) {
if (event.getType() == TickEvent.Type.OUT) {
return;
}
if (Baritone.settings().leftClickWorkaround.get()) {
boolean stillClick = BlockBreakHelper.tick(isInputForcedDown(Input.CLICK_LEFT.keyBinding));
setInputForceState(Input.CLICK_LEFT, stillClick);
}
}
/**
* An {@link Enum} representing the possible inputs that we may want to force.
*/

View File

@@ -0,0 +1,146 @@
/*
* 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.utils;
import baritone.Baritone;
import baritone.api.pathing.goals.Goal;
import baritone.api.process.IBaritoneProcess;
import baritone.api.process.PathingCommand;
import baritone.behavior.PathingBehavior;
import baritone.pathing.path.PathExecutor;
import net.minecraft.util.math.BlockPos;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
public class PathingControlManager {
private final Baritone baritone;
private final HashSet<IBaritoneProcess> processes; // unGh
private IBaritoneProcess inControlLastTick;
private IBaritoneProcess inControlThisTick;
public PathingControlManager(Baritone baritone) {
this.baritone = baritone;
this.processes = new HashSet<>();
}
public void registerProcess(IBaritoneProcess process) {
process.onLostControl(); // make sure it's reset
processes.add(process);
}
public void cancelEverything() {
for (IBaritoneProcess proc : processes) {
proc.onLostControl();
if (proc.isActive() && !proc.isTemporary()) { // it's okay for a temporary thing (like combat pause) to maintain control even if you say to cancel
// but not for a non temporary thing
throw new IllegalStateException(proc.displayName());
}
}
}
public IBaritoneProcess inControlThisTick() {
return inControlThisTick;
}
public void doTheThingWithTheStuff() {
inControlLastTick = inControlThisTick;
PathingCommand cmd = doTheStuff();
if (cmd == null) {
return;
}
PathingBehavior p = baritone.getPathingBehavior();
switch (cmd.commandType) {
case REQUEST_PAUSE:
p.requestPause();
break;
case CANCEL_AND_SET_GOAL:
p.secretInternalSetGoal(cmd.goal);
p.cancelSegmentIfSafe();
break;
case FORCE_REVALIDATE_GOAL_AND_PATH:
p.secretInternalSetGoalAndPath(cmd.goal);
if (cmd.goal == null || revalidateGoal(cmd.goal)) {
// pwnage
p.cancelSegmentIfSafe();
}
break;
case REVALIDATE_GOAL_AND_PATH:
p.secretInternalSetGoalAndPath(cmd.goal);
if (Baritone.settings().cancelOnGoalInvalidation.get() && (cmd.goal == null || revalidateGoal(cmd.goal))) {
p.cancelSegmentIfSafe();
}
break;
case SET_GOAL_AND_PATH:
// now this i can do
if (cmd.goal != null) {
baritone.getPathingBehavior().secretInternalSetGoalAndPath(cmd.goal);
}
break;
default:
throw new IllegalStateException();
}
}
public boolean revalidateGoal(Goal newGoal) {
PathExecutor current = baritone.getPathingBehavior().getCurrent();
if (current != null) {
Goal intended = current.getPath().getGoal();
BlockPos end = current.getPath().getDest();
if (intended.isInGoal(end) && !newGoal.isInGoal(end)) {
// this path used to end in the goal
// but the goal has changed, so there's no reason to continue...
return true;
}
}
return false;
}
public PathingCommand doTheStuff() {
List<IBaritoneProcess> inContention = processes.stream().filter(IBaritoneProcess::isActive).sorted(Comparator.comparingDouble(IBaritoneProcess::priority)).collect(Collectors.toList());
boolean found = false;
boolean cancelOthers = false;
PathingCommand exec = null;
for (int i = inContention.size() - 1; i >= 0; i--) { // truly a gamer moment
IBaritoneProcess proc = inContention.get(i);
if (found) {
if (cancelOthers) {
proc.onLostControl();
}
} else {
exec = proc.onTick(Objects.equals(proc, inControlLastTick) && baritone.getPathingBehavior().calcFailedLastTick(), baritone.getPathingBehavior().isSafeToCancel());
if (exec == null) {
if (proc.isActive()) {
throw new IllegalStateException(proc.displayName());
}
proc.onLostControl();
continue;
}
//System.out.println("Executing command " + exec.commandType + " " + exec.goal + " from " + proc.displayName());
inControlThisTick = proc;
found = true;
cancelOthers = !proc.isTemporary();
}
}
return exec;
}
}