2018-08-07 22:16:53 -05:00
/ *
* This file is part of Baritone .
*
* Baritone is free software : you can redistribute it and / or modify
2018-09-17 17:11:40 -05:00
* it under the terms of the GNU Lesser General Public License as published by
2018-08-07 22:16:53 -05:00
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
2018-08-07 23:15:22 -05:00
* Baritone is distributed in the hope that it will be useful ,
2018-08-07 22:16:53 -05:00
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
2018-09-17 17:11:40 -05:00
* GNU Lesser General Public License for more details .
2018-08-07 22:16:53 -05:00
*
2018-09-17 17:11:40 -05:00
* You should have received a copy of the GNU Lesser General Public License
2018-08-07 22:16:53 -05:00
* along with Baritone . If not , see < https : //www.gnu.org/licenses/>.
* /
2018-08-22 13:15:56 -07:00
package baritone.pathing.movement.movements ;
2018-08-05 21:17:04 -04:00
2018-09-11 20:50:29 -07:00
import baritone.Baritone ;
2018-11-13 11:50:29 -06:00
import baritone.api.IBaritone ;
2018-10-08 20:37:52 -05:00
import baritone.api.pathing.movement.MovementStatus ;
2018-11-14 13:46:16 -08:00
import baritone.api.utils.BetterBlockPos ;
import baritone.api.utils.Rotation ;
import baritone.api.utils.RotationUtils ;
import baritone.api.utils.VecUtils ;
2018-11-13 11:50:29 -06:00
import baritone.api.utils.input.Input ;
2018-10-08 20:37:52 -05:00
import baritone.pathing.movement.CalculationContext ;
import baritone.pathing.movement.Movement ;
import baritone.pathing.movement.MovementHelper ;
import baritone.pathing.movement.MovementState ;
2018-08-22 13:15:56 -07:00
import baritone.utils.BlockStateInterface ;
2018-08-26 02:17:52 -05:00
import net.minecraft.block.* ;
2018-08-05 21:17:04 -04:00
import net.minecraft.block.state.IBlockState ;
import net.minecraft.init.Blocks ;
2018-08-06 15:53:35 -07:00
import net.minecraft.util.EnumFacing ;
2018-08-05 21:17:04 -04:00
import net.minecraft.util.math.BlockPos ;
2018-08-06 15:53:35 -07:00
import net.minecraft.util.math.Vec3d ;
import java.util.Objects ;
2018-08-05 21:17:04 -04:00
public class MovementTraverse extends Movement {
2018-08-07 16:14:36 -05:00
/ * *
* Did we have to place a bridge block or was it always there
* /
private boolean wasTheBridgeBlockAlwaysThere = true ;
2018-08-05 21:17:04 -04:00
2018-11-13 11:50:29 -06:00
public MovementTraverse ( IBaritone baritone , BetterBlockPos from , BetterBlockPos to ) {
super ( baritone , from , to , new BetterBlockPos [ ] { to . up ( ) , to } , to . down ( ) ) ;
2018-08-05 21:17:04 -04:00
}
2018-08-23 11:14:37 -07:00
@Override
public void reset ( ) {
super . reset ( ) ;
wasTheBridgeBlockAlwaysThere = true ;
}
2018-08-05 21:17:04 -04:00
@Override
2018-08-07 16:36:32 -05:00
protected double calculateCost ( CalculationContext context ) {
2018-09-22 22:00:28 -07:00
return cost ( context , src . x , src . y , src . z , dest . x , dest . z ) ;
}
public static double cost ( CalculationContext context , int x , int y , int z , int destX , int destZ ) {
2018-11-11 12:35:04 -08:00
IBlockState pb0 = context . get ( destX , y + 1 , destZ ) ;
IBlockState pb1 = context . get ( destX , y , destZ ) ;
IBlockState destOn = context . get ( destX , y - 1 , destZ ) ;
Block srcDown = context . getBlock ( x , y - 1 , z ) ;
2018-11-13 15:14:29 -06:00
if ( MovementHelper . canWalkOn ( context . bsi ( ) , destX , y - 1 , destZ , destOn ) ) { //this is a walk, not a bridge
2018-08-17 12:24:40 -07:00
double WC = WALK_ONE_BLOCK_COST ;
2018-10-01 10:05:04 -07:00
boolean water = false ;
2018-11-01 15:36:32 -07:00
if ( MovementHelper . isWater ( pb0 . getBlock ( ) ) | | MovementHelper . isWater ( pb1 . getBlock ( ) ) ) {
2018-10-01 14:26:55 -07:00
WC = context . waterWalkSpeed ( ) ;
2018-10-01 10:05:04 -07:00
water = true ;
2018-08-17 12:24:40 -07:00
} else {
2018-09-04 16:19:10 -07:00
if ( destOn . getBlock ( ) = = Blocks . SOUL_SAND ) {
2018-08-17 12:24:40 -07:00
WC + = ( WALK_ONE_OVER_SOUL_SAND_COST - WALK_ONE_BLOCK_COST ) / 2 ;
}
2018-09-04 16:19:10 -07:00
if ( srcDown = = Blocks . SOUL_SAND ) {
2018-08-17 12:24:40 -07:00
WC + = ( WALK_ONE_OVER_SOUL_SAND_COST - WALK_ONE_BLOCK_COST ) / 2 ;
}
2018-08-13 07:05:28 -07:00
}
2018-12-04 14:38:08 -08:00
double hardness1 = MovementHelper . getMiningDurationTicks ( context , destX , y , destZ , pb1 , false ) ;
2018-08-28 12:39:58 -07:00
if ( hardness1 > = COST_INF ) {
return COST_INF ;
}
2018-12-04 14:38:08 -08:00
double hardness2 = MovementHelper . getMiningDurationTicks ( context , destX , y + 1 , destZ , pb0 , true ) ; // only include falling on the upper block to break
2018-08-28 12:39:58 -07:00
if ( hardness1 = = 0 & & hardness2 = = 0 ) {
2018-10-01 10:05:04 -07:00
if ( ! water & & context . canSprint ( ) ) {
// If there's nothing in the way, and this isn't water, and we aren't sneak placing
2018-08-25 18:30:12 -05:00
// We can sprint =D
2018-10-01 10:05:04 -07:00
// Don't check for soul sand, since we can sprint on that too
WC * = SPRINT_MULTIPLIER ;
2018-08-13 13:40:50 -07:00
}
2018-08-05 21:17:04 -04:00
return WC ;
}
2018-09-04 16:19:10 -07:00
if ( srcDown = = Blocks . LADDER | | srcDown = = Blocks . VINE ) {
hardness1 * = 5 ;
hardness2 * = 5 ;
}
2018-08-28 12:39:58 -07:00
return WC + hardness1 + hardness2 ;
2018-08-05 21:17:04 -04:00
} else { //this is a bridge, so we need to place a block
2018-09-03 09:15:18 -07:00
if ( srcDown = = Blocks . LADDER | | srcDown = = Blocks . VINE ) {
2018-08-05 21:17:04 -04:00
return COST_INF ;
}
2018-12-04 15:00:45 -08:00
if ( MovementHelper . isReplacable ( destX , y - 1 , destZ , destOn , context . bsi ( ) ) ) {
2018-11-01 15:36:32 -07:00
boolean throughWater = MovementHelper . isWater ( pb0 . getBlock ( ) ) | | MovementHelper . isWater ( pb1 . getBlock ( ) ) ;
if ( MovementHelper . isWater ( destOn . getBlock ( ) ) & & throughWater ) {
2018-12-04 14:38:08 -08:00
// this happens when assume walk on water is true and this is a traverse in water, which isn't allowed
2018-08-28 12:53:01 -07:00
return COST_INF ;
}
2018-10-12 14:34:33 -07:00
if ( ! context . canPlaceThrowawayAt ( destX , y - 1 , destZ ) ) {
2018-08-11 15:03:14 -07:00
return COST_INF ;
}
2018-12-04 14:38:08 -08:00
double hardness1 = MovementHelper . getMiningDurationTicks ( context , destX , y , destZ , pb1 , false ) ;
2018-09-22 22:00:28 -07:00
if ( hardness1 > = COST_INF ) {
return COST_INF ;
}
2018-12-04 14:38:08 -08:00
double hardness2 = MovementHelper . getMiningDurationTicks ( context , destX , y + 1 , destZ , pb0 , true ) ; // only include falling on the upper block to break
2018-10-01 14:26:55 -07:00
double WC = throughWater ? context . waterWalkSpeed ( ) : WALK_ONE_BLOCK_COST ;
2018-08-28 14:56:21 -07:00
for ( int i = 0 ; i < 4 ; i + + ) {
2018-09-22 22:00:28 -07:00
int againstX = destX + HORIZONTALS [ i ] . getXOffset ( ) ;
int againstZ = destZ + HORIZONTALS [ i ] . getZOffset ( ) ;
2018-12-04 14:38:08 -08:00
if ( againstX = = x & & againstZ = = z ) { // this would be a backplace
2018-08-28 14:56:21 -07:00
continue ;
}
2018-12-04 14:38:08 -08:00
if ( MovementHelper . canPlaceAgainst ( context . bsi ( ) , againstX , y - 1 , againstZ ) ) { // found a side place option
2018-09-22 22:00:28 -07:00
return WC + context . placeBlockCost ( ) + hardness1 + hardness2 ;
2018-08-05 21:17:04 -04:00
}
}
2018-12-04 14:38:08 -08:00
// now that we've checked all possible directions to side place, we actually need to backplace
2018-09-03 09:15:18 -07: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 07:07:42 -07:00
}
2018-09-11 19:05:45 -07:00
if ( srcDown = = Blocks . FLOWING_WATER | | srcDown = = Blocks . WATER ) {
return COST_INF ; // this is obviously impossible
}
2018-12-04 14:38:08 -08:00
WC = WC * SNEAK_ONE_BLOCK_COST / WALK_ONE_BLOCK_COST ; //since we are sneak backplacing, we are sneaking lol
2018-09-22 22:00:28 -07:00
return WC + context . placeBlockCost ( ) + hardness1 + hardness2 ;
2018-08-05 21:17:04 -04:00
}
return COST_INF ;
}
}
@Override
public MovementState updateState ( MovementState state ) {
super . updateState ( state ) ;
2018-10-08 19:57:22 -05:00
if ( state . getStatus ( ) ! = MovementStatus . RUNNING ) {
2018-09-14 16:45:51 -07:00
// if the setting is enabled
if ( ! Baritone . settings ( ) . walkWhileBreaking . get ( ) ) {
return state ;
}
// and if we're prepping (aka mining the block in front)
2018-10-08 19:57:22 -05:00
if ( state . getStatus ( ) ! = MovementStatus . PREPPING ) {
2018-09-14 16:45:51 -07:00
return state ;
}
// and if it's fine to walk into the blocks in front
2018-11-13 15:14:29 -06:00
if ( MovementHelper . avoidWalkingInto ( BlockStateInterface . get ( ctx , positionsToBreak [ 0 ] ) . getBlock ( ) ) ) {
2018-09-14 16:45:51 -07:00
return state ;
}
2018-11-13 15:14:29 -06:00
if ( MovementHelper . avoidWalkingInto ( BlockStateInterface . get ( ctx , positionsToBreak [ 1 ] ) . getBlock ( ) ) ) {
2018-09-14 16:45:51 -07:00
return state ;
}
// and we aren't already pressed up against the block
2018-11-13 11:50:29 -06:00
double dist = Math . max ( Math . abs ( ctx . player ( ) . posX - ( dest . getX ( ) + 0 . 5D ) ) , Math . abs ( ctx . player ( ) . posZ - ( dest . getZ ( ) + 0 . 5D ) ) ) ;
2018-09-14 16:45:51 -07:00
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
2018-11-14 13:24:44 -08:00
float yawToDest = RotationUtils . calcRotationFromVec3d ( ctx . playerHead ( ) , VecUtils . calculateBlockCenter ( ctx . world ( ) , dest ) ) . getYaw ( ) ;
2018-09-25 09:39:59 -05:00
float pitchToBreak = state . getTarget ( ) . getRotation ( ) . get ( ) . getPitch ( ) ;
2018-09-14 16:45:51 -07:00
state . setTarget ( new MovementState . MovementTarget ( new Rotation ( yawToDest , pitchToBreak ) , true ) ) ;
2018-11-13 11:50:29 -06:00
return state . setInput ( Input . MOVE_FORWARD , true ) ;
2018-09-07 21:32:25 -07:00
}
2018-09-14 16:45:51 -07:00
//sneak may have been set to true in the PREPPING state while mining an adjacent block
2018-11-13 11:50:29 -06:00
state . setInput ( Input . SNEAK , false ) ;
2018-09-04 16:19:10 -07:00
2018-11-13 15:14:29 -06:00
Block fd = BlockStateInterface . get ( ctx , src . down ( ) ) . getBlock ( ) ;
2018-08-06 15:53:35 -07:00
boolean ladder = fd instanceof BlockLadder | | fd instanceof BlockVine ;
2018-11-13 15:14:29 -06:00
IBlockState pb0 = BlockStateInterface . get ( ctx , positionsToBreak [ 0 ] ) ;
IBlockState pb1 = BlockStateInterface . get ( ctx , positionsToBreak [ 1 ] ) ;
2018-08-26 02:17:52 -05:00
boolean door = pb0 . getBlock ( ) instanceof BlockDoor | | pb1 . getBlock ( ) instanceof BlockDoor ;
2018-08-14 23:49:08 -07:00
if ( door ) {
boolean isDoorActuallyBlockingUs = false ;
2018-11-13 15:14:29 -06:00
if ( pb0 . getBlock ( ) instanceof BlockDoor & & ! MovementHelper . isDoorPassable ( ctx , src , dest ) ) {
2018-08-14 23:49:08 -07:00
isDoorActuallyBlockingUs = true ;
2018-11-13 15:14:29 -06:00
} else if ( pb1 . getBlock ( ) instanceof BlockDoor & & ! MovementHelper . isDoorPassable ( ctx , dest , src ) ) {
2018-08-14 23:49:08 -07:00
isDoorActuallyBlockingUs = true ;
}
2018-10-27 14:41:25 -07:00
if ( isDoorActuallyBlockingUs & & ! ( Blocks . IRON_DOOR . equals ( pb0 . getBlock ( ) ) | | Blocks . IRON_DOOR . equals ( pb1 . getBlock ( ) ) ) ) {
2018-11-14 13:24:44 -08:00
return state . setTarget ( new MovementState . MovementTarget ( RotationUtils . calcRotationFromVec3d ( ctx . playerHead ( ) , VecUtils . calculateBlockCenter ( ctx . world ( ) , positionsToBreak [ 0 ] ) ) , true ) )
2018-11-13 11:50:29 -06:00
. setInput ( Input . CLICK_RIGHT , true ) ;
2018-08-14 23:49:08 -07:00
}
}
2018-08-25 18:30:12 -05:00
2018-08-26 02:17:52 -05:00
if ( pb0 . getBlock ( ) instanceof BlockFenceGate | | pb1 . getBlock ( ) instanceof BlockFenceGate ) {
BlockPos blocked = null ;
2018-11-13 15:14:29 -06:00
if ( ! MovementHelper . isGatePassable ( ctx , positionsToBreak [ 0 ] , src . up ( ) ) ) {
2018-08-26 02:17:52 -05:00
blocked = positionsToBreak [ 0 ] ;
2018-11-13 15:14:29 -06:00
} else if ( ! MovementHelper . isGatePassable ( ctx , positionsToBreak [ 1 ] , src ) ) {
2018-08-26 02:17:52 -05:00
blocked = positionsToBreak [ 1 ] ;
}
if ( blocked ! = null ) {
2018-11-14 13:24:44 -08:00
return state . setTarget ( new MovementState . MovementTarget ( RotationUtils . calcRotationFromVec3d ( ctx . playerHead ( ) , VecUtils . calculateBlockCenter ( ctx . world ( ) , blocked ) ) , true ) )
2018-11-13 11:50:29 -06:00
. setInput ( Input . CLICK_RIGHT , true ) ;
2018-08-26 02:17:52 -05:00
}
}
2018-11-13 15:14:29 -06:00
boolean isTheBridgeBlockThere = MovementHelper . canWalkOn ( ctx , positionToPlace ) | | ladder ;
2018-11-13 11:50:29 -06:00
BlockPos whereAmI = ctx . playerFeet ( ) ;
2018-08-06 15:53:35 -07:00
if ( whereAmI . getY ( ) ! = dest . getY ( ) & & ! ladder ) {
2018-09-11 13:45:43 -07:00
logDebug ( " Wrong Y coordinate " ) ;
2018-08-06 15:53:35 -07:00
if ( whereAmI . getY ( ) < dest . getY ( ) ) {
2018-11-13 11:50:29 -06:00
state . setInput ( Input . JUMP , true ) ;
2018-08-06 15:53:35 -07:00
}
return state ;
}
2018-08-25 18:30:12 -05:00
2018-08-06 15:53:35 -07:00
if ( isTheBridgeBlockThere ) {
2018-11-13 11:50:29 -06:00
if ( ctx . playerFeet ( ) . equals ( dest ) ) {
2018-10-08 19:57:22 -05:00
return state . setStatus ( MovementStatus . SUCCESS ) ;
2018-08-06 15:53:35 -07:00
}
2018-11-20 18:58:41 -08:00
BlockPos into = dest . subtract ( src ) . add ( dest ) ;
Block intoBelow = BlockStateInterface . get ( ctx , into ) . getBlock ( ) ;
Block intoAbove = BlockStateInterface . get ( ctx , into . up ( ) ) . getBlock ( ) ;
if ( wasTheBridgeBlockAlwaysThere & & ! MovementHelper . isLiquid ( ctx , ctx . playerFeet ( ) ) & & ! MovementHelper . avoidWalkingInto ( intoBelow ) & & ! MovementHelper . avoidWalkingInto ( intoAbove ) ) {
2018-11-13 11:50:29 -06:00
state . setInput ( Input . SPRINT , true ) ;
2018-08-06 15:53:35 -07:00
}
2018-11-13 15:14:29 -06:00
Block destDown = BlockStateInterface . get ( ctx , dest . down ( ) ) . getBlock ( ) ;
2018-09-04 16:19:10 -07:00
if ( whereAmI . getY ( ) ! = dest . getY ( ) & & ladder & & ( destDown instanceof BlockVine | | destDown instanceof BlockLadder ) ) {
2018-11-13 11:50:29 -06:00
new MovementPillar ( baritone , dest . down ( ) , dest ) . updateState ( state ) ; // i'm sorry
2018-08-17 20:46:53 -07:00
return state ;
}
2018-11-13 11:50:29 -06:00
MovementHelper . moveTowards ( ctx , state , positionsToBreak [ 0 ] ) ;
2018-08-06 16:58:06 -07:00
return state ;
2018-08-06 15:53:35 -07:00
} else {
wasTheBridgeBlockAlwaysThere = false ;
2018-08-28 14:56:21 -07:00
for ( int i = 0 ; i < 4 ; i + + ) {
BlockPos against1 = dest . offset ( HORIZONTALS [ i ] ) ;
if ( against1 . equals ( src ) ) {
continue ;
}
against1 = against1 . down ( ) ;
2018-11-13 15:14:29 -06:00
if ( MovementHelper . canPlaceAgainst ( ctx , against1 ) ) {
2018-11-13 11:50:29 -06:00
if ( ! MovementHelper . throwaway ( ctx , true ) ) { // get ready to place a throwaway block
2018-09-11 13:45:43 -07:00
logDebug ( " bb pls get me some blocks. dirt or cobble " ) ;
2018-10-08 19:57:22 -05:00
return state . setStatus ( MovementStatus . UNREACHABLE ) ;
2018-08-06 15:53:35 -07:00
}
2018-09-11 20:50:29 -07:00
if ( ! Baritone . settings ( ) . assumeSafeWalk . get ( ) ) {
2018-11-13 11:50:29 -06:00
state . setInput ( Input . SNEAK , true ) ;
2018-09-11 20:50:29 -07:00
}
2018-11-13 15:14:29 -06:00
Block standingOn = BlockStateInterface . get ( ctx , ctx . playerFeet ( ) . down ( ) ) . getBlock ( ) ;
2018-09-03 09:15:18 -07:00
if ( standingOn . equals ( Blocks . SOUL_SAND ) | | standingOn instanceof BlockSlab ) { // see issue #118
2018-11-13 11:50:29 -06:00
double dist = Math . max ( Math . abs ( dest . getX ( ) + 0 . 5 - ctx . player ( ) . posX ) , Math . abs ( dest . getZ ( ) + 0 . 5 - ctx . player ( ) . posZ ) ) ;
2018-09-01 12:47:43 -07:00
if ( dist < 0 . 85 ) { // 0.5 + 0.3 + epsilon
2018-11-13 11:50:29 -06:00
MovementHelper . moveTowards ( ctx , state , dest ) ;
return state . setInput ( Input . MOVE_FORWARD , false )
. setInput ( Input . MOVE_BACK , true ) ;
2018-09-01 12:47:43 -07:00
}
}
2018-11-13 11:50:29 -06:00
state . setInput ( Input . MOVE_BACK , false ) ;
2018-08-06 15:53:35 -07: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-11-13 11:50:29 -06:00
state . setTarget ( new MovementState . MovementTarget ( RotationUtils . calcRotationFromVec3d ( ctx . playerHead ( ) , new Vec3d ( faceX , faceY , faceZ ) , ctx . playerRotations ( ) ) , true ) ) ;
2018-08-06 15:53:35 -07:00
2018-11-14 13:46:16 -08:00
EnumFacing side = ctx . objectMouseOver ( ) . sideHit ;
if ( Objects . equals ( ctx . getSelectedBlock ( ) . orElse ( null ) , against1 ) & & ( ctx . player ( ) . isSneaking ( ) | | Baritone . settings ( ) . assumeSafeWalk . get ( ) ) & & ctx . getSelectedBlock ( ) . get ( ) . offset ( side ) . equals ( positionToPlace ) ) {
2018-11-13 11:50:29 -06:00
return state . setInput ( Input . CLICK_RIGHT , true ) ;
2018-08-06 15:53:35 -07:00
}
2018-10-15 15:39:01 -07:00
//System.out.println("Trying to look at " + against1 + ", actually looking at" + RayTraceUtils.getSelectedBlock());
2018-11-13 11:50:29 -06:00
return state . setInput ( Input . CLICK_LEFT , true ) ;
2018-08-05 21:52:55 -04:00
}
2018-08-06 15:53:35 -07:00
}
2018-09-11 20:50:29 -07:00
if ( ! Baritone . settings ( ) . assumeSafeWalk . get ( ) ) {
2018-11-13 11:50:29 -06:00
state . setInput ( Input . SNEAK , true ) ;
2018-09-11 20:50:29 -07:00
}
2018-08-06 15:53:35 -07:00
if ( whereAmI . equals ( dest ) ) {
2018-08-25 18:30:12 -05: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 16:14:36 -05:00
// Out.log(from + " " + to + " " + faceX + "," + faceY + "," + faceZ + " " + whereAmI);
2018-11-13 11:50:29 -06:00
if ( ! MovementHelper . throwaway ( ctx , true ) ) { // get ready to place a throwaway block
2018-09-11 13:45:43 -07:00
logDebug ( " bb pls get me some blocks. dirt or cobble " ) ;
2018-10-08 19:57:22 -05:00
return state . setStatus ( MovementStatus . UNREACHABLE ) ;
2018-08-06 15:53:35 -07: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 16:14:36 -05: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-05 21:52:55 -04:00
2018-11-13 11:50:29 -06:00
Rotation backToFace = RotationUtils . calcRotationFromVec3d ( ctx . playerHead ( ) , new Vec3d ( faceX , faceY , faceZ ) , ctx . playerRotations ( ) ) ;
2018-10-05 13:49:47 -07:00
float pitch = backToFace . getPitch ( ) ;
2018-11-13 11:50:29 -06:00
double dist = Math . max ( Math . abs ( ctx . player ( ) . posX - faceX ) , Math . abs ( ctx . player ( ) . posZ - faceZ ) ) ;
2018-10-05 13:49:47 -07:00
if ( dist < 0 . 29 ) {
2018-11-13 11:50:29 -06:00
float yaw = RotationUtils . calcRotationFromVec3d ( VecUtils . getBlockPosCenter ( dest ) , ctx . playerHead ( ) , ctx . playerRotations ( ) ) . getYaw ( ) ;
2018-10-05 13:49:47 -07:00
state . setTarget ( new MovementState . MovementTarget ( new Rotation ( yaw , pitch ) , true ) ) ;
2018-11-13 11:50:29 -06:00
state . setInput ( Input . MOVE_BACK , true ) ;
2018-10-05 13:49:47 -07:00
} else {
state . setTarget ( new MovementState . MovementTarget ( backToFace , true ) ) ;
}
2018-11-13 11:50:29 -06:00
state . setInput ( Input . SNEAK , true ) ;
2018-11-14 13:46:16 -08:00
if ( Objects . equals ( ctx . getSelectedBlock ( ) . orElse ( null ) , goalLook ) ) {
2018-11-13 11:50:29 -06:00
return state . setInput ( Input . CLICK_RIGHT , true ) ; // wait to right click until we are able to place
2018-08-06 15:53:35 -07:00
}
2018-08-07 16:14:36 -05:00
// Out.log("Trying to look at " + goalLook + ", actually looking at" + Baritone.whatAreYouLookingAt());
2018-11-13 11:50:29 -06:00
return state . setInput ( Input . CLICK_LEFT , true ) ;
2018-08-06 15:53:35 -07:00
} else {
2018-11-13 11:50:29 -06:00
MovementHelper . moveTowards ( ctx , state , positionsToBreak [ 0 ] ) ;
2018-08-06 16:58:06 -07:00
return state ;
2018-08-07 16:14:36 -05: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 15:53:35 -07:00
}
2018-08-05 21:17:04 -04:00
}
}
2018-09-04 16:19:10 -07:00
2018-10-06 18:39:30 -07:00
@Override
public boolean safeToCancel ( MovementState state ) {
// if we're in the process of breaking blocks before walking forwards
// or if this isn't a sneak place (the block is already there)
// then it's safe to cancel this
2018-11-13 15:14:29 -06:00
return state . getStatus ( ) ! = MovementStatus . RUNNING | | MovementHelper . canWalkOn ( ctx , dest . down ( ) ) ;
2018-10-06 18:39:30 -07:00
}
2018-09-04 16:19:10 -07:00
@Override
protected boolean prepared ( MovementState state ) {
2018-11-13 11:50:29 -06:00
if ( ctx . playerFeet ( ) . equals ( src ) | | ctx . playerFeet ( ) . equals ( src . down ( ) ) ) {
2018-11-13 15:14:29 -06:00
Block block = BlockStateInterface . getBlock ( ctx , src . down ( ) ) ;
2018-09-04 16:19:10 -07:00
if ( block = = Blocks . LADDER | | block = = Blocks . VINE ) {
2018-11-13 11:50:29 -06:00
state . setInput ( Input . SNEAK , true ) ;
2018-09-04 16:19:10 -07:00
}
}
return super . prepared ( state ) ;
}
2018-08-05 21:17:04 -04:00
}