diff --git a/gradle.properties b/gradle.properties index 28c36dbd..05f57e22 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,5 +4,5 @@ baseGroup=com.jelly.farmhelperv2 mcVersion=1.8.9 modid=farmhelperv2 modName=FarmHelper -version=2.2.5 +version=2.2.6-pre shouldRelease=true diff --git a/src/main/java/com/jelly/farmhelperv2/FarmHelper.java b/src/main/java/com/jelly/farmhelperv2/FarmHelper.java index 765bdf89..cc1436c6 100644 --- a/src/main/java/com/jelly/farmhelperv2/FarmHelper.java +++ b/src/main/java/com/jelly/farmhelperv2/FarmHelper.java @@ -84,11 +84,6 @@ public void onTickSendInfoAboutShittyClient(TickEvent.PlayerTickEvent event) { Notifications.INSTANCE.send("FarmHelper", "Pests Killer Ticks Of Not Seeing Pest While Attacking has been set to 100 ticks because of a bug in the previous version.", 15000); LogUtils.sendWarning("Pests Killer Ticks Of Not Seeing Pest While Attacking has been set to 100 ticks because of a bug in the previous version."); } - if (FarmHelperConfig.configVersion == 1 && FarmHelperConfig.enablePestsDestroyerPathfindingLongerDistances) { - FarmHelperConfig.enablePestsDestroyerPathfindingLongerDistances = false; - Notifications.INSTANCE.send("FarmHelper", "Enable Pests Destroyer Pathfinding Longer Distances has been disabled. We don't recommend using it for now. You can enable it again if you wish.", 15000); - LogUtils.sendWarning("Enable Pests Destroyer Pathfinding Longer Distances has been disabled. We don't recommend using it for now. You can enable it again if you wish."); - } if (FarmHelperConfig.configVersion == 1) FarmHelperConfig.configVersion = 2; sentInfoAboutShittyClient = true; diff --git a/src/main/java/com/jelly/farmhelperv2/config/FarmHelperConfig.java b/src/main/java/com/jelly/farmhelperv2/config/FarmHelperConfig.java index f4d0fdeb..647e7838 100644 --- a/src/main/java/com/jelly/farmhelperv2/config/FarmHelperConfig.java +++ b/src/main/java/com/jelly/farmhelperv2/config/FarmHelperConfig.java @@ -1123,7 +1123,7 @@ public enum SPRAYONATOR_ITEM { @Switch( name = "Sprint while flying", category = PESTS_DESTROYER, subcategory = "Pests Destroyer", - description = "Springs while flying" + description = "Sprints while flying" ) public static boolean sprintWhileFlying = false; @@ -1152,31 +1152,6 @@ public static void triggerManuallyPestsDestroyer() { ) public static OneKeyBind enablePestsDestroyerKeyBind = new OneKeyBind(Keyboard.KEY_NONE); - @Switch( - name = "Recalculate path after pest escaped", category = PESTS_DESTROYER, subcategory = "Pathfinding", - description = "Recalculates the path after pest escaped" - ) - public static boolean recalculatePathAfterPestEscapedEnabled = false; - - @Slider( - name = "Recalculate path after pest escaped X blocks", category = PESTS_DESTROYER, subcategory = "Pathfinding", - description = "", - min = 3, max = 10 - ) - public static int recalculatePathAfterPestEscaped = 5; - - @Switch( - name = "Enable Pests Destroyer Pathfinding for medium distances", category = PESTS_DESTROYER, subcategory = "Pathfinding", - description = "Enables the pests destroyer pathfinding for medium distances", - size = 2 - ) - public static boolean enablePestsDestroyerPathfindingMediumDistances = false; - @Switch( - name = "Enable Pests Destroyer Pathfinding for longer distances (not recommended)", category = PESTS_DESTROYER, subcategory = "Pathfinding", - description = "Enables the pests destroyer pathfinding for longer distances", - size = 2 - ) - public static boolean enablePestsDestroyerPathfindingLongerDistances = false; // // @@ -1641,13 +1616,6 @@ public FarmHelperConfig() { this.addDependency("pestAdditionalGUIDelay", "enablePestsDestroyer"); this.addDependency("sprintWhileFlying", "enablePestsDestroyer"); this.addDependency("pausePestsDestroyerDuringJacobsContest", "enablePestsDestroyer"); - this.addDependency("recalculatePathAfterPestEscapedEnabled", "enablePestsDestroyer"); - this.addDependency("recalculatePathAfterPestEscaped", "recalculatePathAfterPestEscapedEnabled"); - this.addDependency("enablePestsDestroyerPathfindingMediumDistances", "enablePestsDestroyer"); - this.addDependency("enablePestsDestroyerPathfindingLongerDistances", "enablePestsDestroyer"); - - - this.addDependency("recalculatePathAfterPestEscaped", "recalculatePathAfterPestEscapedEnabled"); this.hideIf("infoCookieBuffRequired", () -> GameStateHandler.getInstance().inGarden() || GameStateHandler.getInstance().getCookieBuffState() == GameStateHandler.BuffState.NOT_ACTIVE); diff --git a/src/main/java/com/jelly/farmhelperv2/feature/impl/PestsDestroyer.java b/src/main/java/com/jelly/farmhelperv2/feature/impl/PestsDestroyer.java index ae06e626..12e75094 100644 --- a/src/main/java/com/jelly/farmhelperv2/feature/impl/PestsDestroyer.java +++ b/src/main/java/com/jelly/farmhelperv2/feature/impl/PestsDestroyer.java @@ -32,6 +32,7 @@ import net.minecraftforge.event.world.WorldEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.gameevent.TickEvent; +import org.jetbrains.annotations.Nullable; import java.awt.*; import java.util.List; @@ -67,6 +68,7 @@ public class PestsDestroyer implements IFeature { @Getter private final Clock delayClock = new Clock(); private final Clock delayBetweenBackTaps = new Clock(); + private final Clock delayBetweenFireworks = new Clock(); private final Pattern pestPatternDeskGui = Pattern.compile(".*?(\\d+).*?"); @Getter private Optional currentEntityTarget = Optional.empty(); @@ -163,11 +165,14 @@ public void resetStatesAfterMacroDisabled() { lastFireworkLocation = Optional.empty(); preTpBlockPos = Optional.empty(); delayBetweenBackTaps.reset(); + delayBetweenFireworks.reset(); delayClock.reset(); stuckClock.reset(); preparing = false; enabled = false; lastFireworkTime = 0; + FlyPathfinder.getInstance().stuckCounterWithMotion = 0; + FlyPathfinder.getInstance().stuckCounterWithoutMotion = 0; state = States.IDLE; } @@ -365,7 +370,7 @@ public void onTickExecute(TickEvent.ClientTickEvent event) { case WAIT_FOR_INFO: String chestName2 = InventoryUtils.getInventoryName(); if (chestName2 != null && !chestName2.equals("Configure Plots")) { - LogUtils.sendDebug("Wrong " + chestName2); + LogUtils.sendDebug("Wrong GUI: " + chestName2); PlayerUtils.closeScreen(); delayClock.schedule((long) (FarmHelperConfig.pestAdditionalGUIDelay + 500 + Math.random() * 500)); state = States.OPEN_DESK; @@ -409,6 +414,10 @@ public void onTickExecute(TickEvent.ClientTickEvent event) { } break; case GET_LOCATION: + FlyPathfinder.getInstance().stuckCounterWithMotion = 0; + FlyPathfinder.getInstance().stuckCounterWithoutMotion = 0; + if (FlyPathfinder.getInstance().isRunning()) + FlyPathfinder.getInstance().stop(); if (totalPests == 0) { state = States.GO_BACK; return; @@ -473,6 +482,7 @@ public void onTickExecute(TickEvent.ClientTickEvent event) { LogUtils.sendDebug("[Pests Destroyer] Finished rotating to firework location!"); state = States.FLY_TO_PEST; RotationHandler.getInstance().reset(); + delayBetweenFireworks.schedule(3_000); } ).easeOutBack(true).randomness(true)); delayClock.schedule(300); @@ -498,20 +508,25 @@ public void onTickExecute(TickEvent.ClientTickEvent event) { if (pestsLocations.isEmpty()) { if (!lastFireworkLocation.isPresent()) { + LogUtils.sendDebug("[Pests Destroyer] No firework location found. Looking for a firework."); state = States.GET_LOCATION; break; } - if (mc.thePlayer.getDistance(lastFireworkLocation.get().xCoord, mc.thePlayer.posY, lastFireworkLocation.get().zCoord) < 1.5) { + + if (delayBetweenFireworks.passed() // gives the fly pathfinder some time to move away from stuck location + && mc.thePlayer.getDistance(lastFireworkLocation.get().xCoord, mc.thePlayer.posY, lastFireworkLocation.get().zCoord) < 1.5) { + LogUtils.sendDebug("[Pests Destroyer] Player is close to firework location. Looking for another firework."); + delayBetweenFireworks.reset(); state = States.GET_LOCATION; return; } - Vec3 playerPos = new Vec3(mc.thePlayer.posX, mc.thePlayer.posY, mc.thePlayer.posZ); - Vec3 playerLook = mc.thePlayer.getLookVec(); - Vec3 fireworkPos = new Vec3(lastFireworkLocation.get().xCoord, mc.thePlayer.posY, lastFireworkLocation.get().zCoord); - Vec3 playerToFirework = fireworkPos.subtract(playerPos); - double angle = Math.toDegrees(Math.acos(playerLook.dotProduct(playerToFirework) / (playerLook.lengthVector() * playerToFirework.lengthVector()))); + if (FlyPathfinder.getInstance().isRunning()) + return; + + double angle = getAngleToFireworkPos(); if (angle > 90) { + LogUtils.sendDebug("[Pests Destroyer] Angle > 90"); state = States.GET_LOCATION; return; } @@ -522,19 +537,24 @@ public void onTickExecute(TickEvent.ClientTickEvent event) { FarmHelperConfig.sprintWhileFlying ? mc.gameSettings.keyBindSprint : null, objects ? mc.gameSettings.keyBindJump : null ); - break; - } - Entity closestPest = null; - double closestDistance = Double.MAX_VALUE; - for (Entity entity : pestsLocations) { - double distance = mc.thePlayer.getDistanceToEntity(entity); - if (distance < closestDistance) { - closestDistance = distance; - closestPest = entity; + if (FlyPathfinder.getInstance().isStuck() || FlyPathfinder.getInstance().isStuckWithMotion()) { + LogUtils.sendDebug("[Pests Destroyer] Player is stuck! Falling back to fly pathfinding."); + int plot = pestsPlotMap.get(pestsPlotMap.keySet().stream().findFirst().orElse(null)); + if (plot < 0 || plot > 25) { + LogUtils.sendDebug("[Pests Destroyer] Plot is invalid!"); + KeyBindUtils.stopMovement(); + escapeState = EscapeState.GO_TO_HUB; + } else + flyPathfinding(PlotUtils.getPlotCenter(plot)); + delayClock.schedule(500); + return; } + break; } + Entity closestPest = getClosestPest(); + if (closestPest == null) { state = States.GET_LOCATION; return; @@ -569,7 +589,11 @@ public void onTickExecute(TickEvent.ClientTickEvent event) { Rotation rotationEntity = RotationHandler.getInstance().getRotation(entity); float yawDifference = Math.abs(AngleUtils.normalizeAngle(rotationEntity.getYaw() - AngleUtils.get360RotationYaw())); - if (FarmHelperConfig.pestsKillerTicksOfNotSeeingPestWhileAttacking > 0 && (distanceXZ < 1.5 || distance <= 10) && GameStateHandler.getInstance().getDx() < 0.1 && GameStateHandler.getInstance().getDz() < 0.1 && !canEntityBeSeenIgnoreNonCollidable(entity)) { + if (FarmHelperConfig.pestsKillerTicksOfNotSeeingPestWhileAttacking > 0 + && (distanceXZ < 1.5 || distance <= 10) + && Math.abs(mc.thePlayer.motionX) < 0.1 + && Math.abs(mc.thePlayer.motionZ) < 0.1 + && !canEntityBeSeenIgnoreNonCollidable(entity)) { cantReachPest++; } @@ -582,10 +606,6 @@ public void onTickExecute(TickEvent.ClientTickEvent event) { } if (distance <= 2.5) { - if (FlyPathfinder.getInstance().isRunning()) { - FlyPathfinder.getInstance().stop(); - KeyBindUtils.stopMovement(); - } if (Math.abs(mc.thePlayer.motionX) > 0.1 || Math.abs(mc.thePlayer.motionZ) > 0.1) { if (delayBetweenBackTaps.passed()) { KeyBindUtils.holdThese(mc.gameSettings.keyBindBack, mc.gameSettings.keyBindUseItem); @@ -604,18 +624,41 @@ public void onTickExecute(TickEvent.ClientTickEvent event) { )); } KeyBindUtils.holdThese(mc.gameSettings.keyBindUseItem); - } else if (((distance <= 10 || distanceXZ <= 2) && !FarmHelperConfig.enablePestsDestroyerPathfindingMediumDistances) - || (!FlyPathfinder.getInstance().hasFailed && distanceXZ <= 10 && FarmHelperConfig.enablePestsDestroyerPathfindingMediumDistances)) { + } else { + if (FlyPathfinder.getInstance().isRunning()) { + if (distance < 5) { + LogUtils.sendDebug("[Pests Destroyer] Player is close to pest. Switching back to normal fly."); + FlyPathfinder.getInstance().stop(); + } + break; + } + if (!mc.thePlayer.capabilities.isFlying) { flyAwayFromGround(); delayClock.schedule(350); break; } - if (FarmHelperConfig.enablePestsDestroyerPathfindingMediumDistances && !FlyPathfinder.getInstance().hasFailed) { + if (FlyPathfinder.getInstance().isStuckWithMotion()) { + LogUtils.sendDebug("[Pests Destroyer] Player is stuck with motion. Falling back to fly pathfinding."); flyPathfinding(entity); + delayClock.schedule(500); break; - } else { + } + if (FlyPathfinder.getInstance().isStuck()) { + LogUtils.sendDebug("[Pests Destroyer] Player is stuck. Falling back to fly pathfinding."); + flyPathfinding(entity); + delayClock.schedule(500); + break; + } + + if (distance <= 10 || distanceXZ <= 2) { + if (!mc.thePlayer.capabilities.isFlying) { + flyAwayFromGround(); + delayClock.schedule(350); + break; + } + if (distanceXZ <= 1 && (Math.abs(mc.thePlayer.motionX) > 0.1 || Math.abs(mc.thePlayer.motionZ) > 0.1)) { if (delayBetweenBackTaps.passed()) { KeyBindUtils.holdThese(mc.gameSettings.keyBindBack, distance < 6 ? mc.gameSettings.keyBindUseItem : null); @@ -634,12 +677,8 @@ public void onTickExecute(TickEvent.ClientTickEvent event) { null ).easeOutBack(true).randomness(true)); } - } - } else { - cantReachPest = 0; - if (FarmHelperConfig.enablePestsDestroyerPathfindingLongerDistances && !FlyPathfinder.getInstance().hasFailed) { - flyPathfinding(entity); } else { + cantReachPest = 0; if (distanceXZ < 6 && distance > 10 && mc.thePlayer.capabilities.isFlying) { manipulateHeight(entity, distance, distanceXZ, yawDifference); break; @@ -668,8 +707,8 @@ public void onTickExecute(TickEvent.ClientTickEvent event) { null ).randomness(true)); } + break; } - break; } break; case CHECK_ANOTHER_PEST: @@ -700,6 +739,29 @@ public void onTickExecute(TickEvent.ClientTickEvent event) { } } + @Nullable + private Entity getClosestPest() { + Entity closestPest = null; + double closestDistance = Double.MAX_VALUE; + for (Entity entity : pestsLocations) { + double distance = mc.thePlayer.getDistanceToEntity(entity); + if (distance < closestDistance) { + closestDistance = distance; + closestPest = entity; + } + } + return closestPest; + } + + private double getAngleToFireworkPos() { + if (!lastFireworkLocation.isPresent()) return 0; + Vec3 playerPos = new Vec3(mc.thePlayer.posX, mc.thePlayer.posY, mc.thePlayer.posZ); + Vec3 playerLook = mc.thePlayer.getLookVec(); + Vec3 fireworkPos = new Vec3(lastFireworkLocation.get().xCoord, mc.thePlayer.posY, lastFireworkLocation.get().zCoord); + Vec3 playerToFirework = fireworkPos.subtract(playerPos); + return Math.toDegrees(Math.acos(playerLook.dotProduct(playerToFirework) / (playerLook.lengthVector() * playerToFirework.lengthVector()))); + } + private boolean getVacuum(ItemStack currentItem2) { if (currentItem2 == null || !currentItem2.getDisplayName().contains("Vacuum")) { int vacuum = InventoryUtils.getSlotIdOfItemInHotbar("Vacuum"); @@ -717,33 +779,19 @@ private boolean getVacuum(ItemStack currentItem2) { return false; } - private void flyPathfinding(Entity entity) { - if (!mc.thePlayer.capabilities.isFlying) { - flyAwayFromGround(); - delayClock.schedule(350); - return; - } - if (FarmHelperConfig.recalculatePathAfterPestEscapedEnabled - && FlyPathfinder.getInstance().hasGoal() - && FlyPathfinder.getInstance().getDistanceTo(new BlockPos(entity.posX, entity.posY + entity.getEyeHeight() + 1, entity.posZ)) > FarmHelperConfig.recalculatePathAfterPestEscaped - ) { - FlyPathfinder.getInstance().setGoal(new GoalNear(new BetterBlockPos(entity.posX, entity.posY + entity.getEyeHeight() + 1, entity.posZ), 2)); - LogUtils.sendDebug("[Pests Destroyer] Pest escaped. Recalculating path to " + FlyPathfinder.getInstance().getGoal()); - FlyPathfinder.getInstance().getPathTo(FlyPathfinder.getInstance().getGoal()); - delayClock.schedule(350); - return; - } + private void flyPathfinding(BetterBlockPos betterBlockPos) { + FlyPathfinder.getInstance().stuckCounterWithMotion = 0; + FlyPathfinder.getInstance().stuckCounterWithoutMotion = 0; if (FlyPathfinder.getInstance().hasGoal() && FlyPathfinder.getInstance().hasFailed) { LogUtils.sendDebug("[Pests Destroyer] Failed to get path to " + FlyPathfinder.getInstance().getGoal() + ". Falling back to normal flying behavior."); FlyPathfinder.getInstance().stop(); -// escapeState = EscapeState.GO_TO_HUB; KeyBindUtils.stopMovement(); delayClock.schedule(300); return; } if (!FlyPathfinder.getInstance().hasGoal()) { - LogUtils.sendDebug("[Pests Destroyer] Setting goal to " + String.format("%.2f %.2f %.2f", entity.posX, entity.posY + entity.getEyeHeight() + 1, entity.posZ)); - FlyPathfinder.getInstance().setGoal(new GoalNear(new BetterBlockPos(entity.posX, entity.posY + entity.getEyeHeight() + 1, entity.posZ), 2)); + LogUtils.sendDebug("[Pests Destroyer] Setting goal to " + betterBlockPos); + FlyPathfinder.getInstance().setGoal(new GoalNear(betterBlockPos, 2)); delayClock.schedule(550); return; } @@ -758,6 +806,14 @@ private void flyPathfinding(Entity entity) { } } + private void flyPathfinding(Entity entity) { + flyPathfinding(new BetterBlockPos(entity.posX, entity.posY + entity.getEyeHeight() + 1, entity.posZ)); + } + + private void flyPathfinding(BlockPos blockPos) { + flyPathfinding(new BetterBlockPos(blockPos.getX(), blockPos.getY(), blockPos.getZ())); + } + private boolean isInventoryOpenDelayed() { if (mc.currentScreen != null) { KeyBindUtils.stopMovement(); diff --git a/src/main/java/com/jelly/farmhelperv2/util/PlotUtils.java b/src/main/java/com/jelly/farmhelperv2/util/PlotUtils.java index a619185c..24bb3b73 100644 --- a/src/main/java/com/jelly/farmhelperv2/util/PlotUtils.java +++ b/src/main/java/com/jelly/farmhelperv2/util/PlotUtils.java @@ -100,4 +100,26 @@ private static List> getChunks(int fromX, int toX, int f } return chunks; } + + public static BlockPos getPlotCenter(int plotNumber) { + List> chunks = getPlotBasedOnNumber(plotNumber); + int minX = chunks.stream().mapToInt(Tuple::getFirst).min().orElse(0); + int maxX = chunks.stream().mapToInt(Tuple::getFirst).max().orElse(0); + int minZ = chunks.stream().mapToInt(Tuple::getSecond).min().orElse(0); + int maxZ = chunks.stream().mapToInt(Tuple::getSecond).max().orElse(0); + return new BlockPos((minX + maxX) / 2 * 16, 80, (minZ + maxZ) / 2 * 16); + } + + public static BlockPos getPlotNearestEdgeToPlayer(int plotNumber) { + List> chunks = getPlotBasedOnNumber(plotNumber); + int minX = chunks.stream().mapToInt(Tuple::getFirst).min().orElse(0); + int maxX = chunks.stream().mapToInt(Tuple::getFirst).max().orElse(0); + int minZ = chunks.stream().mapToInt(Tuple::getSecond).min().orElse(0); + int maxZ = chunks.stream().mapToInt(Tuple::getSecond).max().orElse(0); + int playerX = (int) mc.thePlayer.posX; + int playerZ = (int) mc.thePlayer.posZ; + int x = playerX < (minX + maxX) / 2 * 16 ? minX * 16 : maxX * 16; + int z = playerZ < (minZ + maxZ) / 2 * 16 ? minZ * 16 : maxZ * 16; + return new BlockPos(x, 80, z); + } } diff --git a/src/main/java/com/jelly/farmhelperv2/util/helper/FlyPathfinder.java b/src/main/java/com/jelly/farmhelperv2/util/helper/FlyPathfinder.java index 0a4a54a7..b60f4c4d 100644 --- a/src/main/java/com/jelly/farmhelperv2/util/helper/FlyPathfinder.java +++ b/src/main/java/com/jelly/farmhelperv2/util/helper/FlyPathfinder.java @@ -47,8 +47,10 @@ public static FlyPathfinder getInstance() { private final List realPath = new ArrayList<>(); private static final RotationHandler rotation = RotationHandler.getInstance(); private Clock antiStuckDelay = new Clock(); - private int stuckCounterWithoutMotion = 0; - private int stuckCounterWithMotion = 0; + @Setter + public int stuckCounterWithoutMotion = 0; + @Setter + public int stuckCounterWithMotion = 0; private boolean shouldRecalculateLater = false; public boolean hasFailed = false; private Vec3 lastPlayerPos; @@ -157,7 +159,7 @@ public void onTick(TickEvent.ClientTickEvent event) { } else if (!mc.thePlayer.capabilities.isFlying && BlockUtils.getRelativeBlock(0, -1, 1).isPassable(mc.theWorld, BlockUtils.getRelativeBlockPos(0, -1, 1))) mc.thePlayer.capabilities.isFlying = true; double distance3d = mc.thePlayer.getDistance(pathBlocks.get(0).getX() + 0.5, pathBlocks.get(0).getY() + 0.5, pathBlocks.get(0).getZ() + 0.5); - if (distance3d < 0.5) { + if (distance3d < 0.5 || (isPlayerUnderHalfBlock() && distance3d < 1)) { pathBlocks.remove(0); rotation.reset(); if (!pathBlocks.isEmpty()) { @@ -330,6 +332,12 @@ public boolean isStuckWithMotion() { return false; } + public boolean isPlayerUnderHalfBlock() { + return (mc.thePlayer.posY % 1 < 0.701 && mc.thePlayer.posY % 1 > 0.201 + && !BlockUtils.getRelativeFullBlock(0, 2, 0).isPassable(mc.theWorld, BlockUtils.getRelativeFullBlockPos(0, 2, 0)) + ); + } + //region Path smoothing - Nirox version IBaritone baritone = BaritoneAPI.getProvider().getPrimaryBaritone(); public List smoothPath(List path) {