forked from RepoMirrors/baritone
parkour
This commit is contained in:
parent
db3aa5a714
commit
63b04df95d
@ -9,6 +9,7 @@
|
||||
- **Slabs and stairs**
|
||||
- **Falling blocks** Baritone understands the costs of breaking blocks with falling blocks on top, and includes all of their break costs. Additionally, since it avoids breaking any blocks touching a liquid, it won't break the bottom of a gravel stack below a lava lake (anymore).
|
||||
- **Avoiding dangerous blocks** Obviously, it knows not to walk through fire or on magma, not to corner over lava (that deals some damage), not to break any blocks touching a liquid (it might drown), etc.
|
||||
- **Parkour** Sprint jumping over 1, 2, or 3 block gaps
|
||||
|
||||
# Pathing method
|
||||
Baritone uses a modified version of A*.
|
||||
@ -41,8 +42,7 @@ Things it doesn't have yet
|
||||
See <a href="https://github.com/cabaletta/baritone/issues">issues</a> for more.
|
||||
|
||||
Things it may not ever have, from most likely to least likely =(
|
||||
- Parkour (jumping over gaps of any length)
|
||||
- Boats
|
||||
- Pigs
|
||||
- Boats
|
||||
- Horses (2x3 path instead of 1x2)
|
||||
- Elytra
|
||||
|
@ -83,6 +83,11 @@ public class Settings {
|
||||
*/
|
||||
public Setting<Boolean> allowWalkOnBottomSlab = new Setting<>(true);
|
||||
|
||||
/**
|
||||
* You know what it is
|
||||
*/
|
||||
public Setting<Boolean> allowParkour = new Setting<>(true); // disable in release because its sketchy af lol
|
||||
|
||||
/**
|
||||
* For example, if you have Mining Fatigue or Haste, adjust the costs of breaking blocks accordingly.
|
||||
*/
|
||||
|
@ -233,7 +233,11 @@ public class AStarPathFinder extends AbstractNodeCostSearch implements Helper {
|
||||
new MovementDiagonal(pos, EnumFacing.NORTH, EnumFacing.EAST),
|
||||
new MovementDiagonal(pos, EnumFacing.SOUTH, EnumFacing.WEST),
|
||||
new MovementDiagonal(pos, EnumFacing.SOUTH, EnumFacing.EAST),
|
||||
new MovementPillar(pos, new BetterBlockPos(x, y + 1, z))
|
||||
new MovementPillar(pos, new BetterBlockPos(x, y + 1, z)),
|
||||
MovementParkour.calculate(pos, EnumFacing.NORTH),
|
||||
MovementParkour.calculate(pos, EnumFacing.SOUTH),
|
||||
MovementParkour.calculate(pos, EnumFacing.EAST),
|
||||
MovementParkour.calculate(pos, EnumFacing.WEST),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -84,6 +84,10 @@ public abstract class Movement implements Helper, MovementHelper {
|
||||
return getCost(null);
|
||||
}
|
||||
|
||||
protected void override(double cost) {
|
||||
this.cost = cost;
|
||||
}
|
||||
|
||||
public double calculateCostWithoutCaching() {
|
||||
return calculateCost(new CalculationContext());
|
||||
}
|
||||
|
@ -70,6 +70,9 @@ public interface MovementHelper extends ActionCosts, Helper {
|
||||
|
||||
static boolean canWalkThrough(BlockPos pos, IBlockState state) {
|
||||
Block block = state.getBlock();
|
||||
if (block == Blocks.AIR) {
|
||||
return true;
|
||||
}
|
||||
if (block instanceof BlockFire
|
||||
|| block instanceof BlockTripWire
|
||||
|| block instanceof BlockWeb
|
||||
@ -106,6 +109,37 @@ public interface MovementHelper extends ActionCosts, Helper {
|
||||
return block.isPassable(mc.world, pos);
|
||||
}
|
||||
|
||||
/**
|
||||
* canWalkThrough but also won't impede movement at all. so not including doors or fence gates (we'd have to right click),
|
||||
* not including water, and not including ladders or vines or cobwebs (they slow us down)
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
static boolean fullyPassable(BlockPos pos) {
|
||||
return fullyPassable(pos, BlockStateInterface.get(pos));
|
||||
}
|
||||
|
||||
static boolean fullyPassable(BlockPos pos, IBlockState state) {
|
||||
Block block = state.getBlock();
|
||||
if (block == Blocks.AIR) {
|
||||
return true;
|
||||
}
|
||||
if (block == Blocks.FIRE
|
||||
|| block == Blocks.TRIPWIRE
|
||||
|| block == Blocks.WEB
|
||||
|| block == Blocks.VINE
|
||||
|| block == Blocks.LADDER
|
||||
|| block instanceof BlockDoor
|
||||
|| block instanceof BlockFenceGate
|
||||
|| block instanceof BlockSnow
|
||||
|| block instanceof BlockLiquid
|
||||
|| block instanceof BlockTrapDoor
|
||||
|| block instanceof BlockEndPortal) {
|
||||
return false;
|
||||
}
|
||||
return block.isPassable(mc.world, pos);
|
||||
}
|
||||
|
||||
static boolean isReplacable(BlockPos pos, IBlockState state) {
|
||||
// for MovementTraverse and MovementAscend
|
||||
// block double plant defaults to true when the block doesn't match, so don't need to check that case
|
||||
|
@ -0,0 +1,151 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.pathing.movement.movements;
|
||||
|
||||
import baritone.Baritone;
|
||||
import baritone.pathing.movement.CalculationContext;
|
||||
import baritone.pathing.movement.Movement;
|
||||
import baritone.pathing.movement.MovementHelper;
|
||||
import baritone.pathing.movement.MovementState;
|
||||
import baritone.utils.BlockStateInterface;
|
||||
import baritone.utils.InputOverrideHandler;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
public class MovementParkour extends Movement {
|
||||
|
||||
final EnumFacing direction;
|
||||
final int dist;
|
||||
|
||||
private MovementParkour(BlockPos src, int dist, EnumFacing dir) {
|
||||
super(src, src.offset(dir, dist), new BlockPos[]{});
|
||||
this.direction = dir;
|
||||
this.dist = dist;
|
||||
super.override(costFromJumpDistance(dist));
|
||||
}
|
||||
|
||||
public static MovementParkour calculate(BlockPos src, EnumFacing dir) {
|
||||
if (!Baritone.settings().allowParkour.get()) {
|
||||
return null;
|
||||
}
|
||||
IBlockState standingOn = BlockStateInterface.get(src.down());
|
||||
if (standingOn.getBlock() == Blocks.VINE || standingOn.getBlock() == Blocks.LADDER || MovementHelper.isBottomSlab(standingOn)) {
|
||||
return null;
|
||||
}
|
||||
BlockPos adjBlock = src.down().offset(dir);
|
||||
IBlockState adj = BlockStateInterface.get(adjBlock);
|
||||
if (MovementHelper.avoidWalkingInto(adj.getBlock())) { // magma sucks
|
||||
return null;
|
||||
}
|
||||
if (MovementHelper.canWalkOn(adjBlock, adj)) { // don't parkour if we could just traverse (for now)
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!MovementHelper.fullyPassable(src.offset(dir))) {
|
||||
return null;
|
||||
}
|
||||
if (!MovementHelper.fullyPassable(src.up().offset(dir))) {
|
||||
return null;
|
||||
}
|
||||
for (int i = 2; i <= 4; i++) {
|
||||
BlockPos dest = src.offset(dir, i);
|
||||
if (!MovementHelper.fullyPassable(dest)) {
|
||||
return null;
|
||||
}
|
||||
if (!MovementHelper.fullyPassable(dest.up())) {
|
||||
return null;
|
||||
}
|
||||
if (MovementHelper.canWalkOn(dest.down())) {
|
||||
return new MovementParkour(src, i, dir);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static double costFromJumpDistance(int dist) {
|
||||
switch (dist) {
|
||||
case 2:
|
||||
return WALK_ONE_BLOCK_COST * 2; // IDK LOL
|
||||
case 3:
|
||||
return WALK_ONE_BLOCK_COST * 3;
|
||||
case 4:
|
||||
return SPRINT_ONE_BLOCK_COST * 3;
|
||||
}
|
||||
throw new IllegalStateException("LOL");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected double calculateCost(CalculationContext context) {
|
||||
if (!MovementHelper.canWalkOn(dest.down())) {
|
||||
return COST_INF;
|
||||
}
|
||||
if (MovementHelper.avoidWalkingInto(BlockStateInterface.get(src.down().offset(direction)).getBlock())) {
|
||||
return COST_INF;
|
||||
}
|
||||
for (int i = 1; i <= 4; i++) {
|
||||
BlockPos d = src.offset(direction, i);
|
||||
if (!MovementHelper.fullyPassable(d)) {
|
||||
return COST_INF;
|
||||
}
|
||||
if (!MovementHelper.fullyPassable(d.up())) {
|
||||
return COST_INF;
|
||||
}
|
||||
if (d.equals(dest)) {
|
||||
return costFromJumpDistance(i);
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("invalid jump distance?");
|
||||
}
|
||||
|
||||
@Override
|
||||
public MovementState updateState(MovementState state) {
|
||||
super.updateState(state);
|
||||
switch (state.getStatus()) {
|
||||
case WAITING:
|
||||
state.setStatus(MovementState.MovementStatus.RUNNING);
|
||||
case RUNNING:
|
||||
break;
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
if (dist >= 4) {
|
||||
state.setInput(InputOverrideHandler.Input.SPRINT, true);
|
||||
}
|
||||
MovementHelper.moveTowards(state, dest);
|
||||
if (playerFeet().equals(dest)) {
|
||||
if (player().posY - playerFeet().getY() < 0.01) {
|
||||
state.setStatus(MovementState.MovementStatus.SUCCESS);
|
||||
}
|
||||
} else if (!playerFeet().equals(src)) {
|
||||
if (playerFeet().equals(src.offset(direction)) || player().posY - playerFeet().getY() > 0.0001) {
|
||||
state.setInput(InputOverrideHandler.Input.JUMP, true);
|
||||
} else {
|
||||
state.setInput(InputOverrideHandler.Input.SPRINT, false);
|
||||
if (playerFeet().equals(src.offset(direction, -1))) {
|
||||
MovementHelper.moveTowards(state, src);
|
||||
} else {
|
||||
MovementHelper.moveTowards(state, src.offset(direction, -1));
|
||||
}
|
||||
}
|
||||
}
|
||||
return state;
|
||||
}
|
||||
}
|
@ -119,4 +119,10 @@ public final class BetterBlockPos extends BlockPos {
|
||||
Vec3i vec = dir.getDirectionVec();
|
||||
return new BetterBlockPos(x + vec.getX(), y + vec.getY(), z + vec.getZ());
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos offset(EnumFacing dir, int dist) {
|
||||
Vec3i vec = dir.getDirectionVec();
|
||||
return new BetterBlockPos(x + vec.getX() * dist, y + vec.getY() * dist, z + vec.getZ() * dist);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user