From 8d55fba8fd9a90579468e84705e3557f389fb3c8 Mon Sep 17 00:00:00 2001 From: Avtera <69560119+Avtera@users.noreply.github.com> Date: Wed, 13 Nov 2024 14:54:39 +0700 Subject: [PATCH 1/7] compensate for soulsand block height causing farm item pickup goal inside the block --- src/main/java/baritone/process/FarmProcess.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/baritone/process/FarmProcess.java b/src/main/java/baritone/process/FarmProcess.java index b38ba767f..071931ca9 100644 --- a/src/main/java/baritone/process/FarmProcess.java +++ b/src/main/java/baritone/process/FarmProcess.java @@ -379,8 +379,8 @@ public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { if (entity instanceof ItemEntity && entity.onGround()) { ItemEntity ei = (ItemEntity) entity; if (PICKUP_DROPPED.contains(ei.getItem().getItem())) { - // +0.1 because of farmland's 0.9375 dummy height lol - goalz.add(new GoalBlock(new BetterBlockPos(entity.position().x, entity.position().y + 0.1, entity.position().z))); + // +0.1 because of farmland's 0.9375 and soulsand's 0.875 dummy height lol + goalz.add(new GoalBlock(new BetterBlockPos(entity.position().x, entity.position().y + 0.125, entity.position().z))); } } } From 62302f9ee5fd41d5c8e25ec2e0daa65dbc33e542 Mon Sep 17 00:00:00 2001 From: Avtera <69560119+Avtera@users.noreply.github.com> Date: Wed, 13 Nov 2024 14:57:42 +0700 Subject: [PATCH 2/7] add options to enable farm continuously --- src/api/java/baritone/api/Settings.java | 18 +- .../baritone/api/process/IFarmProcess.java | 6 + .../java/baritone/process/FarmProcess.java | 172 ++++++++++++------ 3 files changed, 137 insertions(+), 59 deletions(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index d9cb501ef..03b94415a 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -981,6 +981,22 @@ public final class Settings { */ public final Setting farmMaxScanSize = new Setting<>(256); + /** + * true = farm farm farm, i don't want to stop! + * false = allow farm to stop or fail + */ + public final Setting farmContinuously = new Setting<>(false); + + /** + * How much farming task is enough for the Continuous Farm to resume? + */ + public final Setting farmContinuouslyThreshold = new Setting<>(16); + + /** + * Time interval (in seconds) for the Continuous Farm to check if threshold is fulfilled? + */ + public final Setting farmContinuouslyIntervalSecs = new Setting<>(TimeUnit.MINUTES.toSeconds(2)); + /** * When the cache scan gives less blocks than the maximum threshold (but still above zero), scan the main world too. *

@@ -1397,7 +1413,7 @@ public final class Settings { /** * Desktop notification on farm fail */ - public final Setting notificationOnFarmFail = new Setting<>(true); + public final Setting notificationOnFarmProcess = new Setting<>(true); /** * Desktop notification on build finished diff --git a/src/api/java/baritone/api/process/IFarmProcess.java b/src/api/java/baritone/api/process/IFarmProcess.java index 0c07567de..7405bde5a 100644 --- a/src/api/java/baritone/api/process/IFarmProcess.java +++ b/src/api/java/baritone/api/process/IFarmProcess.java @@ -21,6 +21,12 @@ public interface IFarmProcess extends IBaritoneProcess { + /** + * Resume or pause the Farm Continuously + */ + void pause(); + void resume(); + /** * Begin to search for crops to farm with in specified aria * from specified location. diff --git a/src/main/java/baritone/process/FarmProcess.java b/src/main/java/baritone/process/FarmProcess.java index 071931ca9..4c02ade64 100644 --- a/src/main/java/baritone/process/FarmProcess.java +++ b/src/main/java/baritone/process/FarmProcess.java @@ -65,6 +65,8 @@ public final class FarmProcess extends BaritoneProcessHelper implements IFarmProcess { private boolean active; + private boolean paused; + private Long time; private List locations; private int tickCount; @@ -109,6 +111,20 @@ public boolean isActive() { return active; } + @Override + public void pause() { + this.paused = true; + } + + @Override + public void resume() { + this.paused = false; + } + + public boolean isPaused() { + return this.paused; + } + @Override public void farm(int range, BlockPos pos) { if (pos == null) { @@ -121,6 +137,14 @@ public void farm(int range, BlockPos pos) { locations = null; } + public Long getTime() { + return time; + } + + public void setTime(Long time) { + this.time = time; + } + private enum Harvest { WHEAT((CropBlock) Blocks.WHEAT), CARROTS((CropBlock) Blocks.CARROTS), @@ -220,6 +244,10 @@ public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { if (locations == null) { return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE); } + // Farm Continuously: Block pathing while paused + if (isPaused() && System.currentTimeMillis() < getTime()) { + return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE); + } List toBreak = new ArrayList<>(); List openFarmland = new ArrayList<>(); List bonemealable = new ArrayList<>(); @@ -266,55 +294,36 @@ public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { } } - baritone.getInputOverrideHandler().clearAllKeys(); - BetterBlockPos playerPos = ctx.playerFeet(); - double blockReachDistance = ctx.playerController().getBlockReachDistance(); - for (BlockPos pos : toBreak) { - if (playerPos.distSqr(pos) > blockReachDistance * blockReachDistance) { - continue; - } - Optional rot = RotationUtils.reachable(ctx, pos); - if (rot.isPresent() && isSafeToCancel) { - baritone.getLookBehavior().updateTarget(rot.get(), true); - MovementHelper.switchToBestToolFor(ctx, ctx.world().getBlockState(pos)); - if (ctx.isLookingAt(pos)) { - baritone.getInputOverrideHandler().setInputForceState(Input.CLICK_LEFT, true); + // Farm Continuously: Block input while paused + if (!isPaused()) { + baritone.getInputOverrideHandler().clearAllKeys(); + BetterBlockPos playerPos = ctx.playerFeet(); + double blockReachDistance = ctx.playerController().getBlockReachDistance(); + for (BlockPos pos : toBreak) { + if (playerPos.distSqr(pos) > blockReachDistance * blockReachDistance) { + continue; } - return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE); - } - } - ArrayList both = new ArrayList<>(openFarmland); - both.addAll(openSoulsand); - for (BlockPos pos : both) { - if (playerPos.distSqr(pos) > blockReachDistance * blockReachDistance) { - continue; - } - boolean soulsand = openSoulsand.contains(pos); - Optional rot = RotationUtils.reachableOffset(ctx, pos, new Vec3(pos.getX() + 0.5, pos.getY() + 1, pos.getZ() + 0.5), blockReachDistance, false); - if (rot.isPresent() && isSafeToCancel && baritone.getInventoryBehavior().throwaway(true, soulsand ? this::isNetherWart : this::isPlantable)) { - HitResult result = RayTraceUtils.rayTraceTowards(ctx.player(), rot.get(), blockReachDistance); - if (result instanceof BlockHitResult && ((BlockHitResult) result).getDirection() == Direction.UP) { + Optional rot = RotationUtils.reachable(ctx, pos); + if (rot.isPresent() && isSafeToCancel) { baritone.getLookBehavior().updateTarget(rot.get(), true); + MovementHelper.switchToBestToolFor(ctx, ctx.world().getBlockState(pos)); if (ctx.isLookingAt(pos)) { - baritone.getInputOverrideHandler().setInputForceState(Input.CLICK_RIGHT, true); + baritone.getInputOverrideHandler().setInputForceState(Input.CLICK_LEFT, true); } return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE); } } - } - for (BlockPos pos : openLog) { - if (playerPos.distSqr(pos) > blockReachDistance * blockReachDistance) { - continue; - } - for (Direction dir : Direction.Plane.HORIZONTAL) { - if (!(ctx.world().getBlockState(pos.relative(dir)).getBlock() instanceof AirBlock)) { + ArrayList both = new ArrayList<>(openFarmland); + both.addAll(openSoulsand); + for (BlockPos pos : both) { + if (playerPos.distSqr(pos) > blockReachDistance * blockReachDistance) { continue; } - Vec3 faceCenter = Vec3.atCenterOf(pos).add(Vec3.atLowerCornerOf(dir.getNormal()).scale(0.5)); - Optional rot = RotationUtils.reachableOffset(ctx, pos, faceCenter, blockReachDistance, false); - if (rot.isPresent() && isSafeToCancel && baritone.getInventoryBehavior().throwaway(true, this::isCocoa)) { + boolean soulsand = openSoulsand.contains(pos); + Optional rot = RotationUtils.reachableOffset(ctx, pos, new Vec3(pos.getX() + 0.5, pos.getY() + 1, pos.getZ() + 0.5), blockReachDistance, false); + if (rot.isPresent() && isSafeToCancel && baritone.getInventoryBehavior().throwaway(true, soulsand ? this::isNetherWart : this::isPlantable)) { HitResult result = RayTraceUtils.rayTraceTowards(ctx.player(), rot.get(), blockReachDistance); - if (result instanceof BlockHitResult && ((BlockHitResult) result).getDirection() == dir) { + if (result instanceof BlockHitResult && ((BlockHitResult) result).getDirection() == Direction.UP) { baritone.getLookBehavior().updateTarget(rot.get(), true); if (ctx.isLookingAt(pos)) { baritone.getInputOverrideHandler().setInputForceState(Input.CLICK_RIGHT, true); @@ -323,27 +332,51 @@ public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { } } } - } - for (BlockPos pos : bonemealable) { - if (playerPos.distSqr(pos) > blockReachDistance * blockReachDistance) { - continue; + for (BlockPos pos : openLog) { + if (playerPos.distSqr(pos) > blockReachDistance * blockReachDistance) { + continue; + } + for (Direction dir : Direction.Plane.HORIZONTAL) { + if (!(ctx.world().getBlockState(pos.relative(dir)).getBlock() instanceof AirBlock)) { + continue; + } + Vec3 faceCenter = Vec3.atCenterOf(pos).add(Vec3.atLowerCornerOf(dir.getNormal()).scale(0.5)); + Optional rot = RotationUtils.reachableOffset(ctx, pos, faceCenter, blockReachDistance, false); + if (rot.isPresent() && isSafeToCancel && baritone.getInventoryBehavior().throwaway(true, this::isCocoa)) { + HitResult result = RayTraceUtils.rayTraceTowards(ctx.player(), rot.get(), blockReachDistance); + if (result instanceof BlockHitResult && ((BlockHitResult) result).getDirection() == dir) { + baritone.getLookBehavior().updateTarget(rot.get(), true); + if (ctx.isLookingAt(pos)) { + baritone.getInputOverrideHandler().setInputForceState(Input.CLICK_RIGHT, true); + } + return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE); + } + } + } } - Optional rot = RotationUtils.reachable(ctx, pos); - if (rot.isPresent() && isSafeToCancel && baritone.getInventoryBehavior().throwaway(true, this::isBoneMeal)) { - baritone.getLookBehavior().updateTarget(rot.get(), true); - if (ctx.isLookingAt(pos)) { - baritone.getInputOverrideHandler().setInputForceState(Input.CLICK_RIGHT, true); + for (BlockPos pos : bonemealable) { + if (playerPos.distSqr(pos) > blockReachDistance * blockReachDistance) { + continue; + } + Optional rot = RotationUtils.reachable(ctx, pos); + if (rot.isPresent() && isSafeToCancel && baritone.getInventoryBehavior().throwaway(true, this::isBoneMeal)) { + baritone.getLookBehavior().updateTarget(rot.get(), true); + if (ctx.isLookingAt(pos)) { + baritone.getInputOverrideHandler().setInputForceState(Input.CLICK_RIGHT, true); + } + return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE); } - return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE); } } if (calcFailed) { - logDirect("Farm failed"); - if (Baritone.settings().notificationOnFarmFail.value) { - logNotification("Farm failed", true); + if (!Baritone.settings().farmContinuously.value) { + logDirect("Farm failed"); + if (Baritone.settings().notificationOnFarmProcess.value) { + logNotification("Farm failed", true); + } + onLostControl(); } - onLostControl(); return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE); } @@ -384,14 +417,37 @@ public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { } } } - if (goalz.isEmpty()) { - logDirect("Farm failed"); - if (Baritone.settings().notificationOnFarmFail.value) { - logNotification("Farm failed", true); + if (goalz.isEmpty() && !isPaused()) { + if (!Baritone.settings().farmContinuously.value) { + logDirect("Farm failed"); + if (Baritone.settings().notificationOnFarmProcess.value) { + logNotification("Farm failed", true); + } + onLostControl(); + return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE); + } + // Farm Continuously: Begin pause state after no goals detected + pause(); + setTime(System.currentTimeMillis() + (Baritone.settings().farmContinuouslyIntervalSecs.value * 1000)); + logDirect("Farm standby"); + if (Baritone.settings().notificationOnFarmProcess.value) { + logNotification("Farm standby", false); } - onLostControl(); return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE); } + if (isPaused()) { + // Farm Continuously: Reset the interval if the amount of goals can't fulfill the threshold + if (goalz.size() < Baritone.settings().farmContinuouslyThreshold.value) { + setTime(System.currentTimeMillis() + (Baritone.settings().farmContinuouslyIntervalSecs.value * 1000)); + return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE); + } + // Farm Continuously: Resume farming + resume(); + logDirect("Found " + goalz.size() + " task, farming"); + if (Baritone.settings().notificationOnFarmProcess.value) { + logNotification("Found " + goalz.size() + " task, farming", false); + } + } return new PathingCommand(new GoalComposite(goalz.toArray(new Goal[0])), PathingCommandType.SET_GOAL_AND_PATH); } From ada0c6213adcd6536ee46c324006ba79b2c0acb1 Mon Sep 17 00:00:00 2001 From: Avtera <69560119+Avtera@users.noreply.github.com> Date: Wed, 13 Nov 2024 15:32:50 +0700 Subject: [PATCH 3/7] add option for farm to prioritize item gather --- src/api/java/baritone/api/Settings.java | 5 +++++ src/main/java/baritone/process/FarmProcess.java | 12 ++++++++++++ 2 files changed, 17 insertions(+) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 03b94415a..38bd2f5fc 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -981,6 +981,11 @@ public final class Settings { */ public final Setting farmMaxScanSize = new Setting<>(256); + /** + * Prioritize gathering farm related drops + */ + public final Setting farmPrioritizeGather = new Setting<>(false); + /** * true = farm farm farm, i don't want to stop! * false = allow farm to stop or fail diff --git a/src/main/java/baritone/process/FarmProcess.java b/src/main/java/baritone/process/FarmProcess.java index 4c02ade64..119ed59dc 100644 --- a/src/main/java/baritone/process/FarmProcess.java +++ b/src/main/java/baritone/process/FarmProcess.java @@ -296,6 +296,18 @@ public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { // Farm Continuously: Block input while paused if (!isPaused()) { + // Check if item gather is prioritized + if (Baritone.settings().farmPrioritizeGather.value) { + for (Entity entity : ctx.entities()) { + if (entity instanceof ItemEntity && entity.onGround()) { + ItemEntity ei = (ItemEntity) entity; + if (PICKUP_DROPPED.contains(ei.getItem().getItem())) { + // +0.1 because of farmland's 0.9375 and soulsand's 0.875 dummy height lol + return new PathingCommand(new GoalBlock(new BetterBlockPos(entity.position().x, entity.position().y + 0.125, entity.position().z)), PathingCommandType.SET_GOAL_AND_PATH); + } + } + } + } baritone.getInputOverrideHandler().clearAllKeys(); BetterBlockPos playerPos = ctx.playerFeet(); double blockReachDistance = ctx.playerController().getBlockReachDistance(); From 95db4b4af5677b24f4f5d11f074739f8b0a9295d Mon Sep 17 00:00:00 2001 From: Avtera <69560119+Avtera@users.noreply.github.com> Date: Thu, 14 Nov 2024 08:18:17 +0700 Subject: [PATCH 4/7] fix some dumb mistake for farm continuously --- src/main/java/baritone/process/FarmProcess.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/baritone/process/FarmProcess.java b/src/main/java/baritone/process/FarmProcess.java index 119ed59dc..77c06cb10 100644 --- a/src/main/java/baritone/process/FarmProcess.java +++ b/src/main/java/baritone/process/FarmProcess.java @@ -445,7 +445,7 @@ public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { if (Baritone.settings().notificationOnFarmProcess.value) { logNotification("Farm standby", false); } - return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE); + return new PathingCommand(null, PathingCommandType.SET_GOAL_AND_PATH); } if (isPaused()) { // Farm Continuously: Reset the interval if the amount of goals can't fulfill the threshold @@ -466,6 +466,8 @@ public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { @Override public void onLostControl() { active = false; + this.paused = false; + this.time = null; } @Override From 18597ab8eefb09773c6b46d2266d219f8de7c267 Mon Sep 17 00:00:00 2001 From: Avtera <69560119+Avtera@users.noreply.github.com> Date: Fri, 15 Nov 2024 20:02:51 +0700 Subject: [PATCH 5/7] improved the `#farmPrioritizeGather` to be goal composite --- src/main/java/baritone/process/FarmProcess.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/baritone/process/FarmProcess.java b/src/main/java/baritone/process/FarmProcess.java index 77c06cb10..a77ee558a 100644 --- a/src/main/java/baritone/process/FarmProcess.java +++ b/src/main/java/baritone/process/FarmProcess.java @@ -298,15 +298,19 @@ public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { if (!isPaused()) { // Check if item gather is prioritized if (Baritone.settings().farmPrioritizeGather.value) { + List pickupGoals = new ArrayList<>(); for (Entity entity : ctx.entities()) { if (entity instanceof ItemEntity && entity.onGround()) { ItemEntity ei = (ItemEntity) entity; if (PICKUP_DROPPED.contains(ei.getItem().getItem())) { // +0.1 because of farmland's 0.9375 and soulsand's 0.875 dummy height lol - return new PathingCommand(new GoalBlock(new BetterBlockPos(entity.position().x, entity.position().y + 0.125, entity.position().z)), PathingCommandType.SET_GOAL_AND_PATH); + pickupGoals.add(new GoalBlock(new BetterBlockPos(entity.position().x, entity.position().y + 0.125, entity.position().z))); } } } + if (!(pickupGoals.isEmpty())) { + return new PathingCommand(new GoalComposite(pickupGoals.toArray(new Goal[0])), PathingCommandType.SET_GOAL_AND_PATH); + } } baritone.getInputOverrideHandler().clearAllKeys(); BetterBlockPos playerPos = ctx.playerFeet(); From 71aa05c58d25b0dbe0fd0ca670062bb4722064d9 Mon Sep 17 00:00:00 2001 From: Avtera <69560119+Avtera@users.noreply.github.com> Date: Sat, 16 Nov 2024 23:17:36 +0700 Subject: [PATCH 6/7] improved the farm gather to respect the range from `#farm ` --- src/main/java/baritone/process/FarmProcess.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/baritone/process/FarmProcess.java b/src/main/java/baritone/process/FarmProcess.java index a77ee558a..c35ce4da0 100644 --- a/src/main/java/baritone/process/FarmProcess.java +++ b/src/main/java/baritone/process/FarmProcess.java @@ -300,6 +300,10 @@ public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { if (Baritone.settings().farmPrioritizeGather.value) { List pickupGoals = new ArrayList<>(); for (Entity entity : ctx.entities()) { + //check if the pickupGoals is out of range. + if (range != 0 && entity.blockPosition().distSqr(center) > range * range) { + continue; + } if (entity instanceof ItemEntity && entity.onGround()) { ItemEntity ei = (ItemEntity) entity; if (PICKUP_DROPPED.contains(ei.getItem().getItem())) { @@ -425,6 +429,10 @@ public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { } } for (Entity entity : ctx.entities()) { + //check if the pickupGoals is out of range. + if (range != 0 && entity.blockPosition().distSqr(center) > range * range) { + continue; + } if (entity instanceof ItemEntity && entity.onGround()) { ItemEntity ei = (ItemEntity) entity; if (PICKUP_DROPPED.contains(ei.getItem().getItem())) { From 4848d05c5eaa76f9ea53e7042221f49f4e3e8d4a Mon Sep 17 00:00:00 2001 From: Avtera <69560119+Avtera@users.noreply.github.com> Date: Tue, 19 Nov 2024 02:52:58 +0700 Subject: [PATCH 7/7] Add crop whitelist to `#farm` (farming and pickup) --- src/api/java/baritone/api/Settings.java | 28 +++- .../java/baritone/process/FarmProcess.java | 130 +++++++++++++----- 2 files changed, 117 insertions(+), 41 deletions(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 38bd2f5fc..d5876c67f 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -982,26 +982,44 @@ public final class Settings { public final Setting farmMaxScanSize = new Setting<>(256); /** - * Prioritize gathering farm related drops + * Prioritize pickup crop drops before another farm task */ - public final Setting farmPrioritizeGather = new Setting<>(false); + public final Setting farmPrioritizePickup = new Setting<>(false); /** * true = farm farm farm, i don't want to stop! - * false = allow farm to stop or fail + * false = allow farm to stop or fail */ public final Setting farmContinuously = new Setting<>(false); /** - * How much farming task is enough for the Continuous Farm to resume? + * How much farm task queue is enough for Baritone to resume the continuous farm? + * {@link #farmContinuously} */ public final Setting farmContinuouslyThreshold = new Setting<>(16); /** - * Time interval (in seconds) for the Continuous Farm to check if threshold is fulfilled? + * How long Baritone should wait (in seconds) to check if continuous farm threshold is fulfilled? + * {@link #farmContinuously} */ public final Setting farmContinuouslyIntervalSecs = new Setting<>(TimeUnit.MINUTES.toSeconds(2)); + /** + * Farm whitelist, only interact with crop that is on the {@link #farmWhitelist} list + */ + public final Setting farmEnableWhitelist = new Setting<>(false); + + /** + * Crop block that Baritone is allowed to farm and collect + * {@link #farmEnableWhitelist} + */ + + public final Setting> farmWhitelist = new Setting<>(new ArrayList<>(Arrays.asList( + Blocks.WHEAT, + Blocks.POTATOES, + Blocks.CARROTS + ))); + /** * When the cache scan gives less blocks than the maximum threshold (but still above zero), scan the main world too. *

diff --git a/src/main/java/baritone/process/FarmProcess.java b/src/main/java/baritone/process/FarmProcess.java index c35ce4da0..36c68a149 100644 --- a/src/main/java/baritone/process/FarmProcess.java +++ b/src/main/java/baritone/process/FarmProcess.java @@ -56,10 +56,7 @@ import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.Vec3; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Optional; +import java.util.*; import java.util.function.Predicate; public final class FarmProcess extends BaritoneProcessHelper implements IFarmProcess { @@ -102,6 +99,31 @@ public final class FarmProcess extends BaritoneProcessHelper implements IFarmPro Blocks.CACTUS.asItem() ); + private static final Map CROP_TO_PLANTABLE = new HashMap<>(); + static { + CROP_TO_PLANTABLE.put(Blocks.BEETROOTS, Items.BEETROOT_SEEDS); + CROP_TO_PLANTABLE.put(Blocks.WHEAT, Items.WHEAT_SEEDS); + CROP_TO_PLANTABLE.put(Blocks.CARROTS, Items.CARROT); + CROP_TO_PLANTABLE.put(Blocks.POTATOES, Items.POTATO); + CROP_TO_PLANTABLE.put(Blocks.MELON, Items.MELON_SEEDS); + CROP_TO_PLANTABLE.put(Blocks.PUMPKIN, Items.PUMPKIN_SEEDS); + } + + private static final Map> CROP_TO_DROPPED = new HashMap<>(); + static { + CROP_TO_DROPPED.put(Blocks.BEETROOTS, Arrays.asList(Items.BEETROOT, Items.BEETROOT_SEEDS)); + CROP_TO_DROPPED.put(Blocks.WHEAT, Arrays.asList(Items.WHEAT, Items.WHEAT_SEEDS)); + CROP_TO_DROPPED.put(Blocks.CARROTS, List.of(Items.CARROT)); + CROP_TO_DROPPED.put(Blocks.POTATOES, List.of(Items.POTATO)); + CROP_TO_DROPPED.put(Blocks.MELON, Arrays.asList(Items.MELON_SEEDS, Items.MELON_SLICE)); + CROP_TO_DROPPED.put(Blocks.PUMPKIN, Arrays.asList(Items.PUMPKIN, Items.PUMPKIN_SEEDS)); + CROP_TO_DROPPED.put(Blocks.NETHER_WART, List.of(Items.NETHER_WART)); + CROP_TO_DROPPED.put(Blocks.COCOA, List.of(Items.COCOA_BEANS)); + CROP_TO_DROPPED.put(Blocks.SUGAR_CANE, List.of(Items.SUGAR_CANE)); + CROP_TO_DROPPED.put(Blocks.BAMBOO, List.of(Items.BAMBOO)); + CROP_TO_DROPPED.put(Blocks.CACTUS, List.of(Items.CACTUS)); + } + public FarmProcess(Baritone baritone) { super(baritone); } @@ -202,14 +224,35 @@ public boolean readyToHarvest(Level world, BlockPos pos, BlockState state) { private boolean readyForHarvest(Level world, BlockPos pos, BlockState state) { for (Harvest harvest : Harvest.values()) { if (harvest.block == state.getBlock()) { - return harvest.readyToHarvest(world, pos, state); + if (!Baritone.settings().farmEnableWhitelist.value) { + return harvest.readyToHarvest(world, pos, state); + } else { + for (Block whitelist : Baritone.settings().farmWhitelist.value) { + if ((harvest.block.equals(whitelist)) && (harvest.block == state.getBlock())) { + return harvest.readyToHarvest(world, pos, state); + } + } + } } } return false; } private boolean isPlantable(ItemStack stack) { - return FARMLAND_PLANTABLE.contains(stack.getItem()); + if (!Baritone.settings().farmEnableWhitelist.value) { + return FARMLAND_PLANTABLE.contains(stack.getItem()); + } + if (!FARMLAND_PLANTABLE.contains(stack.getItem())) { + return false; + } else { + List whitelistedFarmlandPlantable = new ArrayList<>(); + for (Block whitelist : Baritone.settings().farmWhitelist.value) { + if (!(CROP_TO_PLANTABLE.get(whitelist) == null) && (CROP_TO_PLANTABLE.get(whitelist)).equals(stack.getItem())) { + whitelistedFarmlandPlantable.add(CROP_TO_PLANTABLE.get(whitelist)); + } + } + return whitelistedFarmlandPlantable.contains(stack.getItem()); + } } private boolean isBoneMeal(ItemStack stack) { @@ -217,11 +260,46 @@ private boolean isBoneMeal(ItemStack stack) { } private boolean isNetherWart(ItemStack stack) { - return !stack.isEmpty() && stack.getItem().equals(Items.NETHER_WART); + if (!Baritone.settings().farmEnableWhitelist.value) { + return !stack.isEmpty() && stack.getItem().equals(Items.NETHER_WART); + } else { + return !stack.isEmpty() && stack.getItem().equals(Items.NETHER_WART) && Baritone.settings().farmWhitelist.value.contains(Blocks.NETHER_WART); + } } private boolean isCocoa(ItemStack stack) { - return !stack.isEmpty() && stack.getItem().equals(Items.COCOA_BEANS); + if (!Baritone.settings().farmEnableWhitelist.value) { + return !stack.isEmpty() && stack.getItem().equals(Items.COCOA_BEANS); + } else { + return !stack.isEmpty() && stack.getItem().equals(Items.COCOA_BEANS) && Baritone.settings().farmWhitelist.value.contains(Blocks.COCOA); + } + } + + private List whereAreTheDrops() { + List pickup = new ArrayList<>(); + for (Entity entity : ctx.entities()) { + //check if the pickupGoals is out of range. + if (range != 0 && entity.blockPosition().distSqr(center) > range * range) { + continue; + } + if (entity instanceof ItemEntity && entity.onGround()) { + ItemEntity ei = (ItemEntity) entity; + if (PICKUP_DROPPED.contains(ei.getItem().getItem())) { + if (!Baritone.settings().farmEnableWhitelist.value) { + // +0.1 because of farmland's 0.9375 and soulsand's 0.875 dummy height lol + pickup.add(new GoalBlock(new BetterBlockPos(entity.position().x, entity.position().y + 0.125, entity.position().z))); + } else { + for (Block whitelist : Baritone.settings().farmWhitelist.value) { + if (!(CROP_TO_DROPPED.get(whitelist) == null) && (CROP_TO_DROPPED.get(whitelist)).contains(ei.getItem().getItem())) { + // +0.1 because of farmland's 0.9375 and soulsand's 0.875 dummy height lol + pickup.add(new GoalBlock(new BetterBlockPos(entity.position().x, entity.position().y + 0.125, entity.position().z))); + } + } + } + } + } + } + return pickup; } @Override @@ -297,23 +375,11 @@ public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { // Farm Continuously: Block input while paused if (!isPaused()) { // Check if item gather is prioritized - if (Baritone.settings().farmPrioritizeGather.value) { - List pickupGoals = new ArrayList<>(); - for (Entity entity : ctx.entities()) { - //check if the pickupGoals is out of range. - if (range != 0 && entity.blockPosition().distSqr(center) > range * range) { - continue; - } - if (entity instanceof ItemEntity && entity.onGround()) { - ItemEntity ei = (ItemEntity) entity; - if (PICKUP_DROPPED.contains(ei.getItem().getItem())) { - // +0.1 because of farmland's 0.9375 and soulsand's 0.875 dummy height lol - pickupGoals.add(new GoalBlock(new BetterBlockPos(entity.position().x, entity.position().y + 0.125, entity.position().z))); - } - } - } + if (Baritone.settings().farmPrioritizePickup.value) { + List pickupGoals = whereAreTheDrops(); if (!(pickupGoals.isEmpty())) { - return new PathingCommand(new GoalComposite(pickupGoals.toArray(new Goal[0])), PathingCommandType.SET_GOAL_AND_PATH); + GoalComposite pickupGoalComposite = new GoalComposite(pickupGoals.toArray(new Goal[0])); + return new PathingCommand(pickupGoalComposite, PathingCommandType.SET_GOAL_AND_PATH); } } baritone.getInputOverrideHandler().clearAllKeys(); @@ -428,18 +494,10 @@ public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { goalz.add(new GoalBlock(pos)); } } - for (Entity entity : ctx.entities()) { - //check if the pickupGoals is out of range. - if (range != 0 && entity.blockPosition().distSqr(center) > range * range) { - continue; - } - if (entity instanceof ItemEntity && entity.onGround()) { - ItemEntity ei = (ItemEntity) entity; - if (PICKUP_DROPPED.contains(ei.getItem().getItem())) { - // +0.1 because of farmland's 0.9375 and soulsand's 0.875 dummy height lol - goalz.add(new GoalBlock(new BetterBlockPos(entity.position().x, entity.position().y + 0.125, entity.position().z))); - } - } + List pickupGoals = whereAreTheDrops(); + if (!(pickupGoals.isEmpty())) { + GoalComposite pickupGoalComposite = new GoalComposite(pickupGoals.toArray(new Goal[0])); + goalz.add(pickupGoalComposite); } if (goalz.isEmpty() && !isPaused()) { if (!Baritone.settings().farmContinuously.value) {