misc movement cleanups
This commit is contained in:
parent
c635ba69fd
commit
e71783105c
@ -51,7 +51,7 @@ public class Settings {
|
||||
));
|
||||
public Setting<Boolean> renderGoal = new Setting<>(true);
|
||||
public Setting<Integer> pathingMaxChunkBorderFetch = new Setting<>(50);
|
||||
public Setting<Double> backtrackCostFavoringCoefficient = new Setting<>(0.9);
|
||||
public Setting<Double> backtrackCostFavoringCoefficient = new Setting<>(0.9); // see issue #18
|
||||
public Setting<Float> pathRenderLineWidth = new Setting<>(5F);
|
||||
public Setting<Float> goalRenderLineWidth = new Setting<>(3F);
|
||||
|
||||
|
@ -151,6 +151,7 @@ public class AStarPathFinder extends AbstractNodeCostSearch implements Helper {
|
||||
throw new IllegalStateException(movementToGetToNeighbor.getClass() + " " + movementToGetToNeighbor + " calculated implausible cost " + actionCost);
|
||||
}
|
||||
if (favoring && favored.contains(dest)) {
|
||||
// see issue #18
|
||||
actionCost *= favorCoeff;
|
||||
}
|
||||
PathNode neighbor = getNodeAtPosition(dest);
|
||||
|
@ -24,7 +24,7 @@ public interface ActionCosts extends ActionCostsButOnlyTheOnesThatMakeMickeyDieI
|
||||
*/
|
||||
double WALK_ONE_BLOCK_COST = 20 / 4.317; // 4.633
|
||||
double WALK_ONE_IN_WATER_COST = 20 / 2.2;
|
||||
double JUMP_ONE_BLOCK_COST = 5.72854;//see below calculation for fall. 1.25 blocks
|
||||
double WALK_ONE_OVER_SOUL_SAND_COST = WALK_ONE_IN_WATER_COST; // TODO issue #7
|
||||
double LADDER_UP_ONE_COST = 20 / 2.35;
|
||||
double LADDER_DOWN_ONE_COST = 20 / 3.0;
|
||||
double SNEAK_ONE_BLOCK_COST = 20 / 1.3;
|
||||
|
@ -20,6 +20,23 @@ package baritone.bot.pathing.movement;
|
||||
public interface ActionCostsButOnlyTheOnesThatMakeMickeyDieInside {
|
||||
double[] FALL_N_BLOCKS_COST = generateFallNBlocksCost();
|
||||
|
||||
double FALL_1_25_BLOCKS_COST = distanceToTicks(1.25);
|
||||
double FALL_0_25_BLOCKS_COST = distanceToTicks(0.25);
|
||||
/**
|
||||
* When you hit space, you get enough upward velocity to go 1.25 blocks
|
||||
* Then, you fall the remaining 0.25 to get on the surface, on block higher.
|
||||
* Since parabolas are symmetric, the amount of time it takes to ascend up from 1 to 1.25
|
||||
* will be the same amount of time that it takes to fall back down from 1.25 to 1.
|
||||
* And the same applies to the overall shape, if it takes X ticks to fall back down 1.25 blocks,
|
||||
* it will take X ticks to reach the peak of your 1.25 block leap.
|
||||
* Therefore, the part of your jump from y=0 to y=1.25 takes distanceToTicks(1.25) ticks,
|
||||
* and the sub-part from y=1 to y=1.25 takes distanceToTicks(0.25) ticks.
|
||||
* Therefore, the other sub-part, from y=0 to y-1, takes distanceToTicks(1.25)-distanceToTicks(0.25) ticks.
|
||||
* That's why JUMP_ONE_BLOCK_COST = FALL_1_25_BLOCKS_COST - FALL_0_25_BLOCKS_COST
|
||||
*/
|
||||
double JUMP_ONE_BLOCK_COST = FALL_1_25_BLOCKS_COST - FALL_0_25_BLOCKS_COST;
|
||||
|
||||
|
||||
static double[] generateFallNBlocksCost() {
|
||||
double[] costs = new double[257];
|
||||
for (int i = 0; i < 257; i++) {
|
||||
|
@ -43,8 +43,8 @@ import java.util.Optional;
|
||||
*/
|
||||
public interface MovementHelper extends ActionCosts, Helper {
|
||||
|
||||
static boolean avoidBreaking(BlockPos pos) {
|
||||
Block b = BlockStateInterface.getBlock(pos);
|
||||
static boolean avoidBreaking(BlockPos pos, IBlockState state) {
|
||||
Block b = state.getBlock();
|
||||
BlockPos below = new BlockPos(pos.getX(), pos.getY() - 1, pos.getZ());
|
||||
return Blocks.ICE.equals(b) // ice becomes water, and water can mess up the path
|
||||
|| b instanceof BlockSilverfish
|
||||
@ -63,8 +63,7 @@ public interface MovementHelper extends ActionCosts, Helper {
|
||||
* @return
|
||||
*/
|
||||
static boolean canWalkThrough(BlockPos pos) {
|
||||
IBlockState state = BlockStateInterface.get(pos);
|
||||
return canWalkThrough(pos, state);
|
||||
return canWalkThrough(pos, BlockStateInterface.get(pos));
|
||||
}
|
||||
|
||||
static boolean canWalkThrough(BlockPos pos, IBlockState state) {
|
||||
@ -126,21 +125,20 @@ public interface MovementHelper extends ActionCosts, Helper {
|
||||
|| block instanceof BlockCactus
|
||||
|| block instanceof BlockFire
|
||||
|| block instanceof BlockEndPortal
|
||||
|| block instanceof BlockWeb
|
||||
|| block instanceof BlockMagma;
|
||||
|| block instanceof BlockWeb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can I walk on this block without anything weird happening like me falling
|
||||
* through? Includes water because we know that we automatically jump on
|
||||
* lava
|
||||
* water
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
static boolean canWalkOn(BlockPos pos, IBlockState state) {
|
||||
|
||||
Block block = state.getBlock();
|
||||
if (block instanceof BlockLadder || block instanceof BlockVine) {
|
||||
if (block instanceof BlockLadder || block instanceof BlockVine) { // TODO reconsider this
|
||||
return true;
|
||||
}
|
||||
if (block instanceof BlockAir) {
|
||||
@ -149,15 +147,14 @@ public interface MovementHelper extends ActionCosts, Helper {
|
||||
if (BlockStateInterface.isWater(block)) {
|
||||
return BlockStateInterface.isWater(pos.up()); // You can only walk on water if there is water above it
|
||||
}
|
||||
if (block.equals(Blocks.MAGMA)) {
|
||||
if (Blocks.MAGMA.equals(block)) {
|
||||
return false;
|
||||
}
|
||||
return state.isBlockNormalCube() && !BlockStateInterface.isLava(block);
|
||||
}
|
||||
|
||||
static boolean canWalkOn(BlockPos pos) {
|
||||
IBlockState state = BlockStateInterface.get(pos);
|
||||
return canWalkOn(pos, state);
|
||||
return canWalkOn(pos, BlockStateInterface.get(pos));
|
||||
}
|
||||
|
||||
static boolean canFall(BlockPos pos) {
|
||||
@ -166,12 +163,16 @@ public interface MovementHelper extends ActionCosts, Helper {
|
||||
|
||||
static double getMiningDurationTicks(ToolSet ts, BlockPos position) {
|
||||
IBlockState state = BlockStateInterface.get(position);
|
||||
return getMiningDurationTicks(ts, position, state);
|
||||
}
|
||||
|
||||
static double getMiningDurationTicks(ToolSet ts, BlockPos position, IBlockState state) {
|
||||
Block block = state.getBlock();
|
||||
if (!block.equals(Blocks.AIR) && !canWalkThrough(position)) {
|
||||
if (!block.equals(Blocks.AIR) && !canWalkThrough(position, state)) {
|
||||
if (!Baritone.settings().allowBreak.get()) {
|
||||
return COST_INF;
|
||||
}
|
||||
if (avoidBreaking(position)) {
|
||||
if (avoidBreaking(position, state)) {
|
||||
return COST_INF;
|
||||
}
|
||||
double m = Blocks.CRAFTING_TABLE.equals(block) ? 10 : 1;
|
||||
|
@ -26,6 +26,7 @@ import baritone.bot.pathing.movement.MovementState.MovementStatus;
|
||||
import baritone.bot.utils.BlockStateInterface;
|
||||
import baritone.bot.utils.InputOverrideHandler;
|
||||
import baritone.bot.utils.Utils;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockFalling;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
@ -82,14 +83,29 @@ public class MovementAscend extends Movement {
|
||||
return COST_INF;
|
||||
}
|
||||
if (BlockStateInterface.get(src.up(3)).getBlock() instanceof BlockFalling) {//it would fall on us and possibly suffocate us
|
||||
return COST_INF;
|
||||
// HOWEVER, we assume that we're standing in the start position
|
||||
// that means that src and src.up(1) are both air
|
||||
// maybe they aren't now, but they will be by the time this starts
|
||||
Block srcUp = BlockStateInterface.get(src.up(1)).getBlock();
|
||||
Block srcUp2 = BlockStateInterface.get(src.up(2)).getBlock();
|
||||
if (!(srcUp instanceof BlockFalling) || !(srcUp2 instanceof BlockFalling)) {
|
||||
// if both of those are BlockFalling, that means that by standing on src
|
||||
// (the presupposition of this Movement)
|
||||
// we have necessarily already cleared the entire BlockFalling stack
|
||||
// on top of our head
|
||||
|
||||
// but if either of them aren't BlockFalling, that means we're still in suffocation danger
|
||||
// so don't do it
|
||||
return COST_INF;
|
||||
}
|
||||
}
|
||||
double halfWalk = WALK_ONE_BLOCK_COST / 2;
|
||||
// TODO maybe change behavior if src.down() is soul sand?
|
||||
double walk = WALK_ONE_BLOCK_COST;
|
||||
if (toPlace.getBlock().equals(Blocks.SOUL_SAND)) {
|
||||
halfWalk *= WALK_ONE_IN_WATER_COST / WALK_ONE_BLOCK_COST;
|
||||
walk *= WALK_ONE_OVER_SOUL_SAND_COST / WALK_ONE_BLOCK_COST;
|
||||
}
|
||||
// we walk half the block to get to the edge, then we walk the other half while simultaneously jumping (math.max because of how it's in parallel)
|
||||
return halfWalk + Math.max(JUMP_ONE_BLOCK_COST, halfWalk) + getTotalHardnessOfBlocksToBreak(context.getToolSet());
|
||||
// we hit space immediately on entering this action
|
||||
return Math.max(JUMP_ONE_BLOCK_COST, walk) + getTotalHardnessOfBlocksToBreak(context.getToolSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -48,7 +48,8 @@ public class MovementDescend extends Movement {
|
||||
// we walk half the block plus 0.3 to get to the edge, then we walk the other 0.2 while simultaneously falling (math.max because of how it's in parallel)
|
||||
double walk = WALK_OFF_BLOCK_COST;
|
||||
if (BlockStateInterface.get(src.down()).getBlock().equals(Blocks.SOUL_SAND)) {
|
||||
walk *= WALK_ONE_IN_WATER_COST / WALK_ONE_BLOCK_COST;
|
||||
// use this ratio to apply the soul sand speed penalty to our 0.8 block distance
|
||||
walk *= WALK_ONE_OVER_SOUL_SAND_COST / WALK_ONE_BLOCK_COST;
|
||||
}
|
||||
return walk + Math.max(FALL_N_BLOCKS_COST[1], CENTER_AFTER_FALL_COST) + getTotalHardnessOfBlocksToBreak(context.getToolSet());
|
||||
}
|
||||
|
@ -78,11 +78,15 @@ public class MovementDiagonal extends Movement {
|
||||
return COST_INF;
|
||||
}
|
||||
double multiplier = WALK_ONE_BLOCK_COST;
|
||||
|
||||
// for either possible soul sand, that affects half of our walking
|
||||
if (destWalkOn.getBlock().equals(Blocks.SOUL_SAND)) {
|
||||
multiplier *= WALK_ONE_IN_WATER_COST / WALK_ONE_BLOCK_COST;
|
||||
} else if (BlockStateInterface.get(src.down()).getBlock().equals(Blocks.SOUL_SAND)) {
|
||||
multiplier *= WALK_ONE_IN_WATER_COST / WALK_ONE_BLOCK_COST;
|
||||
multiplier += (WALK_ONE_OVER_SOUL_SAND_COST - WALK_ONE_BLOCK_COST) / 2;
|
||||
}
|
||||
if (BlockStateInterface.get(src.down()).getBlock().equals(Blocks.SOUL_SAND)) {
|
||||
multiplier += (WALK_ONE_OVER_SOUL_SAND_COST - WALK_ONE_BLOCK_COST) / 2;
|
||||
}
|
||||
|
||||
if (BlockStateInterface.get(positionsToBreak[2].down()).getBlock() instanceof BlockMagma) {
|
||||
return COST_INF;
|
||||
}
|
||||
@ -110,12 +114,15 @@ public class MovementDiagonal extends Movement {
|
||||
return COST_INF;
|
||||
}
|
||||
}
|
||||
if (BlockStateInterface.isWater(src) || BlockStateInterface.isWater(dest)) {
|
||||
// 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
|
||||
multiplier = WALK_ONE_IN_WATER_COST;
|
||||
}
|
||||
if (optionA != 0 || optionB != 0) {
|
||||
multiplier *= SQRT_2 - 0.001; // TODO tune
|
||||
}
|
||||
if (BlockStateInterface.isWater(src) || BlockStateInterface.isWater(dest)) {
|
||||
multiplier *= WALK_ONE_IN_WATER_COST / WALK_ONE_BLOCK_COST;
|
||||
}
|
||||
if (multiplier == WALK_ONE_BLOCK_COST && context.canSprint()) {
|
||||
// if we aren't edging around anything, and we aren't in water or soul sand
|
||||
// we can sprint =D
|
||||
|
@ -25,6 +25,7 @@ import baritone.bot.utils.BlockStateInterface;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockLadder;
|
||||
import net.minecraft.block.BlockVine;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
public class MovementDownward extends Movement {
|
||||
@ -40,12 +41,13 @@ public class MovementDownward extends Movement {
|
||||
if (!MovementHelper.canWalkOn(dest.down())) {
|
||||
return COST_INF;
|
||||
}
|
||||
Block td = BlockStateInterface.get(dest).getBlock();
|
||||
IBlockState d = BlockStateInterface.get(dest);
|
||||
Block td = d.getBlock();
|
||||
boolean ladder = td instanceof BlockLadder || td instanceof BlockVine;
|
||||
if (ladder) {
|
||||
return LADDER_DOWN_ONE_COST;
|
||||
} else {
|
||||
return FALL_N_BLOCKS_COST[1] + getTotalHardnessOfBlocksToBreak(context.getToolSet());
|
||||
return FALL_N_BLOCKS_COST[1] + MovementHelper.getMiningDurationTicks(context.getToolSet(), dest, d);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -49,6 +49,9 @@ public class MovementFall extends Movement {
|
||||
}
|
||||
double placeBucketCost = 0.0;
|
||||
if (!BlockStateInterface.isWater(dest) && src.getY() - dest.getY() > 3) {
|
||||
if (!context.hasWaterBucket()) {
|
||||
return COST_INF;
|
||||
}
|
||||
placeBucketCost = ActionCosts.PLACE_ONE_BLOCK_COST;
|
||||
}
|
||||
double frontTwo = MovementHelper.getMiningDurationTicks(context.getToolSet(), positionsToBreak[0]) + MovementHelper.getMiningDurationTicks(context.getToolSet(), positionsToBreak[1]);
|
||||
@ -56,6 +59,11 @@ public class MovementFall extends Movement {
|
||||
return COST_INF;
|
||||
}
|
||||
for (int i = 2; i < positionsToBreak.length; i++) {
|
||||
// TODO is this the right check here?
|
||||
// miningDurationTicks is all right, but shouldn't it be canWalkThrough instead?
|
||||
// lilypads (i think?) are 0 ticks to mine, but they definitely cause fall damage
|
||||
// same thing for falling through water... we can't actually do that
|
||||
// and falling through signs is possible, but they do have a mining duration, right?
|
||||
if (MovementHelper.getMiningDurationTicks(context.getToolSet(), positionsToBreak[i]) > 0) {
|
||||
//can't break while falling
|
||||
return COST_INF;
|
||||
|
@ -72,9 +72,16 @@ public class MovementTraverse extends Movement {
|
||||
IBlockState pb1 = BlockStateInterface.get(positionsToBreak[1]);
|
||||
IBlockState destOn = BlockStateInterface.get(positionsToPlace[0]);
|
||||
if (MovementHelper.canWalkOn(positionsToPlace[0], destOn)) {//this is a walk, not a bridge
|
||||
double WC = BlockStateInterface.isWater(pb0.getBlock()) || BlockStateInterface.isWater(pb1.getBlock()) ? WALK_ONE_IN_WATER_COST : WALK_ONE_BLOCK_COST;
|
||||
if (destOn.getBlock().equals(Blocks.SOUL_SAND)) {
|
||||
WC *= WALK_ONE_IN_WATER_COST / WALK_ONE_BLOCK_COST;
|
||||
double WC = WALK_ONE_BLOCK_COST;
|
||||
if (BlockStateInterface.isWater(pb0.getBlock()) || BlockStateInterface.isWater(pb1.getBlock())) {
|
||||
WC = WALK_ONE_IN_WATER_COST;
|
||||
} else {
|
||||
if (Blocks.SOUL_SAND.equals(destOn.getBlock())) {
|
||||
WC += (WALK_ONE_OVER_SOUL_SAND_COST - WALK_ONE_BLOCK_COST) / 2;
|
||||
}
|
||||
if (Blocks.SOUL_SAND.equals(BlockStateInterface.get(src.down()).getBlock())) {
|
||||
WC += (WALK_ONE_OVER_SOUL_SAND_COST - WALK_ONE_BLOCK_COST) / 2;
|
||||
}
|
||||
}
|
||||
if (MovementHelper.canWalkThrough(positionsToBreak[0]) && MovementHelper.canWalkThrough(positionsToBreak[1])) {
|
||||
if (WC == WALK_ONE_BLOCK_COST && context.canSprint()) {
|
||||
@ -89,9 +96,8 @@ public class MovementTraverse extends Movement {
|
||||
//Out.log("Can't walk through " + blocksToBreak[0] + " (hardness" + hardness1 + ") or " + blocksToBreak[1] + " (hardness " + hardness2 + ")");
|
||||
return WC + getTotalHardnessOfBlocksToBreak(context.getToolSet());
|
||||
} else {//this is a bridge, so we need to place a block
|
||||
//return 1000000;
|
||||
Block f = BlockStateInterface.get(src.down()).getBlock();
|
||||
if (f instanceof BlockLadder || f instanceof BlockVine) {
|
||||
Block srcDown = BlockStateInterface.get(src.down()).getBlock();
|
||||
if (srcDown instanceof BlockLadder || srcDown instanceof BlockVine) {
|
||||
return COST_INF;
|
||||
}
|
||||
IBlockState pp0 = BlockStateInterface.get(positionsToPlace[0]);
|
||||
|
@ -151,7 +151,12 @@ public final class InputOverrideHandler implements Helper {
|
||||
/**
|
||||
* The sneak input
|
||||
*/
|
||||
SNEAK(mc.gameSettings.keyBindSneak);
|
||||
SNEAK(mc.gameSettings.keyBindSneak),
|
||||
|
||||
/**
|
||||
* The sprint input
|
||||
*/
|
||||
SPRINT(mc.gameSettings.keyBindSprint);
|
||||
|
||||
/**
|
||||
* The actual game {@link KeyBinding} being forced.
|
||||
|
@ -19,8 +19,7 @@ package baritone.bot.pathing.movement;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static baritone.bot.pathing.movement.ActionCostsButOnlyTheOnesThatMakeMickeyDieInside.FALL_N_BLOCKS_COST;
|
||||
import static baritone.bot.pathing.movement.ActionCostsButOnlyTheOnesThatMakeMickeyDieInside.velocity;
|
||||
import static baritone.bot.pathing.movement.ActionCostsButOnlyTheOnesThatMakeMickeyDieInside.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class ActionCostsButOnlyTheOnesThatMakeMickeyDieInsideTest {
|
||||
@ -31,6 +30,9 @@ public class ActionCostsButOnlyTheOnesThatMakeMickeyDieInsideTest {
|
||||
double blocks = ticksToBlocks(FALL_N_BLOCKS_COST[i]);
|
||||
assertEquals(blocks, i, 0.000000000001); // If you add another 0 the test fails at i=217 LOL
|
||||
}
|
||||
assertEquals(FALL_1_25_BLOCKS_COST, 6.2344, 0.00001);
|
||||
assertEquals(FALL_0_25_BLOCKS_COST, 3.0710, 0.00001);
|
||||
assertEquals(JUMP_ONE_BLOCK_COST, 3.1634, 0.00001);
|
||||
}
|
||||
|
||||
public double ticksToBlocks(double ticks) {
|
||||
|
Loading…
Reference in New Issue
Block a user