Merge branch 'master' into bot-system

This commit is contained in:
Brady
2018-11-05 16:06:53 -06:00
22 changed files with 229 additions and 158 deletions
+13 -12
View File
@@ -5,6 +5,7 @@
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/a73d037823b64a5faf597a18d71e3400)](https://www.codacy.com/app/leijurv/baritone?utm_source=github.com&utm_medium=referral&utm_content=cabaletta/baritone&utm_campaign=Badge_Grade) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/a73d037823b64a5faf597a18d71e3400)](https://www.codacy.com/app/leijurv/baritone?utm_source=github.com&utm_medium=referral&utm_content=cabaletta/baritone&utm_campaign=Badge_Grade)
[![HitCount](http://hits.dwyl.com/cabaletta/baritone.svg)](http://hits.dwyl.com/cabaletta/baritone) [![HitCount](http://hits.dwyl.com/cabaletta/baritone.svg)](http://hits.dwyl.com/cabaletta/baritone)
[![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](https://github.com/cabaletta/baritone/issues) [![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](https://github.com/cabaletta/baritone/issues)
[![Minecraft](https://img.shields.io/badge/MC-1.12.2-green.svg)](https://minecraft.gamepedia.com/1.12.2)
A Minecraft pathfinder bot. This project is an updated version of [MineBot](https://github.com/leijurv/MineBot/), A Minecraft pathfinder bot. This project is an updated version of [MineBot](https://github.com/leijurv/MineBot/),
the original version of the bot for Minecraft 1.8, rebuilt for 1.12.2. Baritone focuses on reliability and particularly performance (it's over [29x faster](https://github.com/cabaletta/baritone/pull/180#issuecomment-423822928) than MineBot at calculating paths). the original version of the bot for Minecraft 1.8, rebuilt for 1.12.2. Baritone focuses on reliability and particularly performance (it's over [29x faster](https://github.com/cabaletta/baritone/pull/180#issuecomment-423822928) than MineBot at calculating paths).
@@ -21,29 +22,29 @@ There's also some useful information down below
# Setup # Setup
## IntelliJ's Gradle UI
- Open the project in IntelliJ as a Gradle project
- Run the Gradle task `setupDecompWorkspace`
- Run the Gradle task `genIntellijRuns`
- Refresh the Gradle project (or just restart IntelliJ)
- Select the "Minecraft Client" launch config and run
## Command Line ## Command Line
On Mac OSX and Linux, use `./gradlew` instead of `gradlew`. On Mac OSX and Linux, use `./gradlew` instead of `gradlew`.
Running Baritone: Running Baritone:
``` ```
$ gradlew run $ gradlew runClient
``` ```
Setting up for IntelliJ: Building Baritone:
``` ```
$ gradlew setupDecompWorkspace $ gradlew build
$ gradlew --refresh-dependencies
$ gradlew genIntellijRuns
``` ```
For example, to replace out Impact 4.4's Baritone build with a customized one, build Baritone as above then copy `dist/baritone-api-$VERSION$.jar` into `minecraft/libraries/cabaletta/baritone-api/1.0.0/baritone-api-1.0.0.jar`, replacing the jar that was previously there. You also need to edit `minecraft/versions/1.12.2-Impact_4.4/1.12.2-Impact_4.4.json`, find the line `"name": "cabaletta:baritone-api:1.0.0"`, remove the comma from the end, and entirely remove the line that's immediately after (starts with `"url"`).
## IntelliJ's Gradle UI
- Open the project in IntelliJ as a Gradle project
- Run the Gradle tasks `setupDecompWorkspace` then `genIntellijRuns`
- Refresh the Gradle project (or, to be safe, just restart IntelliJ)
- Select the "Minecraft Client" launch config
- In `Edit Configurations...` you may need to select `baritone_launch` for `Use classpath of module:`.
# Chat control # Chat control
[Defined Here](src/main/java/baritone/utils/ExampleBaritoneControl.java) [Defined Here](src/main/java/baritone/utils/ExampleBaritoneControl.java)
+1 -1
View File
@@ -58,7 +58,7 @@ sourceSets {
minecraft { minecraft {
version = '1.12.2' version = '1.12.2'
mappings = 'snapshot_20180731' mappings = 'stable_39'
tweakClass = 'baritone.launch.BaritoneTweaker' tweakClass = 'baritone.launch.BaritoneTweaker'
runDir = 'run' runDir = 'run'
@@ -17,7 +17,6 @@
package baritone.api.event.events; package baritone.api.event.events;
import baritone.api.event.events.type.EventState;
import baritone.api.event.events.type.ManagedPlayerEvent; import baritone.api.event.events.type.ManagedPlayerEvent;
import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
@@ -35,21 +34,30 @@ public final class RotationMoveEvent extends ManagedPlayerEvent {
private final Type type; private final Type type;
/** /**
* The state of the event * The yaw rotation
*/ */
private final EventState state; private float yaw;
public RotationMoveEvent(EntityPlayerSP player, EventState state, Type type) { public RotationMoveEvent(EntityPlayerSP player, Type type, float yaw) {
super(player); super(player);
this.state = state;
this.type = type; this.type = type;
this.yaw = yaw;
} }
/** /**
* @return The state of the event * Set the yaw movement rotation
*
* @param yaw Yaw rotation
*/ */
public final EventState getState() { public final void setYaw(float yaw) {
return this.state; this.yaw = yaw;
}
/**
* @return The yaw rotation
*/
public final float getYaw() {
return this.yaw;
} }
/** /**
@@ -24,14 +24,12 @@ package baritone.api.event.events.type;
public enum EventState { public enum EventState {
/** /**
* Indicates that whatever movement the event is being * Before the dispatching of what the event is targetting
* dispatched as a result of is about to occur.
*/ */
PRE, PRE,
/** /**
* Indicates that whatever movement the event is being * After the dispatching of what the event is targetting
* dispatched as a result of has already occurred.
*/ */
POST POST
} }
@@ -19,14 +19,17 @@ package baritone.launch.mixins;
import baritone.Baritone; import baritone.Baritone;
import baritone.api.event.events.RotationMoveEvent; import baritone.api.event.events.RotationMoveEvent;
import baritone.api.event.events.type.EventState;
import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import static org.spongepowered.asm.lib.Opcodes.GETFIELD;
/** /**
* @author Brady * @author Brady
* @since 8/21/2018 * @since 8/21/2018
@@ -34,23 +37,37 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(Entity.class) @Mixin(Entity.class)
public class MixinEntity { public class MixinEntity {
@Shadow public float rotationYaw;
/**
* Event called to override the movement direction when walking
*/
private RotationMoveEvent motionUpdateRotationEvent;
@Inject( @Inject(
method = "moveRelative", method = "moveRelative",
at = @At("HEAD") at = @At("HEAD")
) )
private void preMoveRelative(float strafe, float up, float forward, float friction, CallbackInfo ci) { private void preMoveRelative(float strafe, float up, float forward, float friction, CallbackInfo ci) {
Entity _this = (Entity) (Object) this; // noinspection ConstantConditions
if (EntityPlayerSP.class.isInstance(_this)) if (EntityPlayerSP.class.isInstance(this)) {
Baritone.INSTANCE.getGameEventHandler().onPlayerRotationMove(new RotationMoveEvent((EntityPlayerSP) _this, EventState.PRE, RotationMoveEvent.Type.MOTION_UPDATE)); this.motionUpdateRotationEvent = new RotationMoveEvent((EntityPlayerSP) (Object) this, RotationMoveEvent.Type.MOTION_UPDATE, this.rotationYaw);
Baritone.INSTANCE.getGameEventHandler().onPlayerRotationMove(this.motionUpdateRotationEvent);
}
} }
@Inject( @Redirect(
method = "moveRelative", method = "moveRelative",
at = @At("RETURN") at = @At(
value = "FIELD",
opcode = GETFIELD,
target = "net/minecraft/entity/Entity.rotationYaw:F"
)
) )
private void postMoveRelative(float strafe, float up, float forward, float friction, CallbackInfo ci) { private float overrideYaw(Entity self) {
Entity _this = (Entity) (Object) this; if (self instanceof EntityPlayerSP) {
if (EntityPlayerSP.class.isInstance(_this)) return this.motionUpdateRotationEvent.getYaw();
Baritone.INSTANCE.getGameEventHandler().onPlayerRotationMove(new RotationMoveEvent((EntityPlayerSP) _this, EventState.POST, RotationMoveEvent.Type.MOTION_UPDATE)); }
return self.rotationYaw;
} }
} }
@@ -19,41 +19,59 @@ package baritone.launch.mixins;
import baritone.Baritone; import baritone.Baritone;
import baritone.api.event.events.RotationMoveEvent; import baritone.api.event.events.RotationMoveEvent;
import baritone.api.event.events.type.EventState;
import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.EntityLivingBase;
import net.minecraft.world.World;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import static org.spongepowered.asm.lib.Opcodes.GETFIELD;
/** /**
* @author Brady * @author Brady
* @since 9/10/2018 * @since 9/10/2018
*/ */
@Mixin(EntityLivingBase.class) @Mixin(EntityLivingBase.class)
public class MixinEntityLivingBase { public abstract class MixinEntityLivingBase extends Entity {
/**
* Event called to override the movement direction when jumping
*/
private RotationMoveEvent jumpRotationEvent;
public MixinEntityLivingBase(World worldIn, RotationMoveEvent jumpRotationEvent) {
super(worldIn);
this.jumpRotationEvent = jumpRotationEvent;
}
@Inject( @Inject(
method = "jump", method = "jump",
at = @At("HEAD") at = @At("HEAD")
) )
private void preJump(CallbackInfo ci) { private void preMoveRelative(CallbackInfo ci) {
EntityLivingBase _this = (EntityLivingBase) (Object) this; // noinspection ConstantConditions
// This uses Class.isInstance instead of instanceof since proguard optimizes out the instanceof (since MixinEntityLivingBase could never be instanceof EntityLivingBase in normal java) if (EntityPlayerSP.class.isInstance(this)) {
// but proguard isn't smart enough to optimize out this Class.isInstance =) this.jumpRotationEvent = new RotationMoveEvent((EntityPlayerSP) (Object) this, RotationMoveEvent.Type.JUMP, this.rotationYaw);
if (EntityPlayerSP.class.isInstance(_this)) Baritone.INSTANCE.getGameEventHandler().onPlayerRotationMove(this.jumpRotationEvent);
Baritone.INSTANCE.getGameEventHandler().onPlayerRotationMove(new RotationMoveEvent((EntityPlayerSP) _this, EventState.PRE, RotationMoveEvent.Type.JUMP)); }
} }
@Inject( @Redirect(
method = "jump", method = "jump",
at = @At("RETURN") at = @At(
value = "FIELD",
opcode = GETFIELD,
target = "net/minecraft/entity/EntityLivingBase.rotationYaw:F"
)
) )
private void postJump(CallbackInfo ci) { private float overrideYaw(EntityLivingBase self) {
EntityLivingBase _this = (EntityLivingBase) (Object) this; if (self instanceof EntityPlayerSP) {
// See above return this.jumpRotationEvent.getYaw();
if (EntityPlayerSP.class.isInstance(_this)) }
Baritone.INSTANCE.getGameEventHandler().onPlayerRotationMove(new RotationMoveEvent((EntityPlayerSP) _this, EventState.POST, RotationMoveEvent.Type.JUMP)); return self.rotationYaw;
} }
} }
@@ -26,6 +26,7 @@ import baritone.api.utils.Rotation;
import baritone.utils.Helper; import baritone.utils.Helper;
public final class LookBehavior extends Behavior implements ILookBehavior, Helper { public final class LookBehavior extends Behavior implements ILookBehavior, Helper {
/** /**
* Target's values are as follows: * Target's values are as follows:
* <p> * <p>
@@ -63,7 +64,7 @@ public final class LookBehavior extends Behavior implements ILookBehavior, Helpe
} }
// Whether or not we're going to silently set our angles // Whether or not we're going to silently set our angles
boolean silent = Baritone.settings().antiCheatCompatibility.get(); boolean silent = Baritone.settings().antiCheatCompatibility.get() && !this.force;
switch (event.getState()) { switch (event.getState()) {
case PRE: { case PRE: {
@@ -76,14 +77,15 @@ public final class LookBehavior extends Behavior implements ILookBehavior, Helpe
nudgeToLevel(); nudgeToLevel();
} }
this.target = null; this.target = null;
} else if (silent) { }
if (silent) {
this.lastYaw = player().rotationYaw; this.lastYaw = player().rotationYaw;
player().rotationYaw = this.target.getYaw(); player().rotationYaw = this.target.getYaw();
} }
break; break;
} }
case POST: { case POST: {
if (!this.force && silent) { if (silent) {
player().rotationYaw = this.lastYaw; player().rotationYaw = this.lastYaw;
this.target = null; this.target = null;
} }
@@ -97,26 +99,20 @@ public final class LookBehavior extends Behavior implements ILookBehavior, Helpe
@Override @Override
public void onPlayerRotationMove(RotationMoveEvent event) { public void onPlayerRotationMove(RotationMoveEvent event) {
if (this.target != null && !this.force) { if (this.target != null && !this.force) {
switch (event.getState()) {
case PRE:
this.lastYaw = player().rotationYaw;
player().rotationYaw = this.target.getYaw();
break;
case POST:
player().rotationYaw = this.lastYaw;
// If we have antiCheatCompatibility on, we're going to use the target value later in onPlayerUpdate() event.setYaw(this.target.getYaw());
// Also the type has to be MOTION_UPDATE because that is called after JUMP
if (!Baritone.settings().antiCheatCompatibility.get() && event.getType() == RotationMoveEvent.Type.MOTION_UPDATE) { // If we have antiCheatCompatibility on, we're going to use the target value later in onPlayerUpdate()
this.target = null; // Also the type has to be MOTION_UPDATE because that is called after JUMP
} if (!Baritone.settings().antiCheatCompatibility.get() && event.getType() == RotationMoveEvent.Type.MOTION_UPDATE) {
break; this.target = null;
default:
break;
} }
} }
} }
/**
* Nudges the player's pitch to a regular level. (Between {@code -20} and {@code 10}, increments are by {@code 1})
*/
private void nudgeToLevel() { private void nudgeToLevel() {
if (player().rotationPitch < -20) { if (player().rotationPitch < -20) {
player().rotationPitch++; player().rotationPitch++;
@@ -94,7 +94,7 @@ public final class MineBehavior extends Behavior implements IMineBehavior, Helpe
List<BlockPos> locs2 = prune(new ArrayList<>(locs), mining, 64); List<BlockPos> locs2 = prune(new ArrayList<>(locs), mining, 64);
// can't reassign locs, gotta make a new var locs2, because we use it in a lambda right here, and variables you use in a lambda must be effectively final // can't reassign locs, gotta make a new var locs2, because we use it in a lambda right here, and variables you use in a lambda must be effectively final
baritone.getPathingBehavior().setGoalAndPath(new GoalComposite(locs2.stream().map(loc -> coalesce(loc, locs2)).toArray(Goal[]::new))); baritone.getPathingBehavior().setGoalAndPath(new GoalComposite(locs2.stream().map(loc -> coalesce(loc, locs2)).toArray(Goal[]::new)));
knownOreLocations = locs; knownOreLocations = locs2;
return; return;
} }
// we don't know any ore locations at the moment // we don't know any ore locations at the moment
@@ -406,13 +406,9 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
logDebug("no goal"); logDebug("no goal");
return Optional.empty(); return Optional.empty();
} }
if (Baritone.settings().simplifyUnloadedYCoord.get()) { if (Baritone.settings().simplifyUnloadedYCoord.get() && goal instanceof IGoalRenderPos) {
BlockPos pos = null; BlockPos pos = ((IGoalRenderPos) goal).getGoalPos();
if (goal instanceof IGoalRenderPos) { if (world().getChunk(pos) instanceof EmptyChunk) {
pos = ((IGoalRenderPos) goal).getGoalPos();
}
if (pos != null && world().getChunk(pos) instanceof EmptyChunk) {
logDebug("Simplifying " + goal.getClass() + " to GoalXZ due to distance"); logDebug("Simplifying " + goal.getClass() + " to GoalXZ due to distance");
goal = new GoalXZ(pos.getX(), pos.getZ()); goal = new GoalXZ(pos.getX(), pos.getZ());
} }
@@ -131,7 +131,7 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
throw new IllegalStateException(moves + " " + res.x + " " + newX + " " + res.z + " " + newZ); throw new IllegalStateException(moves + " " + res.x + " " + newX + " " + res.z + " " + newZ);
} }
if (!moves.dynamicY && res.y != currentNode.y + moves.yOffset) { if (!moves.dynamicY && res.y != currentNode.y + moves.yOffset) {
throw new IllegalStateException(moves + " " + res.x + " " + newX + " " + res.z + " " + newZ); throw new IllegalStateException(moves + " " + res.y + " " + (currentNode.y + moves.yOffset));
} }
long hashCode = BetterBlockPos.longHash(res.x, res.y, res.z); long hashCode = BetterBlockPos.longHash(res.x, res.y, res.z);
if (favoring && favored.contains(hashCode)) { if (favoring && favored.contains(hashCode)) {
@@ -48,11 +48,7 @@ public class CalculationContext implements Helper {
private final BetterWorldBorder worldBorder; private final BetterWorldBorder worldBorder;
public CalculationContext() { public CalculationContext() {
this(new ToolSet()); this.toolSet = new ToolSet();
}
public CalculationContext(ToolSet toolSet) {
this.toolSet = toolSet;
this.hasThrowaway = Baritone.settings().allowPlace.get() && MovementHelper.throwaway(false); this.hasThrowaway = Baritone.settings().allowPlace.get() && MovementHelper.throwaway(false);
this.hasWaterBucket = Baritone.settings().allowWaterBucketFall.get() && InventoryPlayer.isHotbar(player().inventory.getSlotFor(STACK_BUCKET_WATER)) && !world().provider.isNether(); this.hasWaterBucket = Baritone.settings().allowWaterBucketFall.get() && InventoryPlayer.isHotbar(player().inventory.getSlotFor(STACK_BUCKET_WATER)) && !world().provider.isNether();
this.canSprint = Baritone.settings().allowSprint.get() && player().getFoodStats().getFoodLevel() > 6; this.canSprint = Baritone.settings().allowSprint.get() && player().getFoodStats().getFoodLevel() > 6;
@@ -116,7 +116,7 @@ public abstract class Movement implements IMovement, Helper, MovementHelper {
public MovementStatus update() { public MovementStatus update() {
player().capabilities.isFlying = false; player().capabilities.isFlying = false;
MovementState latestState = updateState(currentState); MovementState latestState = updateState(currentState);
if (BlockStateInterface.isLiquid(playerFeet())) { if (MovementHelper.isLiquid(playerFeet())) {
latestState.setInput(Input.JUMP, true); latestState.setInput(Input.JUMP, true);
} }
if (player().isEntityInsideOpaqueBlock()) { if (player().isEntityInsideOpaqueBlock()) {
@@ -105,7 +105,7 @@ public interface MovementHelper extends ActionCosts, Helper {
} }
throw new IllegalStateException(); throw new IllegalStateException();
} }
if (BlockStateInterface.isFlowing(state)) { if (isFlowing(state)) {
return false; // Don't walk through flowing liquids return false; // Don't walk through flowing liquids
} }
if (block instanceof BlockLiquid) { if (block instanceof BlockLiquid) {
@@ -254,9 +254,6 @@ public interface MovementHelper extends ActionCosts, Helper {
return false; return false;
} }
if (state.isBlockNormalCube()) { if (state.isBlockNormalCube()) {
if (BlockStateInterface.isLava(block) || BlockStateInterface.isWater(block)) {
throw new IllegalStateException();
}
return true; return true;
} }
if (block == Blocks.LADDER || (block == Blocks.VINE && Baritone.settings().allowVines.get())) { // TODO reconsider this if (block == Blocks.LADDER || (block == Blocks.VINE && Baritone.settings().allowVines.get())) { // TODO reconsider this
@@ -268,20 +265,20 @@ public interface MovementHelper extends ActionCosts, Helper {
if (block == Blocks.ENDER_CHEST || block == Blocks.CHEST) { if (block == Blocks.ENDER_CHEST || block == Blocks.CHEST) {
return true; return true;
} }
if (BlockStateInterface.isWater(block)) { if (isWater(block)) {
// since this is called literally millions of times per second, the benefit of not allocating millions of useless "pos.up()" // since this is called literally millions of times per second, the benefit of not allocating millions of useless "pos.up()"
// BlockPos s that we'd just garbage collect immediately is actually noticeable. I don't even think its a decrease in readability // BlockPos s that we'd just garbage collect immediately is actually noticeable. I don't even think its a decrease in readability
Block up = BlockStateInterface.get(x, y + 1, z).getBlock(); Block up = BlockStateInterface.get(x, y + 1, z).getBlock();
if (up == Blocks.WATERLILY) { if (up == Blocks.WATERLILY) {
return true; return true;
} }
if (BlockStateInterface.isFlowing(state) || block == Blocks.FLOWING_WATER) { if (isFlowing(state) || block == Blocks.FLOWING_WATER) {
// the only scenario in which we can walk on flowing water is if it's under still water with jesus off // the only scenario in which we can walk on flowing water is if it's under still water with jesus off
return BlockStateInterface.isWater(up) && !Baritone.settings().assumeWalkOnWater.get(); return isWater(up) && !Baritone.settings().assumeWalkOnWater.get();
} }
// if assumeWalkOnWater is on, we can only walk on water if there isn't water above it // if assumeWalkOnWater is on, we can only walk on water if there isn't water above it
// if assumeWalkOnWater is off, we can only walk on water if there is water above it // if assumeWalkOnWater is off, we can only walk on water if there is water above it
return BlockStateInterface.isWater(up) ^ Baritone.settings().assumeWalkOnWater.get(); return isWater(up) ^ Baritone.settings().assumeWalkOnWater.get();
} }
if (block instanceof BlockGlass || block instanceof BlockStainedGlass) { if (block instanceof BlockGlass || block instanceof BlockStainedGlass) {
return true; return true;
@@ -444,4 +441,47 @@ public interface MovementHelper extends ActionCosts, Helper {
false false
)).setInput(InputOverrideHandler.Input.MOVE_FORWARD, true); )).setInput(InputOverrideHandler.Input.MOVE_FORWARD, true);
} }
/**
* Returns whether or not the specified block is
* water, regardless of whether or not it is flowing.
*
* @param b The block
* @return Whether or not the block is water
*/
static boolean isWater(Block b) {
return b == Blocks.FLOWING_WATER || b == Blocks.WATER;
}
/**
* Returns whether or not the block at the specified pos is
* water, regardless of whether or not it is flowing.
*
* @param bp The block pos
* @return Whether or not the block is water
*/
static boolean isWater(BlockPos bp) {
return isWater(BlockStateInterface.getBlock(bp));
}
static boolean isLava(Block b) {
return b == Blocks.FLOWING_LAVA || b == Blocks.LAVA;
}
/**
* Returns whether or not the specified pos has a liquid
*
* @param p The pos
* @return Whether or not the block is a liquid
*/
static boolean isLiquid(BlockPos p) {
return BlockStateInterface.getBlock(p) instanceof BlockLiquid;
}
static boolean isFlowing(IBlockState state) {
// Will be IFluidState in 1.13
return state.getBlock() instanceof BlockLiquid
&& state.getPropertyKeys().contains(BlockLiquid.LEVEL)
&& state.getValue(BlockLiquid.LEVEL) != 0;
}
} }
@@ -75,7 +75,7 @@ public class MovementAscend extends Movement {
if (!context.canPlaceThrowawayAt(destX, y, destZ)) { if (!context.canPlaceThrowawayAt(destX, y, destZ)) {
return COST_INF; return COST_INF;
} }
if (toPlace.getBlock() != Blocks.AIR && !BlockStateInterface.isWater(toPlace.getBlock()) && !MovementHelper.isReplacable(destX, y, destZ, toPlace)) { if (toPlace.getBlock() != Blocks.AIR && !MovementHelper.isWater(toPlace.getBlock()) && !MovementHelper.isReplacable(destX, y, destZ, toPlace)) {
return COST_INF; return COST_INF;
} }
// TODO: add ability to place against .down() as well as the cardinal directions // TODO: add ability to place against .down() as well as the cardinal directions
@@ -130,7 +130,7 @@ public class MovementDescend extends Movement {
} }
IBlockState ontoBlock = BlockStateInterface.get(destX, newY, destZ); IBlockState ontoBlock = BlockStateInterface.get(destX, newY, destZ);
double tentativeCost = WALK_OFF_BLOCK_COST + FALL_N_BLOCKS_COST[fallHeight] + frontBreak; double tentativeCost = WALK_OFF_BLOCK_COST + FALL_N_BLOCKS_COST[fallHeight] + frontBreak;
if (ontoBlock.getBlock() == Blocks.WATER && !BlockStateInterface.isFlowing(ontoBlock) && BlockStateInterface.getBlock(destX, newY + 1, destZ) != Blocks.WATERLILY) { // TODO flowing check required here? if (ontoBlock.getBlock() == Blocks.WATER && !MovementHelper.isFlowing(ontoBlock) && BlockStateInterface.getBlock(destX, newY + 1, destZ) != Blocks.WATERLILY) { // TODO flowing check required here?
// lilypads are canWalkThrough, but we can't end a fall that should be broken by water if it's covered by a lilypad // lilypads are canWalkThrough, but we can't end a fall that should be broken by water if it's covered by a lilypad
// however, don't return impossible in the lilypad scenario, because we could still jump right on it (water that's below a lilypad is canWalkOn so it works) // however, don't return impossible in the lilypad scenario, because we could still jump right on it (water that's below a lilypad is canWalkOn so it works)
if (Baritone.settings().assumeWalkOnWater.get()) { if (Baritone.settings().assumeWalkOnWater.get()) {
@@ -183,7 +183,7 @@ public class MovementDescend extends Movement {
} }
BlockPos playerFeet = playerFeet(); BlockPos playerFeet = playerFeet();
if (playerFeet.equals(dest) && (BlockStateInterface.isLiquid(dest) || player().posY - playerFeet.getY() < 0.094)) { // lilypads if (playerFeet.equals(dest) && (MovementHelper.isLiquid(dest) || player().posY - playerFeet.getY() < 0.094)) { // lilypads
// Wait until we're actually on the ground before saying we're done because sometimes we continue to fall if the next action starts immediately // Wait until we're actually on the ground before saying we're done because sometimes we continue to fall if the next action starts immediately
return state.setStatus(MovementStatus.SUCCESS); return state.setStatus(MovementStatus.SUCCESS);
/* else { /* else {
@@ -78,11 +78,11 @@ public class MovementDiagonal extends Movement {
multiplier += (WALK_ONE_OVER_SOUL_SAND_COST - WALK_ONE_BLOCK_COST) / 2; multiplier += (WALK_ONE_OVER_SOUL_SAND_COST - WALK_ONE_BLOCK_COST) / 2;
} }
Block cuttingOver1 = BlockStateInterface.get(x, y - 1, destZ).getBlock(); Block cuttingOver1 = BlockStateInterface.get(x, y - 1, destZ).getBlock();
if (cuttingOver1 == Blocks.MAGMA || BlockStateInterface.isLava(cuttingOver1)) { if (cuttingOver1 == Blocks.MAGMA || MovementHelper.isLava(cuttingOver1)) {
return COST_INF; return COST_INF;
} }
Block cuttingOver2 = BlockStateInterface.get(destX, y - 1, z).getBlock(); Block cuttingOver2 = BlockStateInterface.get(destX, y - 1, z).getBlock();
if (cuttingOver2 == Blocks.MAGMA || BlockStateInterface.isLava(cuttingOver2)) { if (cuttingOver2 == Blocks.MAGMA || MovementHelper.isLava(cuttingOver2)) {
return COST_INF; return COST_INF;
} }
IBlockState pb0 = BlockStateInterface.get(x, y, destZ); IBlockState pb0 = BlockStateInterface.get(x, y, destZ);
@@ -115,7 +115,7 @@ public class MovementDiagonal extends Movement {
return COST_INF; return COST_INF;
} }
boolean water = false; boolean water = false;
if (BlockStateInterface.isWater(BlockStateInterface.getBlock(x, y, z)) || BlockStateInterface.isWater(destInto.getBlock())) { if (MovementHelper.isWater(BlockStateInterface.getBlock(x, y, z)) || MovementHelper.isWater(destInto.getBlock())) {
// Ignore previous multiplier // Ignore previous multiplier
// Whatever we were walking on (possibly soul sand) doesn't matter as we're actually floating on water // Whatever we were walking on (possibly soul sand) doesn't matter as we're actually floating on water
// Not even touching the blocks below // Not even touching the blocks below
@@ -145,7 +145,7 @@ public class MovementDiagonal extends Movement {
state.setStatus(MovementStatus.SUCCESS); state.setStatus(MovementStatus.SUCCESS);
return state; return state;
} }
if (!BlockStateInterface.isLiquid(playerFeet())) { if (!MovementHelper.isLiquid(playerFeet())) {
state.setInput(InputOverrideHandler.Input.SPRINT, true); state.setInput(InputOverrideHandler.Input.SPRINT, true);
} }
MovementHelper.moveTowards(state, dest); MovementHelper.moveTowards(state, dest);
@@ -25,7 +25,6 @@ import baritone.pathing.movement.Movement;
import baritone.pathing.movement.MovementHelper; import baritone.pathing.movement.MovementHelper;
import baritone.pathing.movement.MovementState; import baritone.pathing.movement.MovementState;
import baritone.pathing.movement.MovementState.MovementTarget; import baritone.pathing.movement.MovementState.MovementTarget;
import baritone.utils.BlockStateInterface;
import baritone.utils.InputOverrideHandler; import baritone.utils.InputOverrideHandler;
import baritone.utils.pathing.MutableMoveResult; import baritone.utils.pathing.MutableMoveResult;
import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.entity.player.InventoryPlayer;
@@ -63,7 +62,7 @@ public class MovementFall extends Movement {
BlockPos playerFeet = playerFeet(); BlockPos playerFeet = playerFeet();
Rotation targetRotation = null; Rotation targetRotation = null;
if (!BlockStateInterface.isWater(dest) && src.getY() - dest.getY() > Baritone.settings().maxFallHeightNoWater.get() && !playerFeet.equals(dest)) { if (!MovementHelper.isWater(dest) && src.getY() - dest.getY() > Baritone.settings().maxFallHeightNoWater.get() && !playerFeet.equals(dest)) {
if (!InventoryPlayer.isHotbar(player().inventory.getSlotFor(STACK_BUCKET_WATER)) || world().provider.isNether()) { if (!InventoryPlayer.isHotbar(player().inventory.getSlotFor(STACK_BUCKET_WATER)) || world().provider.isNether()) {
return state.setStatus(MovementStatus.UNREACHABLE); return state.setStatus(MovementStatus.UNREACHABLE);
} }
@@ -84,8 +83,8 @@ public class MovementFall extends Movement {
} else { } else {
state.setTarget(new MovementTarget(RotationUtils.calcRotationFromVec3d(playerHead(), VecUtils.getBlockPosCenter(dest)), false)); state.setTarget(new MovementTarget(RotationUtils.calcRotationFromVec3d(playerHead(), VecUtils.getBlockPosCenter(dest)), false));
} }
if (playerFeet.equals(dest) && (player().posY - playerFeet.getY() < 0.094 || BlockStateInterface.isWater(dest))) { // 0.094 because lilypads if (playerFeet.equals(dest) && (player().posY - playerFeet.getY() < 0.094 || MovementHelper.isWater(dest))) { // 0.094 because lilypads
if (BlockStateInterface.isWater(dest)) { if (MovementHelper.isWater(dest)) {
if (InventoryPlayer.isHotbar(player().inventory.getSlotFor(STACK_BUCKET_EMPTY))) { if (InventoryPlayer.isHotbar(player().inventory.getSlotFor(STACK_BUCKET_EMPTY))) {
player().inventory.currentItem = player().inventory.getSlotFor(STACK_BUCKET_EMPTY); player().inventory.currentItem = player().inventory.getSlotFor(STACK_BUCKET_EMPTY);
if (player().motionY >= 0) { if (player().motionY >= 0) {
@@ -93,7 +93,17 @@ public class MovementParkour extends Movement {
if (!MovementHelper.fullyPassable(x, y + 2, z)) { if (!MovementHelper.fullyPassable(x, y + 2, z)) {
return; return;
} }
for (int i = 2; i <= (context.canSprint() ? 4 : 3); i++) { int maxJump;
if (standingOn.getBlock() == Blocks.SOUL_SAND) {
maxJump = 2; // 1 block gap
} else {
if (context.canSprint()) {
maxJump = 4;
} else {
maxJump = 3;
}
}
for (int i = 2; i <= maxJump; i++) {
// TODO perhaps dest.up(3) doesn't need to be fullyPassable, just canWalkThrough, possibly? // TODO perhaps dest.up(3) doesn't need to be fullyPassable, just canWalkThrough, possibly?
for (int y2 = 0; y2 < 4; y2++) { for (int y2 = 0; y2 < 4; y2++) {
if (!MovementHelper.fullyPassable(x + xDiff * i, y + y2, z + zDiff * i)) { if (!MovementHelper.fullyPassable(x + xDiff * i, y + y2, z + zDiff * i)) {
@@ -108,7 +118,7 @@ public class MovementParkour extends Movement {
return; return;
} }
} }
if (!context.canSprint()) { if (maxJump != 4) {
return; return;
} }
if (!Baritone.settings().allowParkourPlace.get()) { if (!Baritone.settings().allowParkourPlace.get()) {
@@ -124,7 +134,7 @@ public class MovementParkour extends Movement {
if (!context.canPlaceThrowawayAt(destX, y - 1, destZ)) { if (!context.canPlaceThrowawayAt(destX, y - 1, destZ)) {
return; return;
} }
if (toPlace.getBlock() != Blocks.AIR && !BlockStateInterface.isWater(toPlace.getBlock()) && !MovementHelper.isReplacable(destX, y - 1, destZ, toPlace)) { if (toPlace.getBlock() != Blocks.AIR && !MovementHelper.isWater(toPlace.getBlock()) && !MovementHelper.isReplacable(destX, y - 1, destZ, toPlace)) {
return; return;
} }
for (int i = 0; i < 5; i++) { for (int i = 0; i < 5; i++) {
@@ -67,9 +67,9 @@ public class MovementPillar extends Movement {
return COST_INF; return COST_INF;
} }
Block srcUp = null; Block srcUp = null;
if (BlockStateInterface.isWater(toBreakBlock) && BlockStateInterface.isWater(fromDown)) { if (MovementHelper.isWater(toBreakBlock) && MovementHelper.isWater(fromDown)) {
srcUp = BlockStateInterface.get(x, y + 1, z).getBlock(); srcUp = BlockStateInterface.get(x, y + 1, z).getBlock();
if (BlockStateInterface.isWater(srcUp)) { if (MovementHelper.isWater(srcUp)) {
return LADDER_UP_ONE_COST; return LADDER_UP_ONE_COST;
} }
} }
@@ -144,7 +144,7 @@ public class MovementPillar extends Movement {
} }
IBlockState fromDown = BlockStateInterface.get(src); IBlockState fromDown = BlockStateInterface.get(src);
if (BlockStateInterface.isWater(fromDown.getBlock()) && BlockStateInterface.isWater(dest)) { if (MovementHelper.isWater(fromDown.getBlock()) && MovementHelper.isWater(dest)) {
// stay centered while swimming up a water column // stay centered while swimming up a water column
state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(playerHead(), VecUtils.getBlockPosCenter(dest)), false)); state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(playerHead(), VecUtils.getBlockPosCenter(dest)), false));
Vec3d destCenter = VecUtils.getBlockPosCenter(dest); Vec3d destCenter = VecUtils.getBlockPosCenter(dest);
@@ -240,7 +240,7 @@ public class MovementPillar extends Movement {
state.setInput(InputOverrideHandler.Input.SNEAK, true); state.setInput(InputOverrideHandler.Input.SNEAK, true);
} }
} }
if (BlockStateInterface.isWater(dest.up())) { if (MovementHelper.isWater(dest.up())) {
return true; return true;
} }
return super.prepared(state); return super.prepared(state);
@@ -66,7 +66,7 @@ public class MovementTraverse extends Movement {
if (MovementHelper.canWalkOn(destX, y - 1, destZ, destOn)) {//this is a walk, not a bridge if (MovementHelper.canWalkOn(destX, y - 1, destZ, destOn)) {//this is a walk, not a bridge
double WC = WALK_ONE_BLOCK_COST; double WC = WALK_ONE_BLOCK_COST;
boolean water = false; boolean water = false;
if (BlockStateInterface.isWater(pb0.getBlock()) || BlockStateInterface.isWater(pb1.getBlock())) { if (MovementHelper.isWater(pb0.getBlock()) || MovementHelper.isWater(pb1.getBlock())) {
WC = context.waterWalkSpeed(); WC = context.waterWalkSpeed();
water = true; water = true;
} else { } else {
@@ -101,8 +101,8 @@ public class MovementTraverse extends Movement {
return COST_INF; return COST_INF;
} }
if (destOn.getBlock().equals(Blocks.AIR) || MovementHelper.isReplacable(destX, y - 1, destZ, destOn)) { if (destOn.getBlock().equals(Blocks.AIR) || MovementHelper.isReplacable(destX, y - 1, destZ, destOn)) {
boolean throughWater = BlockStateInterface.isWater(pb0.getBlock()) || BlockStateInterface.isWater(pb1.getBlock()); boolean throughWater = MovementHelper.isWater(pb0.getBlock()) || MovementHelper.isWater(pb1.getBlock());
if (BlockStateInterface.isWater(destOn.getBlock()) && throughWater) { if (MovementHelper.isWater(destOn.getBlock()) && throughWater) {
return COST_INF; return COST_INF;
} }
if (!context.canPlaceThrowawayAt(destX, y - 1, destZ)) { if (!context.canPlaceThrowawayAt(destX, y - 1, destZ)) {
@@ -223,7 +223,7 @@ public class MovementTraverse extends Movement {
if (playerFeet().equals(dest)) { if (playerFeet().equals(dest)) {
return state.setStatus(MovementStatus.SUCCESS); return state.setStatus(MovementStatus.SUCCESS);
} }
if (wasTheBridgeBlockAlwaysThere && !BlockStateInterface.isLiquid(playerFeet())) { if (wasTheBridgeBlockAlwaysThere && !MovementHelper.isLiquid(playerFeet())) {
state.setInput(InputOverrideHandler.Input.SPRINT, true); state.setInput(InputOverrideHandler.Input.SPRINT, true);
} }
Block destDown = BlockStateInterface.get(dest.down()).getBlock(); Block destDown = BlockStateInterface.get(dest.down()).getBlock();
@@ -22,7 +22,6 @@ import baritone.cache.CachedRegion;
import baritone.cache.WorldData; import baritone.cache.WorldData;
import baritone.cache.WorldProvider; import baritone.cache.WorldProvider;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockLiquid;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks; import net.minecraft.init.Blocks;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
@@ -128,47 +127,4 @@ public class BlockStateInterface implements Helper {
public static Block getBlock(int x, int y, int z) { public static Block getBlock(int x, int y, int z) {
return get(x, y, z).getBlock(); return get(x, y, z).getBlock();
} }
/**
* Returns whether or not the specified block is
* water, regardless of whether or not it is flowing.
*
* @param b The block
* @return Whether or not the block is water
*/
public static boolean isWater(Block b) {
return b == Blocks.FLOWING_WATER || b == Blocks.WATER;
}
/**
* Returns whether or not the block at the specified pos is
* water, regardless of whether or not it is flowing.
*
* @param bp The block pos
* @return Whether or not the block is water
*/
public static boolean isWater(BlockPos bp) {
return isWater(BlockStateInterface.getBlock(bp));
}
public static boolean isLava(Block b) {
return b == Blocks.FLOWING_LAVA || b == Blocks.LAVA;
}
/**
* Returns whether or not the specified pos has a liquid
*
* @param p The pos
* @return Whether or not the block is a liquid
*/
public static boolean isLiquid(BlockPos p) {
return BlockStateInterface.getBlock(p) instanceof BlockLiquid;
}
public static boolean isFlowing(IBlockState state) {
// Will be IFluidState in 1.13
return state.getBlock() instanceof BlockLiquid
&& state.getPropertyKeys().contains(BlockLiquid.LEVEL)
&& state.getValue(BlockLiquid.LEVEL) != 0;
}
} }
@@ -46,6 +46,36 @@ import java.util.stream.Stream;
public class ExampleBaritoneControl extends Behavior implements Helper { public class ExampleBaritoneControl extends Behavior implements Helper {
private static final String HELP_MSG =
"baritone - Output settings into chat\n" +
"settings - Same as baritone\n" +
"goal - Create a goal (one number is '<Y>', two is '<X> <Z>', three is '<X> <Y> <Z>, 'clear' to clear)\n" +
"path - Go towards goal\n" +
"repack - (debug) Repacks chunk cache\n" +
"rescan - (debug) Same as repack\n" +
"axis - Paths towards the closest axis or diagonal axis, at y=120\n" +
"cancel - Cancels current path\n" +
"forcecancel - sudo cancel (only use if very glitched, try toggling 'pause' first)\n" +
"gc - Calls System.gc();\n" +
"invert - Runs away from the goal instead of towards it\n" +
"follow - Follows a player 'follow username'\n" +
"reloadall - (debug) Reloads chunk cache\n" +
"saveall - (debug) Saves chunk cache\n" +
"find - (debug) outputs how many blocks of a certain type are within the cache\n" +
"mine - Paths to and mines specified blocks 'mine x_ore y_ore ...'\n" +
"thisway - Creates a goal X blocks where you're facing\n" +
"list - Lists waypoints under a category\n" +
"get - Same as list\n" +
"show - Same as list\n" +
"save - Saves a waypoint (works but don't try to make sense of it)\n" +
"goto - Paths towards specified block or waypoint\n" +
"spawn - Paths towards world spawn or your most recent bed right-click\n" +
"sethome - Sets \"home\"\n" +
"home - Paths towards \"home\" \n" +
"costs - (debug) all movement costs from current location\n" +
"pause - Toggle pause\n" +
"damn - Daniel ";
public ExampleBaritoneControl(Baritone baritone) { public ExampleBaritoneControl(Baritone baritone) {
super(baritone); super(baritone);
} }
@@ -85,6 +115,12 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
} }
return true; return true;
} }
if (msg.equals("") || msg.equals("help") || msg.equals("?")) {
for (String line : HELP_MSG.split("\n")) {
logDirect(line);
}
return false;
}
if (msg.contains(" ")) { if (msg.contains(" ")) {
String[] data = msg.split(" "); String[] data = msg.split(" ");
if (data.length == 2) { if (data.length == 2) {
@@ -226,7 +262,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
} }
pathingBehavior.setGoal(new GoalRunAway(1, runAwayFrom) { pathingBehavior.setGoal(new GoalRunAway(1, runAwayFrom) {
@Override @Override
public boolean isInGoal(BlockPos pos) { public boolean isInGoal(int x, int y, int z) {
return false; return false;
} }
}); });