diff --git a/.gitmessage b/.gitmessage new file mode 100644 index 000000000..259d0702f --- /dev/null +++ b/.gitmessage @@ -0,0 +1,31 @@ + (<ticket>) + +# 📝 Update README.md (WD-1234) +# ✅ Add unit test for inputs (WD-1234) + +# <emoji> can be: +# 🎨 :art: when improving structure of the code +# ⚡️ :zap: when improving performance +# 🔥 :fire: when removing code or files +# ✨ :sparkles: when introducing new features +# 🚧 :construction: when work in progress +# 🔨 :hammer: when refactoring code +# 📝 :memo: when writing docs +# 💄 :lipstick: when updating the UI and style files +# 📈 :chart_with_upwards_trend: when adding analytics or tracking code +# 🌐 :globe_with_meridians: when adding internationalization and localization +# ✏️ :pencil2: when fixing typos +# 🚚 :truck: when moving or renaming files +# ✅ :white_check_mark: when adding tests + +# 👌 :ok_hand: when updating code due to code review changes +# 🐛 :bug: when fixing a bug +# 🚑 :ambulance: when doing a critical hotfix +# 🚨 :rotating_light: when removing linter warnings + +# 🔀 :twisted_rightwards_arrows: when merging branches +# ⬆️ :arrow_up: when upgrading dependencies +# ⬇️ :arrow_down: when downgrading dependencies +# 🔧 :wrench: when changing configuration files +# 🔖 :bookmark: when releasing / version tagging +# 💚 :green_heart: when fixing the CI build diff --git a/README.md b/README.md index 26ff3b3b2..274dbe0f5 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ For 1.15.2, [click here](https://www.youtube.com/watch?v=j1qKtCZFURM) and see de This project is an updated version of [MineBot](https://github.com/leijurv/MineBot/), the original version of the bot for Minecraft 1.8.9, rebuilt for 1.12.2 through 1.15.2. Baritone focuses on reliability and particularly performance (it's over [30x faster](https://github.com/cabaletta/baritone/pull/180#issuecomment-423822928) than MineBot at calculating paths). -Have committed at least once a day from Aug 1 2018 to Aug 1 2019. +Have committed at least once a day from Aug 1, 2018, to Aug 1, 2019. 1Leijurv3DWTrGAfmmiTphjhXLvQiHg7K2 @@ -71,7 +71,7 @@ The API is heavily documented, you can find the Javadocs for the latest release Please note that usage of anything located outside of the ``baritone.api`` package is not supported by the API release jar. -Below is an example of basic usage for changing some settings, and then pathing to a X/Z goal. +Below is an example of basic usage for changing some settings, and then pathing to an X/Z goal. ``` BaritoneAPI.getSettings().allowSprint.value = true; @@ -84,7 +84,7 @@ BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().setGoalAnd ## Can I use Baritone as a library in my custom utility client? -That's what it's for, sure! (As long as usage is in compliance with the LGPL 3.0 License) +That's what it's for, sure! (As long as usage complies with the LGPL 3.0 License) ## How is it so fast? diff --git a/build.gradle b/build.gradle index f92ec606f..04c8fdbf4 100755 --- a/build.gradle +++ b/build.gradle @@ -16,7 +16,7 @@ */ group 'baritone' -version '1.6.1' +version '1.6.2' buildscript { repositories { @@ -28,6 +28,9 @@ buildscript { name = 'impactdevelopment-repo' url = 'https://impactdevelopment.github.io/maven/' } + maven { + url = 'https://www.dogforce-games.com/maven/' + } jcenter() } @@ -85,7 +88,7 @@ task sourceJar(type: Jar, dependsOn: classes) { } minecraft { - mappings channel: 'snapshot', version: '20200723-1.16.1' + mappings channel: 'snapshot', version: '20200813-1.16.1' if (getProject().hasProperty("baritone.forge_build")) { reobfMappings 'searge' @@ -138,15 +141,17 @@ repositories { name = 'spongepowered-repo' url = 'http://repo.spongepowered.org/maven/' } - maven { name = 'impactdevelopment-repo' url = 'https://impactdevelopment.github.io/maven/' } + maven { + url = 'https://www.dogforce-games.com/maven/' + } } dependencies { - minecraft 'com.github.ImpactDevelopment:Vanilla:1.16.1' + minecraft 'com.github.ImpactDevelopment:Vanilla:1.16.2' runtime launchCompile('net.minecraft:launchwrapper:1.12') { exclude module: 'lwjgl' diff --git a/scripts/proguard.pro b/scripts/proguard.pro index 7e67a22ac..b4b1e021b 100644 --- a/scripts/proguard.pro +++ b/scripts/proguard.pro @@ -28,6 +28,13 @@ -keep class baritone.api.utils.MyChunkPos { *; } # even in standalone we need to keep this for gson reflect +# Keep any class or member annotated with @KeepName so we dont have to put everything in the script +-keep,allowobfuscation @interface baritone.KeepName +-keep @baritone.KeepName class * +-keepclassmembers class * { + @baritone.KeepName *; +} + # setting names are reflected from field names, so keep field names -keepclassmembers class baritone.api.Settings { public <fields>; diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 9130165f7..168d5a0f6 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -61,6 +61,19 @@ public final class Settings { */ public final Setting<Boolean> allowInventory = new Setting<>(false); + /** + * Disable baritone's auto-tool at runtime, but still assume that another mod will provide auto tool functionality + * <p> + * Specifically, path calculation will still assume that an auto tool wil run at execution time, even though + * Baritone itself will not do that. + */ + public final Setting<Boolean> assumeExternalAutoTool = new Setting<>(false); + + /** + * If this setting is on, no auto tool will occur at all, not at calculation time nor execution time + */ + public final Setting<Boolean> disableAutoTool = new Setting<>(false); + /** * It doesn't actually take twenty ticks to place a block, this cost is so high * because we want to generally conserve blocks which might be limited. @@ -190,6 +203,15 @@ public final class Settings { ))); + /** + * A list of blocks to become air + * <p> + * If a schematic asks for a block on this list, only air will be accepted at that location (and nothing on buildIgnoreBlocks) + */ + public final Setting<List<Block>> okIfAir = new Setting<>(new ArrayList<>(Arrays.asList( + + ))); + /** * If this is true, the builder will treat all non-air blocks as correct. It will only place new blocks. */ @@ -432,6 +454,11 @@ public final class Settings { */ public final Setting<Boolean> simplifyUnloadedYCoord = new Setting<>(true); + /** + * Whenever a block changes, repack the whole chunk that it's in + */ + public final Setting<Boolean> repackOnAnyBlockChange = new Setting<>(true); + /** * If a movement takes this many ticks more than its initial cost estimate, cancel it */ @@ -1060,10 +1087,35 @@ public final class Settings { public final Setting<Boolean> renderSelectionCorners = new Setting<>(true); /** - * Desktop Notifications + * Desktop notifications */ public final Setting<Boolean> desktopNotifications = new Setting<>(false); + /** + * Desktop notification on path complete + */ + public final Setting<Boolean> notificationOnPathComplete = new Setting<>(true); + + /** + * Desktop notification on farm fail + */ + public final Setting<Boolean> notificationOnFarmFail = new Setting<>(true); + + /** + * Desktop notification on build finished + */ + public final Setting<Boolean> notificationOnBuildFinished = new Setting<>(true); + + /** + * Desktop notification on explore finished + */ + public final Setting<Boolean> notificationOnExploreFinished = new Setting<>(true); + + /** + * Desktop notification on mine fail + */ + public final Setting<Boolean> notificationOnMineFail = new Setting<>(true); + /** * A map of lowercase setting field names to their respective setting */ diff --git a/src/api/java/baritone/api/command/datatypes/BlockById.java b/src/api/java/baritone/api/command/datatypes/BlockById.java index 113238df0..0c8270193 100644 --- a/src/api/java/baritone/api/command/datatypes/BlockById.java +++ b/src/api/java/baritone/api/command/datatypes/BlockById.java @@ -32,7 +32,7 @@ public enum BlockById implements IDatatypeFor<Block> { public Block get(IDatatypeContext ctx) throws CommandException { ResourceLocation id = new ResourceLocation(ctx.getConsumer().getString()); Block block; - if ((block = Registry.BLOCK.getValue(id).orElse(null)) == null) { + if ((block = Registry.BLOCK.func_241873_b(id).orElse(null)) == null) { throw new IllegalArgumentException("no block found by that id"); } return block; diff --git a/src/api/java/baritone/api/command/datatypes/EntityClassById.java b/src/api/java/baritone/api/command/datatypes/EntityClassById.java index 763815f0f..71870ef2e 100644 --- a/src/api/java/baritone/api/command/datatypes/EntityClassById.java +++ b/src/api/java/baritone/api/command/datatypes/EntityClassById.java @@ -32,7 +32,7 @@ public enum EntityClassById implements IDatatypeFor<EntityType> { public EntityType get(IDatatypeContext ctx) throws CommandException { ResourceLocation id = new ResourceLocation(ctx.getConsumer().getString()); EntityType entity; - if ((entity = Registry.ENTITY_TYPE.getValue(id).orElse(null)) == null) { + if ((entity = Registry.ENTITY_TYPE.func_241873_b(id).orElse(null)) == null) { throw new IllegalArgumentException("no entity found by that id"); } return entity; diff --git a/src/api/java/baritone/api/utils/BlockOptionalMeta.java b/src/api/java/baritone/api/utils/BlockOptionalMeta.java index 3fa7778cf..4abd9087c 100644 --- a/src/api/java/baritone/api/utils/BlockOptionalMeta.java +++ b/src/api/java/baritone/api/utils/BlockOptionalMeta.java @@ -29,6 +29,7 @@ import net.minecraft.resources.*; import net.minecraft.util.ResourceLocation; import net.minecraft.util.Unit; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.vector.Vector3d; import javax.annotation.Nonnull; import java.util.*; @@ -132,7 +133,7 @@ public final class BlockOptionalMeta { public static LootTableManager getManager() { if (manager == null) { - ResourcePackList<?> rpl = new ResourcePackList<>(ResourcePackInfo::new, new ServerPackFinder()); + ResourcePackList rpl = new ResourcePackList(ResourcePackInfo::new, new ServerPackFinder()); rpl.reloadPacksFromFinders(); IResourcePack thePack = rpl.getAllPacks().iterator().next().getResourcePack(); IReloadableResourceManager resourceManager = new SimpleReloadableResourceManager(ResourcePackType.SERVER_DATA); @@ -163,7 +164,7 @@ public final class BlockOptionalMeta { getManager().getLootTableFromLocation(lootTableLocation).generate( new LootContext.Builder(null) .withRandom(new Random()) - .withParameter(LootParameters.POSITION, BlockPos.ZERO) + .withParameter(LootParameters.field_237457_g_, Vector3d.copy(BlockPos.NULL_VECTOR)) .withParameter(LootParameters.TOOL, ItemStack.EMPTY) .withNullableParameter(LootParameters.BLOCK_ENTITY, null) .withParameter(LootParameters.BLOCK_STATE, block.getDefaultState()) diff --git a/src/api/java/baritone/api/utils/BlockUtils.java b/src/api/java/baritone/api/utils/BlockUtils.java index d6ef34f3d..3ee95f6af 100644 --- a/src/api/java/baritone/api/utils/BlockUtils.java +++ b/src/api/java/baritone/api/utils/BlockUtils.java @@ -57,7 +57,7 @@ public class BlockUtils { if (resourceCache.containsKey(name)) { return null; // cached as null } - block = Registry.BLOCK.getValue(ResourceLocation.tryCreate(name.contains(":") ? name : "minecraft:" + name)).orElse(null); + block = Registry.BLOCK.func_241873_b(ResourceLocation.tryCreate(name.contains(":") ? name : "minecraft:" + name)).orElse(null); Map<String, Block> copy = new HashMap<>(resourceCache); // read only copy is safe, wont throw concurrentmodification copy.put(name, block); resourceCache = copy; diff --git a/src/launch/java/baritone/launch/mixins/MixinClientPlayNetHandler.java b/src/launch/java/baritone/launch/mixins/MixinClientPlayNetHandler.java index e31856c4d..e29307ce7 100644 --- a/src/launch/java/baritone/launch/mixins/MixinClientPlayNetHandler.java +++ b/src/launch/java/baritone/launch/mixins/MixinClientPlayNetHandler.java @@ -17,15 +17,19 @@ package baritone.launch.mixins; +import baritone.Baritone; import baritone.api.BaritoneAPI; import baritone.api.IBaritone; import baritone.api.event.events.ChunkEvent; import baritone.api.event.events.type.EventState; +import baritone.cache.CachedChunk; import net.minecraft.client.entity.player.ClientPlayerEntity; import net.minecraft.client.network.play.ClientPlayNetHandler; +import net.minecraft.network.play.server.SChangeBlockPacket; import net.minecraft.network.play.server.SChunkDataPacket; import net.minecraft.network.play.server.SCombatPacket; -import net.minecraft.network.play.server.SUnloadChunkPacket; +import net.minecraft.network.play.server.SMultiBlockChangePacket; +import net.minecraft.util.math.ChunkPos; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -83,30 +87,58 @@ public class MixinClientPlayNetHandler { } @Inject( - method = "processChunkUnload", - at = @At("HEAD") + method = "handleBlockChange", + at = @At("RETURN") ) - private void preChunkUnload(SUnloadChunkPacket packet, CallbackInfo ci) { + private void postHandleBlockChange(SChangeBlockPacket packetIn, CallbackInfo ci) { + if (!Baritone.settings().repackOnAnyBlockChange.value) { + return; + } + if (!CachedChunk.BLOCKS_TO_KEEP_TRACK_OF.contains(packetIn.getState().getBlock())) { + return; + } for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) { ClientPlayerEntity player = ibaritone.getPlayerContext().player(); if (player != null && player.connection == (ClientPlayNetHandler) (Object) this) { ibaritone.getGameEventHandler().onChunkEvent( - new ChunkEvent(EventState.PRE, ChunkEvent.Type.UNLOAD, packet.getX(), packet.getZ()) + new ChunkEvent( + EventState.POST, + ChunkEvent.Type.POPULATE_FULL, + packetIn.getPos().getX() >> 4, + packetIn.getPos().getZ() >> 4 + ) ); } } } @Inject( - method = "processChunkUnload", + method = "handleMultiBlockChange", at = @At("RETURN") ) - private void postChunkUnload(SUnloadChunkPacket packet, CallbackInfo ci) { + private void postHandleMultiBlockChange(SMultiBlockChangePacket packetIn, CallbackInfo ci) { + if (!Baritone.settings().repackOnAnyBlockChange.value) { + return; + } + ChunkPos[] chunkPos = new ChunkPos[1]; + packetIn.func_244310_a((pos, state) -> { + if (CachedChunk.BLOCKS_TO_KEEP_TRACK_OF.contains(state.getBlock())) { + chunkPos[0] = new ChunkPos(pos); + } + }); + if (chunkPos[0] == null) { + return; + } for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) { ClientPlayerEntity player = ibaritone.getPlayerContext().player(); if (player != null && player.connection == (ClientPlayNetHandler) (Object) this) { ibaritone.getGameEventHandler().onChunkEvent( - new ChunkEvent(EventState.POST, ChunkEvent.Type.UNLOAD, packet.getX(), packet.getZ()) + new ChunkEvent( + EventState.POST, + ChunkEvent.Type.POPULATE_FULL, + chunkPos[0].x, + chunkPos[0].z + ) ); } } diff --git a/src/launch/java/baritone/launch/mixins/MixinCommandSuggestionHelper.java b/src/launch/java/baritone/launch/mixins/MixinCommandSuggestionHelper.java index 06abfd674..00497ab6b 100644 --- a/src/launch/java/baritone/launch/mixins/MixinCommandSuggestionHelper.java +++ b/src/launch/java/baritone/launch/mixins/MixinCommandSuggestionHelper.java @@ -45,11 +45,11 @@ public class MixinCommandSuggestionHelper { @Shadow @Final - private TextFieldWidget field_228095_d_; + private TextFieldWidget inputField; @Shadow @Final - private List<String> field_228103_l_; + private List<String> exceptionList; @Shadow private CompletableFuture<Suggestions> suggestionsFuture; @@ -61,7 +61,7 @@ public class MixinCommandSuggestionHelper { ) private void preUpdateSuggestion(CallbackInfo ci) { // Anything that is present in the input text before the cursor position - String prefix = this.field_228095_d_.getText().substring(0, Math.min(this.field_228095_d_.getText().length(), this.field_228095_d_.getCursorPosition())); + String prefix = this.inputField.getText().substring(0, Math.min(this.inputField.getText().length(), this.inputField.getCursorPosition())); TabCompleteEvent event = new TabCompleteEvent(prefix); BaritoneAPI.getProvider().getPrimaryBaritone().getGameEventHandler().onPreTabComplete(event); @@ -75,14 +75,14 @@ public class MixinCommandSuggestionHelper { ci.cancel(); // TODO: Support populating the command usage - this.field_228103_l_.clear(); + this.exceptionList.clear(); if (event.completions.length == 0) { this.suggestionsFuture = Suggestions.empty(); } else { - int offset = this.field_228095_d_.getText().endsWith(" ") - ? this.field_228095_d_.getCursorPosition() - : this.field_228095_d_.getText().lastIndexOf(" ") + 1; // If there is no space this is still 0 haha yes + int offset = this.inputField.getText().endsWith(" ") + ? this.inputField.getCursorPosition() + : this.inputField.getText().lastIndexOf(" ") + 1; // If there is no space this is still 0 haha yes List<Suggestion> suggestionList = Stream.of(event.completions) .map(s -> new Suggestion(StringRange.between(offset, offset + s.length()), s)) diff --git a/src/main/java/baritone/KeepName.java b/src/main/java/baritone/KeepName.java new file mode 100644 index 000000000..20f08e7b8 --- /dev/null +++ b/src/main/java/baritone/KeepName.java @@ -0,0 +1,21 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see <https://www.gnu.org/licenses/>. + */ + +package baritone; + +// Annotation for classes and class members that should not be renamed by proguard +public @interface KeepName { } diff --git a/src/main/java/baritone/cache/CachedChunk.java b/src/main/java/baritone/cache/CachedChunk.java index 0c931cefe..556a7e3c4 100644 --- a/src/main/java/baritone/cache/CachedChunk.java +++ b/src/main/java/baritone/cache/CachedChunk.java @@ -202,11 +202,11 @@ public final class CachedChunk { } if (type == PathingBlockType.SOLID) { - if (y == 127 && dimension == World.field_234919_h_) { + if (y == 127 && dimension == World.THE_NETHER) { // nether roof is always unbreakable return Blocks.BEDROCK.getDefaultState(); } - if (y < 5 && dimension == World.field_234918_g_) { + if (y < 5 && dimension == World.OVERWORLD) { // solid blocks below 5 are commonly bedrock // however, returning bedrock always would be a little yikes // discourage paths that include breaking blocks below 5 a little more heavily just so that it takes paths breaking what's known to be stone (at 5 or above) instead of what could maybe be bedrock (below 5) diff --git a/src/main/java/baritone/cache/CachedWorld.java b/src/main/java/baritone/cache/CachedWorld.java index 3cfb8623f..20f554e6c 100644 --- a/src/main/java/baritone/cache/CachedWorld.java +++ b/src/main/java/baritone/cache/CachedWorld.java @@ -27,6 +27,7 @@ import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import net.minecraft.util.RegistryKey; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.ChunkPos; import net.minecraft.world.World; import net.minecraft.world.chunk.Chunk; @@ -35,6 +36,8 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.LinkedBlockingQueue; /** @@ -58,7 +61,17 @@ public final class CachedWorld implements ICachedWorld, Helper { */ private final String directory; - private final LinkedBlockingQueue<Chunk> toPack = new LinkedBlockingQueue<>(); + /** + * Queue of positions to pack. Refers to the toPackMap, in that every element of this queue will be a + * key in that map. + */ + private final LinkedBlockingQueue<ChunkPos> toPackQueue = new LinkedBlockingQueue<>(); + + /** + * All chunk positions pending packing. This map will be updated in-place if a new update to the chunk occurs + * while waiting in the queue for the packer thread to get to it. + */ + private final Map<ChunkPos, Chunk> toPackMap = new ConcurrentHashMap<>(); private final RegistryKey<World> dimension; @@ -91,10 +104,8 @@ public final class CachedWorld implements ICachedWorld, Helper { @Override public final void queueForPacking(Chunk chunk) { - try { - toPack.put(chunk); - } catch (InterruptedException e) { - e.printStackTrace(); + if (toPackMap.put(chunk.getPos(), chunk) == null) { + toPackQueue.add(chunk.getPos()); } } @@ -295,13 +306,9 @@ public final class CachedWorld implements ICachedWorld, Helper { public void run() { while (true) { - // TODO: Add CachedWorld unloading to remove the redundancy of having this - LinkedBlockingQueue<Chunk> queue = toPack; - if (queue == null) { - break; - } try { - Chunk chunk = queue.take(); + ChunkPos pos = toPackQueue.take(); + Chunk chunk = toPackMap.remove(pos); CachedChunk cached = ChunkPacker.pack(chunk); CachedWorld.this.updateCachedChunk(cached); //System.out.println("Processed chunk at " + chunk.x + "," + chunk.z); diff --git a/src/main/java/baritone/cache/ChunkPacker.java b/src/main/java/baritone/cache/ChunkPacker.java index 214a9b91c..4791ad781 100644 --- a/src/main/java/baritone/cache/ChunkPacker.java +++ b/src/main/java/baritone/cache/ChunkPacker.java @@ -158,13 +158,13 @@ public final class ChunkPacker { return Blocks.LAVA.getDefaultState(); case SOLID: // Dimension solid types - if (dimension == World.field_234918_g_) { + if (dimension == World.OVERWORLD) { return Blocks.STONE.getDefaultState(); } - if (dimension == World.field_234919_h_) { + if (dimension == World.THE_NETHER) { return Blocks.NETHERRACK.getDefaultState(); } - if (dimension == World.field_234920_i_) { + if (dimension == World.THE_END) { return Blocks.END_STONE.getDefaultState(); } default: diff --git a/src/main/java/baritone/cache/WorldProvider.java b/src/main/java/baritone/cache/WorldProvider.java index b56c0fdf8..ac0ba2070 100644 --- a/src/main/java/baritone/cache/WorldProvider.java +++ b/src/main/java/baritone/cache/WorldProvider.java @@ -64,7 +64,7 @@ public class WorldProvider implements IWorldProvider, Helper { // If there is an integrated server running (Aka Singleplayer) then do magic to find the world save file if (mc.isSingleplayer()) { - directory = DimensionType.func_236031_a_(world, integratedServer.func_240776_a_(FolderName.field_237253_i_).toFile()); + directory = DimensionType.func_236031_a_(world, integratedServer.func_240776_a_(FolderName.DOT).toFile()); // Gets the "depth" of this directory relative the the game's run directory, 2 is the location of the world if (directory.toPath().relativize(mc.gameDir.toPath()).getNameCount() != 2) { diff --git a/src/main/java/baritone/command/defaults/ExecutionControlCommands.java b/src/main/java/baritone/command/defaults/ExecutionControlCommands.java index 4a04b9e09..1b024c3b8 100644 --- a/src/main/java/baritone/command/defaults/ExecutionControlCommands.java +++ b/src/main/java/baritone/command/defaults/ExecutionControlCommands.java @@ -79,7 +79,7 @@ public class ExecutionControlCommands { } } ); - pauseCommand = new Command(baritone, "pause") { + pauseCommand = new Command(baritone, "pause", "p") { @Override public void execute(String label, IArgConsumer args) throws CommandException { args.requireMax(0); @@ -112,7 +112,7 @@ public class ExecutionControlCommands { ); } }; - resumeCommand = new Command(baritone, "resume") { + resumeCommand = new Command(baritone, "resume", "r") { @Override public void execute(String label, IArgConsumer args) throws CommandException { args.requireMax(0); @@ -171,7 +171,7 @@ public class ExecutionControlCommands { ); } }; - cancelCommand = new Command(baritone, "cancel", "stop") { + cancelCommand = new Command(baritone, "cancel", "c", "stop") { @Override public void execute(String label, IArgConsumer args) throws CommandException { args.requireMax(0); diff --git a/src/main/java/baritone/command/defaults/FollowCommand.java b/src/main/java/baritone/command/defaults/FollowCommand.java index f74a4a064..3fd997ec8 100644 --- a/src/main/java/baritone/command/defaults/FollowCommand.java +++ b/src/main/java/baritone/command/defaults/FollowCommand.java @@ -17,6 +17,7 @@ package baritone.command.defaults; +import baritone.KeepName; import baritone.api.IBaritone; import baritone.api.command.Command; import baritone.api.command.datatypes.EntityClassById; @@ -132,6 +133,7 @@ public class FollowCommand extends Command { ); } + @KeepName private enum FollowGroup { ENTITIES(LivingEntity.class::isInstance), PLAYERS(PlayerEntity.class::isInstance); /* , @@ -144,6 +146,7 @@ public class FollowCommand extends Command { } } + @KeepName private enum FollowList { ENTITY(EntityClassById.INSTANCE), PLAYER(NearbyPlayer.INSTANCE); diff --git a/src/main/java/baritone/command/defaults/GotoCommand.java b/src/main/java/baritone/command/defaults/GotoCommand.java index 28e768296..a6fe4e22b 100644 --- a/src/main/java/baritone/command/defaults/GotoCommand.java +++ b/src/main/java/baritone/command/defaults/GotoCommand.java @@ -72,7 +72,7 @@ public class GotoCommand extends Command { @Override public List<String> getLongDesc() { return Arrays.asList( - "The got command tells Baritone to head towards a given goal or block.", + "The goto command tells Baritone to head towards a given goal or block.", "", "Wherever a coordinate is expected, you can use ~ just like in regular Minecraft commands. Or, you can just use regular numbers.", "", diff --git a/src/main/java/baritone/event/GameEventHandler.java b/src/main/java/baritone/event/GameEventHandler.java index 148f7c913..eff8689b5 100644 --- a/src/main/java/baritone/event/GameEventHandler.java +++ b/src/main/java/baritone/event/GameEventHandler.java @@ -115,7 +115,7 @@ public final class GameEventHandler implements IEventBus, Helper { if (event.getState() == EventState.POST) { cache.closeWorld(); if (event.getWorld() != null) { - cache.initWorld(event.getWorld().func_234923_W_()); + cache.initWorld(event.getWorld().getDimensionKey()); } } diff --git a/src/main/java/baritone/pathing/movement/CalculationContext.java b/src/main/java/baritone/pathing/movement/CalculationContext.java index 260e403af..d47569b47 100644 --- a/src/main/java/baritone/pathing/movement/CalculationContext.java +++ b/src/main/java/baritone/pathing/movement/CalculationContext.java @@ -32,7 +32,6 @@ import net.minecraft.entity.player.PlayerInventory; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; import net.minecraft.util.math.BlockPos; -import net.minecraft.world.DimensionType; import net.minecraft.world.World; import static baritone.api.pathing.movement.ActionCosts.COST_INF; @@ -86,7 +85,7 @@ public class CalculationContext { this.bsi = new BlockStateInterface(world, worldData, forUseOnAnotherThread); this.toolSet = new ToolSet(player); this.hasThrowaway = Baritone.settings().allowPlace.value && ((Baritone) baritone).getInventoryBehavior().hasGenericThrowaway(); - this.hasWaterBucket = Baritone.settings().allowWaterBucketFall.value && PlayerInventory.isHotbar(player.inventory.getSlotFor(STACK_BUCKET_WATER)) && world.func_234922_V_() != DimensionType.THE_NETHER; + this.hasWaterBucket = Baritone.settings().allowWaterBucketFall.value && PlayerInventory.isHotbar(player.inventory.getSlotFor(STACK_BUCKET_WATER)) && world.getDimensionKey() != World.THE_NETHER; this.canSprint = Baritone.settings().allowSprint.value && player.getFoodStats().getFoodLevel() > 6; this.placeBlockCost = Baritone.settings().blockPlacementPenalty.value; this.allowBreak = Baritone.settings().allowBreak.value; diff --git a/src/main/java/baritone/pathing/movement/MovementHelper.java b/src/main/java/baritone/pathing/movement/MovementHelper.java index 49851eebd..3c804067c 100644 --- a/src/main/java/baritone/pathing/movement/MovementHelper.java +++ b/src/main/java/baritone/pathing/movement/MovementHelper.java @@ -436,7 +436,9 @@ public interface MovementHelper extends ActionCosts, Helper { * @param ts previously calculated ToolSet */ static void switchToBestToolFor(IPlayerContext ctx, BlockState b, ToolSet ts, boolean preferSilkTouch) { - ctx.player().inventory.currentItem = ts.getBestSlot(b.getBlock(), preferSilkTouch); + if (!Baritone.settings().disableAutoTool.value && !Baritone.settings().assumeExternalAutoTool.value) { + ctx.player().inventory.currentItem = ts.getBestSlot(b.getBlock(), preferSilkTouch); + } } static void moveTowards(IPlayerContext ctx, MovementState state, BlockPos pos) { diff --git a/src/main/java/baritone/pathing/movement/movements/MovementDiagonal.java b/src/main/java/baritone/pathing/movement/movements/MovementDiagonal.java index 417d25a20..f3e675c34 100644 --- a/src/main/java/baritone/pathing/movement/movements/MovementDiagonal.java +++ b/src/main/java/baritone/pathing/movement/movements/MovementDiagonal.java @@ -56,6 +56,14 @@ public class MovementDiagonal extends Movement { super(baritone, start, end, new BetterBlockPos[]{dir1, dir1.up(), dir2, dir2.up(), end, end.up()}); } + @Override + protected boolean safeToCancel(MovementState state) { + return ctx.playerFeet().equals(src) || (( + MovementHelper.canWalkOn(ctx, new BlockPos(src.x, src.y - 1, dest.z)) + ) && + MovementHelper.canWalkOn(ctx, new BlockPos(dest.x, src.y - 1, src.z))); + } + @Override public double calculateCost(CalculationContext context) { MutableMoveResult result = new MutableMoveResult(); diff --git a/src/main/java/baritone/pathing/movement/movements/MovementFall.java b/src/main/java/baritone/pathing/movement/movements/MovementFall.java index da36ac5f8..9d36c4b5a 100644 --- a/src/main/java/baritone/pathing/movement/movements/MovementFall.java +++ b/src/main/java/baritone/pathing/movement/movements/MovementFall.java @@ -42,7 +42,7 @@ import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.vector.Vector3d; import net.minecraft.util.math.vector.Vector3i; -import net.minecraft.world.DimensionType; +import net.minecraft.world.World; import java.util.HashSet; import java.util.Optional; @@ -97,7 +97,7 @@ public class MovementFall extends Movement { Block destBlock = destState.getBlock(); boolean isWater = destState.getFluidState().getFluid() instanceof WaterFluid; if (!isWater && willPlaceBucket() && !playerFeet.equals(dest)) { - if (!PlayerInventory.isHotbar(ctx.player().inventory.getSlotFor(STACK_BUCKET_WATER)) || ctx.world().func_234922_V_() == DimensionType.THE_NETHER) { + if (!PlayerInventory.isHotbar(ctx.player().inventory.getSlotFor(STACK_BUCKET_WATER)) || ctx.world().getDimensionKey() == World.THE_NETHER) { return state.setStatus(MovementStatus.UNREACHABLE); } diff --git a/src/main/java/baritone/process/BuilderProcess.java b/src/main/java/baritone/process/BuilderProcess.java index 6f9b85bea..b04c07ada 100644 --- a/src/main/java/baritone/process/BuilderProcess.java +++ b/src/main/java/baritone/process/BuilderProcess.java @@ -39,6 +39,7 @@ import baritone.pathing.movement.Movement; import baritone.pathing.movement.MovementHelper; import baritone.utils.BaritoneProcessHelper; import baritone.utils.BlockStateInterface; +import baritone.utils.NotificationHelper; import baritone.utils.PathingCommandContext; import baritone.utils.schematic.MapArtSchematic; import baritone.utils.schematic.SchematicSystem; @@ -424,6 +425,9 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil numRepeats++; if (repeat.equals(new Vector3i(0, 0, 0)) || (max != -1 && numRepeats >= max)) { logDirect("Done building"); + if (Baritone.settings().desktopNotifications.value && Baritone.settings().notificationOnBuildFinished.value) { + NotificationHelper.notify("Done building", false); + } onLostControl(); return null; } @@ -791,10 +795,13 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil if (desired == null) { return true; } - if (current.getBlock() instanceof AirBlock && desired.getBlock() instanceof AirBlock) { + if (current.getBlock() instanceof FlowingFluidBlock && Baritone.settings().okIfWater.value) { return true; } - if ((current.getBlock() == Blocks.WATER || current.getBlock() == Blocks.LAVA) && Baritone.settings().okIfWater.value) { + if (current.getBlock() instanceof AirBlock && Baritone.settings().okIfAir.value.contains(desired.getBlock())) { + return true; + } + if (desired.getBlock() instanceof AirBlock && Baritone.settings().buildIgnoreBlocks.value.contains(current.getBlock())) { return true; } // TODO more complicated comparison logic I guess diff --git a/src/main/java/baritone/process/CustomGoalProcess.java b/src/main/java/baritone/process/CustomGoalProcess.java index b45c7d6f9..f925bec79 100644 --- a/src/main/java/baritone/process/CustomGoalProcess.java +++ b/src/main/java/baritone/process/CustomGoalProcess.java @@ -23,6 +23,7 @@ import baritone.api.process.ICustomGoalProcess; import baritone.api.process.PathingCommand; import baritone.api.process.PathingCommandType; import baritone.utils.BaritoneProcessHelper; +import baritone.utils.NotificationHelper; /** * As set by ExampleBaritoneControl or something idk @@ -93,6 +94,9 @@ public final class CustomGoalProcess extends BaritoneProcessHelper implements IC if (Baritone.settings().disconnectOnArrival.value) { ctx.world().sendQuittingDisconnectingPacket(); } + if (Baritone.settings().desktopNotifications.value && Baritone.settings().notificationOnPathComplete.value) { + NotificationHelper.notify("Pathing complete", false); + } return new PathingCommand(this.goal, PathingCommandType.CANCEL_AND_SET_GOAL); } return new PathingCommand(this.goal, PathingCommandType.SET_GOAL_AND_PATH); diff --git a/src/main/java/baritone/process/ExploreProcess.java b/src/main/java/baritone/process/ExploreProcess.java index 220ae3b12..c42ece0e5 100644 --- a/src/main/java/baritone/process/ExploreProcess.java +++ b/src/main/java/baritone/process/ExploreProcess.java @@ -29,6 +29,7 @@ import baritone.api.process.PathingCommandType; import baritone.api.utils.MyChunkPos; import baritone.cache.CachedWorld; import baritone.utils.BaritoneProcessHelper; +import baritone.utils.NotificationHelper; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import it.unimi.dsi.fastutil.longs.LongOpenHashSet; @@ -83,12 +84,18 @@ public final class ExploreProcess extends BaritoneProcessHelper implements IExpl public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { if (calcFailed) { logDirect("Failed"); + if (Baritone.settings().desktopNotifications.value && Baritone.settings().notificationOnExploreFinished.value) { + NotificationHelper.notify("Exploration failed", true); + } onLostControl(); return null; } IChunkFilter filter = calcFilter(); if (!Baritone.settings().disableCompletionCheck.value && filter.countRemain() == 0) { logDirect("Explored all chunks"); + if (Baritone.settings().desktopNotifications.value && Baritone.settings().notificationOnExploreFinished.value) { + NotificationHelper.notify("Explored all chunks", false); + } onLostControl(); return null; } diff --git a/src/main/java/baritone/process/FarmProcess.java b/src/main/java/baritone/process/FarmProcess.java index b8412de91..d2dc3c0f1 100644 --- a/src/main/java/baritone/process/FarmProcess.java +++ b/src/main/java/baritone/process/FarmProcess.java @@ -31,6 +31,7 @@ import baritone.api.utils.input.Input; import baritone.cache.WorldScanner; import baritone.pathing.movement.MovementHelper; import baritone.utils.BaritoneProcessHelper; +import baritone.utils.NotificationHelper; import net.minecraft.block.*; import net.minecraft.entity.Entity; import net.minecraft.entity.item.ItemEntity; @@ -254,6 +255,9 @@ public final class FarmProcess extends BaritoneProcessHelper implements IFarmPro if (calcFailed) { logDirect("Farm failed"); + if (Baritone.settings().desktopNotifications.value && Baritone.settings().notificationOnFarmFail.value) { + NotificationHelper.notify("Farm failed", true); + } onLostControl(); return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE); } diff --git a/src/main/java/baritone/process/MineProcess.java b/src/main/java/baritone/process/MineProcess.java index 108a0c780..3991d8db4 100644 --- a/src/main/java/baritone/process/MineProcess.java +++ b/src/main/java/baritone/process/MineProcess.java @@ -30,6 +30,7 @@ import baritone.pathing.movement.CalculationContext; import baritone.pathing.movement.MovementHelper; import baritone.utils.BaritoneProcessHelper; import baritone.utils.BlockStateInterface; +import baritone.utils.NotificationHelper; import net.minecraft.block.*; import net.minecraft.client.world.ClientWorld; import net.minecraft.entity.Entity; @@ -85,10 +86,16 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro if (calcFailed) { if (!knownOreLocations.isEmpty() && Baritone.settings().blacklistClosestOnFailure.value) { logDirect("Unable to find any path to " + filter + ", blacklisting presumably unreachable closest instance..."); + if (Baritone.settings().desktopNotifications.value && Baritone.settings().notificationOnMineFail.value) { + NotificationHelper.notify("Unable to find any path to " + filter + ", blacklisting presumably unreachable closest instance...", true); + } knownOreLocations.stream().min(Comparator.comparingDouble(ctx.playerFeet()::distanceSq)).ifPresent(blacklist::add); knownOreLocations.removeIf(blacklist::contains); } else { logDirect("Unable to find any path to " + filter + ", canceling mine"); + if (Baritone.settings().desktopNotifications.value && Baritone.settings().notificationOnMineFail.value) { + NotificationHelper.notify("Unable to find any path to " + filter + ", canceling mine", true); + } cancel(); return null; } @@ -219,6 +226,9 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro locs.addAll(dropped); if (locs.isEmpty()) { logDirect("No locations for " + filter + " known, cancelling"); + if (Baritone.settings().desktopNotifications.value && Baritone.settings().notificationOnMineFail.value) { + NotificationHelper.notify("No locations for " + filter + " known, cancelling", true); + } cancel(); return; } diff --git a/src/main/java/baritone/utils/BaritoneAutoTest.java b/src/main/java/baritone/utils/BaritoneAutoTest.java index a54e85fa1..bc72a3627 100644 --- a/src/main/java/baritone/utils/BaritoneAutoTest.java +++ b/src/main/java/baritone/utils/BaritoneAutoTest.java @@ -32,11 +32,11 @@ import net.minecraft.client.settings.CloudOption; import net.minecraft.client.settings.GraphicsFanciness; import net.minecraft.client.settings.ParticleStatus; import net.minecraft.client.tutorial.TutorialSteps; -import net.minecraft.server.IDynamicRegistries; import net.minecraft.server.integrated.IntegratedServer; import net.minecraft.util.HTTPUtil; import net.minecraft.util.datafix.codec.DatapackCodec; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.registry.DynamicRegistries; import net.minecraft.world.*; import net.minecraft.world.gen.settings.DimensionGeneratorSettings; import net.minecraft.world.server.ServerWorld; @@ -85,7 +85,7 @@ public class BaritoneAutoTest implements AbstractGameEventListener, Helper { s.chatScale = 0.0F; s.ambientOcclusionStatus = AmbientOcclusionStatus.OFF; s.cloudOption = CloudOption.OFF; - s.field_238330_f_ = GraphicsFanciness.FAST; + s.graphicFanciness = GraphicsFanciness.FAST; s.tutorialStep = TutorialSteps.NONE; s.hideGUI = true; s.fov = 30.0F; @@ -99,18 +99,19 @@ public class BaritoneAutoTest implements AbstractGameEventListener, Helper { System.out.println("Beginning Baritone automatic test routine"); mc.displayGuiScreen(null); WorldSettings worldsettings = new WorldSettings("BaritoneAutoTest", GameType.SURVIVAL, false, Difficulty.NORMAL, true, new GameRules(), DatapackCodec.field_234880_a_); - mc.func_238192_a_("BaritoneAutoTest", worldsettings, IDynamicRegistries.func_239770_b_(), DimensionGeneratorSettings.field_236202_b_.create(false, OptionalLong.of(TEST_SEED))); + final DynamicRegistries.Impl impl = DynamicRegistries.func_239770_b_(); + mc.func_238192_a_("BaritoneAutoTest", worldsettings, impl, DimensionGeneratorSettings.func_242752_a(impl).create(false, OptionalLong.of(TEST_SEED))); } IntegratedServer server = mc.getIntegratedServer(); // If the integrated server is launched and the world has initialized, set the spawn point // to our defined starting position - if (server != null && server.getWorld(World.field_234918_g_) != null) { + if (server != null && server.getWorld(World.OVERWORLD) != null) { server.setDifficultyForAllWorlds(Difficulty.PEACEFUL, true); if (mc.player == null) { server.execute(() -> { - server.getWorld(World.field_234918_g_).func_241124_a__(STARTING_POSITION); + server.getWorld(World.OVERWORLD).func_241124_a__(STARTING_POSITION, 0.0f); server.getCommandManager().handleCommand(server.getCommandSource(), "/difficulty peaceful"); int result = server.getCommandManager().handleCommand(server.getCommandSource(), "/gamerule spawnRadius 0"); if (result != 0) { @@ -121,7 +122,7 @@ public class BaritoneAutoTest implements AbstractGameEventListener, Helper { // If the world has initialized, set the spawn point to our defined starting position if (world != null) { world.getGameRules().get(GameRules.SPAWN_RADIUS).func_234909_b_("0"); - world.func_241124_a__(STARTING_POSITION); + world.func_241124_a__(STARTING_POSITION, 0.0f); } } } diff --git a/src/main/java/baritone/utils/ToolSet.java b/src/main/java/baritone/utils/ToolSet.java index edd033061..811fd905d 100644 --- a/src/main/java/baritone/utils/ToolSet.java +++ b/src/main/java/baritone/utils/ToolSet.java @@ -89,12 +89,27 @@ public class ToolSet { } /** - * Calculate which tool on the hotbar is best for mining + * Calculate which tool on the hotbar is best for mining, depending on an override setting, + * related to auto tool movement cost, it will either return current selected slot, or the best slot. * * @param b the blockstate to be mined * @return An int containing the index in the tools array that worked best */ + public int getBestSlot(Block b, boolean preferSilkTouch) { + return getBestSlot(b, preferSilkTouch, false); + } + + public int getBestSlot(Block b, boolean preferSilkTouch, boolean pathingCalculation) { + + /* + If we actually want know what efficiency our held item has instead of the best one + possible, this lets us make pathing depend on the actual tool to be used (if auto tool is disabled) + */ + if (Baritone.settings().disableAutoTool.value && pathingCalculation) { + return player.inventory.currentItem; + } + int best = 0; double highestSpeed = Double.NEGATIVE_INFINITY; int lowestCost = Integer.MIN_VALUE; @@ -130,7 +145,7 @@ public class ToolSet { * @return A double containing the destruction ticks with the best tool */ private double getBestDestructionTime(Block b) { - ItemStack stack = player.inventory.getStackInSlot(getBestSlot(b, false)); + ItemStack stack = player.inventory.getStackInSlot(getBestSlot(b, false, true)); return calculateSpeedVsBlock(stack, b.getDefaultState()) * avoidanceMultiplier(b); }