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-02 21:28:35 +00:00
package baritone.bot.pathing.movement ;
2018-08-02 17:25:46 +00:00
2018-08-08 19:51:04 +00:00
import baritone.bot.InputOverrideHandler ;
2018-08-06 21:32:54 +00:00
import baritone.bot.behavior.impl.LookBehaviorUtils ;
2018-08-08 19:51:04 +00:00
import baritone.bot.pathing.movement.MovementState.MovementTarget ;
2018-08-07 13:16:38 +00:00
import baritone.bot.pathing.movement.movements.MovementDescend ;
import baritone.bot.pathing.movement.movements.MovementFall ;
2018-08-08 19:51:04 +00:00
import baritone.bot.utils.* ;
2018-08-02 17:25:46 +00:00
import net.minecraft.block.* ;
import net.minecraft.block.state.IBlockState ;
import net.minecraft.client.Minecraft ;
2018-08-06 22:53:35 +00:00
import net.minecraft.client.entity.EntityPlayerSP ;
2018-08-04 02:14:50 +00:00
import net.minecraft.entity.Entity ;
2018-08-02 17:49:31 +00:00
import net.minecraft.init.Blocks ;
2018-08-06 22:53:35 +00:00
import net.minecraft.item.Item ;
import net.minecraft.item.ItemStack ;
2018-08-07 13:16:38 +00:00
import net.minecraft.util.EnumFacing ;
2018-08-06 22:53:35 +00:00
import net.minecraft.util.NonNullList ;
2018-08-02 17:25:46 +00:00
import net.minecraft.util.math.BlockPos ;
2018-08-04 02:14:50 +00:00
import net.minecraft.util.math.RayTraceResult ;
2018-08-02 17:25:46 +00:00
2018-08-06 22:53:35 +00:00
import java.util.Arrays ;
import java.util.List ;
2018-08-06 07:21:47 +00:00
import java.util.Optional ;
2018-08-02 17:25:46 +00:00
/ * *
* Static helpers for cost calculation
*
* @author leijurv
* /
2018-08-04 02:14:50 +00:00
public interface MovementHelper extends ActionCosts , Helper {
2018-08-03 07:51:10 +00:00
2018-08-07 00:50:39 +00:00
List < Item > ACCEPTABLE_THROWAWAY_ITEMS = Arrays . asList (
Item . getItemFromBlock ( Blocks . DIRT ) ,
Item . getItemFromBlock ( Blocks . COBBLESTONE )
) ;
2018-08-02 17:25:46 +00:00
static boolean avoidBreaking ( BlockPos pos ) {
2018-08-06 21:32:54 +00:00
Block b = BlockStateInterface . getBlock ( pos ) ;
2018-08-07 01:18:16 +00:00
BlockPos below = new BlockPos ( pos . getX ( ) , pos . getY ( ) - 1 , pos . getZ ( ) ) ;
2018-08-02 17:56:26 +00:00
return Blocks . ICE . equals ( b ) // ice becomes water, and water can mess up the path
2018-08-04 22:17:53 +00:00
| | b instanceof BlockSilverfish
2018-08-06 21:32:54 +00:00
| | BlockStateInterface . isLiquid ( new BlockPos ( pos . getX ( ) , pos . getY ( ) + 1 , pos . getZ ( ) ) ) //don't break anything touching liquid on any side
| | BlockStateInterface . isLiquid ( new BlockPos ( pos . getX ( ) + 1 , pos . getY ( ) , pos . getZ ( ) ) )
| | BlockStateInterface . isLiquid ( new BlockPos ( pos . getX ( ) - 1 , pos . getY ( ) , pos . getZ ( ) ) )
| | BlockStateInterface . isLiquid ( new BlockPos ( pos . getX ( ) , pos . getY ( ) , pos . getZ ( ) + 1 ) )
| | BlockStateInterface . isLiquid ( new BlockPos ( pos . getX ( ) , pos . getY ( ) , pos . getZ ( ) - 1 ) )
| | ( ! ( b instanceof BlockLilyPad & & BlockStateInterface . isWater ( below ) ) & & BlockStateInterface . isLiquid ( below ) ) ; //if it's a lilypad above water, it's ok to break, otherwise don't break if its liquid
2018-08-02 17:25:46 +00:00
}
/ * *
* Can I walk through this block ? e . g . air , saplings , torches , etc
*
* @param pos
* @return
* /
2018-08-07 01:18:16 +00:00
static boolean canWalkThrough ( BlockPos pos ) {
IBlockState state = BlockStateInterface . get ( pos ) ;
2018-08-07 14:39:55 +00:00
return canWalkThrough ( pos , state ) ;
}
static boolean canWalkThrough ( BlockPos pos , IBlockState state ) {
2018-08-02 17:25:46 +00:00
Block block = state . getBlock ( ) ;
2018-08-04 22:17:53 +00:00
if ( block instanceof BlockLilyPad
| | block instanceof BlockFire
| | block instanceof BlockTripWire ) { //you can't actually walk through a lilypad from the side, and you shouldn't walk through fire
2018-08-02 17:25:46 +00:00
return false ;
}
2018-08-07 01:25:46 +00:00
if ( BlockStateInterface . isFlowing ( pos ) | | BlockStateInterface . isLiquid ( pos . up ( ) ) ) {
2018-08-02 17:55:26 +00:00
return false ; // Don't walk through flowing liquids
2018-08-02 17:25:46 +00:00
}
2018-08-06 21:32:54 +00:00
return block . isPassable ( mc . world , pos ) ;
2018-08-02 17:25:46 +00:00
}
2018-08-03 20:31:33 +00:00
static boolean avoidWalkingInto ( Block block ) {
2018-08-06 21:32:54 +00:00
return BlockStateInterface . isLava ( block )
2018-08-03 20:31:33 +00:00
| | block instanceof BlockCactus
2018-08-04 22:17:53 +00:00
| | block instanceof BlockFire
| | block instanceof BlockEndPortal
| | block instanceof BlockWeb ;
2018-08-02 17:25:46 +00:00
}
/ * *
* Can I walk on this block without anything weird happening like me falling
* through ? Includes water because we know that we automatically jump on
* lava
*
* @return
* /
2018-08-07 02:48:09 +00:00
static boolean canWalkOn ( BlockPos pos , IBlockState state ) {
2018-08-02 17:25:46 +00:00
Block block = state . getBlock ( ) ;
if ( block instanceof BlockLadder | | block instanceof BlockVine ) {
return true ;
}
2018-08-06 02:09:29 +00:00
if ( block instanceof BlockAir ) {
return false ;
}
2018-08-06 21:32:54 +00:00
if ( BlockStateInterface . isWater ( block ) ) {
return BlockStateInterface . isWater ( pos . up ( ) ) ; // You can only walk on water if there is water above it
2018-08-02 17:25:46 +00:00
}
2018-08-06 21:32:54 +00:00
return state . isBlockNormalCube ( ) & & ! BlockStateInterface . isLava ( block ) ;
2018-08-02 17:25:46 +00:00
}
2018-08-02 17:49:31 +00:00
2018-08-07 02:48:09 +00:00
static boolean canWalkOn ( BlockPos pos ) {
IBlockState state = BlockStateInterface . get ( pos ) ;
return canWalkOn ( pos , state ) ;
}
2018-08-02 17:49:31 +00:00
static boolean canFall ( BlockPos pos ) {
return BlockStateInterface . get ( pos ) . getBlock ( ) instanceof BlockFalling ;
}
2018-08-07 01:18:16 +00:00
static double getMiningDurationTicks ( ToolSet ts , BlockPos position ) {
IBlockState state = BlockStateInterface . get ( position ) ;
Block block = state . getBlock ( ) ;
if ( ! block . equals ( Blocks . AIR ) & & ! canWalkThrough ( position ) ) {
2018-08-02 17:49:31 +00:00
if ( avoidBreaking ( position ) ) {
return COST_INF ;
}
//if (!Baritone.allowBreakOrPlace) {
// return COST_INF;
//}
2018-08-02 17:57:11 +00:00
double m = Blocks . CRAFTING_TABLE . equals ( block ) ? 10 : 1 ;
2018-08-07 01:18:16 +00:00
return m / ts . getStrVsBlock ( state , position ) + BREAK_ONE_BLOCK_ADD ;
2018-08-02 17:49:31 +00:00
}
return 0 ;
}
2018-08-04 02:14:50 +00:00
/ * *
* The entity the player is currently looking at
*
2018-08-06 07:21:47 +00:00
* @return the entity object
2018-08-04 02:14:50 +00:00
* /
2018-08-06 07:21:47 +00:00
static Optional < Entity > whatEntityAmILookingAt ( ) {
2018-08-04 02:14:50 +00:00
if ( mc . objectMouseOver ! = null & & mc . objectMouseOver . typeOfHit = = RayTraceResult . Type . ENTITY ) {
2018-08-06 07:21:47 +00:00
return Optional . of ( mc . objectMouseOver . entityHit ) ;
2018-08-04 02:14:50 +00:00
}
2018-08-06 07:21:47 +00:00
return Optional . empty ( ) ;
2018-08-04 02:14:50 +00:00
}
/ * *
* AutoTool
* /
static void switchToBestTool ( ) {
2018-08-06 21:32:54 +00:00
LookBehaviorUtils . getSelectedBlock ( ) . ifPresent ( pos - > {
2018-08-06 07:21:47 +00:00
IBlockState state = BlockStateInterface . get ( pos ) ;
if ( state . getBlock ( ) . equals ( Blocks . AIR ) ) {
return ;
}
switchToBestToolFor ( state ) ;
} ) ;
2018-08-04 02:14:50 +00:00
}
/ * *
* AutoTool for a specific block
*
* @param b the blockstate to mine
* /
static void switchToBestToolFor ( IBlockState b ) {
switchToBestToolFor ( b , new ToolSet ( ) ) ;
}
/ * *
* AutoTool for a specific block with precomputed ToolSet data
*
* @param b the blockstate to mine
* @param ts previously calculated ToolSet
* /
static void switchToBestToolFor ( IBlockState b , ToolSet ts ) {
2018-08-06 07:21:47 +00:00
mc . player . inventory . currentItem = ts . getBestSlot ( b ) ;
2018-08-04 02:14:50 +00:00
}
2018-08-06 22:53:35 +00:00
static boolean switchtothrowaway ( ) {
EntityPlayerSP p = Minecraft . getMinecraft ( ) . player ;
NonNullList < ItemStack > inv = p . inventory . mainInventory ;
for ( byte i = 0 ; i < 9 ; i + + ) {
ItemStack item = inv . get ( i ) ;
if ( ACCEPTABLE_THROWAWAY_ITEMS . contains ( item . getItem ( ) ) ) {
p . inventory . currentItem = i ;
return true ;
}
}
return false ;
}
2018-08-08 19:51:04 +00:00
static MovementState moveTowards ( MovementState state , BlockPos pos ) {
return state . setTarget ( new MovementTarget ( new Rotation ( Utils . calcRotationFromVec3d ( mc . player . getPositionEyes ( 1 . 0F ) ,
2018-08-08 22:31:41 +00:00
Utils . getBlockPosCenter ( pos ) ,
2018-08-08 19:51:04 +00:00
new Rotation ( mc . player . rotationYaw , mc . player . rotationPitch ) ) . getFirst ( ) , mc . player . rotationPitch ) )
) . setInput ( InputOverrideHandler . Input . MOVE_FORWARD , true ) ;
}
2018-08-07 13:16:38 +00:00
static Movement generateMovementFallOrDescend ( BlockPos pos , EnumFacing direction ) {
BlockPos dest = pos . offset ( direction ) ;
BlockPos destUp = dest . up ( ) ;
BlockPos destDown = dest . down ( ) ;
for ( int i = 0 ; i < 4 ; i + + ) {
if ( ! ( BlockStateInterface . get ( destUp . down ( i ) ) . getBlock ( ) instanceof BlockAir ) ) {
//if any of these four aren't air, that means that a fall N isn't possible
//so try a movementdescend
//if all four of them are air, a movementdescend isn't possible anyway
return new MovementDescend ( pos , destDown ) ;
}
}
// we're clear for a fall 2
// let's see how far we can fall
for ( int fallHeight = 3 ; true ; fallHeight + + ) {
BlockPos onto = dest . down ( fallHeight ) ;
if ( onto . getY ( ) < = 0 ) {
break ;
}
2018-08-07 14:39:55 +00:00
IBlockState ontoBlock = BlockStateInterface . get ( onto ) ;
if ( BlockStateInterface . isWater ( ontoBlock . getBlock ( ) ) ) {
2018-08-07 13:16:38 +00:00
return new MovementFall ( pos , onto ) ;
}
2018-08-07 14:39:55 +00:00
if ( canWalkThrough ( onto , ontoBlock ) ) {
continue ;
}
if ( canWalkOn ( onto , ontoBlock ) ) {
return new MovementFall ( pos , onto . up ( ) ) ;
2018-08-07 13:16:38 +00:00
}
break ;
}
return null ;
}
2018-08-06 22:53:35 +00:00
static boolean hasthrowaway ( ) {
EntityPlayerSP p = Minecraft . getMinecraft ( ) . player ;
NonNullList < ItemStack > inv = p . inventory . mainInventory ;
for ( byte i = 0 ; i < 9 ; i + + ) {
ItemStack item = inv . get ( i ) ;
if ( ACCEPTABLE_THROWAWAY_ITEMS . contains ( item . getItem ( ) ) ) {
return true ;
}
}
return false ;
}
2018-08-02 17:25:46 +00:00
}