From a64e07685b1eb83471846e3dd07ee172bd1cd5d8 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Tue, 21 Aug 2018 11:54:55 -0700 Subject: [PATCH 01/19] lazy chunk loading --- .../java/baritone/bot/chunk/CachedWorld.java | 2 +- .../bot/chunk/CachedWorldProvider.java | 19 ------------------- 2 files changed, 1 insertion(+), 20 deletions(-) diff --git a/src/main/java/baritone/bot/chunk/CachedWorld.java b/src/main/java/baritone/bot/chunk/CachedWorld.java index f8b2c216..d5c5c04a 100644 --- a/src/main/java/baritone/bot/chunk/CachedWorld.java +++ b/src/main/java/baritone/bot/chunk/CachedWorld.java @@ -53,7 +53,7 @@ public final class CachedWorld implements ICachedChunkAccess { @Override public final PathingBlockType getBlockType(int x, int y, int z) { - CachedRegion region = getRegion(x >> 9, z >> 9); + CachedRegion region = getOrCreateRegion(x >> 9, z >> 9); if (region != null) { return region.getBlockType(x & 511, y, z & 511); } diff --git a/src/main/java/baritone/bot/chunk/CachedWorldProvider.java b/src/main/java/baritone/bot/chunk/CachedWorldProvider.java index e5ff7509..e6062d6d 100644 --- a/src/main/java/baritone/bot/chunk/CachedWorldProvider.java +++ b/src/main/java/baritone/bot/chunk/CachedWorldProvider.java @@ -31,8 +31,6 @@ import java.nio.file.Path; import java.util.HashMap; import java.util.Map; import java.util.function.Consumer; -import java.util.regex.Matcher; -import java.util.regex.Pattern; /** * @author Brady @@ -42,8 +40,6 @@ public enum CachedWorldProvider implements Helper { INSTANCE; - private static final Pattern REGION_REGEX = Pattern.compile("r\\.(-?[0-9]+)\\.(-?[0-9]+)\\.bcr"); - private final Map singlePlayerWorldCache = new HashMap<>(); private CachedWorld currentWorld; @@ -68,21 +64,6 @@ public enum CachedWorldProvider implements Helper { } this.currentWorld = this.singlePlayerWorldCache.computeIfAbsent(dir.toString(), CachedWorld::new); - - try { - Files.list(dir).forEach(path -> { - String file = path.getFileName().toString(); - Matcher matcher = REGION_REGEX.matcher(file); - if (matcher.matches()) { - int rx = Integer.parseInt(matcher.group(1)); - int ry = Integer.parseInt(matcher.group(2)); - // Recognize the region for when we load from file - this.currentWorld.getOrCreateRegion(rx, ry); - } - }); - } catch (Exception ignored) {} - - this.currentWorld.load(); } // TODO: Store server worlds } From 800078a75cfda321d1aebb6250af272e23e91cc7 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Tue, 21 Aug 2018 12:18:54 -0700 Subject: [PATCH 02/19] only gzip changed regions --- .../java/baritone/bot/chunk/CachedRegion.java | 14 +++++++++++++- .../java/baritone/bot/chunk/CachedWorld.java | 16 ++-------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/main/java/baritone/bot/chunk/CachedRegion.java b/src/main/java/baritone/bot/chunk/CachedRegion.java index b7bc3580..b0cda611 100644 --- a/src/main/java/baritone/bot/chunk/CachedRegion.java +++ b/src/main/java/baritone/bot/chunk/CachedRegion.java @@ -17,8 +17,8 @@ package baritone.bot.chunk; -import baritone.bot.utils.pathing.PathingBlockType; import baritone.bot.utils.GZIPUtils; +import baritone.bot.utils.pathing.PathingBlockType; import java.io.FileInputStream; import java.io.FileOutputStream; @@ -52,9 +52,15 @@ public final class CachedRegion implements ICachedChunkAccess { */ private final int z; + /** + * Has this region been modified since its most recent load or save + */ + private boolean hasUnsavedChanges; + CachedRegion(int x, int z) { this.x = x; this.z = z; + this.hasUnsavedChanges = false; } @Override @@ -74,6 +80,7 @@ public final class CachedRegion implements ICachedChunkAccess { } else { chunk.updateContents(data); } + hasUnsavedChanges = true; } private CachedChunk getChunk(int chunkX, int chunkZ) { @@ -92,6 +99,9 @@ public final class CachedRegion implements ICachedChunkAccess { } public final void save(String directory) { + if (!hasUnsavedChanges) { + return; + } try { Path path = Paths.get(directory); if (!Files.exists(path)) @@ -115,6 +125,7 @@ public final class CachedRegion implements ICachedChunkAccess { } } } + hasUnsavedChanges = false; } catch (IOException ignored) {} } @@ -148,6 +159,7 @@ public final class CachedRegion implements ICachedChunkAccess { } } } + hasUnsavedChanges = false; } catch (IOException ignored) {} } diff --git a/src/main/java/baritone/bot/chunk/CachedWorld.java b/src/main/java/baritone/bot/chunk/CachedWorld.java index d5c5c04a..eb7513a3 100644 --- a/src/main/java/baritone/bot/chunk/CachedWorld.java +++ b/src/main/java/baritone/bot/chunk/CachedWorld.java @@ -54,18 +54,13 @@ public final class CachedWorld implements ICachedChunkAccess { @Override public final PathingBlockType getBlockType(int x, int y, int z) { CachedRegion region = getOrCreateRegion(x >> 9, z >> 9); - if (region != null) { - return region.getBlockType(x & 511, y, z & 511); - } - return null; + return region.getBlockType(x & 511, y, z & 511); } @Override public final void updateCachedChunk(int chunkX, int chunkZ, BitSet data) { CachedRegion region = getOrCreateRegion(chunkX >> 5, chunkZ >> 5); - if (region != null) { - region.updateCachedChunk(chunkX & 31, chunkZ & 31, data); - } + region.updateCachedChunk(chunkX & 31, chunkZ & 31, data); } public final void save() { @@ -75,13 +70,6 @@ public final class CachedWorld implements ICachedChunkAccess { }); } - public final void load() { - this.cachedRegions.values().forEach(region -> { - if (region != null) - region.load(this.directory); - }); - } - /** * Returns the region at the specified region coordinates * From 5bc8adc7771aaedb01f456fd1e560be3b927ed20 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Tue, 21 Aug 2018 12:22:45 -0700 Subject: [PATCH 03/19] debug --- src/main/java/baritone/bot/chunk/CachedRegion.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/baritone/bot/chunk/CachedRegion.java b/src/main/java/baritone/bot/chunk/CachedRegion.java index b0cda611..1853bf44 100644 --- a/src/main/java/baritone/bot/chunk/CachedRegion.java +++ b/src/main/java/baritone/bot/chunk/CachedRegion.java @@ -107,6 +107,7 @@ public final class CachedRegion implements ICachedChunkAccess { if (!Files.exists(path)) Files.createDirectories(path); + System.out.println("Saving region " + x + "," + z + " to disk"); Path regionFile = getRegionFile(path, this.x, this.z); if (!Files.exists(regionFile)) Files.createFile(regionFile); @@ -139,6 +140,8 @@ public final class CachedRegion implements ICachedChunkAccess { if (!Files.exists(regionFile)) return; + System.out.println("Loading region " + x + "," + z + " from disk"); + byte[] decompressed; try (FileInputStream in = new FileInputStream(regionFile.toFile())) { decompressed = GZIPUtils.decompress(in); From 7623b8b386e5d46bdfd71adaee07daece77b0fac Mon Sep 17 00:00:00 2001 From: Leijurv Date: Tue, 21 Aug 2018 13:06:36 -0700 Subject: [PATCH 04/19] reworked saving --- .../java/baritone/bot/chunk/CachedChunk.java | 5 -- .../java/baritone/bot/chunk/CachedRegion.java | 65 ++++++++++++------- .../java/baritone/bot/utils/GZIPUtils.java | 56 ---------------- 3 files changed, 41 insertions(+), 85 deletions(-) delete mode 100644 src/main/java/baritone/bot/utils/GZIPUtils.java diff --git a/src/main/java/baritone/bot/chunk/CachedChunk.java b/src/main/java/baritone/bot/chunk/CachedChunk.java index c85cc88c..8316345f 100644 --- a/src/main/java/baritone/bot/chunk/CachedChunk.java +++ b/src/main/java/baritone/bot/chunk/CachedChunk.java @@ -40,11 +40,6 @@ public final class CachedChunk implements IBlockTypeAccess { */ public static final int SIZE_IN_BYTES = SIZE / 8; - /** - * An array of just 0s with the length of {@link CachedChunk#SIZE_IN_BYTES} - */ - public static final byte[] EMPTY_CHUNK = new byte[SIZE_IN_BYTES]; - /** * The chunk x coordinate */ diff --git a/src/main/java/baritone/bot/chunk/CachedRegion.java b/src/main/java/baritone/bot/chunk/CachedRegion.java index 1853bf44..cbdcc9ed 100644 --- a/src/main/java/baritone/bot/chunk/CachedRegion.java +++ b/src/main/java/baritone/bot/chunk/CachedRegion.java @@ -17,18 +17,15 @@ package baritone.bot.chunk; -import baritone.bot.utils.GZIPUtils; import baritone.bot.utils.pathing.PathingBlockType; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; +import java.io.*; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.Arrays; import java.util.BitSet; import java.util.function.Consumer; +import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; /** @@ -36,6 +33,13 @@ import java.util.zip.GZIPOutputStream; * @since 8/3/2018 9:35 PM */ public final class CachedRegion implements ICachedChunkAccess { + private static final byte CHUNK_NOT_PRESENT = 0; + private static final byte CHUNK_PRESENT = 1; + + /** + * Magic value to detect invalid cache files, or incompatible cache files saved in an old version of Baritone + */ + private static final int CACHED_REGION_MAGIC = 456022910; /** * All of the chunks in this region: A 32x32 array of them. @@ -111,13 +115,19 @@ public final class CachedRegion implements ICachedChunkAccess { Path regionFile = getRegionFile(path, this.x, this.z); if (!Files.exists(regionFile)) Files.createFile(regionFile); - try (FileOutputStream fileOut = new FileOutputStream(regionFile.toFile()); GZIPOutputStream out = new GZIPOutputStream(fileOut)) { + try ( + FileOutputStream fileOut = new FileOutputStream(regionFile.toFile()); + GZIPOutputStream gzipOut = new GZIPOutputStream(fileOut); + DataOutputStream out = new DataOutputStream(gzipOut); + ) { + out.writeInt(CACHED_REGION_MAGIC); for (int z = 0; z < 32; z++) { for (int x = 0; x < 32; x++) { CachedChunk chunk = this.chunks[x][z]; if (chunk == null) { - out.write(CachedChunk.EMPTY_CHUNK); + out.write(CHUNK_NOT_PRESENT); } else { + out.write(CHUNK_PRESENT); byte[] chunkBytes = chunk.toByteArray(); out.write(chunkBytes); // Messy, but fills the empty 0s that should be trailing to fill up the space. @@ -142,23 +152,30 @@ public final class CachedRegion implements ICachedChunkAccess { System.out.println("Loading region " + x + "," + z + " from disk"); - byte[] decompressed; - try (FileInputStream in = new FileInputStream(regionFile.toFile())) { - decompressed = GZIPUtils.decompress(in); - } - - if (decompressed == null) - return; - - for (int z = 0; z < 32; z++) { - for (int x = 0; x < 32; x++) { - int index = (x + (z << 5)) * CachedChunk.SIZE_IN_BYTES; - byte[] bytes = Arrays.copyOfRange(decompressed, index, index + CachedChunk.SIZE_IN_BYTES); - if (isAllZeros(bytes)) { - this.chunks[x][z] = null; - } else { - BitSet bits = BitSet.valueOf(bytes); - updateCachedChunk(x, z, bits); + try ( + FileInputStream fileIn = new FileInputStream(regionFile.toFile()); + GZIPInputStream gzipIn = new GZIPInputStream(fileIn); + DataInputStream in = new DataInputStream(gzipIn); + ) { + int magic = in.readInt(); + if (magic != CACHED_REGION_MAGIC) { + throw new IOException("Bad magic value " + magic); + } + for (int z = 0; z < 32; z++) { + for (int x = 0; x < 32; x++) { + int isChunkPresent = in.read(); + switch (isChunkPresent) { + case CHUNK_PRESENT: + byte[] bytes = new byte[CachedChunk.SIZE_IN_BYTES]; + in.readFully(bytes); + BitSet bits = BitSet.valueOf(bytes); + updateCachedChunk(x, z, bits); + case CHUNK_NOT_PRESENT: + this.chunks[x][z] = null; + break; + default: + throw new IOException("Malformed stream"); + } } } } diff --git a/src/main/java/baritone/bot/utils/GZIPUtils.java b/src/main/java/baritone/bot/utils/GZIPUtils.java deleted file mode 100644 index 7b15e580..00000000 --- a/src/main/java/baritone/bot/utils/GZIPUtils.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * This file is part of Baritone. - * - * Baritone is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Baritone is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Baritone. If not, see . - */ - -package baritone.bot.utils; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.zip.GZIPInputStream; -import java.util.zip.GZIPOutputStream; - -/** - * @author Brady - * @since 8/3/2018 10:18 PM - */ -public final class GZIPUtils { - - private GZIPUtils() { - } - - public static byte[] compress(byte[] in) throws IOException { - ByteArrayOutputStream byteStream = new ByteArrayOutputStream(in.length); - - try (GZIPOutputStream gzipStream = new GZIPOutputStream(byteStream)) { - gzipStream.write(in); - } - return byteStream.toByteArray(); - } - - public static byte[] decompress(InputStream in) throws IOException { - ByteArrayOutputStream outStream = new ByteArrayOutputStream(); - - try (GZIPInputStream gzipStream = new GZIPInputStream(in)) { - byte[] buffer = new byte[1024]; - int len; - while ((len = gzipStream.read(buffer)) > 0) { - outStream.write(buffer, 0, len); - } - } - return outStream.toByteArray(); - } -} From 05cc63f4ffc4d16d1024c8f7f4806f8679f6f929 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Tue, 21 Aug 2018 13:10:00 -0700 Subject: [PATCH 05/19] comment --- src/main/java/baritone/bot/chunk/CachedRegion.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/baritone/bot/chunk/CachedRegion.java b/src/main/java/baritone/bot/chunk/CachedRegion.java index cbdcc9ed..6fe78009 100644 --- a/src/main/java/baritone/bot/chunk/CachedRegion.java +++ b/src/main/java/baritone/bot/chunk/CachedRegion.java @@ -159,6 +159,9 @@ public final class CachedRegion implements ICachedChunkAccess { ) { int magic = in.readInt(); if (magic != CACHED_REGION_MAGIC) { + // in the future, if we change the format on disk + // we can keep converters for the old format + // by switching on the magic value, and either loading it normally, or loading through a converter. throw new IOException("Bad magic value " + magic); } for (int z = 0; z < 32; z++) { From 7d6d34c5aaf01dc1f587ac97412412bb684d71ac Mon Sep 17 00:00:00 2001 From: Leijurv Date: Tue, 21 Aug 2018 13:17:44 -0700 Subject: [PATCH 06/19] idiocy --- src/main/java/baritone/bot/chunk/CachedRegion.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/baritone/bot/chunk/CachedRegion.java b/src/main/java/baritone/bot/chunk/CachedRegion.java index 6fe78009..a70cfc65 100644 --- a/src/main/java/baritone/bot/chunk/CachedRegion.java +++ b/src/main/java/baritone/bot/chunk/CachedRegion.java @@ -173,6 +173,7 @@ public final class CachedRegion implements ICachedChunkAccess { in.readFully(bytes); BitSet bits = BitSet.valueOf(bytes); updateCachedChunk(x, z, bits); + break; case CHUNK_NOT_PRESENT: this.chunks[x][z] = null; break; From 530f87ad140b5deaaf38ffecfd486d93e39efc8f Mon Sep 17 00:00:00 2001 From: Leijurv Date: Tue, 21 Aug 2018 13:18:58 -0700 Subject: [PATCH 07/19] full integrity check --- src/main/java/baritone/bot/chunk/CachedRegion.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/baritone/bot/chunk/CachedRegion.java b/src/main/java/baritone/bot/chunk/CachedRegion.java index a70cfc65..05d6ee9d 100644 --- a/src/main/java/baritone/bot/chunk/CachedRegion.java +++ b/src/main/java/baritone/bot/chunk/CachedRegion.java @@ -135,6 +135,7 @@ public final class CachedRegion implements ICachedChunkAccess { } } } + out.writeInt(~CACHED_REGION_MAGIC); } hasUnsavedChanges = false; } catch (IOException ignored) {} @@ -182,6 +183,10 @@ public final class CachedRegion implements ICachedChunkAccess { } } } + int fileEndMagic = in.readInt(); + if (fileEndMagic != ~magic) { + throw new IOException("Bad end of file magic"); + } } hasUnsavedChanges = false; } catch (IOException ignored) {} From 40dd2e33f6f1061e81193a70cf4b627f219c02dc Mon Sep 17 00:00:00 2001 From: Leijurv Date: Tue, 21 Aug 2018 13:39:28 -0700 Subject: [PATCH 08/19] fixed setting name --- src/main/java/baritone/bot/Settings.java | 2 +- src/main/java/baritone/bot/event/GameEventHandler.java | 4 ++-- src/main/java/baritone/bot/pathing/calc/AStarPathFinder.java | 2 +- src/main/java/baritone/bot/utils/BlockStateInterface.java | 2 +- src/main/java/baritone/bot/utils/ExampleBaritoneControl.java | 5 ++++- 5 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/main/java/baritone/bot/Settings.java b/src/main/java/baritone/bot/Settings.java index 13da50bb..68fcd4c2 100644 --- a/src/main/java/baritone/bot/Settings.java +++ b/src/main/java/baritone/bot/Settings.java @@ -157,7 +157,7 @@ public class Settings { /** * The big one. Download all chunks in simplified 2-bit format and save them for better very-long-distance pathing. */ - public Setting chuckCaching = new Setting<>(false); + public Setting chunkCaching = new Setting<>(true); /** * Print all the debug messages to chat diff --git a/src/main/java/baritone/bot/event/GameEventHandler.java b/src/main/java/baritone/bot/event/GameEventHandler.java index 32bcde8c..4221d3bc 100644 --- a/src/main/java/baritone/bot/event/GameEventHandler.java +++ b/src/main/java/baritone/bot/event/GameEventHandler.java @@ -108,7 +108,7 @@ public final class GameEventHandler implements IGameEventListener, Helper { && type == ChunkEvent.Type.UNLOAD && mc.world.getChunkProvider().isChunkGeneratedAt(event.getX(), event.getZ()); - if (Baritone.settings().chuckCaching.get()) { + if (Baritone.settings().chunkCaching.get()) { if (isPostPopulate || isPreUnload) { CachedWorldProvider.INSTANCE.ifWorldLoaded(world -> world.updateCachedChunk(event.getX(), event.getZ(), @@ -132,7 +132,7 @@ public final class GameEventHandler implements IGameEventListener, Helper { @Override public void onWorldEvent(WorldEvent event) { - if (Baritone.settings().chuckCaching.get()) { + if (Baritone.settings().chunkCaching.get()) { CachedWorldProvider cache = CachedWorldProvider.INSTANCE; switch (event.getState()) { diff --git a/src/main/java/baritone/bot/pathing/calc/AStarPathFinder.java b/src/main/java/baritone/bot/pathing/calc/AStarPathFinder.java index e34a7eff..9f60a80c 100644 --- a/src/main/java/baritone/bot/pathing/calc/AStarPathFinder.java +++ b/src/main/java/baritone/bot/pathing/calc/AStarPathFinder.java @@ -94,7 +94,7 @@ public class AStarPathFinder extends AbstractNodeCostSearch implements Helper { int numNodes = 0; int numEmptyChunk = 0; boolean favoring = favoredPositions.isPresent(); - boolean cache = Baritone.settings().chuckCaching.get(); // grab all settings beforehand so that changing settings during pathing doesn't cause a crash or unpredictable behavior + boolean cache = Baritone.settings().chunkCaching.get(); // grab all settings beforehand so that changing settings during pathing doesn't cause a crash or unpredictable behavior int pathingMaxChunkBorderFetch = Baritone.settings().pathingMaxChunkBorderFetch.get(); double favorCoeff = Baritone.settings().backtrackCostFavoringCoefficient.get(); boolean minimumImprovementRepropagation = Baritone.settings().minimumImprovementRepropagation.get(); diff --git a/src/main/java/baritone/bot/utils/BlockStateInterface.java b/src/main/java/baritone/bot/utils/BlockStateInterface.java index cddd7351..591f43cb 100644 --- a/src/main/java/baritone/bot/utils/BlockStateInterface.java +++ b/src/main/java/baritone/bot/utils/BlockStateInterface.java @@ -41,7 +41,7 @@ public class BlockStateInterface implements Helper { if (chunk.isLoaded()) { return chunk.getBlockState(pos); } - if (Baritone.settings().chuckCaching.get()) { + if (Baritone.settings().chunkCaching.get()) { CachedWorld world = CachedWorldProvider.INSTANCE.getCurrentWorld(); if (world != null) { PathingBlockType type = world.getBlockType(pos); diff --git a/src/main/java/baritone/bot/utils/ExampleBaritoneControl.java b/src/main/java/baritone/bot/utils/ExampleBaritoneControl.java index a200789d..0fc62b71 100644 --- a/src/main/java/baritone/bot/utils/ExampleBaritoneControl.java +++ b/src/main/java/baritone/bot/utils/ExampleBaritoneControl.java @@ -23,7 +23,10 @@ import baritone.bot.behavior.Behavior; import baritone.bot.behavior.impl.PathingBehavior; import baritone.bot.event.events.ChatEvent; import baritone.bot.pathing.calc.AStarPathFinder; -import baritone.bot.pathing.goals.*; +import baritone.bot.pathing.goals.Goal; +import baritone.bot.pathing.goals.GoalBlock; +import baritone.bot.pathing.goals.GoalXZ; +import baritone.bot.pathing.goals.GoalYLevel; import baritone.bot.pathing.movement.ActionCosts; import baritone.bot.pathing.movement.CalculationContext; import baritone.bot.pathing.movement.Movement; From a9cac7718e6c2cfb7cf75383a1bfcfe1e8d7f686 Mon Sep 17 00:00:00 2001 From: Brady Date: Tue, 21 Aug 2018 16:36:51 -0500 Subject: [PATCH 09/19] Fix inputs overrides not resetting when out of world, fixes #43 --- .../java/baritone/bot/behavior/impl/PathingBehavior.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/baritone/bot/behavior/impl/PathingBehavior.java b/src/main/java/baritone/bot/behavior/impl/PathingBehavior.java index 269cf200..55b27b0d 100644 --- a/src/main/java/baritone/bot/behavior/impl/PathingBehavior.java +++ b/src/main/java/baritone/bot/behavior/impl/PathingBehavior.java @@ -56,8 +56,7 @@ public class PathingBehavior extends Behavior { @Override public void onTick(TickEvent event) { if (event.getType() == TickEvent.Type.OUT) { - current = null; - next = null; + this.cancel(); return; } if (current == null) { @@ -148,7 +147,9 @@ public class PathingBehavior extends Behavior { return current; } - public PathExecutor getNext() {return next;} + public PathExecutor getNext() { + return next; + } public Optional getPath() { return Optional.ofNullable(current).map(PathExecutor::getPath); From 194dd7abe7e8e3a5361b7b7a7e6e754d943883cb Mon Sep 17 00:00:00 2001 From: Brady Date: Tue, 21 Aug 2018 17:04:10 -0500 Subject: [PATCH 10/19] Automatically disable auto-jump while pathing is active, fixes #31 --- .../bot/behavior/impl/LookBehavior.java | 6 ++- .../bot/behavior/impl/MemoryBehavior.java | 7 ++- .../bot/behavior/impl/PathingBehavior.java | 18 ++++++++ .../baritone/bot/event/GameEventHandler.java | 4 +- .../bot/event/events/PlayerUpdateEvent.java | 44 +++++++++++++++++++ .../listener/AbstractGameEventListener.java | 2 +- .../event/listener/IGameEventListener.java | 2 +- .../launch/mixins/MixinEntityPlayerSP.java | 19 +++++++- src/main/resources/mixins.baritone.json | 3 ++ 9 files changed, 95 insertions(+), 10 deletions(-) create mode 100644 src/main/java/baritone/bot/event/events/PlayerUpdateEvent.java diff --git a/src/main/java/baritone/bot/behavior/impl/LookBehavior.java b/src/main/java/baritone/bot/behavior/impl/LookBehavior.java index 016df45e..36fc0e33 100644 --- a/src/main/java/baritone/bot/behavior/impl/LookBehavior.java +++ b/src/main/java/baritone/bot/behavior/impl/LookBehavior.java @@ -18,6 +18,8 @@ package baritone.bot.behavior.impl; import baritone.bot.behavior.Behavior; +import baritone.bot.event.events.PlayerUpdateEvent; +import baritone.bot.event.events.type.EventState; import baritone.bot.utils.Rotation; public class LookBehavior extends Behavior { @@ -39,8 +41,8 @@ public class LookBehavior extends Behavior { } @Override - public void onPlayerUpdate() { - if (target != null) { + public void onPlayerUpdate(PlayerUpdateEvent event) { + if (event.getState() == EventState.PRE && target != null) { player().rotationYaw = target.getFirst(); float oldPitch = player().rotationPitch; float desiredPitch = target.getSecond(); diff --git a/src/main/java/baritone/bot/behavior/impl/MemoryBehavior.java b/src/main/java/baritone/bot/behavior/impl/MemoryBehavior.java index 5803fb78..33ca56f1 100644 --- a/src/main/java/baritone/bot/behavior/impl/MemoryBehavior.java +++ b/src/main/java/baritone/bot/behavior/impl/MemoryBehavior.java @@ -2,6 +2,8 @@ package baritone.bot.behavior.impl; import baritone.bot.behavior.Behavior; import baritone.bot.event.events.PacketEvent; +import baritone.bot.event.events.PlayerUpdateEvent; +import baritone.bot.event.events.type.EventState; import net.minecraft.item.ItemStack; import net.minecraft.network.Packet; import net.minecraft.network.play.client.CPacketCloseWindow; @@ -35,8 +37,9 @@ public class MemoryBehavior extends Behavior { private final Map rememberedInventories = new HashMap<>(); @Override - public void onPlayerUpdate() { - updateInventory(); + public void onPlayerUpdate(PlayerUpdateEvent event) { + if (event.getState() == EventState.PRE) + updateInventory(); } @Override diff --git a/src/main/java/baritone/bot/behavior/impl/PathingBehavior.java b/src/main/java/baritone/bot/behavior/impl/PathingBehavior.java index 55b27b0d..324028db 100644 --- a/src/main/java/baritone/bot/behavior/impl/PathingBehavior.java +++ b/src/main/java/baritone/bot/behavior/impl/PathingBehavior.java @@ -19,6 +19,7 @@ package baritone.bot.behavior.impl; import baritone.bot.Baritone; import baritone.bot.behavior.Behavior; +import baritone.bot.event.events.PlayerUpdateEvent; import baritone.bot.event.events.RenderEvent; import baritone.bot.event.events.TickEvent; import baritone.bot.pathing.calc.AStarPathFinder; @@ -53,6 +54,8 @@ public class PathingBehavior extends Behavior { private final Object pathPlanLock = new Object(); + private boolean lastAutoJump; + @Override public void onTick(TickEvent event) { if (event.getType() == TickEvent.Type.OUT) { @@ -132,6 +135,21 @@ public class PathingBehavior extends Behavior { } } + @Override + public void onPlayerUpdate(PlayerUpdateEvent event) { + if (current != null) { + switch (event.getState()) { + case PRE: + lastAutoJump = mc.gameSettings.autoJump; + mc.gameSettings.autoJump = false; + break; + case POST: + mc.gameSettings.autoJump = lastAutoJump; + break; + } + } + } + public Optional ticksRemainingInSegment() { if (current == null) { return Optional.empty(); diff --git a/src/main/java/baritone/bot/event/GameEventHandler.java b/src/main/java/baritone/bot/event/GameEventHandler.java index 7beeb3d6..b6f365e9 100644 --- a/src/main/java/baritone/bot/event/GameEventHandler.java +++ b/src/main/java/baritone/bot/event/GameEventHandler.java @@ -69,8 +69,8 @@ public final class GameEventHandler implements IGameEventListener, Helper { } @Override - public final void onPlayerUpdate() { - dispatch(IGameEventListener::onPlayerUpdate); + public final void onPlayerUpdate(PlayerUpdateEvent event) { + dispatch(listener -> listener.onPlayerUpdate(event)); } @Override diff --git a/src/main/java/baritone/bot/event/events/PlayerUpdateEvent.java b/src/main/java/baritone/bot/event/events/PlayerUpdateEvent.java new file mode 100644 index 00000000..1046c060 --- /dev/null +++ b/src/main/java/baritone/bot/event/events/PlayerUpdateEvent.java @@ -0,0 +1,44 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Baritone. If not, see . + */ + +package baritone.bot.event.events; + +import baritone.bot.event.events.type.EventState; + +/** + * @author Brady + * @since 8/21/2018 + */ +public final class PlayerUpdateEvent { + + /** + * The state of the event + */ + private final EventState state; + + public PlayerUpdateEvent(EventState state) { + this.state = state; + } + + /** + * @return The state of the event + */ + public final EventState getState() { + return this.state; + } + +} diff --git a/src/main/java/baritone/bot/event/listener/AbstractGameEventListener.java b/src/main/java/baritone/bot/event/listener/AbstractGameEventListener.java index a3e4251d..09534fdc 100644 --- a/src/main/java/baritone/bot/event/listener/AbstractGameEventListener.java +++ b/src/main/java/baritone/bot/event/listener/AbstractGameEventListener.java @@ -52,7 +52,7 @@ public interface AbstractGameEventListener extends IGameEventListener { default void onTick(TickEvent event) {} @Override - default void onPlayerUpdate() {} + default void onPlayerUpdate(PlayerUpdateEvent event) {} @Override default void onProcessKeyBinds() {} diff --git a/src/main/java/baritone/bot/event/listener/IGameEventListener.java b/src/main/java/baritone/bot/event/listener/IGameEventListener.java index d2b0cd28..31b549fc 100644 --- a/src/main/java/baritone/bot/event/listener/IGameEventListener.java +++ b/src/main/java/baritone/bot/event/listener/IGameEventListener.java @@ -63,7 +63,7 @@ public interface IGameEventListener { * Run once per game tick from before the player rotation is sent to the server. * @see EntityPlayerSP#onUpdate() */ - void onPlayerUpdate(); + void onPlayerUpdate(PlayerUpdateEvent event); /** * Run once per game tick from before keybinds are processed. diff --git a/src/main/java/baritone/launch/mixins/MixinEntityPlayerSP.java b/src/main/java/baritone/launch/mixins/MixinEntityPlayerSP.java index 1ecb6d57..16849798 100644 --- a/src/main/java/baritone/launch/mixins/MixinEntityPlayerSP.java +++ b/src/main/java/baritone/launch/mixins/MixinEntityPlayerSP.java @@ -19,6 +19,8 @@ package baritone.launch.mixins; import baritone.bot.Baritone; import baritone.bot.event.events.ChatEvent; +import baritone.bot.event.events.PlayerUpdateEvent; +import baritone.bot.event.events.type.EventState; import net.minecraft.client.entity.EntityPlayerSP; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -53,7 +55,20 @@ public class MixinEntityPlayerSP { by = -3 ) ) - private void onUpdate(CallbackInfo ci) { - Baritone.INSTANCE.getGameEventHandler().onPlayerUpdate(); + private void onPreUpdate(CallbackInfo ci) { + Baritone.INSTANCE.getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent(EventState.PRE)); + } + + @Inject( + method = "onUpdate", + at = @At( + value = "INVOKE", + target = "net/minecraft/client/entity/EntityPlayerSP.onUpdateWalkingPlayer()V", + shift = At.Shift.BY, + by = 2 + ) + ) + private void onPostUpdate(CallbackInfo ci) { + Baritone.INSTANCE.getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent(EventState.POST)); } } diff --git a/src/main/resources/mixins.baritone.json b/src/main/resources/mixins.baritone.json index 72f7d4dc..86521c33 100755 --- a/src/main/resources/mixins.baritone.json +++ b/src/main/resources/mixins.baritone.json @@ -4,6 +4,9 @@ "refmap": "mixins.client.refmap.json", "compatibilityLevel": "JAVA_8", "verbose": false, + "injectors": { + "maxShiftBy": 2 + }, "client": [ "MixinEntityPlayerSP", "MixinEntityRenderer", From 14dddfb1de8db948effa913492b0022b943d1d9f Mon Sep 17 00:00:00 2001 From: Leijurv Date: Tue, 21 Aug 2018 15:18:35 -0700 Subject: [PATCH 11/19] chunk packing linkedblockingqueue --- .../java/baritone/bot/chunk/CachedRegion.java | 20 +++++---- .../java/baritone/bot/chunk/CachedWorld.java | 42 +++++++++++++++++-- .../bot/chunk/CachedWorldProvider.java | 10 +++++ .../java/baritone/bot/chunk/ChunkPacker.java | 11 ++--- .../bot/chunk/ICachedChunkAccess.java | 31 -------------- .../baritone/bot/event/GameEventHandler.java | 12 +++--- 6 files changed, 74 insertions(+), 52 deletions(-) delete mode 100644 src/main/java/baritone/bot/chunk/ICachedChunkAccess.java diff --git a/src/main/java/baritone/bot/chunk/CachedRegion.java b/src/main/java/baritone/bot/chunk/CachedRegion.java index 05d6ee9d..8f2dfc9b 100644 --- a/src/main/java/baritone/bot/chunk/CachedRegion.java +++ b/src/main/java/baritone/bot/chunk/CachedRegion.java @@ -17,6 +17,7 @@ package baritone.bot.chunk; +import baritone.bot.utils.pathing.IBlockTypeAccess; import baritone.bot.utils.pathing.PathingBlockType; import java.io.*; @@ -32,7 +33,7 @@ import java.util.zip.GZIPOutputStream; * @author Brady * @since 8/3/2018 9:35 PM */ -public final class CachedRegion implements ICachedChunkAccess { +public final class CachedRegion implements IBlockTypeAccess { private static final byte CHUNK_NOT_PRESENT = 0; private static final byte CHUNK_PRESENT = 1; @@ -76,8 +77,7 @@ public final class CachedRegion implements ICachedChunkAccess { return null; } - @Override - public final void updateCachedChunk(int chunkX, int chunkZ, BitSet data) { + final void updateCachedChunk(int chunkX, int chunkZ, BitSet data) { CachedChunk chunk = this.getChunk(chunkX, chunkZ); if (chunk == null) { this.chunks[chunkX][chunkZ] = new CachedChunk(chunkX, chunkZ, data); @@ -111,7 +111,7 @@ public final class CachedRegion implements ICachedChunkAccess { if (!Files.exists(path)) Files.createDirectories(path); - System.out.println("Saving region " + x + "," + z + " to disk"); + System.out.println("Saving region " + x + "," + z + " to disk " + path); Path regionFile = getRegionFile(path, this.x, this.z); if (!Files.exists(regionFile)) Files.createFile(regionFile); @@ -138,7 +138,10 @@ public final class CachedRegion implements ICachedChunkAccess { out.writeInt(~CACHED_REGION_MAGIC); } hasUnsavedChanges = false; - } catch (IOException ignored) {} + System.out.println("Saved region successfully"); + } catch (IOException ex) { + ex.printStackTrace(); + } } public void load(String directory) { @@ -151,7 +154,7 @@ public final class CachedRegion implements ICachedChunkAccess { if (!Files.exists(regionFile)) return; - System.out.println("Loading region " + x + "," + z + " from disk"); + System.out.println("Loading region " + x + "," + z + " from disk " + path); try ( FileInputStream fileIn = new FileInputStream(regionFile.toFile()); @@ -189,7 +192,10 @@ public final class CachedRegion implements ICachedChunkAccess { } } hasUnsavedChanges = false; - } catch (IOException ignored) {} + System.out.println("Loaded region successfully"); + } catch (IOException ex) { + ex.printStackTrace(); + } } private static boolean isAllZeros(final byte[] array) { diff --git a/src/main/java/baritone/bot/chunk/CachedWorld.java b/src/main/java/baritone/bot/chunk/CachedWorld.java index eb7513a3..d3900f6f 100644 --- a/src/main/java/baritone/bot/chunk/CachedWorld.java +++ b/src/main/java/baritone/bot/chunk/CachedWorld.java @@ -17,18 +17,21 @@ package baritone.bot.chunk; +import baritone.bot.utils.pathing.IBlockTypeAccess; import baritone.bot.utils.pathing.PathingBlockType; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; +import net.minecraft.world.chunk.Chunk; import java.util.BitSet; +import java.util.concurrent.LinkedBlockingQueue; import java.util.function.Consumer; /** * @author Brady * @since 8/4/2018 12:02 AM */ -public final class CachedWorld implements ICachedChunkAccess { +public final class CachedWorld implements IBlockTypeAccess { /** * The maximum number of regions in any direction from (0,0) @@ -45,10 +48,21 @@ public final class CachedWorld implements ICachedChunkAccess { */ private final String directory; + private final LinkedBlockingQueue toPack = new LinkedBlockingQueue<>(); + public CachedWorld(String directory) { this.directory = directory; // Insert an invalid region element cachedRegions.put(0, null); + new PackerThread().start(); + } + + public final void queueForPacking(Chunk chunk) { + try { + toPack.put(chunk); + } catch (InterruptedException e) { + e.printStackTrace(); + } } @Override @@ -57,17 +71,19 @@ public final class CachedWorld implements ICachedChunkAccess { return region.getBlockType(x & 511, y, z & 511); } - @Override - public final void updateCachedChunk(int chunkX, int chunkZ, BitSet data) { + private void updateCachedChunk(int chunkX, int chunkZ, BitSet data) { CachedRegion region = getOrCreateRegion(chunkX >> 5, chunkZ >> 5); region.updateCachedChunk(chunkX & 31, chunkZ & 31, data); } public final void save() { + long start = System.currentTimeMillis(); this.cachedRegions.values().forEach(region -> { if (region != null) region.save(this.directory); }); + long now = System.currentTimeMillis(); + System.out.println("World save took " + (now - start) + "ms"); } /** @@ -129,4 +145,24 @@ public final class CachedWorld implements ICachedChunkAccess { private boolean isRegionInWorld(int regionX, int regionZ) { return regionX <= REGION_MAX && regionX >= -REGION_MAX && regionZ <= REGION_MAX && regionZ >= -REGION_MAX; } + + private class PackerThread extends Thread { + public void run() { + while (true) { + LinkedBlockingQueue queue = toPack; + if (queue == null) { + break; + } + try { + Chunk chunk = queue.take(); + BitSet packed = ChunkPacker.createPackedChunk(chunk); + CachedWorld.this.updateCachedChunk(chunk.x, chunk.z, packed); + //System.out.println("Processed chunk at " + chunk.x + "," + chunk.z); + } catch (InterruptedException e) { + e.printStackTrace(); + break; + } + } + } + } } diff --git a/src/main/java/baritone/bot/chunk/CachedWorldProvider.java b/src/main/java/baritone/bot/chunk/CachedWorldProvider.java index e6062d6d..b59c3a52 100644 --- a/src/main/java/baritone/bot/chunk/CachedWorldProvider.java +++ b/src/main/java/baritone/bot/chunk/CachedWorldProvider.java @@ -69,7 +69,17 @@ public enum CachedWorldProvider implements Helper { } public final void closeWorld() { + CachedWorld world = this.currentWorld; this.currentWorld = null; + if (world == null) { + return; + } + new Thread() { + public void run() { + System.out.println("Started saving the world in a new thread"); + world.save(); + } + }.start(); } public final void ifWorldLoaded(Consumer currentWorldConsumer) { diff --git a/src/main/java/baritone/bot/chunk/ChunkPacker.java b/src/main/java/baritone/bot/chunk/ChunkPacker.java index 7b8fbbe4..25ef3b39 100644 --- a/src/main/java/baritone/bot/chunk/ChunkPacker.java +++ b/src/main/java/baritone/bot/chunk/ChunkPacker.java @@ -18,9 +18,9 @@ package baritone.bot.chunk; import baritone.bot.pathing.movement.MovementHelper; -import baritone.bot.utils.pathing.PathingBlockType; import baritone.bot.utils.BlockStateInterface; import baritone.bot.utils.Helper; +import baritone.bot.utils.pathing.PathingBlockType; import net.minecraft.block.Block; import net.minecraft.block.BlockAir; import net.minecraft.block.state.IBlockState; @@ -29,8 +29,6 @@ import net.minecraft.world.chunk.Chunk; import java.util.BitSet; -import static net.minecraft.block.Block.NULL_AABB; - /** * @author Brady * @since 8/3/2018 1:09 AM @@ -39,7 +37,8 @@ public final class ChunkPacker implements Helper { private ChunkPacker() {} - public static BitSet createPackedChunk(Chunk chunk) { + public static synchronized BitSet createPackedChunk(Chunk chunk) { + long start = System.currentTimeMillis(); BitSet bitSet = new BitSet(CachedChunk.SIZE); try { for (int y = 0; y < 256; y++) { @@ -55,6 +54,8 @@ public final class ChunkPacker implements Helper { } catch (Exception e) { e.printStackTrace(); } + long end = System.currentTimeMillis(); + //System.out.println("Chunk packing took " + (end - start) + "ms for " + chunk.x + "," + chunk.z); return bitSet; } @@ -69,7 +70,7 @@ public final class ChunkPacker implements Helper { return PathingBlockType.AVOID; } - if (block instanceof BlockAir || state.getCollisionBoundingBox(mc.world, pos) == NULL_AABB) { + if (block instanceof BlockAir) { return PathingBlockType.AIR; } diff --git a/src/main/java/baritone/bot/chunk/ICachedChunkAccess.java b/src/main/java/baritone/bot/chunk/ICachedChunkAccess.java deleted file mode 100644 index 9cb4e649..00000000 --- a/src/main/java/baritone/bot/chunk/ICachedChunkAccess.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of Baritone. - * - * Baritone is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Baritone is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Baritone. If not, see . - */ - -package baritone.bot.chunk; - -import baritone.bot.utils.pathing.IBlockTypeAccess; - -import java.util.BitSet; - -/** - * @author Brady - * @since 8/4/2018 1:10 AM - */ -public interface ICachedChunkAccess extends IBlockTypeAccess { - - void updateCachedChunk(int chunkX, int chunkZ, BitSet data); -} diff --git a/src/main/java/baritone/bot/event/GameEventHandler.java b/src/main/java/baritone/bot/event/GameEventHandler.java index 4221d3bc..c83f6815 100644 --- a/src/main/java/baritone/bot/event/GameEventHandler.java +++ b/src/main/java/baritone/bot/event/GameEventHandler.java @@ -36,9 +36,7 @@ package baritone.bot.event; import baritone.bot.Baritone; import baritone.bot.behavior.Behavior; -import baritone.bot.chunk.CachedWorld; import baritone.bot.chunk.CachedWorldProvider; -import baritone.bot.chunk.ChunkPacker; import baritone.bot.event.events.*; import baritone.bot.event.events.type.EventState; import baritone.bot.event.listener.IGameEventListener; @@ -49,6 +47,7 @@ import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.settings.KeyBinding; +import net.minecraft.world.chunk.Chunk; import org.lwjgl.input.Keyboard; import java.util.function.Consumer; @@ -110,9 +109,10 @@ public final class GameEventHandler implements IGameEventListener, Helper { if (Baritone.settings().chunkCaching.get()) { if (isPostPopulate || isPreUnload) { - CachedWorldProvider.INSTANCE.ifWorldLoaded(world -> - world.updateCachedChunk(event.getX(), event.getZ(), - ChunkPacker.createPackedChunk(mc.world.getChunk(event.getX(), event.getZ())))); + CachedWorldProvider.INSTANCE.ifWorldLoaded(world -> { + Chunk chunk = mc.world.getChunk(event.getX(), event.getZ()); + world.queueForPacking(chunk); + }); } } @@ -137,7 +137,7 @@ public final class GameEventHandler implements IGameEventListener, Helper { switch (event.getState()) { case PRE: - cache.ifWorldLoaded(CachedWorld::save); + cache.closeWorld(); break; case POST: cache.closeWorld(); From eb34c1fc240f31788bf9575db7adb0ffdae12505 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Tue, 21 Aug 2018 15:20:33 -0700 Subject: [PATCH 12/19] unneeded slowdown --- src/main/java/baritone/bot/chunk/ChunkPacker.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/baritone/bot/chunk/ChunkPacker.java b/src/main/java/baritone/bot/chunk/ChunkPacker.java index 25ef3b39..de8f3179 100644 --- a/src/main/java/baritone/bot/chunk/ChunkPacker.java +++ b/src/main/java/baritone/bot/chunk/ChunkPacker.java @@ -37,7 +37,7 @@ public final class ChunkPacker implements Helper { private ChunkPacker() {} - public static synchronized BitSet createPackedChunk(Chunk chunk) { + public static BitSet createPackedChunk(Chunk chunk) { long start = System.currentTimeMillis(); BitSet bitSet = new BitSet(CachedChunk.SIZE); try { From 843bc1777765852f6e87a789ba1fcc04a2fbd37c Mon Sep 17 00:00:00 2001 From: Brady Date: Tue, 21 Aug 2018 17:52:09 -0500 Subject: [PATCH 13/19] Add forceRotations field to MovementState Preparation for silent moving --- .../bot/pathing/movement/Movement.java | 4 ++-- .../bot/pathing/movement/MovementHelper.java | 10 +++++---- .../bot/pathing/movement/MovementState.java | 22 ++++++++++++++----- .../movement/movements/MovementAscend.java | 2 +- .../movement/movements/MovementFall.java | 4 ++-- .../movement/movements/MovementPillar.java | 2 +- .../movement/movements/MovementTraverse.java | 6 ++--- src/main/java/baritone/bot/utils/ToolSet.java | 2 +- 8 files changed, 33 insertions(+), 19 deletions(-) diff --git a/src/main/java/baritone/bot/pathing/movement/Movement.java b/src/main/java/baritone/bot/pathing/movement/Movement.java index 84540a75..5b31c147 100644 --- a/src/main/java/baritone/bot/pathing/movement/Movement.java +++ b/src/main/java/baritone/bot/pathing/movement/Movement.java @@ -131,7 +131,7 @@ public abstract class Movement implements Helper, MovementHelper { Optional reachable = LookBehaviorUtils.reachable(blockPos); if (reachable.isPresent()) { player().inventory.currentItem = new ToolSet().getBestSlot(BlockStateInterface.get(blockPos)); - state.setTarget(new MovementState.MovementTarget(reachable.get())).setInput(Input.CLICK_LEFT, true); + state.setTarget(new MovementState.MovementTarget(reachable.get(), true)).setInput(Input.CLICK_LEFT, true); return false; } //get rekt minecraft @@ -139,7 +139,7 @@ public abstract class Movement implements Helper, MovementHelper { //i dont care if theres snow in the way!!!!!!! //you dont own me!!!! state.setTarget(new MovementState.MovementTarget(Utils.calcRotationFromVec3d(mc.player.getPositionEyes(1.0F), - Utils.getBlockPosCenter(blockPos))) + Utils.getBlockPosCenter(blockPos)), true) ).setInput(InputOverrideHandler.Input.CLICK_LEFT, true); return false; } diff --git a/src/main/java/baritone/bot/pathing/movement/MovementHelper.java b/src/main/java/baritone/bot/pathing/movement/MovementHelper.java index aef088e1..7e84a1cd 100644 --- a/src/main/java/baritone/bot/pathing/movement/MovementHelper.java +++ b/src/main/java/baritone/bot/pathing/movement/MovementHelper.java @@ -255,10 +255,12 @@ public interface MovementHelper extends ActionCosts, Helper { } static void moveTowards(MovementState state, BlockPos pos) { - state.setTarget(new MovementTarget(new Rotation(Utils.calcRotationFromVec3d(mc.player.getPositionEyes(1.0F), - Utils.getBlockPosCenter(pos), - new Rotation(mc.player.rotationYaw, mc.player.rotationPitch)).getFirst(), mc.player.rotationPitch)) - ).setInput(InputOverrideHandler.Input.MOVE_FORWARD, true); + state.setTarget(new MovementTarget( + new Rotation(Utils.calcRotationFromVec3d(mc.player.getPositionEyes(1.0F), + Utils.getBlockPosCenter(pos), + new Rotation(mc.player.rotationYaw, mc.player.rotationPitch)).getFirst(), mc.player.rotationPitch), + false + )).setInput(InputOverrideHandler.Input.MOVE_FORWARD, true); } static Movement generateMovementFallOrDescend(BlockPos pos, BlockPos dest, CalculationContext calcContext) { diff --git a/src/main/java/baritone/bot/pathing/movement/MovementState.java b/src/main/java/baritone/bot/pathing/movement/MovementState.java index efc56c08..2d2d3497 100644 --- a/src/main/java/baritone/bot/pathing/movement/MovementState.java +++ b/src/main/java/baritone/bot/pathing/movement/MovementState.java @@ -93,21 +93,29 @@ public class MovementState { */ public Rotation rotation; + /** + * Whether or not this target must force rotations. + *

+ * {@code true} if we're trying to place or break blocks, {@code false} if we're trying to look at the movement location + */ + private boolean forceRotations; + public MovementTarget() { - this(null, null); + this(null, null, false); } public MovementTarget(Vec3d position) { - this(position, null); + this(position, null, false); } - public MovementTarget(Rotation rotation) { - this(null, rotation); + public MovementTarget(Rotation rotation, boolean forceRotations) { + this(null, rotation, forceRotations); } - public MovementTarget(Vec3d position, Rotation rotation) { + public MovementTarget(Vec3d position, Rotation rotation, boolean forceRotations) { this.position = position; this.rotation = rotation; + this.forceRotations = forceRotations; } public final Optional getPosition() { @@ -117,5 +125,9 @@ public class MovementState { public final Optional getRotation() { return Optional.ofNullable(this.rotation); } + + public boolean hasToForceRotations() { + return this.forceRotations; + } } } diff --git a/src/main/java/baritone/bot/pathing/movement/movements/MovementAscend.java b/src/main/java/baritone/bot/pathing/movement/movements/MovementAscend.java index 5fc408aa..5f180fdf 100644 --- a/src/main/java/baritone/bot/pathing/movement/movements/MovementAscend.java +++ b/src/main/java/baritone/bot/pathing/movement/movements/MovementAscend.java @@ -139,7 +139,7 @@ public class MovementAscend extends Movement { double faceX = (dest.getX() + anAgainst.getX() + 1.0D) * 0.5D; double faceY = (dest.getY() + anAgainst.getY()) * 0.5D; double faceZ = (dest.getZ() + anAgainst.getZ() + 1.0D) * 0.5D; - state.setTarget(new MovementState.MovementTarget(Utils.calcRotationFromVec3d(playerHead(), new Vec3d(faceX, faceY, faceZ), playerRotations()))); + state.setTarget(new MovementState.MovementTarget(Utils.calcRotationFromVec3d(playerHead(), new Vec3d(faceX, faceY, faceZ), playerRotations()), true)); EnumFacing side = Minecraft.getMinecraft().objectMouseOver.sideHit; if (Objects.equals(LookBehaviorUtils.getSelectedBlock().orElse(null), anAgainst) && LookBehaviorUtils.getSelectedBlock().get().offset(side).equals(positionsToPlace[0])) { ticksWithoutPlacement++; diff --git a/src/main/java/baritone/bot/pathing/movement/movements/MovementFall.java b/src/main/java/baritone/bot/pathing/movement/movements/MovementFall.java index fe7dde7b..d8c055fc 100644 --- a/src/main/java/baritone/bot/pathing/movement/movements/MovementFall.java +++ b/src/main/java/baritone/bot/pathing/movement/movements/MovementFall.java @@ -101,9 +101,9 @@ public class MovementFall extends Movement { } if (targetRotation.isPresent()) { state.setInput(InputOverrideHandler.Input.CLICK_RIGHT, true) - .setTarget(new MovementTarget(targetRotation.get())); + .setTarget(new MovementTarget(targetRotation.get(), true)); } else { - state.setTarget(new MovementTarget(Utils.calcRotationFromVec3d(playerHead(), Utils.getBlockPosCenter(dest)))); + state.setTarget(new MovementTarget(Utils.calcRotationFromVec3d(playerHead(), Utils.getBlockPosCenter(dest)), true)); } if (playerFeet.equals(dest) && (player().posY - playerFeet.getY() < 0.094 // lilypads || BlockStateInterface.isWater(dest))) { diff --git a/src/main/java/baritone/bot/pathing/movement/movements/MovementPillar.java b/src/main/java/baritone/bot/pathing/movement/movements/MovementPillar.java index bcc23fdc..9c1cd885 100644 --- a/src/main/java/baritone/bot/pathing/movement/movements/MovementPillar.java +++ b/src/main/java/baritone/bot/pathing/movement/movements/MovementPillar.java @@ -115,7 +115,7 @@ public class MovementPillar extends Movement { if (!ladder) { state.setTarget(new MovementState.MovementTarget(Utils.calcRotationFromVec3d(mc.player.getPositionEyes(1.0F), Utils.getBlockPosCenter(positionsToPlace[0]), - new Rotation(mc.player.rotationYaw, mc.player.rotationPitch)))); + new Rotation(mc.player.rotationYaw, mc.player.rotationPitch)), true)); } EntityPlayerSP thePlayer = Minecraft.getMinecraft().player; boolean blockIsThere = MovementHelper.canWalkOn(src) || ladder; diff --git a/src/main/java/baritone/bot/pathing/movement/movements/MovementTraverse.java b/src/main/java/baritone/bot/pathing/movement/movements/MovementTraverse.java index 2ca97995..4b5d8f1c 100644 --- a/src/main/java/baritone/bot/pathing/movement/movements/MovementTraverse.java +++ b/src/main/java/baritone/bot/pathing/movement/movements/MovementTraverse.java @@ -148,7 +148,7 @@ public class MovementTraverse extends Movement { } if (isDoorActuallyBlockingUs) { if (!(Blocks.IRON_DOOR.equals(srcBlock) || Blocks.IRON_DOOR.equals(pb0.getBlock()) || Blocks.IRON_DOOR.equals(pb1.getBlock()))) { - state.setTarget(new MovementState.MovementTarget(Utils.calcRotationFromVec3d(playerHead(), Utils.calcCenterFromCoords(positionsToBreak[0], world())))); + state.setTarget(new MovementState.MovementTarget(Utils.calcRotationFromVec3d(playerHead(), Utils.calcCenterFromCoords(positionsToBreak[0], world())), true)); state.setInput(InputOverrideHandler.Input.CLICK_RIGHT, true); return state; } @@ -190,7 +190,7 @@ public class MovementTraverse extends Movement { double faceX = (dest.getX() + against1.getX() + 1.0D) * 0.5D; double faceY = (dest.getY() + against1.getY()) * 0.5D; double faceZ = (dest.getZ() + against1.getZ() + 1.0D) * 0.5D; - state.setTarget(new MovementState.MovementTarget(Utils.calcRotationFromVec3d(playerHead(), new Vec3d(faceX, faceY, faceZ), playerRotations()))); + state.setTarget(new MovementState.MovementTarget(Utils.calcRotationFromVec3d(playerHead(), new Vec3d(faceX, faceY, faceZ), playerRotations()), true)); EnumFacing side = Minecraft.getMinecraft().objectMouseOver.sideHit; if (Objects.equals(LookBehaviorUtils.getSelectedBlock().orElse(null), against1) && Minecraft.getMinecraft().player.isSneaking()) { @@ -217,7 +217,7 @@ public class MovementTraverse extends Movement { double faceZ = (dest.getZ() + src.getZ() + 1.0D) * 0.5D; // faceX, faceY, faceZ is the middle of the face between from and to BlockPos goalLook = src.down(); // this is the block we were just standing on, and the one we want to place against - state.setTarget(new MovementState.MovementTarget(Utils.calcRotationFromVec3d(playerHead(), new Vec3d(faceX, faceY, faceZ), playerRotations()))); + state.setTarget(new MovementState.MovementTarget(Utils.calcRotationFromVec3d(playerHead(), new Vec3d(faceX, faceY, faceZ), playerRotations()), true)); state.setInput(InputOverrideHandler.Input.MOVE_BACK, true); state.setInput(InputOverrideHandler.Input.SNEAK, true); diff --git a/src/main/java/baritone/bot/utils/ToolSet.java b/src/main/java/baritone/bot/utils/ToolSet.java index 935e157f..d75c3c03 100644 --- a/src/main/java/baritone/bot/utils/ToolSet.java +++ b/src/main/java/baritone/bot/utils/ToolSet.java @@ -164,7 +164,7 @@ public class ToolSet implements Helper { event.setSlot(this.overrideSlot); } - public final void setOverrideSlot(int overrideSlot) { + final void setOverrideSlot(int overrideSlot) { this.overrideSlot = overrideSlot; } } From c96b9cb6af3c6428e51377ee8f4234e658370ad0 Mon Sep 17 00:00:00 2001 From: Brady Date: Tue, 21 Aug 2018 18:19:20 -0500 Subject: [PATCH 14/19] Added free look option --- src/main/java/baritone/bot/Settings.java | 10 +++- .../bot/behavior/impl/LookBehavior.java | 42 ++++++++++++-- .../baritone/bot/event/GameEventHandler.java | 11 +++- .../bot/event/events/PlayerUpdateEvent.java | 1 - .../bot/event/events/RelativeMoveEvent.java | 43 ++++++++++++++ .../listener/AbstractGameEventListener.java | 3 + .../event/listener/IGameEventListener.java | 11 +++- .../bot/pathing/movement/Movement.java | 8 ++- .../baritone/launch/mixins/MixinEntity.java | 56 +++++++++++++++++++ src/main/resources/mixins.baritone.json | 1 + 10 files changed, 174 insertions(+), 12 deletions(-) create mode 100644 src/main/java/baritone/bot/event/events/RelativeMoveEvent.java create mode 100644 src/main/java/baritone/launch/mixins/MixinEntity.java diff --git a/src/main/java/baritone/bot/Settings.java b/src/main/java/baritone/bot/Settings.java index f3069051..479c86cd 100644 --- a/src/main/java/baritone/bot/Settings.java +++ b/src/main/java/baritone/bot/Settings.java @@ -202,6 +202,11 @@ public class Settings { */ public Setting fadePath = new Setting<>(false); + /** + * Move without having to force the client-sided rotations + */ + public Setting freeLook = new Setting<>(true); + public final Map> byLowerName; public final List> allSettings; @@ -210,6 +215,7 @@ public class Settings { private String name; private final Class klass; + @SuppressWarnings("unchecked") private Setting(T value) { if (value == null) { throw new IllegalArgumentException("Cannot determine value type class from null"); @@ -218,6 +224,7 @@ public class Settings { this.klass = (Class) value.getClass(); } + @SuppressWarnings("unchecked") public final K get() { return (K) value; } @@ -244,7 +251,7 @@ public class Settings { try { for (Field field : temp) { if (field.getType().equals(Setting.class)) { - Setting setting = (Setting) field.get(this); + Setting setting = (Setting) field.get(this); String name = field.getName(); setting.name = name; name = name.toLowerCase(); @@ -262,6 +269,7 @@ public class Settings { allSettings = Collections.unmodifiableList(tmpAll); } + @SuppressWarnings("unchecked") public List> getByValueType(Class klass) { ArrayList> result = new ArrayList<>(); for (Setting setting : allSettings) { diff --git a/src/main/java/baritone/bot/behavior/impl/LookBehavior.java b/src/main/java/baritone/bot/behavior/impl/LookBehavior.java index 36fc0e33..2b470362 100644 --- a/src/main/java/baritone/bot/behavior/impl/LookBehavior.java +++ b/src/main/java/baritone/bot/behavior/impl/LookBehavior.java @@ -17,8 +17,11 @@ package baritone.bot.behavior.impl; +import baritone.bot.Baritone; +import baritone.bot.Settings; import baritone.bot.behavior.Behavior; import baritone.bot.event.events.PlayerUpdateEvent; +import baritone.bot.event.events.RelativeMoveEvent; import baritone.bot.event.events.type.EventState; import baritone.bot.utils.Rotation; @@ -36,21 +39,50 @@ public class LookBehavior extends Behavior { */ private Rotation target; - public void updateTarget(Rotation target) { + /** + * Whether or not rotations are currently being forced + */ + private boolean force; + + /** + * The last player yaw angle. Used when free looking + * + * @see Settings#freeLook + */ + private float lastYaw; + + public void updateTarget(Rotation target, boolean force) { this.target = target; + this.force = force || !Baritone.settings().freeLook.get(); } @Override public void onPlayerUpdate(PlayerUpdateEvent event) { - if (event.getState() == EventState.PRE && target != null) { - player().rotationYaw = target.getFirst(); + if (event.getState() == EventState.PRE && this.target != null && this.force) { + player().rotationYaw = this.target.getFirst(); float oldPitch = player().rotationPitch; - float desiredPitch = target.getSecond(); + float desiredPitch = this.target.getSecond(); player().rotationPitch = desiredPitch; if (desiredPitch == oldPitch) { nudgeToLevel(); } - target = null; + this.target = null; + } + } + + @Override + public void onPlayerRelativeMove(RelativeMoveEvent event) { + if (this.target != null && !force) { + switch (event.getState()) { + case PRE: + this.lastYaw = player().rotationYaw; + player().rotationYaw = this.target.getFirst(); + break; + case POST: + player().rotationYaw = this.lastYaw; + this.target = null; + break; + } } } diff --git a/src/main/java/baritone/bot/event/GameEventHandler.java b/src/main/java/baritone/bot/event/GameEventHandler.java index 1ffe9861..72917145 100644 --- a/src/main/java/baritone/bot/event/GameEventHandler.java +++ b/src/main/java/baritone/bot/event/GameEventHandler.java @@ -156,17 +156,22 @@ public final class GameEventHandler implements IGameEventListener, Helper { @Override public final void onSendPacket(PacketEvent event) { - dispatch(behavior -> behavior.onSendPacket(event)); + dispatch(listener -> listener.onSendPacket(event)); } @Override public final void onReceivePacket(PacketEvent event) { - dispatch(behavior -> behavior.onReceivePacket(event)); + dispatch(listener -> listener.onReceivePacket(event)); } @Override public final void onQueryItemSlotForBlocks(ItemSlotEvent event) { - dispatch(behavior -> behavior.onQueryItemSlotForBlocks(event)); + dispatch(listener -> listener.onQueryItemSlotForBlocks(event)); + } + + @Override + public void onPlayerRelativeMove(RelativeMoveEvent event) { + dispatch(listener -> listener.onPlayerRelativeMove(event)); } public final void registerEventListener(IGameEventListener listener) { diff --git a/src/main/java/baritone/bot/event/events/PlayerUpdateEvent.java b/src/main/java/baritone/bot/event/events/PlayerUpdateEvent.java index 1046c060..b1b703fb 100644 --- a/src/main/java/baritone/bot/event/events/PlayerUpdateEvent.java +++ b/src/main/java/baritone/bot/event/events/PlayerUpdateEvent.java @@ -40,5 +40,4 @@ public final class PlayerUpdateEvent { public final EventState getState() { return this.state; } - } diff --git a/src/main/java/baritone/bot/event/events/RelativeMoveEvent.java b/src/main/java/baritone/bot/event/events/RelativeMoveEvent.java new file mode 100644 index 00000000..cf7f03ad --- /dev/null +++ b/src/main/java/baritone/bot/event/events/RelativeMoveEvent.java @@ -0,0 +1,43 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Baritone. If not, see . + */ + +package baritone.bot.event.events; + +import baritone.bot.event.events.type.EventState; + +/** + * @author Brady + * @since 8/21/2018 + */ +public final class RelativeMoveEvent { + + /** + * The state of the event + */ + private final EventState state; + + public RelativeMoveEvent(EventState state) { + this.state = state; + } + + /** + * @return The state of the event + */ + public final EventState getState() { + return this.state; + } +} diff --git a/src/main/java/baritone/bot/event/listener/AbstractGameEventListener.java b/src/main/java/baritone/bot/event/listener/AbstractGameEventListener.java index 09534fdc..91bb183e 100644 --- a/src/main/java/baritone/bot/event/listener/AbstractGameEventListener.java +++ b/src/main/java/baritone/bot/event/listener/AbstractGameEventListener.java @@ -77,4 +77,7 @@ public interface AbstractGameEventListener extends IGameEventListener { @Override default void onQueryItemSlotForBlocks(ItemSlotEvent event) {} + + @Override + default void onPlayerRelativeMove(RelativeMoveEvent event) {} } diff --git a/src/main/java/baritone/bot/event/listener/IGameEventListener.java b/src/main/java/baritone/bot/event/listener/IGameEventListener.java index 31b549fc..260e6e9e 100644 --- a/src/main/java/baritone/bot/event/listener/IGameEventListener.java +++ b/src/main/java/baritone/bot/event/listener/IGameEventListener.java @@ -42,6 +42,7 @@ import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.client.multiplayer.WorldClient; import net.minecraft.client.renderer.EntityRenderer; import net.minecraft.client.settings.GameSettings; +import net.minecraft.entity.Entity; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.network.NetworkManager; import net.minecraft.network.Packet; @@ -60,7 +61,8 @@ public interface IGameEventListener { void onTick(TickEvent event); /** - * Run once per game tick from before the player rotation is sent to the server. + * Run once per game tick from before and after the player rotation is sent to the server. + * * @see EntityPlayerSP#onUpdate() */ void onPlayerUpdate(PlayerUpdateEvent event); @@ -123,4 +125,11 @@ public interface IGameEventListener { * @see InventoryPlayer#canHarvestBlock(IBlockState) */ void onQueryItemSlotForBlocks(ItemSlotEvent event); + + /** + * Run once per game tick from before and after the player's moveRelative method is called + * + * @see Entity#moveRelative(float, float, float, float) + */ + void onPlayerRelativeMove(RelativeMoveEvent event); } diff --git a/src/main/java/baritone/bot/pathing/movement/Movement.java b/src/main/java/baritone/bot/pathing/movement/Movement.java index 5b31c147..b2c77a8f 100644 --- a/src/main/java/baritone/bot/pathing/movement/Movement.java +++ b/src/main/java/baritone/bot/pathing/movement/Movement.java @@ -105,7 +105,13 @@ public abstract class Movement implements Helper, MovementHelper { if (BlockStateInterface.isLiquid(playerFeet())) { latestState.setInput(Input.JUMP, true); } - latestState.getTarget().getRotation().ifPresent(LookBehavior.INSTANCE::updateTarget); + + // 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 -> + LookBehavior.INSTANCE.updateTarget( + rotation, + latestState.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 latestState.getInputStates().forEach((input, forced) -> { diff --git a/src/main/java/baritone/launch/mixins/MixinEntity.java b/src/main/java/baritone/launch/mixins/MixinEntity.java new file mode 100644 index 00000000..0901f295 --- /dev/null +++ b/src/main/java/baritone/launch/mixins/MixinEntity.java @@ -0,0 +1,56 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Baritone. If not, see . + */ + +package baritone.launch.mixins; + +import baritone.bot.Baritone; +import baritone.bot.event.events.RelativeMoveEvent; +import baritone.bot.event.events.type.EventState; +import baritone.bot.utils.Helper; +import net.minecraft.entity.Entity; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +/** + * @author Brady + * @since 8/21/2018 + */ +@Mixin(Entity.class) +public class MixinEntity { + + @Inject( + method = "moveRelative", + at = @At("HEAD") + ) + private void preMoveRelative(float strafe, float up, float forward, float friction, CallbackInfo ci) { + Entity _this = (Entity) (Object) this; + if (_this == Helper.mc.player) + Baritone.INSTANCE.getGameEventHandler().onPlayerRelativeMove(new RelativeMoveEvent(EventState.PRE)); + } + + @Inject( + method = "moveRelative", + at = @At("RETURN") + ) + private void postMoveRelative(float strafe, float up, float forward, float friction, CallbackInfo ci) { + Entity _this = (Entity) (Object) this; + if (_this == Helper.mc.player) + Baritone.INSTANCE.getGameEventHandler().onPlayerRelativeMove(new RelativeMoveEvent(EventState.POST)); + } +} diff --git a/src/main/resources/mixins.baritone.json b/src/main/resources/mixins.baritone.json index 86521c33..025d42f8 100755 --- a/src/main/resources/mixins.baritone.json +++ b/src/main/resources/mixins.baritone.json @@ -8,6 +8,7 @@ "maxShiftBy": 2 }, "client": [ + "MixinEntity", "MixinEntityPlayerSP", "MixinEntityRenderer", "MixinGameSettings", From 86f45202d0b740162d0bd08a82dcd136f691cafe Mon Sep 17 00:00:00 2001 From: Leijurv Date: Tue, 21 Aug 2018 16:20:08 -0700 Subject: [PATCH 15/19] ignore y coordinate for distance, fixes #62 --- src/main/java/baritone/bot/Settings.java | 9 +++++++++ .../baritone/bot/behavior/impl/PathingBehavior.java | 11 +++++++++++ .../java/baritone/bot/pathing/goals/GoalYLevel.java | 4 ++-- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/main/java/baritone/bot/Settings.java b/src/main/java/baritone/bot/Settings.java index f3069051..075218aa 100644 --- a/src/main/java/baritone/bot/Settings.java +++ b/src/main/java/baritone/bot/Settings.java @@ -135,6 +135,15 @@ public class Settings { */ public Setting maxFallHeight = new Setting<>(3); + /** + * If your goal is a GoalBlock in an unloaded chunk, assume it's far enough away that the Y coord + * doesn't matter yet, and replace it with a GoalXZ to the same place before calculating a path. + * Once a segment ends within chunk load range of the GoalBlock, it will go back to normal behavior + * of considering the Y coord. The reasoning is that if your X and Z are 10,000 blocks away, + * your Y coordinate's accuracy doesn't matter at all until you get much much closer. + */ + public Setting simplifyUnloadedYCoord = new Setting<>(true); + /** * If a movement takes this many ticks more than its initial cost estimate, cancel it */ diff --git a/src/main/java/baritone/bot/behavior/impl/PathingBehavior.java b/src/main/java/baritone/bot/behavior/impl/PathingBehavior.java index 324028db..54101a16 100644 --- a/src/main/java/baritone/bot/behavior/impl/PathingBehavior.java +++ b/src/main/java/baritone/bot/behavior/impl/PathingBehavior.java @@ -26,12 +26,15 @@ import baritone.bot.pathing.calc.AStarPathFinder; import baritone.bot.pathing.calc.AbstractNodeCostSearch; import baritone.bot.pathing.calc.IPathFinder; import baritone.bot.pathing.goals.Goal; +import baritone.bot.pathing.goals.GoalBlock; +import baritone.bot.pathing.goals.GoalXZ; import baritone.bot.pathing.path.IPath; import baritone.bot.pathing.path.PathExecutor; import baritone.bot.utils.BlockStateInterface; import baritone.bot.utils.PathRenderer; import net.minecraft.init.Blocks; import net.minecraft.util.math.BlockPos; +import net.minecraft.world.chunk.EmptyChunk; import java.awt.*; import java.util.Collections; @@ -258,10 +261,18 @@ public class PathingBehavior extends Behavior { * @return */ private Optional findPath(BlockPos start, Optional previous) { + Goal goal = this.goal; if (goal == null) { displayChatMessageRaw("no goal"); return Optional.empty(); } + if (Baritone.settings().simplifyUnloadedYCoord.get() && goal instanceof GoalBlock) { + BlockPos pos = ((GoalBlock) goal).getGoalPos(); + if (world().getChunk(pos) instanceof EmptyChunk) { + displayChatMessageRaw("Simplifying GoalBlock to GoalXZ due to distance"); + goal = new GoalXZ(pos.getX(), pos.getZ()); + } + } try { IPathFinder pf = new AStarPathFinder(start, goal, previous.map(IPath::positions)); return pf.calculate(); diff --git a/src/main/java/baritone/bot/pathing/goals/GoalYLevel.java b/src/main/java/baritone/bot/pathing/goals/GoalYLevel.java index f9c4a9da..3fdb5fee 100644 --- a/src/main/java/baritone/bot/pathing/goals/GoalYLevel.java +++ b/src/main/java/baritone/bot/pathing/goals/GoalYLevel.java @@ -44,11 +44,11 @@ public class GoalYLevel implements Goal { public double heuristic(BlockPos pos) { if (pos.getY() > level) { // need to descend - return FALL_N_BLOCKS_COST[1] * (pos.getY() - level); + return FALL_N_BLOCKS_COST[2] / 2 * (pos.getY() - level); } if (pos.getY() < level) { // need to ascend - return (level - pos.getY()) * JUMP_ONE_BLOCK_COST; + return (level - pos.getY()) * JUMP_ONE_BLOCK_COST * 0.9; } return 0; } From 71abf0c27ecbd8890a7957ccbb24a647d410e09b Mon Sep 17 00:00:00 2001 From: Brady Date: Tue, 21 Aug 2018 18:24:31 -0500 Subject: [PATCH 16/19] Fix MovementFall from forcing rotations when unnecessary --- .../baritone/bot/pathing/movement/movements/MovementFall.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/baritone/bot/pathing/movement/movements/MovementFall.java b/src/main/java/baritone/bot/pathing/movement/movements/MovementFall.java index d8c055fc..aedec7e0 100644 --- a/src/main/java/baritone/bot/pathing/movement/movements/MovementFall.java +++ b/src/main/java/baritone/bot/pathing/movement/movements/MovementFall.java @@ -103,7 +103,7 @@ public class MovementFall extends Movement { state.setInput(InputOverrideHandler.Input.CLICK_RIGHT, true) .setTarget(new MovementTarget(targetRotation.get(), true)); } else { - state.setTarget(new MovementTarget(Utils.calcRotationFromVec3d(playerHead(), Utils.getBlockPosCenter(dest)), true)); + state.setTarget(new MovementTarget(Utils.calcRotationFromVec3d(playerHead(), Utils.getBlockPosCenter(dest)), false)); } if (playerFeet.equals(dest) && (player().posY - playerFeet.getY() < 0.094 // lilypads || BlockStateInterface.isWater(dest))) { From d4a6618b55cebe740df46503564f329b662b452d Mon Sep 17 00:00:00 2001 From: Leijurv Date: Tue, 21 Aug 2018 16:50:24 -0700 Subject: [PATCH 17/19] lol that was dumb --- .../bot/pathing/movement/movements/MovementTraverse.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/baritone/bot/pathing/movement/movements/MovementTraverse.java b/src/main/java/baritone/bot/pathing/movement/movements/MovementTraverse.java index 4b5d8f1c..e93612a6 100644 --- a/src/main/java/baritone/bot/pathing/movement/movements/MovementTraverse.java +++ b/src/main/java/baritone/bot/pathing/movement/movements/MovementTraverse.java @@ -111,7 +111,7 @@ public class MovementTraverse extends Movement { return WC + context.placeBlockCost() + getTotalHardnessOfBlocksToBreak(context); } } - if (BlockStateInterface.get(src).getBlock().equals(Blocks.SOUL_SAND)) { + if (BlockStateInterface.get(src.down()).getBlock().equals(Blocks.SOUL_SAND)) { return COST_INF; // can't sneak and backplace against soul sand =/ } WC = WC * SNEAK_ONE_BLOCK_COST / WALK_ONE_BLOCK_COST;//since we are placing, we are sneaking From 4c0d581d7f918ddcda53940e462be69cc15061a5 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Tue, 21 Aug 2018 16:56:49 -0700 Subject: [PATCH 18/19] crucial performance optimization --- .../bot/pathing/movement/movements/MovementTraverse.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/baritone/bot/pathing/movement/movements/MovementTraverse.java b/src/main/java/baritone/bot/pathing/movement/movements/MovementTraverse.java index e93612a6..f01eb771 100644 --- a/src/main/java/baritone/bot/pathing/movement/movements/MovementTraverse.java +++ b/src/main/java/baritone/bot/pathing/movement/movements/MovementTraverse.java @@ -111,7 +111,7 @@ public class MovementTraverse extends Movement { return WC + context.placeBlockCost() + getTotalHardnessOfBlocksToBreak(context); } } - if (BlockStateInterface.get(src.down()).getBlock().equals(Blocks.SOUL_SAND)) { + if (Blocks.SOUL_SAND.equals(srcDown)) { return COST_INF; // can't sneak and backplace against soul sand =/ } WC = WC * SNEAK_ONE_BLOCK_COST / WALK_ONE_BLOCK_COST;//since we are placing, we are sneaking From 9f12a0ab6f673921fcd0e2b6b266e557fa58cf16 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Tue, 21 Aug 2018 17:16:00 -0700 Subject: [PATCH 19/19] max fall height even with bucket, fixes #57 --- src/main/java/baritone/bot/Settings.java | 8 +++++++- .../bot/pathing/movement/CalculationContext.java | 15 +++++++++++---- .../bot/pathing/movement/MovementHelper.java | 2 +- .../pathing/movement/movements/MovementFall.java | 7 +++++-- 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/main/java/baritone/bot/Settings.java b/src/main/java/baritone/bot/Settings.java index fb079be0..1203a8a3 100644 --- a/src/main/java/baritone/bot/Settings.java +++ b/src/main/java/baritone/bot/Settings.java @@ -133,7 +133,13 @@ public class Settings { * 3 won't deal any damage. But if you just want to get down the mountain quickly and you have * Feather Falling IV, you might set it a bit higher, like 4 or 5. */ - public Setting maxFallHeight = new Setting<>(3); + public Setting maxFallHeightNoWater = new Setting<>(3); + + /** + * How far are you allowed to fall onto solid ground (with a water bucket)? + * It's not that reliable, so I've set it below what would kill an unarmored player (23) + */ + public Setting maxFallHeightBucket = new Setting<>(20); /** * If your goal is a GoalBlock in an unloaded chunk, assume it's far enough away that the Y coord diff --git a/src/main/java/baritone/bot/pathing/movement/CalculationContext.java b/src/main/java/baritone/bot/pathing/movement/CalculationContext.java index 03d4aba7..6bd09012 100644 --- a/src/main/java/baritone/bot/pathing/movement/CalculationContext.java +++ b/src/main/java/baritone/bot/pathing/movement/CalculationContext.java @@ -38,7 +38,8 @@ public class CalculationContext implements Helper { private final boolean canSprint; private final double placeBlockCost; private final boolean allowBreak; - private final int maxFallHeight; + private final int maxFallHeightNoWater; + private final int maxFallHeightBucket; public CalculationContext() { this(new ToolSet()); @@ -52,7 +53,8 @@ public class CalculationContext implements Helper { this.canSprint = Baritone.settings().allowSprint.get() && player().getFoodStats().getFoodLevel() > 6; this.placeBlockCost = Baritone.settings().blockPlacementPenalty.get(); this.allowBreak = Baritone.settings().allowBreak.get(); - this.maxFallHeight = Baritone.settings().maxFallHeight.get(); + this.maxFallHeightNoWater = Baritone.settings().maxFallHeightNoWater.get(); + this.maxFallHeightBucket = Baritone.settings().maxFallHeightBucket.get(); // why cache these things here, why not let the movements just get directly from settings? // because if some movements are calculated one way and others are calculated another way, // then you get a wildly inconsistent path that isn't optimal for either scenario. @@ -82,7 +84,12 @@ public class CalculationContext implements Helper { return allowBreak; } - public int maxFallHeight(){ - return maxFallHeight; + public int maxFallHeightNoWater() { + return maxFallHeightNoWater; } + + public int maxFallHeightBucket() { + return maxFallHeightBucket; + } + } diff --git a/src/main/java/baritone/bot/pathing/movement/MovementHelper.java b/src/main/java/baritone/bot/pathing/movement/MovementHelper.java index 7e84a1cd..0d239b15 100644 --- a/src/main/java/baritone/bot/pathing/movement/MovementHelper.java +++ b/src/main/java/baritone/bot/pathing/movement/MovementHelper.java @@ -299,7 +299,7 @@ public interface MovementHelper extends ActionCosts, Helper { continue; } if (canWalkOn(onto, ontoBlock)) { - if (calcContext.hasWaterBucket() || fallHeight <= 4) { + if ((calcContext.hasWaterBucket() && fallHeight <= calcContext.maxFallHeightBucket() + 1) || fallHeight <= calcContext.maxFallHeightNoWater() + 1) { // fallHeight = 4 means onto.up() is 3 blocks down, which is the max return new MovementFall(pos, onto.up()); } else { diff --git a/src/main/java/baritone/bot/pathing/movement/movements/MovementFall.java b/src/main/java/baritone/bot/pathing/movement/movements/MovementFall.java index aedec7e0..f98aca7d 100644 --- a/src/main/java/baritone/bot/pathing/movement/movements/MovementFall.java +++ b/src/main/java/baritone/bot/pathing/movement/movements/MovementFall.java @@ -52,10 +52,13 @@ public class MovementFall extends Movement { return COST_INF; } double placeBucketCost = 0.0; - if (!BlockStateInterface.isWater(dest) && src.getY() - dest.getY() > context.maxFallHeight()) { + if (!BlockStateInterface.isWater(dest) && src.getY() - dest.getY() > context.maxFallHeightNoWater()) { if (!context.hasWaterBucket()) { return COST_INF; } + if (src.getY() - dest.getY() > context.maxFallHeightBucket()) { + return COST_INF; + } placeBucketCost = context.placeBlockCost(); } double frontTwo = MovementHelper.getMiningDurationTicks(context, positionsToBreak[0]) + MovementHelper.getMiningDurationTicks(context, positionsToBreak[1]); @@ -89,7 +92,7 @@ public class MovementFall extends Movement { } BlockPos playerFeet = playerFeet(); Optional targetRotation = Optional.empty(); - if (!BlockStateInterface.isWater(dest) && src.getY() - dest.getY() > Baritone.settings().maxFallHeight.get() && !playerFeet.equals(dest)) { + if (!BlockStateInterface.isWater(dest) && src.getY() - dest.getY() > Baritone.settings().maxFallHeightNoWater.get() && !playerFeet.equals(dest)) { if (!player().inventory.hasItemStack(STACK_BUCKET_WATER) || world().provider.isNether()) { // TODO check if water bucket is on hotbar or main inventory state.setStatus(MovementStatus.UNREACHABLE); return state;