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-05 05:15:18 +00:00
package baritone.bot.behavior.impl ;
2018-08-05 03:19:32 +00:00
2018-08-07 04:07:15 +00:00
import baritone.bot.Baritone ;
2018-08-05 05:15:18 +00:00
import baritone.bot.behavior.Behavior ;
2018-08-05 22:38:11 +00:00
import baritone.bot.event.events.ChatEvent ;
2018-08-05 21:48:10 +00:00
import baritone.bot.event.events.RenderEvent ;
2018-08-05 23:57:50 +00:00
import baritone.bot.event.events.TickEvent ;
2018-08-05 22:38:11 +00:00
import baritone.bot.pathing.calc.AStarPathFinder ;
2018-08-05 22:53:11 +00:00
import baritone.bot.pathing.calc.AbstractNodeCostSearch ;
2018-08-05 22:38:11 +00:00
import baritone.bot.pathing.calc.IPathFinder ;
import baritone.bot.pathing.goals.Goal ;
import baritone.bot.pathing.goals.GoalBlock ;
2018-08-07 14:47:37 +00:00
import baritone.bot.pathing.goals.GoalXZ ;
2018-08-06 23:12:41 +00:00
import baritone.bot.pathing.movement.Movement ;
2018-08-05 03:28:32 +00:00
import baritone.bot.pathing.path.IPath ;
2018-08-05 03:25:05 +00:00
import baritone.bot.pathing.path.PathExecutor ;
2018-08-05 22:53:11 +00:00
import baritone.bot.utils.BlockStateInterface ;
import net.minecraft.block.Block ;
import net.minecraft.block.state.IBlockState ;
2018-08-05 22:38:11 +00:00
import net.minecraft.client.Minecraft ;
import net.minecraft.client.entity.EntityPlayerSP ;
import net.minecraft.client.renderer.BufferBuilder ;
import net.minecraft.client.renderer.GlStateManager ;
import net.minecraft.client.renderer.Tessellator ;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats ;
import net.minecraft.entity.player.EntityPlayer ;
2018-08-05 22:53:11 +00:00
import net.minecraft.init.Blocks ;
import net.minecraft.util.math.AxisAlignedBB ;
2018-08-05 22:38:11 +00:00
import net.minecraft.util.math.BlockPos ;
import org.lwjgl.opengl.GL11 ;
import java.awt.* ;
import java.util.List ;
2018-08-06 07:21:47 +00:00
import java.util.Optional ;
2018-08-05 03:25:05 +00:00
2018-08-05 03:28:32 +00:00
public class PathingBehavior extends Behavior {
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 05:25:08 +00:00
private PathingBehavior ( ) { }
2018-08-05 03:25:05 +00:00
private PathExecutor current ;
2018-08-05 22:38:11 +00:00
private Goal goal ;
2018-08-05 03:28:32 +00:00
@Override
2018-08-05 23:57:50 +00:00
public void onTick ( TickEvent event ) {
2018-08-06 22:53:35 +00:00
if ( event . getType ( ) = = TickEvent . Type . OUT | | current = = null ) {
2018-08-05 03:28:32 +00:00
return ;
}
2018-08-06 01:17:04 +00:00
current . onTick ( event ) ;
2018-08-05 03:28:32 +00:00
if ( current . failed ( ) | | current . finished ( ) ) {
current = null ;
2018-08-07 04:07:15 +00:00
if ( ! goal . isInGoal ( playerFeet ( ) ) )
findPathInNewThread ( playerFeet ( ) , true ) ;
2018-08-05 03:28:32 +00:00
}
}
public PathExecutor getExecutor ( ) {
return current ;
}
2018-08-06 07:21:47 +00:00
public Optional < IPath > getPath ( ) {
return Optional . ofNullable ( current ) . map ( PathExecutor : : getPath ) ;
2018-08-05 03:28:32 +00:00
}
2018-08-05 21:48:10 +00:00
2018-08-05 22:38:11 +00:00
@Override
public void onSendChatMessage ( ChatEvent event ) {
String msg = event . getMessage ( ) ;
if ( msg . equals ( " goal " ) ) {
goal = new GoalBlock ( playerFeet ( ) ) ;
2018-08-05 23:56:21 +00:00
displayChatMessageRaw ( " Goal: " + goal ) ;
2018-08-05 22:38:11 +00:00
event . cancel ( ) ;
return ;
}
if ( msg . equals ( " path " ) ) {
findPathInNewThread ( playerFeet ( ) , true ) ;
event . cancel ( ) ;
return ;
}
2018-08-06 14:01:25 +00:00
if ( msg . toLowerCase ( ) . equals ( " slowpath " ) ) {
AStarPathFinder . slowPath ^ = true ;
event . cancel ( ) ;
return ;
}
2018-08-07 04:07:15 +00:00
if ( msg . toLowerCase ( ) . equals ( " cancel " ) ) {
current = null ;
Baritone . INSTANCE . getInputOverrideHandler ( ) . clearAllKeys ( ) ;
event . cancel ( ) ;
displayChatMessageRaw ( " ok canceled " ) ;
return ;
}
2018-08-07 14:47:37 +00:00
if ( msg . toLowerCase ( ) . startsWith ( " thisway " ) ) {
goal = fromAngleAndDirection ( Double . parseDouble ( msg . substring ( 7 ) . trim ( ) ) ) ;
displayChatMessageRaw ( " Goal: " + goal ) ;
event . cancel ( ) ;
return ;
}
}
2018-08-05 22:38:11 +00:00
2018-08-07 14:47:37 +00:00
public GoalXZ fromAngleAndDirection ( double distance ) {
double theta = ( ( double ) player ( ) . rotationYaw ) * Math . PI / 180D ;
double x = player ( ) . posX - Math . sin ( theta ) * distance ;
double z = player ( ) . posZ + Math . cos ( theta ) * distance ;
return new GoalXZ ( ( int ) x , ( int ) z ) ;
2018-08-05 22:38:11 +00:00
}
/ * *
* In a new thread , pathfind to target blockpos
*
* @param start
* @param talkAboutIt
* /
public void findPathInNewThread ( final BlockPos start , final boolean talkAboutIt ) {
2018-08-05 23:56:21 +00:00
new Thread ( ( ) - > {
if ( talkAboutIt ) {
displayChatMessageRaw ( " Starting to search for path from " + start + " to " + goal ) ;
}
2018-08-05 22:38:11 +00:00
2018-08-06 08:23:40 +00:00
findPath ( start ) . map ( PathExecutor : : new ) . ifPresent ( path - > current = path ) ;
2018-08-05 23:56:21 +00:00
/ * isThereAnythingInProgress = false ;
if ( ! currentPath . goal . isInGoal ( currentPath . end ) ) {
if ( talkAboutIt ) {
Out . gui ( " I couldn't get all the way to " + goal + " , but I'm going to get as close as I can. " + currentPath . numNodes + " nodes considered " , Out . Mode . Standard ) ;
2018-08-05 22:38:11 +00:00
}
2018-08-05 23:56:21 +00:00
planAhead ( ) ;
} else if ( talkAboutIt ) {
2018-08-06 14:14:20 +00:00
Out . gui ( , Out . Mode . Debug ) ;
2018-08-05 23:56:21 +00:00
} * /
2018-08-06 14:14:20 +00:00
if ( talkAboutIt & & current ! = null & & current . getPath ( ) ! = null ) {
displayChatMessageRaw ( " Finished finding a path from " + start + " to " + goal + " . " + current . getPath ( ) . getNumNodesConsidered ( ) + " nodes considered " ) ;
}
2018-08-05 23:56:21 +00:00
} ) . start ( ) ;
2018-08-05 22:38:11 +00:00
}
/ * *
* Actually do the pathing
*
* @param start
* @return
* /
2018-08-06 07:21:47 +00:00
private Optional < IPath > findPath ( BlockPos start ) {
2018-08-05 22:38:11 +00:00
if ( goal = = null ) {
2018-08-05 23:56:21 +00:00
displayChatMessageRaw ( " no goal " ) ;
2018-08-06 07:21:47 +00:00
return Optional . empty ( ) ;
2018-08-05 22:38:11 +00:00
}
try {
IPathFinder pf = new AStarPathFinder ( start , goal ) ;
2018-08-06 07:21:47 +00:00
return pf . calculate ( ) ;
2018-08-05 22:38:11 +00:00
} catch ( Exception e ) {
e . printStackTrace ( ) ;
2018-08-06 07:21:47 +00:00
return Optional . empty ( ) ;
2018-08-05 22:38:11 +00:00
}
}
2018-08-05 21:48:10 +00:00
@Override
public void onRenderPass ( RenderEvent event ) {
2018-08-05 22:38:11 +00:00
//System.out.println("Render passing");
//System.out.println(event.getPartialTicks());
2018-08-05 22:53:11 +00:00
float partialTicks = event . getPartialTicks ( ) ;
2018-08-06 23:09:28 +00:00
long start = System . currentTimeMillis ( ) ;
2018-08-06 07:21:47 +00:00
// Render the current path, if there is one
2018-08-09 20:08:56 +00:00
if ( current ! = null & & current . getPath ( ) ! = null ) {
int renderBegin = Math . max ( current . getPosition ( ) - 3 , 0 ) ;
drawPath ( current . getPath ( ) , renderBegin , player ( ) , partialTicks , Color . RED ) ;
}
2018-08-06 23:09:28 +00:00
long split = System . currentTimeMillis ( ) ;
2018-08-06 22:53:35 +00:00
getPath ( ) . ifPresent ( path - > {
2018-08-06 23:12:41 +00:00
for ( Movement m : path . movements ( ) ) {
for ( BlockPos pos : m . toPlace ( ) )
drawSelectionBox ( player ( ) , pos , partialTicks , Color . GREEN ) ;
for ( BlockPos pos : m . toBreak ( ) ) {
drawSelectionBox ( player ( ) , pos , partialTicks , Color . RED ) ;
}
2018-08-06 22:53:35 +00:00
}
} ) ;
2018-08-06 07:21:47 +00:00
// If there is a path calculation currently running, render the path calculation process
AbstractNodeCostSearch . getCurrentlyRunning ( ) . ifPresent ( currentlyRunning - > {
currentlyRunning . bestPathSoFar ( ) . ifPresent ( p - > {
2018-08-09 20:08:56 +00:00
drawPath ( p , 0 , player ( ) , partialTicks , Color . BLUE ) ;
2018-08-06 07:21:47 +00:00
currentlyRunning . pathToMostRecentNodeConsidered ( ) . ifPresent ( mr - > {
2018-08-09 20:08:56 +00:00
drawPath ( mr , 0 , player ( ) , partialTicks , Color . CYAN ) ;
2018-08-05 22:53:11 +00:00
drawSelectionBox ( player ( ) , mr . getDest ( ) , partialTicks , Color . CYAN ) ;
2018-08-06 07:21:47 +00:00
} ) ;
} ) ;
} ) ;
2018-08-06 23:09:28 +00:00
long end = System . currentTimeMillis ( ) ;
2018-08-07 02:48:09 +00:00
// if (end - start > 0)
// System.out.println("Frame took " + (split - start) + " " + (end - split));
2018-08-05 22:38:11 +00:00
}
2018-08-09 20:03:07 +00:00
private static BlockPos diff ( BlockPos a , BlockPos b ) {
return new BlockPos ( a . getX ( ) - b . getX ( ) , a . getY ( ) - b . getY ( ) , a . getZ ( ) - b . getZ ( ) ) ;
}
2018-08-09 20:08:56 +00:00
public void drawPath ( IPath path , int startIndex , EntityPlayerSP player , float partialTicks , Color color ) {
2018-08-05 22:38:11 +00:00
GlStateManager . enableBlend ( ) ;
GlStateManager . tryBlendFuncSeparate ( 770 , 771 , 1 , 0 ) ;
GlStateManager . color ( color . getColorComponents ( null ) [ 0 ] , color . getColorComponents ( null ) [ 1 ] , color . getColorComponents ( null ) [ 2 ] , 0 . 4F ) ;
GL11 . glLineWidth ( 3 . 0F ) ;
GlStateManager . disableTexture2D ( ) ;
GlStateManager . depthMask ( false ) ;
2018-08-05 22:53:11 +00:00
List < BlockPos > positions = path . positions ( ) ;
2018-08-09 20:03:07 +00:00
int next ;
2018-08-09 20:08:56 +00:00
for ( int i = startIndex ; i < positions . size ( ) - 1 ; i = next ) {
2018-08-09 20:03:07 +00:00
BlockPos start = positions . get ( i ) ;
next = i + 1 ;
BlockPos end = positions . get ( next ) ;
BlockPos direction = diff ( start , end ) ;
while ( next + 1 < positions . size ( ) & & direction . equals ( diff ( end , positions . get ( next + 1 ) ) ) ) {
next + + ;
end = positions . get ( next ) ;
}
double x1 = start . getX ( ) ;
double y1 = start . getY ( ) ;
double z1 = start . getZ ( ) ;
double x2 = end . getX ( ) ;
double y2 = end . getY ( ) ;
double z2 = end . getZ ( ) ;
2018-08-05 22:53:11 +00:00
drawLine ( player , x1 , y1 , z1 , x2 , y2 , z2 , partialTicks ) ;
2018-08-05 22:38:11 +00:00
}
//GlStateManager.color(0.0f, 0.0f, 0.0f, 0.4f);
GlStateManager . depthMask ( true ) ;
GlStateManager . enableTexture2D ( ) ;
GlStateManager . disableBlend ( ) ;
}
public static void drawLine ( EntityPlayer player , double bp1x , double bp1y , double bp1z , double bp2x , double bp2y , double bp2z , float partialTicks ) {
Tessellator tessellator = Tessellator . getInstance ( ) ;
2018-08-06 07:48:42 +00:00
BufferBuilder buffer = tessellator . getBuffer ( ) ;
2018-08-05 22:38:11 +00:00
double d0 = player . lastTickPosX + ( player . posX - player . lastTickPosX ) * ( double ) partialTicks ;
double d1 = player . lastTickPosY + ( player . posY - player . lastTickPosY ) * ( double ) partialTicks ;
double d2 = player . lastTickPosZ + ( player . posZ - player . lastTickPosZ ) * ( double ) partialTicks ;
2018-08-06 07:48:42 +00:00
buffer . begin ( 3 , DefaultVertexFormats . POSITION ) ;
buffer . pos ( bp1x + 0 . 5D - d0 , bp1y + 0 . 5D - d1 , bp1z + 0 . 5D - d2 ) . endVertex ( ) ;
buffer . pos ( bp2x + 0 . 5D - d0 , bp2y + 0 . 5D - d1 , bp2z + 0 . 5D - d2 ) . endVertex ( ) ;
buffer . pos ( bp2x + 0 . 5D - d0 , bp2y + 0 . 53D - d1 , bp2z + 0 . 5D - d2 ) . endVertex ( ) ;
buffer . pos ( bp1x + 0 . 5D - d0 , bp1y + 0 . 53D - d1 , bp1z + 0 . 5D - d2 ) . endVertex ( ) ;
buffer . pos ( bp1x + 0 . 5D - d0 , bp1y + 0 . 5D - d1 , bp1z + 0 . 5D - d2 ) . endVertex ( ) ;
2018-08-05 22:38:11 +00:00
tessellator . draw ( ) ;
2018-08-05 21:48:10 +00:00
}
2018-08-05 22:53:11 +00:00
public static void drawSelectionBox ( EntityPlayer player , BlockPos blockpos , float partialTicks , Color color ) {
GlStateManager . enableBlend ( ) ;
GlStateManager . tryBlendFuncSeparate ( 770 , 771 , 1 , 0 ) ;
GlStateManager . color ( color . getColorComponents ( null ) [ 0 ] , color . getColorComponents ( null ) [ 1 ] , color . getColorComponents ( null ) [ 2 ] , 0 . 4F ) ;
GL11 . glLineWidth ( 5 . 0F ) ;
GlStateManager . disableTexture2D ( ) ;
GlStateManager . depthMask ( false ) ;
float f = 0 . 002F ;
//BlockPos blockpos = movingObjectPositionIn.getBlockPos();
IBlockState state = BlockStateInterface . get ( blockpos ) ;
Block block = state . getBlock ( ) ;
if ( block . equals ( Blocks . AIR ) ) {
block = Blocks . DIRT ;
}
//block.setBlockBoundsBasedOnState(Minecraft.getMinecraft().world, blockpos);
double d0 = player . lastTickPosX + ( player . posX - player . lastTickPosX ) * ( double ) partialTicks ;
double d1 = player . lastTickPosY + ( player . posY - player . lastTickPosY ) * ( double ) partialTicks ;
double d2 = player . lastTickPosZ + ( player . posZ - player . lastTickPosZ ) * ( double ) partialTicks ;
2018-08-09 21:05:14 +00:00
AxisAlignedBB toDraw = state . getSelectedBoundingBox ( Minecraft . getMinecraft ( ) . world , blockpos ) . expand ( 0 . 0020000000949949026D , 0 . 0020000000949949026D , 0 . 0020000000949949026D ) . offset ( - d0 , - d1 , - d2 ) ;
2018-08-05 22:53:11 +00:00
Tessellator tessellator = Tessellator . getInstance ( ) ;
2018-08-06 07:48:42 +00:00
BufferBuilder buffer = tessellator . getBuffer ( ) ;
buffer . begin ( 3 , DefaultVertexFormats . POSITION ) ;
buffer . pos ( toDraw . minX , toDraw . minY , toDraw . minZ ) . endVertex ( ) ;
buffer . pos ( toDraw . maxX , toDraw . minY , toDraw . minZ ) . endVertex ( ) ;
buffer . pos ( toDraw . maxX , toDraw . minY , toDraw . maxZ ) . endVertex ( ) ;
buffer . pos ( toDraw . minX , toDraw . minY , toDraw . maxZ ) . endVertex ( ) ;
buffer . pos ( toDraw . minX , toDraw . minY , toDraw . minZ ) . endVertex ( ) ;
2018-08-05 22:53:11 +00:00
tessellator . draw ( ) ;
2018-08-06 07:48:42 +00:00
buffer . begin ( 3 , DefaultVertexFormats . POSITION ) ;
buffer . pos ( toDraw . minX , toDraw . maxY , toDraw . minZ ) . endVertex ( ) ;
buffer . pos ( toDraw . maxX , toDraw . maxY , toDraw . minZ ) . endVertex ( ) ;
buffer . pos ( toDraw . maxX , toDraw . maxY , toDraw . maxZ ) . endVertex ( ) ;
buffer . pos ( toDraw . minX , toDraw . maxY , toDraw . maxZ ) . endVertex ( ) ;
buffer . pos ( toDraw . minX , toDraw . maxY , toDraw . minZ ) . endVertex ( ) ;
2018-08-05 22:53:11 +00:00
tessellator . draw ( ) ;
2018-08-06 07:48:42 +00:00
buffer . begin ( 1 , DefaultVertexFormats . POSITION ) ;
buffer . pos ( toDraw . minX , toDraw . minY , toDraw . minZ ) . endVertex ( ) ;
buffer . pos ( toDraw . minX , toDraw . maxY , toDraw . minZ ) . endVertex ( ) ;
buffer . pos ( toDraw . maxX , toDraw . minY , toDraw . minZ ) . endVertex ( ) ;
buffer . pos ( toDraw . maxX , toDraw . maxY , toDraw . minZ ) . endVertex ( ) ;
buffer . pos ( toDraw . maxX , toDraw . minY , toDraw . maxZ ) . endVertex ( ) ;
buffer . pos ( toDraw . maxX , toDraw . maxY , toDraw . maxZ ) . endVertex ( ) ;
buffer . pos ( toDraw . minX , toDraw . minY , toDraw . maxZ ) . endVertex ( ) ;
buffer . pos ( toDraw . minX , toDraw . maxY , toDraw . maxZ ) . endVertex ( ) ;
2018-08-05 22:53:11 +00:00
tessellator . draw ( ) ;
GlStateManager . depthMask ( true ) ;
GlStateManager . enableTexture2D ( ) ;
GlStateManager . disableBlend ( ) ;
}
2018-08-05 03:19:32 +00:00
}