diff --git a/README.md b/README.md
index 2cabfd77..ef568f0c 100644
--- a/README.md
+++ b/README.md
@@ -5,6 +5,7 @@
[](https://www.codacy.com/app/leijurv/baritone?utm_source=github.com&utm_medium=referral&utm_content=cabaletta/baritone&utm_campaign=Badge_Grade)
[](http://hits.dwyl.com/cabaletta/baritone)
[](https://github.com/cabaletta/baritone/issues)
+[](https://minecraft.gamepedia.com/1.12.2)
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).
@@ -21,29 +22,29 @@ There's also some useful information down below
# 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
On Mac OSX and Linux, use `./gradlew` instead of `gradlew`.
Running Baritone:
```
-$ gradlew run
+$ gradlew runClient
```
-Setting up for IntelliJ:
+Building Baritone:
```
-$ gradlew setupDecompWorkspace
-$ gradlew --refresh-dependencies
-$ gradlew genIntellijRuns
+$ gradlew build
```
+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
[Defined Here](src/main/java/baritone/utils/ExampleBaritoneControl.java)
diff --git a/build.gradle b/build.gradle
index abb75959..e0b556a2 100755
--- a/build.gradle
+++ b/build.gradle
@@ -58,7 +58,7 @@ sourceSets {
minecraft {
version = '1.12.2'
- mappings = 'snapshot_20180731'
+ mappings = 'stable_39'
tweakClass = 'baritone.launch.BaritoneTweaker'
runDir = 'run'
diff --git a/src/api/java/baritone/api/event/events/RotationMoveEvent.java b/src/api/java/baritone/api/event/events/RotationMoveEvent.java
index 7a7514db..790318e0 100644
--- a/src/api/java/baritone/api/event/events/RotationMoveEvent.java
+++ b/src/api/java/baritone/api/event/events/RotationMoveEvent.java
@@ -17,7 +17,6 @@
package baritone.api.event.events;
-import baritone.api.event.events.type.EventState;
import baritone.api.event.events.type.ManagedPlayerEvent;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.entity.Entity;
@@ -35,21 +34,30 @@ public final class RotationMoveEvent extends ManagedPlayerEvent {
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);
- this.state = state;
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() {
- return this.state;
+ public final void setYaw(float yaw) {
+ this.yaw = yaw;
+ }
+
+ /**
+ * @return The yaw rotation
+ */
+ public final float getYaw() {
+ return this.yaw;
}
/**
diff --git a/src/api/java/baritone/api/event/events/type/EventState.java b/src/api/java/baritone/api/event/events/type/EventState.java
index 10b633bd..072e12c1 100644
--- a/src/api/java/baritone/api/event/events/type/EventState.java
+++ b/src/api/java/baritone/api/event/events/type/EventState.java
@@ -24,14 +24,12 @@ package baritone.api.event.events.type;
public enum EventState {
/**
- * Indicates that whatever movement the event is being
- * dispatched as a result of is about to occur.
+ * Before the dispatching of what the event is targetting
*/
PRE,
/**
- * Indicates that whatever movement the event is being
- * dispatched as a result of has already occurred.
+ * After the dispatching of what the event is targetting
*/
POST
}
diff --git a/src/launch/java/baritone/launch/mixins/MixinEntity.java b/src/launch/java/baritone/launch/mixins/MixinEntity.java
index fe019bb7..6623e1c2 100644
--- a/src/launch/java/baritone/launch/mixins/MixinEntity.java
+++ b/src/launch/java/baritone/launch/mixins/MixinEntity.java
@@ -19,14 +19,17 @@ package baritone.launch.mixins;
import baritone.Baritone;
import baritone.api.event.events.RotationMoveEvent;
-import baritone.api.event.events.type.EventState;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.entity.Entity;
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.Inject;
+import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+import static org.spongepowered.asm.lib.Opcodes.GETFIELD;
+
/**
* @author Brady
* @since 8/21/2018
@@ -34,23 +37,37 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(Entity.class)
public class MixinEntity {
+ @Shadow public float rotationYaw;
+
+ /**
+ * Event called to override the movement direction when walking
+ */
+ private RotationMoveEvent motionUpdateRotationEvent;
+
@Inject(
method = "moveRelative",
at = @At("HEAD")
)
private void preMoveRelative(float strafe, float up, float forward, float friction, CallbackInfo ci) {
- Entity _this = (Entity) (Object) this;
- if (EntityPlayerSP.class.isInstance(_this))
- Baritone.INSTANCE.getGameEventHandler().onPlayerRotationMove(new RotationMoveEvent((EntityPlayerSP) _this, EventState.PRE, RotationMoveEvent.Type.MOTION_UPDATE));
+ // noinspection ConstantConditions
+ if (EntityPlayerSP.class.isInstance(this)) {
+ this.motionUpdateRotationEvent = new RotationMoveEvent((EntityPlayerSP) (Object) this, RotationMoveEvent.Type.MOTION_UPDATE, this.rotationYaw);
+ Baritone.INSTANCE.getGameEventHandler().onPlayerRotationMove(this.motionUpdateRotationEvent);
+ }
}
- @Inject(
+ @Redirect(
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) {
- Entity _this = (Entity) (Object) this;
- if (EntityPlayerSP.class.isInstance(_this))
- Baritone.INSTANCE.getGameEventHandler().onPlayerRotationMove(new RotationMoveEvent((EntityPlayerSP) _this, EventState.POST, RotationMoveEvent.Type.MOTION_UPDATE));
+ private float overrideYaw(Entity self) {
+ if (self instanceof EntityPlayerSP) {
+ return this.motionUpdateRotationEvent.getYaw();
+ }
+ return self.rotationYaw;
}
}
diff --git a/src/launch/java/baritone/launch/mixins/MixinEntityLivingBase.java b/src/launch/java/baritone/launch/mixins/MixinEntityLivingBase.java
index 6313b3a1..8e2eb515 100644
--- a/src/launch/java/baritone/launch/mixins/MixinEntityLivingBase.java
+++ b/src/launch/java/baritone/launch/mixins/MixinEntityLivingBase.java
@@ -19,41 +19,59 @@ package baritone.launch.mixins;
import baritone.Baritone;
import baritone.api.event.events.RotationMoveEvent;
-import baritone.api.event.events.type.EventState;
import net.minecraft.client.entity.EntityPlayerSP;
+import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
+import net.minecraft.world.World;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+import static org.spongepowered.asm.lib.Opcodes.GETFIELD;
+
/**
* @author Brady
* @since 9/10/2018
*/
@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(
method = "jump",
at = @At("HEAD")
)
- private void preJump(CallbackInfo ci) {
- EntityLivingBase _this = (EntityLivingBase) (Object) this;
- // This uses Class.isInstance instead of instanceof since proguard optimizes out the instanceof (since MixinEntityLivingBase could never be instanceof EntityLivingBase in normal java)
- // but proguard isn't smart enough to optimize out this Class.isInstance =)
- if (EntityPlayerSP.class.isInstance(_this))
- Baritone.INSTANCE.getGameEventHandler().onPlayerRotationMove(new RotationMoveEvent((EntityPlayerSP) _this, EventState.PRE, RotationMoveEvent.Type.JUMP));
+ private void preMoveRelative(CallbackInfo ci) {
+ // noinspection ConstantConditions
+ if (EntityPlayerSP.class.isInstance(this)) {
+ this.jumpRotationEvent = new RotationMoveEvent((EntityPlayerSP) (Object) this, RotationMoveEvent.Type.JUMP, this.rotationYaw);
+ Baritone.INSTANCE.getGameEventHandler().onPlayerRotationMove(this.jumpRotationEvent);
+ }
}
- @Inject(
+ @Redirect(
method = "jump",
- at = @At("RETURN")
+ at = @At(
+ value = "FIELD",
+ opcode = GETFIELD,
+ target = "net/minecraft/entity/EntityLivingBase.rotationYaw:F"
+ )
)
- private void postJump(CallbackInfo ci) {
- EntityLivingBase _this = (EntityLivingBase) (Object) this;
- // See above
- if (EntityPlayerSP.class.isInstance(_this))
- Baritone.INSTANCE.getGameEventHandler().onPlayerRotationMove(new RotationMoveEvent((EntityPlayerSP) _this, EventState.POST, RotationMoveEvent.Type.JUMP));
+ private float overrideYaw(EntityLivingBase self) {
+ if (self instanceof EntityPlayerSP) {
+ return this.jumpRotationEvent.getYaw();
+ }
+ return self.rotationYaw;
}
}
diff --git a/src/main/java/baritone/behavior/LookBehavior.java b/src/main/java/baritone/behavior/LookBehavior.java
index ac3a4698..ee8548a2 100644
--- a/src/main/java/baritone/behavior/LookBehavior.java
+++ b/src/main/java/baritone/behavior/LookBehavior.java
@@ -26,6 +26,7 @@ import baritone.api.utils.Rotation;
import baritone.utils.Helper;
public final class LookBehavior extends Behavior implements ILookBehavior, Helper {
+
/**
* Target's values are as follows:
*
@@ -63,7 +64,7 @@ public final class LookBehavior extends Behavior implements ILookBehavior, Helpe
}
// 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()) {
case PRE: {
@@ -76,14 +77,15 @@ public final class LookBehavior extends Behavior implements ILookBehavior, Helpe
nudgeToLevel();
}
this.target = null;
- } else if (silent) {
+ }
+ if (silent) {
this.lastYaw = player().rotationYaw;
player().rotationYaw = this.target.getYaw();
}
break;
}
case POST: {
- if (!this.force && silent) {
+ if (silent) {
player().rotationYaw = this.lastYaw;
this.target = null;
}
@@ -97,26 +99,20 @@ public final class LookBehavior extends Behavior implements ILookBehavior, Helpe
@Override
public void onPlayerRotationMove(RotationMoveEvent event) {
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()
- // 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) {
- this.target = null;
- }
- break;
- default:
- break;
+ event.setYaw(this.target.getYaw());
+
+ // If we have antiCheatCompatibility on, we're going to use the target value later in onPlayerUpdate()
+ // 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) {
+ this.target = null;
}
}
}
+ /**
+ * Nudges the player's pitch to a regular level. (Between {@code -20} and {@code 10}, increments are by {@code 1})
+ */
private void nudgeToLevel() {
if (player().rotationPitch < -20) {
player().rotationPitch++;
diff --git a/src/main/java/baritone/behavior/MineBehavior.java b/src/main/java/baritone/behavior/MineBehavior.java
index d76f0dc1..4d37f5ff 100644
--- a/src/main/java/baritone/behavior/MineBehavior.java
+++ b/src/main/java/baritone/behavior/MineBehavior.java
@@ -94,7 +94,7 @@ public final class MineBehavior extends Behavior implements IMineBehavior, Helpe
List 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
baritone.getPathingBehavior().setGoalAndPath(new GoalComposite(locs2.stream().map(loc -> coalesce(loc, locs2)).toArray(Goal[]::new)));
- knownOreLocations = locs;
+ knownOreLocations = locs2;
return;
}
// we don't know any ore locations at the moment
diff --git a/src/main/java/baritone/behavior/PathingBehavior.java b/src/main/java/baritone/behavior/PathingBehavior.java
index d8bf9a1d..7a3a16b7 100644
--- a/src/main/java/baritone/behavior/PathingBehavior.java
+++ b/src/main/java/baritone/behavior/PathingBehavior.java
@@ -406,13 +406,9 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
logDebug("no goal");
return Optional.empty();
}
- if (Baritone.settings().simplifyUnloadedYCoord.get()) {
- BlockPos pos = null;
- if (goal instanceof IGoalRenderPos) {
- pos = ((IGoalRenderPos) goal).getGoalPos();
- }
-
- if (pos != null && world().getChunk(pos) instanceof EmptyChunk) {
+ if (Baritone.settings().simplifyUnloadedYCoord.get() && goal instanceof IGoalRenderPos) {
+ BlockPos pos = ((IGoalRenderPos) goal).getGoalPos();
+ if (world().getChunk(pos) instanceof EmptyChunk) {
logDebug("Simplifying " + goal.getClass() + " to GoalXZ due to distance");
goal = new GoalXZ(pos.getX(), pos.getZ());
}
diff --git a/src/main/java/baritone/pathing/calc/AStarPathFinder.java b/src/main/java/baritone/pathing/calc/AStarPathFinder.java
index f9a15e36..83830ac0 100644
--- a/src/main/java/baritone/pathing/calc/AStarPathFinder.java
+++ b/src/main/java/baritone/pathing/calc/AStarPathFinder.java
@@ -131,7 +131,7 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
throw new IllegalStateException(moves + " " + res.x + " " + newX + " " + res.z + " " + newZ);
}
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);
if (favoring && favored.contains(hashCode)) {
diff --git a/src/main/java/baritone/pathing/movement/CalculationContext.java b/src/main/java/baritone/pathing/movement/CalculationContext.java
index 00c063af..ca6936a5 100644
--- a/src/main/java/baritone/pathing/movement/CalculationContext.java
+++ b/src/main/java/baritone/pathing/movement/CalculationContext.java
@@ -48,11 +48,7 @@ public class CalculationContext implements Helper {
private final BetterWorldBorder worldBorder;
public CalculationContext() {
- this(new ToolSet());
- }
-
- public CalculationContext(ToolSet toolSet) {
- this.toolSet = toolSet;
+ this.toolSet = new ToolSet();
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.canSprint = Baritone.settings().allowSprint.get() && player().getFoodStats().getFoodLevel() > 6;
diff --git a/src/main/java/baritone/pathing/movement/Movement.java b/src/main/java/baritone/pathing/movement/Movement.java
index a2edb2c9..aacd7f9f 100644
--- a/src/main/java/baritone/pathing/movement/Movement.java
+++ b/src/main/java/baritone/pathing/movement/Movement.java
@@ -116,7 +116,7 @@ public abstract class Movement implements IMovement, Helper, MovementHelper {
public MovementStatus update() {
player().capabilities.isFlying = false;
MovementState latestState = updateState(currentState);
- if (BlockStateInterface.isLiquid(playerFeet())) {
+ if (MovementHelper.isLiquid(playerFeet())) {
latestState.setInput(Input.JUMP, true);
}
if (player().isEntityInsideOpaqueBlock()) {
diff --git a/src/main/java/baritone/pathing/movement/MovementHelper.java b/src/main/java/baritone/pathing/movement/MovementHelper.java
index d887a714..0ea254b1 100644
--- a/src/main/java/baritone/pathing/movement/MovementHelper.java
+++ b/src/main/java/baritone/pathing/movement/MovementHelper.java
@@ -105,7 +105,7 @@ public interface MovementHelper extends ActionCosts, Helper {
}
throw new IllegalStateException();
}
- if (BlockStateInterface.isFlowing(state)) {
+ if (isFlowing(state)) {
return false; // Don't walk through flowing liquids
}
if (block instanceof BlockLiquid) {
@@ -254,9 +254,6 @@ public interface MovementHelper extends ActionCosts, Helper {
return false;
}
if (state.isBlockNormalCube()) {
- if (BlockStateInterface.isLava(block) || BlockStateInterface.isWater(block)) {
- throw new IllegalStateException();
- }
return true;
}
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) {
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()"
// 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();
if (up == Blocks.WATERLILY) {
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
- 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 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) {
return true;
@@ -444,4 +441,47 @@ public interface MovementHelper extends ActionCosts, Helper {
false
)).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;
+ }
}
diff --git a/src/main/java/baritone/pathing/movement/movements/MovementAscend.java b/src/main/java/baritone/pathing/movement/movements/MovementAscend.java
index e0d41047..cd0744e4 100644
--- a/src/main/java/baritone/pathing/movement/movements/MovementAscend.java
+++ b/src/main/java/baritone/pathing/movement/movements/MovementAscend.java
@@ -75,7 +75,7 @@ public class MovementAscend extends Movement {
if (!context.canPlaceThrowawayAt(destX, y, destZ)) {
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;
}
// TODO: add ability to place against .down() as well as the cardinal directions
diff --git a/src/main/java/baritone/pathing/movement/movements/MovementDescend.java b/src/main/java/baritone/pathing/movement/movements/MovementDescend.java
index 5fb78d74..a8874989 100644
--- a/src/main/java/baritone/pathing/movement/movements/MovementDescend.java
+++ b/src/main/java/baritone/pathing/movement/movements/MovementDescend.java
@@ -130,7 +130,7 @@ public class MovementDescend extends Movement {
}
IBlockState ontoBlock = BlockStateInterface.get(destX, newY, destZ);
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
// 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()) {
@@ -183,7 +183,7 @@ public class MovementDescend extends Movement {
}
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
return state.setStatus(MovementStatus.SUCCESS);
/* else {
diff --git a/src/main/java/baritone/pathing/movement/movements/MovementDiagonal.java b/src/main/java/baritone/pathing/movement/movements/MovementDiagonal.java
index 19f72fca..9848d671 100644
--- a/src/main/java/baritone/pathing/movement/movements/MovementDiagonal.java
+++ b/src/main/java/baritone/pathing/movement/movements/MovementDiagonal.java
@@ -78,11 +78,11 @@ public class MovementDiagonal extends Movement {
multiplier += (WALK_ONE_OVER_SOUL_SAND_COST - WALK_ONE_BLOCK_COST) / 2;
}
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;
}
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;
}
IBlockState pb0 = BlockStateInterface.get(x, y, destZ);
@@ -115,7 +115,7 @@ public class MovementDiagonal extends Movement {
return COST_INF;
}
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
// Whatever we were walking on (possibly soul sand) doesn't matter as we're actually floating on water
// Not even touching the blocks below
@@ -145,7 +145,7 @@ public class MovementDiagonal extends Movement {
state.setStatus(MovementStatus.SUCCESS);
return state;
}
- if (!BlockStateInterface.isLiquid(playerFeet())) {
+ if (!MovementHelper.isLiquid(playerFeet())) {
state.setInput(InputOverrideHandler.Input.SPRINT, true);
}
MovementHelper.moveTowards(state, dest);
diff --git a/src/main/java/baritone/pathing/movement/movements/MovementFall.java b/src/main/java/baritone/pathing/movement/movements/MovementFall.java
index f7d63f17..8f9feb41 100644
--- a/src/main/java/baritone/pathing/movement/movements/MovementFall.java
+++ b/src/main/java/baritone/pathing/movement/movements/MovementFall.java
@@ -25,7 +25,6 @@ import baritone.pathing.movement.Movement;
import baritone.pathing.movement.MovementHelper;
import baritone.pathing.movement.MovementState;
import baritone.pathing.movement.MovementState.MovementTarget;
-import baritone.utils.BlockStateInterface;
import baritone.utils.InputOverrideHandler;
import baritone.utils.pathing.MutableMoveResult;
import net.minecraft.entity.player.InventoryPlayer;
@@ -63,7 +62,7 @@ public class MovementFall extends Movement {
BlockPos playerFeet = playerFeet();
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()) {
return state.setStatus(MovementStatus.UNREACHABLE);
}
@@ -84,8 +83,8 @@ public class MovementFall extends Movement {
} else {
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 (BlockStateInterface.isWater(dest)) {
+ if (playerFeet.equals(dest) && (player().posY - playerFeet.getY() < 0.094 || MovementHelper.isWater(dest))) { // 0.094 because lilypads
+ if (MovementHelper.isWater(dest)) {
if (InventoryPlayer.isHotbar(player().inventory.getSlotFor(STACK_BUCKET_EMPTY))) {
player().inventory.currentItem = player().inventory.getSlotFor(STACK_BUCKET_EMPTY);
if (player().motionY >= 0) {
diff --git a/src/main/java/baritone/pathing/movement/movements/MovementParkour.java b/src/main/java/baritone/pathing/movement/movements/MovementParkour.java
index 825c99f4..68bddae0 100644
--- a/src/main/java/baritone/pathing/movement/movements/MovementParkour.java
+++ b/src/main/java/baritone/pathing/movement/movements/MovementParkour.java
@@ -93,7 +93,17 @@ public class MovementParkour extends Movement {
if (!MovementHelper.fullyPassable(x, y + 2, z)) {
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?
for (int y2 = 0; y2 < 4; y2++) {
if (!MovementHelper.fullyPassable(x + xDiff * i, y + y2, z + zDiff * i)) {
@@ -108,7 +118,7 @@ public class MovementParkour extends Movement {
return;
}
}
- if (!context.canSprint()) {
+ if (maxJump != 4) {
return;
}
if (!Baritone.settings().allowParkourPlace.get()) {
@@ -124,7 +134,7 @@ public class MovementParkour extends Movement {
if (!context.canPlaceThrowawayAt(destX, y - 1, destZ)) {
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;
}
for (int i = 0; i < 5; i++) {
diff --git a/src/main/java/baritone/pathing/movement/movements/MovementPillar.java b/src/main/java/baritone/pathing/movement/movements/MovementPillar.java
index c11df54a..d85a6b55 100644
--- a/src/main/java/baritone/pathing/movement/movements/MovementPillar.java
+++ b/src/main/java/baritone/pathing/movement/movements/MovementPillar.java
@@ -67,9 +67,9 @@ public class MovementPillar extends Movement {
return COST_INF;
}
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();
- if (BlockStateInterface.isWater(srcUp)) {
+ if (MovementHelper.isWater(srcUp)) {
return LADDER_UP_ONE_COST;
}
}
@@ -144,7 +144,7 @@ public class MovementPillar extends Movement {
}
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
state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(playerHead(), VecUtils.getBlockPosCenter(dest)), false));
Vec3d destCenter = VecUtils.getBlockPosCenter(dest);
@@ -240,7 +240,7 @@ public class MovementPillar extends Movement {
state.setInput(InputOverrideHandler.Input.SNEAK, true);
}
}
- if (BlockStateInterface.isWater(dest.up())) {
+ if (MovementHelper.isWater(dest.up())) {
return true;
}
return super.prepared(state);
diff --git a/src/main/java/baritone/pathing/movement/movements/MovementTraverse.java b/src/main/java/baritone/pathing/movement/movements/MovementTraverse.java
index 7f9c3902..1f56ffe4 100644
--- a/src/main/java/baritone/pathing/movement/movements/MovementTraverse.java
+++ b/src/main/java/baritone/pathing/movement/movements/MovementTraverse.java
@@ -66,7 +66,7 @@ public class MovementTraverse extends Movement {
if (MovementHelper.canWalkOn(destX, y - 1, destZ, destOn)) {//this is a walk, not a bridge
double WC = WALK_ONE_BLOCK_COST;
boolean water = false;
- if (BlockStateInterface.isWater(pb0.getBlock()) || BlockStateInterface.isWater(pb1.getBlock())) {
+ if (MovementHelper.isWater(pb0.getBlock()) || MovementHelper.isWater(pb1.getBlock())) {
WC = context.waterWalkSpeed();
water = true;
} else {
@@ -101,8 +101,8 @@ public class MovementTraverse extends Movement {
return COST_INF;
}
if (destOn.getBlock().equals(Blocks.AIR) || MovementHelper.isReplacable(destX, y - 1, destZ, destOn)) {
- boolean throughWater = BlockStateInterface.isWater(pb0.getBlock()) || BlockStateInterface.isWater(pb1.getBlock());
- if (BlockStateInterface.isWater(destOn.getBlock()) && throughWater) {
+ boolean throughWater = MovementHelper.isWater(pb0.getBlock()) || MovementHelper.isWater(pb1.getBlock());
+ if (MovementHelper.isWater(destOn.getBlock()) && throughWater) {
return COST_INF;
}
if (!context.canPlaceThrowawayAt(destX, y - 1, destZ)) {
@@ -223,7 +223,7 @@ public class MovementTraverse extends Movement {
if (playerFeet().equals(dest)) {
return state.setStatus(MovementStatus.SUCCESS);
}
- if (wasTheBridgeBlockAlwaysThere && !BlockStateInterface.isLiquid(playerFeet())) {
+ if (wasTheBridgeBlockAlwaysThere && !MovementHelper.isLiquid(playerFeet())) {
state.setInput(InputOverrideHandler.Input.SPRINT, true);
}
Block destDown = BlockStateInterface.get(dest.down()).getBlock();
diff --git a/src/main/java/baritone/utils/BlockStateInterface.java b/src/main/java/baritone/utils/BlockStateInterface.java
index 2c0384b2..7133fa12 100644
--- a/src/main/java/baritone/utils/BlockStateInterface.java
+++ b/src/main/java/baritone/utils/BlockStateInterface.java
@@ -22,7 +22,6 @@ import baritone.cache.CachedRegion;
import baritone.cache.WorldData;
import baritone.cache.WorldProvider;
import net.minecraft.block.Block;
-import net.minecraft.block.BlockLiquid;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
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) {
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;
- }
}
diff --git a/src/main/java/baritone/utils/ExampleBaritoneControl.java b/src/main/java/baritone/utils/ExampleBaritoneControl.java
index 02c48885..77dbcef5 100644
--- a/src/main/java/baritone/utils/ExampleBaritoneControl.java
+++ b/src/main/java/baritone/utils/ExampleBaritoneControl.java
@@ -46,6 +46,36 @@ import java.util.stream.Stream;
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 '', two is ' ', three is ' , '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) {
super(baritone);
}
@@ -85,6 +115,12 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
}
return true;
}
+ if (msg.equals("") || msg.equals("help") || msg.equals("?")) {
+ for (String line : HELP_MSG.split("\n")) {
+ logDirect(line);
+ }
+ return false;
+ }
if (msg.contains(" ")) {
String[] data = msg.split(" ");
if (data.length == 2) {
@@ -226,7 +262,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
}
pathingBehavior.setGoal(new GoalRunAway(1, runAwayFrom) {
@Override
- public boolean isInGoal(BlockPos pos) {
+ public boolean isInGoal(int x, int y, int z) {
return false;
}
});