Merge pull request #1946 from CDAGaming/1.16.2

✔️ 1.16.1 -> 1.16.2
This commit is contained in:
Leijurv 2020-08-17 17:00:42 -07:00 committed by GitHub
commit 0102ce8fad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 281 additions and 65 deletions

31
.gitmessage Normal file
View File

@ -0,0 +1,31 @@
<emoji> <title> (<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

View File

@ -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?

View File

@ -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'

View File

@ -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>;

View File

@ -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
*/

View File

@ -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;

View File

@ -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;

View File

@ -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())

View File

@ -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;

View File

@ -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
)
);
}
}

View File

@ -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))

View File

@ -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 { }

View File

@ -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)

View File

@ -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);

View File

@ -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:

View File

@ -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) {

View File

@ -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);

View File

@ -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);

View File

@ -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.",
"",

View File

@ -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());
}
}

View File

@ -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;

View File

@ -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) {

View File

@ -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();

View File

@ -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);
}

View File

@ -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

View File

@ -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);

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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);
}
}
}

View File

@ -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);
}