diff --git a/src/main/java/baritone/Baritone.java b/src/main/java/baritone/Baritone.java
index f7a20b0f..33916d59 100755
--- a/src/main/java/baritone/Baritone.java
+++ b/src/main/java/baritone/Baritone.java
@@ -80,6 +80,7 @@ public class Baritone implements IBaritone {
private CustomGoalProcess customGoalProcess;
private BuilderProcess builderProcess;
private ExploreProcess exploreProcess;
+ private FarmProcess farmProcess;
private PathingControlManager pathingControlManager;
@@ -120,6 +121,7 @@ public class Baritone implements IBaritone {
getToBlockProcess = new GetToBlockProcess(this);
builderProcess = new BuilderProcess(this);
exploreProcess = new ExploreProcess(this);
+ farmProcess = new FarmProcess(this);
}
this.worldProvider = new WorldProvider();
@@ -197,6 +199,10 @@ public class Baritone implements IBaritone {
return this.mineProcess;
}
+ public FarmProcess getFarmProcess() {
+ return this.farmProcess;
+ }
+
@Override
public PathingBehavior getPathingBehavior() {
return this.pathingBehavior;
diff --git a/src/main/java/baritone/pathing/movement/movements/MovementParkour.java b/src/main/java/baritone/pathing/movement/movements/MovementParkour.java
index ce5f77e9..fbf57e6c 100644
--- a/src/main/java/baritone/pathing/movement/movements/MovementParkour.java
+++ b/src/main/java/baritone/pathing/movement/movements/MovementParkour.java
@@ -106,7 +106,9 @@ public class MovementParkour extends Movement {
return;
}
}
- if (MovementHelper.canWalkOn(context.bsi, x + xDiff * i, y - 1, z + zDiff * i)) {
+ IBlockState landingOn = context.bsi.get0(x + xDiff * i, y - 1, z + zDiff * i);
+ // farmland needs to be canwalkon otherwise farm can never work at all, but we want to specifically disallow ending a jumy on farmland haha
+ if (landingOn.getBlock() != Blocks.FARMLAND && MovementHelper.canWalkOn(context.bsi, x + xDiff * i, y - 1, z + zDiff * i, landingOn)) {
res.x = x + xDiff * i;
res.y = y;
res.z = z + zDiff * i;
diff --git a/src/main/java/baritone/process/FarmProcess.java b/src/main/java/baritone/process/FarmProcess.java
new file mode 100644
index 00000000..9d27f953
--- /dev/null
+++ b/src/main/java/baritone/process/FarmProcess.java
@@ -0,0 +1,121 @@
+/*
+ * 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.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.process.PathingCommand;
+import baritone.api.process.PathingCommandType;
+import baritone.api.utils.Rotation;
+import baritone.api.utils.RotationUtils;
+import baritone.api.utils.input.Input;
+import baritone.cache.WorldScanner;
+import baritone.utils.BaritoneProcessHelper;
+import net.minecraft.block.BlockAir;
+import net.minecraft.block.BlockCrops;
+import net.minecraft.block.state.IBlockState;
+import net.minecraft.init.Blocks;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.RayTraceResult;
+import net.minecraft.util.math.Vec3d;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+
+public class FarmProcess extends BaritoneProcessHelper {
+
+ private boolean active;
+
+ public FarmProcess(Baritone baritone) {
+ super(baritone);
+ }
+
+ @Override
+ public boolean isActive() {
+ return active;
+ }
+
+ public void doit() {
+ active = true;
+ }
+
+ @Override
+ public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) {
+ List memes = WorldScanner.INSTANCE.scanChunkRadius(ctx, Arrays.asList(Blocks.FARMLAND, Blocks.WHEAT), 256, 10, 4);
+
+ List toBreak = new ArrayList<>();
+ List toRightClickOnTop = new ArrayList<>();
+ for (BlockPos pos : memes) {
+ IBlockState state = ctx.world().getBlockState(pos);
+ if (state.getBlock() == Blocks.FARMLAND) {
+ if (ctx.world().getBlockState(pos.up()).getBlock() instanceof BlockAir) {
+ toRightClickOnTop.add(pos);
+ }
+ } else {
+ if (state.getValue(BlockCrops.AGE) == 7) {
+ toBreak.add(pos);
+ }
+ }
+ }
+
+ baritone.getInputOverrideHandler().clearAllKeys();
+ for (BlockPos pos : toBreak) {
+ Optional rot = RotationUtils.reachable(ctx, pos);
+ if (rot.isPresent()) {
+ baritone.getLookBehavior().updateTarget(rot.get(), true);
+ if (ctx.objectMouseOver() != null && ctx.objectMouseOver().typeOfHit == RayTraceResult.Type.BLOCK && ctx.objectMouseOver().getBlockPos().equals(pos)) {
+ baritone.getInputOverrideHandler().setInputForceState(Input.CLICK_LEFT, true);
+ }
+ return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE);
+ }
+ }
+ for (BlockPos pos : toRightClickOnTop) {
+ Optional rot = RotationUtils.reachableOffset(ctx.player(), pos, new Vec3d(pos.getX() + 0.5, pos.getY() + 1, pos.getZ() + 0.5), ctx.playerController().getBlockReachDistance());
+ if (rot.isPresent()) {
+ baritone.getLookBehavior().updateTarget(rot.get(), true);
+ if (ctx.objectMouseOver() != null && ctx.objectMouseOver().typeOfHit == RayTraceResult.Type.BLOCK && ctx.objectMouseOver().getBlockPos().equals(pos)) {
+ baritone.getInputOverrideHandler().setInputForceState(Input.CLICK_RIGHT, true);
+ }
+ return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE);
+ }
+ }
+
+ List goalz = new ArrayList<>();
+ for (BlockPos pos : toBreak) {
+ goalz.add(new GoalBlock(pos));
+ }
+ for (BlockPos pos : toRightClickOnTop) {
+ goalz.add(new GoalBlock(pos.up()));
+ }
+ return new PathingCommand(new GoalComposite(goalz.toArray(new Goal[0])), PathingCommandType.SET_GOAL_AND_PATH);
+ }
+
+ @Override
+ public void onLostControl() {
+ active = false;
+ }
+
+ @Override
+ public String displayName0() {
+ return "Farming";
+ }
+}
diff --git a/src/main/java/baritone/utils/ExampleBaritoneControl.java b/src/main/java/baritone/utils/ExampleBaritoneControl.java
index f4261f07..4a819d74 100644
--- a/src/main/java/baritone/utils/ExampleBaritoneControl.java
+++ b/src/main/java/baritone/utils/ExampleBaritoneControl.java
@@ -382,6 +382,11 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
logDirect("okay");
return true;
}
+ if (msg.equals("farm")) {
+ baritone.getFarmProcess().doit();
+ logDirect("farming");
+ return true;
+ }
if (msg.equals("echest")) {
Optional> contents = baritone.getMemoryBehavior().echest();
if (contents.isPresent()) {