2018-08-08 03:16:53 +00:00
/ *
* This file is part of Baritone .
*
* Baritone is free software : you can redistribute it and / or modify
2018-09-17 22:11:40 +00:00
* it under the terms of the GNU Lesser General Public License as published by
2018-08-08 03:16:53 +00:00
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
2018-08-08 04:15:22 +00:00
* Baritone is distributed in the hope that it will be useful ,
2018-08-08 03:16:53 +00:00
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
2018-09-17 22:11:40 +00:00
* GNU Lesser General Public License for more details .
2018-08-08 03:16:53 +00:00
*
2018-09-17 22:11:40 +00:00
* You should have received a copy of the GNU Lesser General Public License
2018-08-08 03:16:53 +00:00
* along with Baritone . If not , see < https : //www.gnu.org/licenses/>.
* /
2018-08-22 20:15:56 +00:00
package baritone.pathing.movement.movements ;
2018-08-06 01:17:04 +00:00
2018-09-12 03:50:29 +00:00
import baritone.Baritone ;
2018-09-12 22:58:33 +00:00
import baritone.behavior.LookBehaviorUtils ;
2018-08-22 20:15:56 +00:00
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 ;
2018-09-14 23:45:51 +00:00
import baritone.utils.Rotation ;
2018-08-22 20:15:56 +00:00
import baritone.utils.Utils ;
2018-09-09 16:22:35 +00:00
import baritone.utils.pathing.BetterBlockPos ;
2018-08-26 07:17:52 +00:00
import net.minecraft.block.* ;
2018-08-06 01:17:04 +00:00
import net.minecraft.block.state.IBlockState ;
import net.minecraft.client.Minecraft ;
import net.minecraft.init.Blocks ;
2018-08-06 22:53:35 +00:00
import net.minecraft.util.EnumFacing ;
2018-08-06 01:17:04 +00:00
import net.minecraft.util.math.BlockPos ;
2018-08-06 22:53:35 +00:00
import net.minecraft.util.math.Vec3d ;
import java.util.Objects ;
2018-08-06 01:17:04 +00:00
public class MovementTraverse extends Movement {
2018-08-07 21:14:36 +00:00
/ * *
* Did we have to place a bridge block or was it always there
* /
private boolean wasTheBridgeBlockAlwaysThere = true ;
2018-08-06 01:17:04 +00:00
2018-09-09 16:22:35 +00:00
public MovementTraverse ( BetterBlockPos from , BetterBlockPos to ) {
2018-08-28 20:41:44 +00:00
super ( from , to , new BlockPos [ ] { to . up ( ) , to } , to . down ( ) ) ;
2018-08-06 01:17:04 +00:00
}
2018-08-23 18:14:37 +00:00
@Override
public void reset ( ) {
super . reset ( ) ;
wasTheBridgeBlockAlwaysThere = true ;
}
2018-08-06 01:17:04 +00:00
@Override
2018-08-07 21:36:32 +00:00
protected double calculateCost ( CalculationContext context ) {
2018-08-06 01:17:04 +00:00
IBlockState pb0 = BlockStateInterface . get ( positionsToBreak [ 0 ] ) ;
IBlockState pb1 = BlockStateInterface . get ( positionsToBreak [ 1 ] ) ;
2018-08-28 20:41:44 +00:00
IBlockState destOn = BlockStateInterface . get ( positionToPlace ) ;
2018-09-04 23:19:10 +00:00
Block srcDown = BlockStateInterface . getBlock ( src . down ( ) ) ;
2018-08-28 20:41:44 +00:00
if ( MovementHelper . canWalkOn ( positionToPlace , destOn ) ) { //this is a walk, not a bridge
2018-08-17 19:24:40 +00:00
double WC = WALK_ONE_BLOCK_COST ;
if ( BlockStateInterface . isWater ( pb0 . getBlock ( ) ) | | BlockStateInterface . isWater ( pb1 . getBlock ( ) ) ) {
WC = WALK_ONE_IN_WATER_COST ;
} else {
2018-09-04 23:19:10 +00:00
if ( destOn . getBlock ( ) = = Blocks . SOUL_SAND ) {
2018-08-17 19:24:40 +00:00
WC + = ( WALK_ONE_OVER_SOUL_SAND_COST - WALK_ONE_BLOCK_COST ) / 2 ;
}
2018-09-04 23:19:10 +00:00
if ( srcDown = = Blocks . SOUL_SAND ) {
2018-08-17 19:24:40 +00:00
WC + = ( WALK_ONE_OVER_SOUL_SAND_COST - WALK_ONE_BLOCK_COST ) / 2 ;
}
2018-08-13 14:05:28 +00:00
}
2018-08-28 19:39:58 +00:00
double hardness1 = MovementHelper . getMiningDurationTicks ( context , positionsToBreak [ 0 ] , pb0 , true ) ;
if ( hardness1 > = COST_INF ) {
return COST_INF ;
}
double hardness2 = MovementHelper . getMiningDurationTicks ( context , positionsToBreak [ 1 ] , pb1 , false ) ;
if ( hardness1 = = 0 & & hardness2 = = 0 ) {
2018-08-17 17:52:58 +00:00
if ( WC = = WALK_ONE_BLOCK_COST & & context . canSprint ( ) ) {
2018-08-25 23:30:12 +00:00
// If there's nothing in the way, and this isn't water or soul sand, and we aren't sneak placing
// We can sprint =D
2018-08-13 20:40:50 +00:00
WC = SPRINT_ONE_BLOCK_COST ;
}
2018-08-06 01:17:04 +00:00
return WC ;
}
2018-09-04 23:19:10 +00:00
if ( srcDown = = Blocks . LADDER | | srcDown = = Blocks . VINE ) {
hardness1 * = 5 ;
hardness2 * = 5 ;
}
2018-08-28 19:39:58 +00:00
return WC + hardness1 + hardness2 ;
2018-08-06 01:17:04 +00:00
} else { //this is a bridge, so we need to place a block
2018-09-03 16:15:18 +00:00
if ( srcDown = = Blocks . LADDER | | srcDown = = Blocks . VINE ) {
2018-08-06 01:17:04 +00:00
return COST_INF ;
}
2018-08-28 20:41:44 +00:00
if ( destOn . getBlock ( ) . equals ( Blocks . AIR ) | | MovementHelper . isReplacable ( positionToPlace , destOn ) ) {
2018-08-28 19:53:01 +00:00
boolean throughWater = BlockStateInterface . isWater ( pb0 . getBlock ( ) ) | | BlockStateInterface . isWater ( pb1 . getBlock ( ) ) ;
if ( BlockStateInterface . isWater ( destOn . getBlock ( ) ) & & throughWater ) {
return COST_INF ;
}
2018-08-11 22:03:14 +00:00
if ( ! context . hasThrowaway ( ) ) {
return COST_INF ;
}
2018-08-28 19:53:01 +00:00
double WC = throughWater ? WALK_ONE_IN_WATER_COST : WALK_ONE_BLOCK_COST ;
2018-08-28 21:56:21 +00:00
for ( int i = 0 ; i < 4 ; i + + ) {
BlockPos against1 = dest . offset ( HORIZONTALS [ i ] ) ;
if ( against1 . equals ( src ) ) {
continue ;
}
against1 = against1 . down ( ) ;
2018-08-28 22:01:24 +00:00
if ( MovementHelper . canPlaceAgainst ( against1 ) ) {
2018-08-17 20:17:16 +00:00
return WC + context . placeBlockCost ( ) + getTotalHardnessOfBlocksToBreak ( context ) ;
2018-08-06 01:17:04 +00:00
}
}
2018-09-03 16:15:18 +00:00
if ( srcDown = = Blocks . SOUL_SAND | | ( srcDown instanceof BlockSlab & & ! ( ( BlockSlab ) srcDown ) . isDouble ( ) ) ) {
return COST_INF ; // can't sneak and backplace against soul sand or half slabs =/
2018-08-13 14:07:42 +00:00
}
2018-09-12 02:05:45 +00:00
if ( srcDown = = Blocks . FLOWING_WATER | | srcDown = = Blocks . WATER ) {
return COST_INF ; // this is obviously impossible
}
2018-08-06 01:17:04 +00:00
WC = WC * SNEAK_ONE_BLOCK_COST / WALK_ONE_BLOCK_COST ; //since we are placing, we are sneaking
2018-08-17 20:17:16 +00:00
return WC + context . placeBlockCost ( ) + getTotalHardnessOfBlocksToBreak ( context ) ;
2018-08-06 01:17:04 +00:00
}
return COST_INF ;
2018-08-25 23:30:12 +00:00
// Out.log("Can't walk on " + Baritone.get(positionsToPlace[0]).getBlock());
2018-08-06 01:17:04 +00:00
}
}
@Override
public MovementState updateState ( MovementState state ) {
super . updateState ( state ) ;
2018-09-08 04:32:25 +00:00
if ( state . getStatus ( ) ! = MovementState . MovementStatus . RUNNING ) {
2018-09-14 23:45:51 +00:00
// if the setting is enabled
if ( ! Baritone . settings ( ) . walkWhileBreaking . get ( ) ) {
return state ;
}
// and if we're prepping (aka mining the block in front)
if ( state . getStatus ( ) ! = MovementState . MovementStatus . PREPPING ) {
return state ;
}
// and if it's fine to walk into the blocks in front
if ( MovementHelper . avoidWalkingInto ( BlockStateInterface . get ( positionsToBreak [ 0 ] ) . getBlock ( ) ) ) {
return state ;
}
if ( MovementHelper . avoidWalkingInto ( BlockStateInterface . get ( positionsToBreak [ 1 ] ) . getBlock ( ) ) ) {
return state ;
}
// and we aren't already pressed up against the block
double dist = Math . max ( Math . abs ( player ( ) . posX - ( dest . getX ( ) + 0 . 5D ) ) , Math . abs ( player ( ) . posZ - ( dest . getZ ( ) + 0 . 5D ) ) ) ;
if ( dist < 0 . 83 ) {
return state ;
}
// combine the yaw to the center of the destination, and the pitch to the specific block we're trying to break
// it's safe to do this since the two blocks we break (in a traverse) are right on top of each other and so will have the same yaw
float yawToDest = Utils . calcRotationFromVec3d ( playerHead ( ) , Utils . calcCenterFromCoords ( dest , world ( ) ) ) . getFirst ( ) ;
float pitchToBreak = state . getTarget ( ) . getRotation ( ) . get ( ) . getSecond ( ) ;
state . setTarget ( new MovementState . MovementTarget ( new Rotation ( yawToDest , pitchToBreak ) , true ) ) ;
return state . setInput ( InputOverrideHandler . Input . MOVE_FORWARD , true ) ;
2018-09-08 04:32:25 +00:00
}
2018-09-14 23:45:51 +00:00
//sneak may have been set to true in the PREPPING state while mining an adjacent block
2018-09-04 23:19:10 +00:00
state . setInput ( InputOverrideHandler . Input . SNEAK , false ) ;
2018-08-06 22:53:35 +00:00
Block fd = BlockStateInterface . get ( src . down ( ) ) . getBlock ( ) ;
boolean ladder = fd instanceof BlockLadder | | fd instanceof BlockVine ;
2018-08-15 06:49:08 +00:00
IBlockState pb0 = BlockStateInterface . get ( positionsToBreak [ 0 ] ) ;
IBlockState pb1 = BlockStateInterface . get ( positionsToBreak [ 1 ] ) ;
2018-08-26 07:17:52 +00:00
boolean door = pb0 . getBlock ( ) instanceof BlockDoor | | pb1 . getBlock ( ) instanceof BlockDoor ;
2018-08-15 06:49:08 +00:00
if ( door ) {
boolean isDoorActuallyBlockingUs = false ;
2018-08-26 07:17:52 +00:00
if ( pb0 . getBlock ( ) instanceof BlockDoor & & ! MovementHelper . isDoorPassable ( src , dest ) ) {
2018-08-15 06:49:08 +00:00
isDoorActuallyBlockingUs = true ;
} else if ( pb1 . getBlock ( ) instanceof BlockDoor & & ! MovementHelper . isDoorPassable ( dest , src ) ) {
isDoorActuallyBlockingUs = true ;
}
if ( isDoorActuallyBlockingUs ) {
2018-08-26 07:17:52 +00:00
if ( ! ( Blocks . IRON_DOOR . equals ( pb0 . getBlock ( ) ) | | Blocks . IRON_DOOR . equals ( pb1 . getBlock ( ) ) ) ) {
2018-09-17 17:17:42 +00:00
return state . setTarget ( new MovementState . MovementTarget ( Utils . calcRotationFromVec3d ( playerHead ( ) , Utils . calcCenterFromCoords ( positionsToBreak [ 0 ] , world ( ) ) ) , true ) )
. setInput ( InputOverrideHandler . Input . CLICK_RIGHT , true ) ;
2018-08-18 04:02:41 +00:00
}
2018-08-15 06:49:08 +00:00
}
}
2018-08-25 23:30:12 +00:00
2018-08-26 07:17:52 +00:00
if ( pb0 . getBlock ( ) instanceof BlockFenceGate | | pb1 . getBlock ( ) instanceof BlockFenceGate ) {
BlockPos blocked = null ;
if ( ! MovementHelper . isGatePassable ( positionsToBreak [ 0 ] , src . up ( ) ) ) {
blocked = positionsToBreak [ 0 ] ;
} else if ( ! MovementHelper . isGatePassable ( positionsToBreak [ 1 ] , src ) ) {
blocked = positionsToBreak [ 1 ] ;
}
if ( blocked ! = null ) {
2018-09-17 17:17:42 +00:00
return state . setTarget ( new MovementState . MovementTarget ( Utils . calcRotationFromVec3d ( playerHead ( ) , Utils . calcCenterFromCoords ( blocked , world ( ) ) ) , true ) )
. setInput ( InputOverrideHandler . Input . CLICK_RIGHT , true ) ;
2018-08-26 07:17:52 +00:00
}
}
2018-08-28 20:41:44 +00:00
boolean isTheBridgeBlockThere = MovementHelper . canWalkOn ( positionToPlace ) | | ladder ;
2018-08-06 22:53:35 +00:00
BlockPos whereAmI = playerFeet ( ) ;
if ( whereAmI . getY ( ) ! = dest . getY ( ) & & ! ladder ) {
2018-09-11 20:45:43 +00:00
logDebug ( " Wrong Y coordinate " ) ;
2018-08-06 22:53:35 +00:00
if ( whereAmI . getY ( ) < dest . getY ( ) ) {
state . setInput ( InputOverrideHandler . Input . JUMP , true ) ;
}
return state ;
}
2018-08-25 23:30:12 +00:00
2018-08-06 22:53:35 +00:00
if ( isTheBridgeBlockThere ) {
if ( playerFeet ( ) . equals ( dest ) ) {
2018-09-17 17:17:42 +00:00
return state . setStatus ( MovementState . MovementStatus . SUCCESS ) ;
2018-08-06 22:53:35 +00:00
}
2018-08-26 15:12:57 +00:00
if ( wasTheBridgeBlockAlwaysThere & & ! BlockStateInterface . isLiquid ( playerFeet ( ) ) ) {
state . setInput ( InputOverrideHandler . Input . SPRINT , true ) ;
2018-08-06 22:53:35 +00:00
}
2018-08-18 03:46:53 +00:00
Block destDown = BlockStateInterface . get ( dest . down ( ) ) . getBlock ( ) ;
2018-09-04 23:19:10 +00:00
if ( whereAmI . getY ( ) ! = dest . getY ( ) & & ladder & & ( destDown instanceof BlockVine | | destDown instanceof BlockLadder ) ) {
2018-08-18 03:46:53 +00:00
new MovementPillar ( dest . down ( ) , dest ) . updateState ( state ) ; // i'm sorry
return state ;
}
2018-08-08 19:51:04 +00:00
MovementHelper . moveTowards ( state , positionsToBreak [ 0 ] ) ;
2018-08-06 23:58:06 +00:00
return state ;
2018-08-06 22:53:35 +00:00
} else {
wasTheBridgeBlockAlwaysThere = false ;
2018-08-28 21:56:21 +00:00
for ( int i = 0 ; i < 4 ; i + + ) {
BlockPos against1 = dest . offset ( HORIZONTALS [ i ] ) ;
if ( against1 . equals ( src ) ) {
continue ;
}
against1 = against1 . down ( ) ;
2018-08-28 22:01:24 +00:00
if ( MovementHelper . canPlaceAgainst ( against1 ) ) {
2018-08-11 22:03:14 +00:00
if ( ! MovementHelper . throwaway ( true ) ) { // get ready to place a throwaway block
2018-09-11 20:45:43 +00:00
logDebug ( " bb pls get me some blocks. dirt or cobble " ) ;
2018-08-12 00:03:18 +00:00
return state . setStatus ( MovementState . MovementStatus . UNREACHABLE ) ;
2018-08-06 22:53:35 +00:00
}
2018-09-12 03:50:29 +00:00
if ( ! Baritone . settings ( ) . assumeSafeWalk . get ( ) ) {
state . setInput ( InputOverrideHandler . Input . SNEAK , true ) ;
}
2018-09-03 16:15:18 +00:00
Block standingOn = BlockStateInterface . get ( playerFeet ( ) . down ( ) ) . getBlock ( ) ;
if ( standingOn . equals ( Blocks . SOUL_SAND ) | | standingOn instanceof BlockSlab ) { // see issue #118
2018-09-01 19:47:43 +00:00
double dist = Math . max ( Math . abs ( dest . getX ( ) + 0 . 5 - player ( ) . posX ) , Math . abs ( dest . getZ ( ) + 0 . 5 - player ( ) . posZ ) ) ;
if ( dist < 0 . 85 ) { // 0.5 + 0.3 + epsilon
MovementHelper . moveTowards ( state , dest ) ;
2018-09-17 17:17:42 +00:00
return state . setInput ( InputOverrideHandler . Input . MOVE_FORWARD , false )
. setInput ( InputOverrideHandler . Input . MOVE_BACK , true ) ;
2018-09-01 19:47:43 +00:00
}
}
state . setInput ( InputOverrideHandler . Input . MOVE_BACK , false ) ;
2018-08-06 22:53:35 +00:00
double faceX = ( dest . getX ( ) + against1 . getX ( ) + 1 . 0D ) * 0 . 5D ;
double faceY = ( dest . getY ( ) + against1 . getY ( ) ) * 0 . 5D ;
double faceZ = ( dest . getZ ( ) + against1 . getZ ( ) + 1 . 0D ) * 0 . 5D ;
2018-08-21 22:52:09 +00:00
state . setTarget ( new MovementState . MovementTarget ( Utils . calcRotationFromVec3d ( playerHead ( ) , new Vec3d ( faceX , faceY , faceZ ) , playerRotations ( ) ) , true ) ) ;
2018-08-06 22:53:35 +00:00
EnumFacing side = Minecraft . getMinecraft ( ) . objectMouseOver . sideHit ;
if ( Objects . equals ( LookBehaviorUtils . getSelectedBlock ( ) . orElse ( null ) , against1 ) & & Minecraft . getMinecraft ( ) . player . isSneaking ( ) ) {
2018-08-28 20:41:44 +00:00
if ( LookBehaviorUtils . getSelectedBlock ( ) . get ( ) . offset ( side ) . equals ( positionToPlace ) ) {
2018-08-25 23:30:12 +00:00
return state . setInput ( InputOverrideHandler . Input . CLICK_RIGHT , true ) ;
2018-08-06 22:53:35 +00:00
}
2018-09-17 00:11:04 +00:00
// wrong side?
2018-08-06 22:53:35 +00:00
}
2018-08-07 02:48:09 +00:00
System . out . println ( " Trying to look at " + against1 + " , actually looking at " + LookBehaviorUtils . getSelectedBlock ( ) ) ;
2018-08-25 23:30:12 +00:00
return state . setInput ( InputOverrideHandler . Input . CLICK_LEFT , true ) ;
2018-08-06 01:52:55 +00:00
}
2018-08-06 22:53:35 +00:00
}
2018-09-12 03:50:29 +00:00
if ( ! Baritone . settings ( ) . assumeSafeWalk . get ( ) ) {
state . setInput ( InputOverrideHandler . Input . SNEAK , true ) ;
}
2018-08-06 22:53:35 +00:00
if ( whereAmI . equals ( dest ) ) {
2018-08-25 23:30:12 +00:00
// If we are in the block that we are trying to get to, we are sneaking over air and we need to place a block beneath us against the one we just walked off of
2018-08-07 21:14:36 +00:00
// Out.log(from + " " + to + " " + faceX + "," + faceY + "," + faceZ + " " + whereAmI);
2018-08-11 22:03:14 +00:00
if ( ! MovementHelper . throwaway ( true ) ) { // get ready to place a throwaway block
2018-09-11 20:45:43 +00:00
logDebug ( " bb pls get me some blocks. dirt or cobble " ) ;
2018-08-12 00:03:18 +00:00
return state . setStatus ( MovementState . MovementStatus . UNREACHABLE ) ;
2018-08-06 22:53:35 +00:00
}
double faceX = ( dest . getX ( ) + src . getX ( ) + 1 . 0D ) * 0 . 5D ;
double faceY = ( dest . getY ( ) + src . getY ( ) - 1 . 0D ) * 0 . 5D ;
double faceZ = ( dest . getZ ( ) + src . getZ ( ) + 1 . 0D ) * 0 . 5D ;
2018-08-07 21:14:36 +00:00
// faceX, faceY, faceZ is the middle of the face between from and to
BlockPos goalLook = src . down ( ) ; // this is the block we were just standing on, and the one we want to place against
2018-08-21 22:52:09 +00:00
state . setTarget ( new MovementState . MovementTarget ( Utils . calcRotationFromVec3d ( playerHead ( ) , new Vec3d ( faceX , faceY , faceZ ) , playerRotations ( ) ) , true ) ) ;
2018-08-06 01:52:55 +00:00
2018-08-06 22:53:35 +00:00
state . setInput ( InputOverrideHandler . Input . MOVE_BACK , true ) ;
state . setInput ( InputOverrideHandler . Input . SNEAK , true ) ;
if ( Objects . equals ( LookBehaviorUtils . getSelectedBlock ( ) . orElse ( null ) , goalLook ) ) {
2018-09-17 17:17:42 +00:00
return state . setInput ( InputOverrideHandler . Input . CLICK_RIGHT , true ) ; // wait to right click until we are able to place
2018-08-06 22:53:35 +00:00
}
2018-08-07 21:14:36 +00:00
// Out.log("Trying to look at " + goalLook + ", actually looking at" + Baritone.whatAreYouLookingAt());
2018-09-02 20:34:15 +00:00
return state . setInput ( InputOverrideHandler . Input . CLICK_LEFT , true ) ;
2018-08-06 22:53:35 +00:00
} else {
2018-08-08 19:51:04 +00:00
MovementHelper . moveTowards ( state , positionsToBreak [ 0 ] ) ;
2018-08-06 23:58:06 +00:00
return state ;
2018-08-07 21:14:36 +00:00
// TODO MovementManager.moveTowardsBlock(to); // move towards not look at because if we are bridging for a couple blocks in a row, it is faster if we dont spin around and walk forwards then spin around and place backwards for every block
2018-08-06 22:53:35 +00:00
}
2018-08-06 01:17:04 +00:00
}
}
2018-09-04 23:19:10 +00:00
@Override
protected boolean prepared ( MovementState state ) {
if ( playerFeet ( ) . equals ( src ) | | playerFeet ( ) . equals ( src . down ( ) ) ) {
Block block = BlockStateInterface . getBlock ( src . down ( ) ) ;
if ( block = = Blocks . LADDER | | block = = Blocks . VINE ) {
state . setInput ( InputOverrideHandler . Input . SNEAK , true ) ;
}
}
return super . prepared ( state ) ;
}
2018-08-06 01:17:04 +00:00
}