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-09-12 22:58:33 +00:00
package baritone.behavior ;
2018-08-22 20:15:56 +00:00
import baritone.Baritone ;
2018-09-23 23:29:03 +00:00
import baritone.api.behavior.IPathingBehavior ;
2018-08-28 00:37:21 +00:00
import baritone.api.event.events.PathEvent ;
import baritone.api.event.events.PlayerUpdateEvent ;
import baritone.api.event.events.RenderEvent ;
import baritone.api.event.events.TickEvent ;
2018-10-09 23:40:04 +00:00
import baritone.api.pathing.calc.IPath ;
import baritone.api.pathing.calc.IPathFinder ;
2018-09-24 16:57:06 +00:00
import baritone.api.pathing.goals.Goal ;
2018-10-01 04:32:13 +00:00
import baritone.api.pathing.goals.GoalXZ ;
2018-10-09 01:37:52 +00:00
import baritone.api.utils.BetterBlockPos ;
2018-10-01 04:32:13 +00:00
import baritone.api.utils.interfaces.IGoalRenderPos ;
2018-08-22 20:15:56 +00:00
import baritone.pathing.calc.AStarPathFinder ;
import baritone.pathing.calc.AbstractNodeCostSearch ;
2018-10-09 23:40:04 +00:00
import baritone.pathing.calc.CutoffPath ;
2018-09-02 16:22:51 +00:00
import baritone.pathing.movement.MovementHelper ;
2018-08-22 20:15:56 +00:00
import baritone.pathing.path.PathExecutor ;
2018-09-24 23:05:02 +00:00
import baritone.utils.BlockBreakHelper ;
2018-09-12 22:53:29 +00:00
import baritone.utils.Helper ;
2018-08-22 20:15:56 +00:00
import baritone.utils.PathRenderer ;
2018-08-05 22:38:11 +00:00
import net.minecraft.util.math.BlockPos ;
2018-08-21 23:20:08 +00:00
import net.minecraft.world.chunk.EmptyChunk ;
2018-08-05 22:38:11 +00:00
2018-10-11 00:05:51 +00:00
import java.util.* ;
2018-10-18 22:04:40 +00:00
import java.util.concurrent.LinkedBlockingQueue ;
2018-09-23 15:54:26 +00:00
import java.util.stream.Collectors ;
2018-08-05 03:25:05 +00:00
2018-09-23 23:29:03 +00:00
public final class PathingBehavior extends Behavior implements IPathingBehavior , Helper {
2018-08-05 05:25:08 +00:00
2018-08-05 03:28:32 +00:00
public static final PathingBehavior INSTANCE = new PathingBehavior ( ) ;
2018-08-05 03:25:05 +00:00
private PathExecutor current ;
2018-08-13 18:49:36 +00:00
private PathExecutor next ;
2018-08-05 03:25:05 +00:00
2018-08-05 22:38:11 +00:00
private Goal goal ;
2018-08-13 19:35:44 +00:00
private volatile boolean isPathCalcInProgress ;
private final Object pathCalcLock = new Object ( ) ;
private final Object pathPlanLock = new Object ( ) ;
2018-08-21 22:04:10 +00:00
private boolean lastAutoJump ;
2018-10-18 22:04:40 +00:00
private final LinkedBlockingQueue < PathEvent > toDispatch = new LinkedBlockingQueue < > ( ) ;
2018-09-17 03:16:05 +00:00
private PathingBehavior ( ) { }
2018-10-18 22:04:40 +00:00
private void queuePathEvent ( PathEvent event ) {
toDispatch . add ( event ) ;
}
private void dispatchEvents ( ) {
ArrayList < PathEvent > curr = new ArrayList < > ( ) ;
toDispatch . drainTo ( curr ) ;
for ( PathEvent event : curr ) {
Baritone . INSTANCE . getGameEventHandler ( ) . onPathEvent ( event ) ;
}
2018-08-23 22:39:02 +00:00
}
2018-08-05 03:28:32 +00:00
@Override
2018-08-05 23:57:50 +00:00
public void onTick ( TickEvent event ) {
2018-10-18 22:04:40 +00:00
dispatchEvents ( ) ;
2018-08-13 20:13:42 +00:00
if ( event . getType ( ) = = TickEvent . Type . OUT ) {
2018-10-18 22:04:40 +00:00
cancel ( ) ;
2018-08-13 20:13:42 +00:00
return ;
}
2018-09-12 22:25:01 +00:00
mc . playerController . setPlayerCapabilities ( mc . player ) ;
2018-10-18 22:04:40 +00:00
tickPath ( ) ;
dispatchEvents ( ) ;
}
private void tickPath ( ) {
2018-08-13 20:13:42 +00:00
if ( current = = null ) {
2018-08-05 03:28:32 +00:00
return ;
}
2018-10-18 22:04:40 +00:00
boolean safe = current . onTick ( ) ;
2018-08-13 19:35:44 +00:00
synchronized ( pathPlanLock ) {
if ( current . failed ( ) | | current . finished ( ) ) {
current = null ;
2018-08-16 23:51:43 +00:00
if ( goal = = null | | goal . isInGoal ( playerFeet ( ) ) ) {
2018-09-11 20:45:43 +00:00
logDebug ( " All done. At " + goal ) ;
2018-10-18 22:04:40 +00:00
queuePathEvent ( PathEvent . AT_GOAL ) ;
2018-08-13 19:56:08 +00:00
next = null ;
return ;
}
2018-08-13 19:35:44 +00:00
if ( next ! = null & & ! next . getPath ( ) . positions ( ) . contains ( playerFeet ( ) ) ) {
// if the current path failed, we may not actually be on the next one, so make sure
2018-09-11 20:45:43 +00:00
logDebug ( " Discarding next path as it does not contain current position " ) ;
2018-08-13 19:35:44 +00:00
// for example if we had a nicely planned ahead path that starts where current ends
// that's all fine and good
// but if we fail in the middle of current
// we're nowhere close to our planned ahead path
// so need to discard it sadly.
2018-10-18 22:04:40 +00:00
queuePathEvent ( PathEvent . DISCARD_NEXT ) ;
2018-08-13 19:35:44 +00:00
next = null ;
}
if ( next ! = null ) {
2018-09-11 20:45:43 +00:00
logDebug ( " Continuing on to planned next path " ) ;
2018-10-18 22:04:40 +00:00
queuePathEvent ( PathEvent . CONTINUING_ONTO_PLANNED_NEXT ) ;
2018-08-13 19:35:44 +00:00
current = next ;
next = null ;
2018-10-18 22:04:40 +00:00
current . onTick ( ) ;
2018-08-13 19:35:44 +00:00
return ;
}
// at this point, current just ended, but we aren't in the goal and have no plan for the future
synchronized ( pathCalcLock ) {
if ( isPathCalcInProgress ) {
2018-10-18 22:04:40 +00:00
queuePathEvent ( PathEvent . PATH_FINISHED_NEXT_STILL_CALCULATING ) ;
2018-08-13 19:35:44 +00:00
// if we aren't calculating right now
return ;
}
2018-10-18 22:04:40 +00:00
queuePathEvent ( PathEvent . CALC_STARTED ) ;
2018-08-18 19:21:21 +00:00
findPathInNewThread ( pathStart ( ) , true , Optional . empty ( ) ) ;
2018-08-13 19:35:44 +00:00
}
return ;
}
// at this point, we know current is in progress
2018-10-27 21:41:25 +00:00
if ( safe & & next ! = null & & next . snipsnapifpossible ( ) ) {
// a movement just ended; jump directly onto the next path
logDebug ( " Splicing into planned next path early... " ) ;
queuePathEvent ( PathEvent . SPLICING_ONTO_NEXT_EARLY ) ;
current = next ;
next = null ;
current . onTick ( ) ;
return ;
2018-08-13 19:35:44 +00:00
}
synchronized ( pathCalcLock ) {
if ( isPathCalcInProgress ) {
// if we aren't calculating right now
return ;
}
if ( next ! = null ) {
// and we have no plan for what to do next
return ;
}
2018-08-16 23:51:43 +00:00
if ( goal = = null | | goal . isInGoal ( current . getPath ( ) . getDest ( ) ) ) {
2018-08-13 19:35:44 +00:00
// and this path dosen't get us all the way there
return ;
}
2018-08-16 00:29:45 +00:00
if ( ticksRemainingInSegment ( ) . get ( ) < Baritone . settings ( ) . planningTickLookAhead . get ( ) ) {
2018-08-13 19:35:44 +00:00
// and this path has 5 seconds or less left
2018-09-11 20:45:43 +00:00
logDebug ( " Path almost over. Planning ahead... " ) ;
2018-10-18 22:04:40 +00:00
queuePathEvent ( PathEvent . NEXT_SEGMENT_CALC_STARTED ) ;
2018-08-16 22:10:15 +00:00
findPathInNewThread ( current . getPath ( ) . getDest ( ) , false , Optional . of ( current . getPath ( ) ) ) ;
2018-08-13 19:35:44 +00:00
}
}
2018-08-05 03:28:32 +00:00
}
}
2018-08-21 22:04:10 +00:00
@Override
public void onPlayerUpdate ( PlayerUpdateEvent event ) {
if ( current ! = null ) {
switch ( event . getState ( ) ) {
case PRE :
lastAutoJump = mc . gameSettings . autoJump ;
mc . gameSettings . autoJump = false ;
break ;
case POST :
mc . gameSettings . autoJump = lastAutoJump ;
break ;
2018-09-17 02:50:07 +00:00
default :
break ;
2018-08-21 22:04:10 +00:00
}
}
}
2018-09-23 23:29:03 +00:00
@Override
2018-08-16 00:29:45 +00:00
public Optional < Double > ticksRemainingInSegment ( ) {
if ( current = = null ) {
return Optional . empty ( ) ;
}
return Optional . of ( current . getPath ( ) . ticksRemainingFrom ( current . getPosition ( ) ) ) ;
}
2018-09-23 23:29:03 +00:00
@Override
2018-08-14 03:57:29 +00:00
public void setGoal ( Goal goal ) {
this . goal = goal ;
2018-08-07 14:47:37 +00:00
}
2018-08-05 22:38:11 +00:00
2018-10-26 04:21:42 +00:00
public boolean setGoalAndPath ( Goal goal ) {
setGoal ( goal ) ;
return path ( ) ;
}
2018-09-23 23:29:03 +00:00
@Override
2018-08-25 22:09:47 +00:00
public Goal getGoal ( ) {
return goal ;
}
2018-10-09 01:37:52 +00:00
@Override
2018-08-14 22:32:16 +00:00
public PathExecutor getCurrent ( ) {
2018-08-09 21:48:10 +00:00
return current ;
}
2018-10-09 01:37:52 +00:00
@Override
2018-08-21 21:36:51 +00:00
public PathExecutor getNext ( ) {
return next ;
}
2018-08-14 22:32:16 +00:00
2018-10-09 01:37:52 +00:00
@Override
2018-10-09 02:09:54 +00:00
public Optional < IPathFinder > getPathFinder ( ) {
2018-10-09 01:37:52 +00:00
return Optional . ofNullable ( AbstractNodeCostSearch . currentlyRunning ( ) ) ;
2018-08-05 22:38:11 +00:00
}
2018-09-23 23:29:03 +00:00
@Override
public boolean isPathing ( ) {
return this . current ! = null ;
}
@Override
2018-09-12 22:25:01 +00:00
public void cancel ( ) {
2018-10-18 22:04:40 +00:00
queuePathEvent ( PathEvent . CANCELED ) ;
2018-08-14 03:57:29 +00:00
current = null ;
next = null ;
Baritone . INSTANCE . getInputOverrideHandler ( ) . clearAllKeys ( ) ;
2018-08-28 18:17:11 +00:00
AbstractNodeCostSearch . getCurrentlyRunning ( ) . ifPresent ( AbstractNodeCostSearch : : cancel ) ;
2018-09-24 23:05:02 +00:00
BlockBreakHelper . stopBreakingBlock ( ) ;
2018-09-12 01:26:10 +00:00
}
2018-09-24 16:57:06 +00:00
public void forceCancel ( ) { // NOT exposed on public api
isPathCalcInProgress = false ;
}
2018-08-28 18:43:28 +00:00
/ * *
* Start calculating a path if we aren ' t already
*
* @return true if this call started path calculation , false if it was already calculating or executing a path
* /
2018-09-23 23:29:03 +00:00
@Override
2018-08-28 18:43:28 +00:00
public boolean path ( ) {
2018-08-31 21:58:23 +00:00
if ( goal = = null ) {
return false ;
}
if ( goal . isInGoal ( playerFeet ( ) ) ) {
return false ;
}
2018-08-16 22:10:15 +00:00
synchronized ( pathPlanLock ) {
if ( current ! = null ) {
2018-08-28 18:43:28 +00:00
return false ;
2018-08-14 03:57:29 +00:00
}
2018-08-16 22:10:15 +00:00
synchronized ( pathCalcLock ) {
if ( isPathCalcInProgress ) {
2018-08-28 18:43:28 +00:00
return false ;
2018-08-16 22:10:15 +00:00
}
2018-10-18 22:04:40 +00:00
queuePathEvent ( PathEvent . CALC_STARTED ) ;
2018-08-18 19:21:21 +00:00
findPathInNewThread ( pathStart ( ) , true , Optional . empty ( ) ) ;
2018-08-28 18:43:28 +00:00
return true ;
2018-08-16 22:10:15 +00:00
}
2018-08-14 03:57:29 +00:00
}
}
2018-09-23 23:29:03 +00:00
/ * *
2018-10-11 00:05:51 +00:00
* See issue # 209
*
2018-09-23 23:29:03 +00:00
* @return The starting { @link BlockPos } for a new path
* /
2018-10-11 00:05:51 +00:00
public BlockPos pathStart ( ) {
2018-09-22 15:47:02 +00:00
BetterBlockPos feet = playerFeet ( ) ;
2018-10-11 00:05:51 +00:00
if ( ! MovementHelper . canWalkOn ( feet . down ( ) ) ) {
if ( player ( ) . onGround ) {
double playerX = player ( ) . posX ;
double playerZ = player ( ) . posZ ;
ArrayList < BetterBlockPos > closest = new ArrayList < > ( ) ;
for ( int dx = - 1 ; dx < = 1 ; dx + + ) {
for ( int dz = - 1 ; dz < = 1 ; dz + + ) {
closest . add ( new BetterBlockPos ( feet . x + dx , feet . y , feet . z + dz ) ) ;
}
}
closest . sort ( Comparator . comparingDouble ( pos - > ( ( pos . x + 0 . 5D ) - playerX ) * ( ( pos . x + 0 . 5D ) - playerX ) + ( ( pos . z + 0 . 5D ) - playerZ ) * ( ( pos . z + 0 . 5D ) - playerZ ) ) ) ;
for ( int i = 0 ; i < 4 ; i + + ) {
BetterBlockPos possibleSupport = closest . get ( i ) ;
double xDist = Math . abs ( ( possibleSupport . x + 0 . 5D ) - playerX ) ;
double zDist = Math . abs ( ( possibleSupport . z + 0 . 5D ) - playerZ ) ;
if ( xDist > 0 . 8 & & zDist > 0 . 8 ) {
// can't possibly be sneaking off of this one, we're too far away
continue ;
}
if ( MovementHelper . canWalkOn ( possibleSupport . down ( ) ) & & MovementHelper . canWalkThrough ( possibleSupport ) & & MovementHelper . canWalkThrough ( possibleSupport . up ( ) ) ) {
// this is plausible
logDebug ( " Faking path start assuming player is standing off the edge of a block " ) ;
return possibleSupport ;
}
}
} else {
// !onGround
// we're in the middle of a jump
if ( MovementHelper . canWalkOn ( feet . down ( ) . down ( ) ) ) {
logDebug ( " Faking path start assuming player is midair and falling " ) ;
return feet . down ( ) ;
}
}
2018-08-18 19:21:21 +00:00
}
return feet ;
}
2018-08-05 22:38:11 +00:00
/ * *
* In a new thread , pathfind to target blockpos
*
* @param start
* @param talkAboutIt
* /
2018-08-16 22:10:15 +00:00
private void findPathInNewThread ( final BlockPos start , final boolean talkAboutIt , final Optional < IPath > previous ) {
2018-08-13 19:35:44 +00:00
synchronized ( pathCalcLock ) {
if ( isPathCalcInProgress ) {
throw new IllegalStateException ( " Already doing it " ) ;
}
isPathCalcInProgress = true ;
}
2018-09-16 21:14:50 +00:00
Baritone . INSTANCE . getExecutor ( ) . execute ( ( ) - > {
2018-08-05 23:56:21 +00:00
if ( talkAboutIt ) {
2018-09-11 20:45:43 +00:00
logDebug ( " Starting to search for path from " + start + " to " + goal ) ;
2018-08-05 23:56:21 +00:00
}
2018-08-05 22:38:11 +00:00
2018-08-19 18:45:50 +00:00
Optional < IPath > path = findPath ( start , previous ) ;
if ( Baritone . settings ( ) . cutoffAtLoadBoundary . get ( ) ) {
2018-10-09 00:23:43 +00:00
path = path . map ( p - > {
2018-10-09 05:10:50 +00:00
IPath result = p . cutoffAtLoadedChunks ( ) ;
2018-10-09 00:23:43 +00:00
2018-10-09 05:10:50 +00:00
if ( result instanceof CutoffPath ) {
2018-10-09 00:23:43 +00:00
logDebug ( " Cutting off path at edge of loaded chunks " ) ;
2018-10-09 05:10:50 +00:00
logDebug ( " Length decreased by " + ( p . length ( ) - result . length ( ) ) ) ;
2018-10-09 00:23:43 +00:00
} else {
logDebug ( " Path ends within loaded chunks " ) ;
}
2018-10-09 05:10:50 +00:00
return result ;
2018-10-09 00:23:43 +00:00
} ) ;
2018-08-19 18:45:50 +00:00
}
2018-10-09 00:23:43 +00:00
Optional < PathExecutor > executor = path . map ( p - > {
2018-10-09 05:10:50 +00:00
IPath result = p . staticCutoff ( goal ) ;
2018-10-09 00:23:43 +00:00
2018-10-09 05:10:50 +00:00
if ( result instanceof CutoffPath ) {
logDebug ( " Static cutoff " + p . length ( ) + " to " + result . length ( ) ) ;
2018-10-09 00:23:43 +00:00
}
2018-10-09 05:10:50 +00:00
return result ;
2018-10-09 00:23:43 +00:00
} ) . map ( PathExecutor : : new ) ;
2018-08-23 22:39:02 +00:00
synchronized ( pathPlanLock ) {
if ( current = = null ) {
if ( executor . isPresent ( ) ) {
2018-10-18 22:04:40 +00:00
queuePathEvent ( PathEvent . CALC_FINISHED_NOW_EXECUTING ) ;
2018-08-23 22:39:02 +00:00
current = executor . get ( ) ;
2018-08-13 19:35:44 +00:00
} else {
2018-10-18 22:04:40 +00:00
queuePathEvent ( PathEvent . CALC_FAILED ) ;
2018-08-23 22:39:02 +00:00
}
} else {
if ( next = = null ) {
if ( executor . isPresent ( ) ) {
2018-10-18 22:04:40 +00:00
queuePathEvent ( PathEvent . NEXT_SEGMENT_CALC_FINISHED ) ;
2018-08-23 22:39:02 +00:00
next = executor . get ( ) ;
2018-08-13 19:35:44 +00:00
} else {
2018-10-18 22:04:40 +00:00
queuePathEvent ( PathEvent . NEXT_CALC_FAILED ) ;
2018-08-13 19:35:44 +00:00
}
2018-08-23 22:39:02 +00:00
} else {
throw new IllegalStateException ( " I have no idea what to do with this path " ) ;
2018-08-13 19:35:44 +00:00
}
}
2018-08-23 22:39:02 +00:00
}
2018-08-06 14:14:20 +00:00
if ( talkAboutIt & & current ! = null & & current . getPath ( ) ! = null ) {
2018-08-16 23:51:43 +00:00
if ( goal = = null | | goal . isInGoal ( current . getPath ( ) . getDest ( ) ) ) {
2018-09-11 20:45:43 +00:00
logDebug ( " Finished finding a path from " + start + " to " + goal + " . " + current . getPath ( ) . getNumNodesConsidered ( ) + " nodes considered " ) ;
2018-08-16 00:53:42 +00:00
} else {
2018-09-11 20:45:43 +00:00
logDebug ( " Found path segment from " + start + " towards " + goal + " . " + current . getPath ( ) . getNumNodesConsidered ( ) + " nodes considered " ) ;
2018-08-16 00:53:42 +00:00
}
2018-08-06 14:14:20 +00:00
}
2018-08-13 19:35:44 +00:00
synchronized ( pathCalcLock ) {
isPathCalcInProgress = false ;
}
2018-09-16 21:14:50 +00:00
} ) ;
2018-08-05 22:38:11 +00:00
}
/ * *
* Actually do the pathing
*
* @param start
* @return
* /
2018-08-16 22:10:15 +00:00
private Optional < IPath > findPath ( BlockPos start , Optional < IPath > previous ) {
2018-08-21 23:20:08 +00:00
Goal goal = this . goal ;
2018-08-05 22:38:11 +00:00
if ( goal = = null ) {
2018-09-11 20:45:43 +00:00
logDebug ( " no goal " ) ;
2018-08-06 07:21:47 +00:00
return Optional . empty ( ) ;
2018-08-05 22:38:11 +00:00
}
2018-08-28 15:55:56 +00:00
if ( Baritone . settings ( ) . simplifyUnloadedYCoord . get ( ) ) {
BlockPos pos = null ;
2018-09-17 02:24:13 +00:00
if ( goal instanceof IGoalRenderPos ) {
2018-09-17 02:18:39 +00:00
pos = ( ( IGoalRenderPos ) goal ) . getGoalPos ( ) ;
2018-09-17 02:24:13 +00:00
}
2018-09-17 02:18:39 +00:00
2018-08-28 15:55:56 +00:00
if ( pos ! = null & & world ( ) . getChunk ( pos ) instanceof EmptyChunk ) {
2018-10-02 17:19:14 +00:00
logDebug ( " Simplifying " + goal . getClass ( ) + " to GoalXZ due to distance " ) ;
2018-08-21 23:20:08 +00:00
goal = new GoalXZ ( pos . getX ( ) , pos . getZ ( ) ) ;
}
}
2018-09-02 20:51:38 +00:00
long timeout ;
if ( current = = null ) {
timeout = Baritone . settings ( ) . pathTimeoutMS . < Long > get ( ) ;
} else {
timeout = Baritone . settings ( ) . planAheadTimeoutMS . < Long > get ( ) ;
}
2018-10-03 14:52:17 +00:00
Optional < HashSet < Long > > favoredPositions ;
if ( Baritone . settings ( ) . backtrackCostFavoringCoefficient . get ( ) = = 1D ) {
favoredPositions = Optional . empty ( ) ;
} else {
favoredPositions = previous . map ( IPath : : positions ) . map ( Collection : : stream ) . map ( x - > x . map ( BetterBlockPos : : longHash ) ) . map ( x - > x . collect ( Collectors . toList ( ) ) ) . map ( HashSet : : new ) ; // <-- okay this is EPIC
}
2018-08-05 22:38:11 +00:00
try {
2018-10-03 14:57:24 +00:00
IPathFinder pf = new AStarPathFinder ( start . getX ( ) , start . getY ( ) , start . getZ ( ) , goal , favoredPositions ) ;
2018-09-02 20:51:38 +00:00
return pf . calculate ( timeout ) ;
2018-08-05 22:38:11 +00:00
} catch ( Exception e ) {
2018-09-11 20:45:43 +00:00
logDebug ( " Pathing exception: " + e ) ;
2018-08-05 22:38:11 +00:00
e . printStackTrace ( ) ;
2018-08-06 07:21:47 +00:00
return Optional . empty ( ) ;
2018-08-05 22:38:11 +00:00
}
}
2018-09-17 17:56:37 +00:00
public void revalidateGoal ( ) {
if ( ! Baritone . settings ( ) . cancelOnGoalInvalidation . get ( ) ) {
return ;
}
2018-10-03 14:43:45 +00:00
synchronized ( pathPlanLock ) {
if ( current = = null | | goal = = null ) {
return ;
}
Goal intended = current . getPath ( ) . getGoal ( ) ;
BlockPos end = current . getPath ( ) . getDest ( ) ;
if ( intended . isInGoal ( end ) & & ! goal . isInGoal ( end ) ) {
// this path used to end in the goal
// but the goal has changed, so there's no reason to continue...
cancel ( ) ;
}
2018-09-17 17:56:37 +00:00
}
}
2018-08-05 21:48:10 +00:00
@Override
public void onRenderPass ( RenderEvent event ) {
2018-10-08 22:11:07 +00:00
PathRenderer . render ( event , this ) ;
2018-08-05 22:53:11 +00:00
}
2018-09-24 02:35:36 +00:00
@Override
public void onDisable ( ) {
Baritone . INSTANCE . getInputOverrideHandler ( ) . clearAllKeys ( ) ;
}
2018-08-05 03:19:32 +00:00
}