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
* 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 .
*
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
* 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/>.
* /
2018-08-22 20:15:56 +00:00
package baritone.pathing.movement ;
2018-08-02 04:07:55 +00:00
2018-08-22 20:15:56 +00:00
import baritone.Baritone ;
import baritone.behavior.impl.LookBehavior ;
import baritone.behavior.impl.LookBehaviorUtils ;
import baritone.pathing.movement.MovementState.MovementStatus ;
import baritone.pathing.movement.movements.MovementDownward ;
import baritone.pathing.movement.movements.MovementPillar ;
import baritone.pathing.movement.movements.MovementTraverse ;
import baritone.utils.* ;
2018-08-14 03:09:27 +00:00
import net.minecraft.block.Block ;
import net.minecraft.block.BlockLadder ;
import net.minecraft.block.BlockVine ;
2018-08-02 07:12:51 +00:00
import net.minecraft.util.math.BlockPos ;
2018-08-02 14:59:51 +00:00
import net.minecraft.util.math.Vec3d ;
2018-08-02 07:12:51 +00:00
2018-08-06 22:53:35 +00:00
import java.util.ArrayList ;
2018-08-02 22:35:36 +00:00
import java.util.Optional ;
2018-08-22 20:15:56 +00:00
import static baritone.utils.InputOverrideHandler.Input ;
2018-08-06 00:37:42 +00:00
2018-08-05 03:01:38 +00:00
public abstract class Movement implements Helper , MovementHelper {
2018-08-03 07:51:10 +00:00
2018-08-04 22:17:53 +00:00
private MovementState currentState = new MovementState ( ) . setStatus ( MovementStatus . PREPPING ) ;
2018-08-07 21:14:36 +00:00
2018-08-02 18:12:56 +00:00
protected final BlockPos src ;
2018-08-03 07:51:10 +00:00
2018-08-02 18:12:56 +00:00
protected final BlockPos dest ;
2018-08-03 07:51:10 +00:00
2018-08-03 03:30:35 +00:00
/ * *
* The positions that need to be broken before this movement can ensue
* /
2018-08-07 21:14:36 +00:00
protected final BlockPos [ ] positionsToBreak ;
2018-08-03 07:51:10 +00:00
2018-08-03 03:30:35 +00:00
/ * *
* The positions where we need to place a block before this movement can ensue
* /
2018-08-07 21:14:36 +00:00
protected final BlockPos [ ] positionsToPlace ;
2018-08-02 07:12:51 +00:00
2018-08-06 00:27:45 +00:00
private Double cost ;
2018-08-03 03:30:35 +00:00
protected Movement ( BlockPos src , BlockPos dest , BlockPos [ ] toBreak , BlockPos [ ] toPlace ) {
2018-08-02 22:35:36 +00:00
this . src = src ;
this . dest = dest ;
2018-08-03 03:30:35 +00:00
this . positionsToBreak = toBreak ;
this . positionsToPlace = toPlace ;
2018-08-02 14:59:51 +00:00
}
2018-08-03 03:30:35 +00:00
protected Movement ( BlockPos src , BlockPos dest , BlockPos [ ] toBreak , BlockPos [ ] toPlace , Vec3d rotationTarget ) {
this ( src , dest , toBreak , toPlace ) ;
2018-08-02 07:12:51 +00:00
}
2018-08-07 21:36:32 +00:00
public double getCost ( CalculationContext context ) {
2018-08-06 00:27:45 +00:00
if ( cost = = null ) {
2018-08-07 21:36:32 +00:00
if ( context = = null )
context = new CalculationContext ( ) ;
2018-08-14 03:09:27 +00:00
cost = calculateCost0 ( context ) ;
2018-08-06 00:27:45 +00:00
}
return cost ;
}
2018-08-14 17:47:31 +00:00
private double calculateCost0 ( CalculationContext context ) {
2018-08-14 03:09:27 +00:00
if ( ! ( this instanceof MovementPillar ) & & ! ( this instanceof MovementTraverse ) & & ! ( this instanceof MovementDownward ) ) {
Block fromDown = BlockStateInterface . get ( src . down ( ) ) . getBlock ( ) ;
if ( fromDown instanceof BlockLadder | | fromDown instanceof BlockVine ) {
return COST_INF ;
}
}
return calculateCost ( context ) ;
}
2018-08-13 18:50:49 +00:00
protected abstract double calculateCost ( CalculationContext context ) ;
2018-08-06 00:27:45 +00:00
public double recalculateCost ( ) {
cost = null ;
return getCost ( null ) ;
}
2018-08-02 07:12:51 +00:00
2018-08-05 03:01:38 +00:00
/ * *
* Handles the execution of the latest Movement
* State , and offers a Status to the calling class .
*
* @return Status
* /
2018-08-04 18:49:52 +00:00
public MovementStatus update ( ) {
2018-08-11 20:08:16 +00:00
player ( ) . setSprinting ( false ) ;
2018-08-04 22:17:53 +00:00
MovementState latestState = updateState ( currentState ) ;
2018-08-07 15:09:27 +00:00
if ( BlockStateInterface . isLiquid ( playerFeet ( ) ) ) {
latestState . setInput ( Input . JUMP , true ) ;
}
2018-08-21 23:19:20 +00:00
// If the movement target has to force the new rotations, or we aren't using silent move, then force the rotations
latestState . getTarget ( ) . getRotation ( ) . ifPresent ( rotation - >
LookBehavior . INSTANCE . updateTarget (
rotation ,
latestState . getTarget ( ) . hasToForceRotations ( ) ) ) ;
2018-08-06 04:42:17 +00:00
// TODO: calculate movement inputs from latestState.getGoal().position
// latestState.getTarget().position.ifPresent(null); NULL CONSUMER REALLY SHOULDN'T BE THE FINAL THING YOU SHOULD REALLY REPLACE THIS WITH ALMOST ACTUALLY ANYTHING ELSE JUST PLEASE DON'T LEAVE IT AS IT IS THANK YOU KANYE
2018-08-07 21:14:36 +00:00
latestState . getInputStates ( ) . forEach ( ( input , forced ) - > {
2018-08-06 01:52:55 +00:00
Baritone . INSTANCE . getInputOverrideHandler ( ) . setInputForceState ( input , forced ) ;
} ) ;
2018-08-07 21:14:36 +00:00
latestState . getInputStates ( ) . replaceAll ( ( input , forced ) - > false ) ;
2018-08-02 08:15:51 +00:00
currentState = latestState ;
2018-08-02 14:01:34 +00:00
if ( isFinished ( ) )
2018-08-06 01:17:54 +00:00
onFinish ( latestState ) ;
2018-08-04 22:17:53 +00:00
return currentState . getStatus ( ) ;
2018-08-02 08:15:51 +00:00
}
2018-08-12 04:27:46 +00:00
protected boolean prepared ( MovementState state ) {
2018-08-18 19:33:00 +00:00
if ( state . getStatus ( ) = = MovementStatus . WAITING ) {
return true ;
}
2018-08-12 15:17:23 +00:00
boolean somethingInTheWay = false ;
2018-08-06 04:42:17 +00:00
for ( BlockPos blockPos : positionsToBreak ) {
2018-08-07 01:18:16 +00:00
if ( ! MovementHelper . canWalkThrough ( blockPos ) ) {
2018-08-12 15:17:23 +00:00
somethingInTheWay = true ;
2018-08-06 00:50:59 +00:00
Optional < Rotation > reachable = LookBehaviorUtils . reachable ( blockPos ) ;
2018-08-06 04:42:17 +00:00
if ( reachable . isPresent ( ) ) {
2018-08-13 14:08:53 +00:00
player ( ) . inventory . currentItem = new ToolSet ( ) . getBestSlot ( BlockStateInterface . get ( blockPos ) ) ;
2018-08-21 22:52:09 +00:00
state . setTarget ( new MovementState . MovementTarget ( reachable . get ( ) , true ) ) . setInput ( Input . CLICK_LEFT , true ) ;
2018-08-06 00:37:42 +00:00
return false ;
2018-08-06 04:42:17 +00:00
}
2018-08-21 03:17:55 +00:00
//get rekt minecraft
//i'm doing it anyway
//i dont care if theres snow in the way!!!!!!!
//you dont own me!!!!
state . setTarget ( new MovementState . MovementTarget ( Utils . calcRotationFromVec3d ( mc . player . getPositionEyes ( 1 . 0F ) ,
2018-08-21 22:52:09 +00:00
Utils . getBlockPosCenter ( blockPos ) ) , true )
2018-08-21 03:17:55 +00:00
) . setInput ( InputOverrideHandler . Input . CLICK_LEFT , true ) ;
return false ;
2018-08-04 22:17:53 +00:00
}
2018-08-04 18:49:52 +00:00
}
2018-08-12 15:17:23 +00:00
if ( somethingInTheWay ) {
// There's a block or blocks that we can't walk through, but we have no target rotation to reach any
// So don't return true, actually set state to unreachable
state . setStatus ( MovementStatus . UNREACHABLE ) ;
return true ;
}
2018-08-04 22:17:53 +00:00
return true ;
2018-08-04 18:49:52 +00:00
}
2018-08-02 08:15:51 +00:00
public boolean isFinished ( ) {
2018-08-02 21:28:35 +00:00
return ( currentState . getStatus ( ) ! = MovementStatus . RUNNING
2018-08-06 00:37:42 +00:00
& & currentState . getStatus ( ) ! = MovementStatus . PREPPING
2018-08-02 21:28:35 +00:00
& & currentState . getStatus ( ) ! = MovementStatus . WAITING ) ;
2018-08-02 07:12:51 +00:00
}
2018-08-02 18:05:47 +00:00
public BlockPos getSrc ( ) {
2018-08-02 18:12:56 +00:00
return src ;
2018-08-02 18:05:47 +00:00
}
public BlockPos getDest ( ) {
2018-08-02 18:12:56 +00:00
return dest ;
2018-08-02 18:05:47 +00:00
}
2018-08-03 03:40:27 +00:00
/ * *
2018-08-06 01:17:54 +00:00
* Run cleanup on state finish and declare success .
2018-08-03 03:40:27 +00:00
* /
2018-08-06 01:17:54 +00:00
public void onFinish ( MovementState state ) {
2018-08-07 21:14:36 +00:00
state . getInputStates ( ) . replaceAll ( ( input , forced ) - > false ) ;
state . getInputStates ( ) . forEach ( ( input , forced ) - > Baritone . INSTANCE . getInputOverrideHandler ( ) . setInputForceState ( input , forced ) ) ;
2018-08-06 01:17:54 +00:00
}
2018-08-03 03:40:27 +00:00
2018-08-06 02:08:23 +00:00
public void cancel ( ) {
2018-08-07 21:14:36 +00:00
currentState . getInputStates ( ) . replaceAll ( ( input , forced ) - > false ) ;
currentState . getInputStates ( ) . forEach ( ( input , forced ) - > Baritone . INSTANCE . getInputOverrideHandler ( ) . setInputForceState ( input , forced ) ) ;
2018-08-06 02:08:23 +00:00
currentState . setStatus ( MovementStatus . CANCELED ) ;
}
2018-08-07 00:34:49 +00:00
2018-08-17 20:17:16 +00:00
public double getTotalHardnessOfBlocksToBreak ( CalculationContext ctx ) {
2018-08-07 00:34:49 +00:00
/ *
double sum = 0 ;
HashSet < BlockPos > toBreak = new HashSet ( ) ;
for ( BlockPos positionsToBreak1 : positionsToBreak ) {
toBreak . add ( positionsToBreak1 ) ;
if ( this instanceof ActionFall ) { //if we are digging straight down, assume we have already broken the sand above us
continue ;
}
BlockPos tmp = positionsToBreak1 . up ( ) ;
while ( canFall ( tmp ) ) {
toBreak . add ( tmp ) ;
tmp = tmp . up ( ) ;
}
}
for ( BlockPos pos : toBreak ) {
sum + = getHardness ( ts , Baritone . get ( pos ) , pos ) ;
if ( sum > = COST_INF ) {
return COST_INF ;
}
}
if ( ! Baritone . allowBreakOrPlace | | ! Baritone . hasThrowaway ) {
for ( int i = 0 ; i < blocksToPlace . length ; i + + ) {
if ( ! canWalkOn ( positionsToPlace [ i ] ) ) {
return COST_INF ;
}
}
} * /
//^ the above implementation properly deals with falling blocks, TODO integrate
double sum = 0 ;
for ( BlockPos pos : positionsToBreak ) {
2018-08-17 20:17:16 +00:00
sum + = MovementHelper . getMiningDurationTicks ( ctx , pos ) ;
2018-08-07 00:34:49 +00:00
if ( sum > = COST_INF ) {
return COST_INF ;
}
}
return sum ;
}
2018-08-02 07:12:51 +00:00
/ * *
2018-08-02 21:28:35 +00:00
* Calculate latest movement state .
2018-08-02 07:12:51 +00:00
* Gets called once a tick .
*
* @return
* /
2018-08-04 18:49:52 +00:00
public MovementState updateState ( MovementState state ) {
2018-08-18 19:36:40 +00:00
if ( ! prepared ( state ) ) {
2018-08-04 18:49:52 +00:00
return state . setStatus ( MovementStatus . PREPPING ) ;
2018-08-18 19:36:40 +00:00
} else if ( state . getStatus ( ) = = MovementStatus . PREPPING ) {
2018-08-06 01:00:36 +00:00
state . setStatus ( MovementStatus . WAITING ) ;
2018-08-06 00:37:42 +00:00
}
2018-08-04 18:49:52 +00:00
return state ;
}
2018-08-06 22:53:35 +00:00
2018-08-06 23:09:28 +00:00
public ArrayList < BlockPos > toBreakCached = null ;
public ArrayList < BlockPos > toPlaceCached = null ;
2018-08-12 15:40:44 +00:00
public ArrayList < BlockPos > toWalkIntoCached = null ;
2018-08-06 23:09:28 +00:00
2018-08-06 22:53:35 +00:00
public ArrayList < BlockPos > toBreak ( ) {
2018-08-06 23:09:28 +00:00
if ( toBreakCached ! = null ) {
return toBreakCached ;
}
2018-08-06 22:53:35 +00:00
ArrayList < BlockPos > result = new ArrayList < > ( ) ;
2018-08-07 00:34:49 +00:00
for ( BlockPos positionToBreak : positionsToBreak ) {
2018-08-07 01:18:16 +00:00
if ( ! MovementHelper . canWalkThrough ( positionToBreak ) ) {
2018-08-07 00:34:49 +00:00
result . add ( positionToBreak ) ;
2018-08-06 22:53:35 +00:00
}
}
2018-08-06 23:09:28 +00:00
toBreakCached = result ;
2018-08-06 22:53:35 +00:00
return result ;
}
public ArrayList < BlockPos > toPlace ( ) {
2018-08-06 23:09:28 +00:00
if ( toPlaceCached ! = null ) {
return toPlaceCached ;
}
2018-08-06 22:53:35 +00:00
ArrayList < BlockPos > result = new ArrayList < > ( ) ;
2018-08-07 00:34:49 +00:00
for ( BlockPos positionToBreak : positionsToPlace ) {
if ( ! MovementHelper . canWalkOn ( positionToBreak ) ) {
result . add ( positionToBreak ) ;
2018-08-06 22:53:35 +00:00
}
}
2018-08-06 23:09:28 +00:00
toPlaceCached = result ;
2018-08-06 22:53:35 +00:00
return result ;
}
2018-08-12 15:40:44 +00:00
2018-08-14 22:58:53 +00:00
public ArrayList < BlockPos > toWalkInto ( ) { // overridden by movementdiagonal
2018-08-12 15:40:44 +00:00
if ( toWalkIntoCached = = null ) {
toWalkIntoCached = new ArrayList < > ( ) ;
}
return toWalkIntoCached ;
}
2018-08-02 04:07:55 +00:00
}