2018-08-28 18:43:28 +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-28 18:43:28 +00:00
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* Baritone is distributed in the hope that it will be useful ,
* 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-28 18:43:28 +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-28 18:43:28 +00:00
* along with Baritone . If not , see < https : //www.gnu.org/licenses/>.
* /
2018-11-04 05:11:52 +00:00
package baritone.process ;
2018-08-28 18:28:36 +00:00
2018-09-15 17:34:02 +00:00
import baritone.Baritone ;
2019-09-07 00:46:26 +00:00
import baritone.api.pathing.goals.* ;
2018-11-04 05:11:52 +00:00
import baritone.api.process.IMineProcess ;
import baritone.api.process.PathingCommand ;
import baritone.api.process.PathingCommandType ;
2019-09-07 00:46:26 +00:00
import baritone.api.utils.* ;
2019-04-18 05:17:09 +00:00
import baritone.api.utils.input.Input ;
2019-08-31 00:12:05 +00:00
import baritone.cache.CachedChunk ;
2018-09-11 17:28:03 +00:00
import baritone.cache.WorldScanner ;
2018-11-23 17:00:52 +00:00
import baritone.pathing.movement.CalculationContext ;
2018-10-26 04:21:42 +00:00
import baritone.pathing.movement.MovementHelper ;
2018-11-04 05:11:52 +00:00
import baritone.utils.BaritoneProcessHelper ;
2018-08-28 18:43:28 +00:00
import baritone.utils.BlockStateInterface ;
2019-08-31 00:12:05 +00:00
import net.minecraft.block.Block ;
2019-04-18 05:17:09 +00:00
import net.minecraft.block.BlockAir ;
2019-04-25 17:49:54 +00:00
import net.minecraft.block.BlockFalling ;
2019-04-18 05:17:09 +00:00
import net.minecraft.block.state.IBlockState ;
2018-11-06 02:31:59 +00:00
import net.minecraft.entity.Entity ;
import net.minecraft.entity.item.EntityItem ;
2018-09-16 20:00:44 +00:00
import net.minecraft.init.Blocks ;
2018-09-17 21:22:45 +00:00
import net.minecraft.item.ItemStack ;
2018-08-28 18:43:28 +00:00
import net.minecraft.util.math.BlockPos ;
2018-11-06 02:31:59 +00:00
import net.minecraft.world.World ;
2018-08-28 18:43:28 +00:00
2019-09-07 00:46:26 +00:00
import java.util.* ;
2018-08-28 18:43:28 +00:00
import java.util.stream.Collectors ;
2019-04-25 06:10:41 +00:00
import static baritone.api.pathing.movement.ActionCosts.COST_INF ;
2018-08-28 18:43:28 +00:00
/ * *
* Mine blocks of a certain type
*
* @author leijurv
* /
2018-11-04 05:11:52 +00:00
public final class MineProcess extends BaritoneProcessHelper implements IMineProcess {
2019-09-19 20:40:46 +00:00
2018-11-04 05:11:52 +00:00
private static final int ORE_LOCATIONS_COUNT = 64 ;
2018-09-12 22:53:29 +00:00
2019-08-30 22:38:15 +00:00
private BlockOptionalMetaLookup filter ;
2018-10-26 03:08:52 +00:00
private List < BlockPos > knownOreLocations ;
2019-03-12 03:06:19 +00:00
private List < BlockPos > blacklist ; // inaccessible
2018-10-26 04:21:42 +00:00
private BlockPos branchPoint ;
2018-11-08 01:27:57 +00:00
private GoalRunAway branchPointRunaway ;
2018-10-26 03:08:52 +00:00
private int desiredQuantity ;
2018-11-04 05:11:52 +00:00
private int tickCount ;
2018-08-28 18:43:28 +00:00
2018-11-04 05:11:52 +00:00
public MineProcess ( Baritone baritone ) {
2019-03-12 01:24:31 +00:00
super ( baritone ) ;
2018-10-28 01:45:17 +00:00
}
2018-09-17 03:16:05 +00:00
2018-09-14 16:21:52 +00:00
@Override
2018-11-04 05:11:52 +00:00
public boolean isActive ( ) {
2019-08-30 18:55:25 +00:00
return filter ! = null ;
2018-11-04 05:11:52 +00:00
}
@Override
2018-11-05 22:19:50 +00:00
public PathingCommand onTick ( boolean calcFailed , boolean isSafeToCancel ) {
2018-10-26 03:08:52 +00:00
if ( desiredQuantity > 0 ) {
2019-08-30 18:55:25 +00:00
int curr = ctx . player ( ) . inventory . mainInventory . stream ( )
2019-09-07 00:46:26 +00:00
. filter ( stack - > filter . has ( stack ) )
. mapToInt ( ItemStack : : getCount ) . sum ( ) ;
2019-08-30 18:55:25 +00:00
System . out . println ( " Currently have " + curr + " valid items " ) ;
2018-10-26 03:08:52 +00:00
if ( curr > = desiredQuantity ) {
2019-08-30 18:55:25 +00:00
logDirect ( " Have " + curr + " valid items " ) ;
2018-09-17 21:22:45 +00:00
cancel ( ) ;
2018-11-04 05:11:52 +00:00
return null ;
2018-09-17 21:22:45 +00:00
}
}
2019-05-08 05:40:03 +00:00
if ( calcFailed ) {
if ( ! knownOreLocations . isEmpty ( ) & & Baritone . settings ( ) . blacklistClosestOnFailure . value ) {
2019-08-30 18:55:25 +00:00
logDirect ( " Unable to find any path to " + filter + " , blacklisting presumably unreachable closest instance... " ) ;
2019-05-08 05:40:03 +00:00
knownOreLocations . stream ( ) . min ( Comparator . comparingDouble ( ctx . player ( ) : : getDistanceSq ) ) . ifPresent ( blacklist : : add ) ;
knownOreLocations . removeIf ( blacklist : : contains ) ;
2019-05-08 18:51:48 +00:00
} else {
2019-08-30 18:55:25 +00:00
logDirect ( " Unable to find any path to " + filter + " , canceling mine " ) ;
2019-05-08 18:51:48 +00:00
cancel ( ) ;
return null ;
2019-05-08 05:40:03 +00:00
}
2018-11-05 22:19:50 +00:00
}
2019-07-11 17:41:24 +00:00
if ( ! Baritone . settings ( ) . allowBreak . value ) {
logDirect ( " Unable to mine when allowBreak is false! " ) ;
cancel ( ) ;
return null ;
}
2019-03-05 05:30:04 +00:00
int mineGoalUpdateInterval = Baritone . settings ( ) . mineGoalUpdateInterval . value ;
2019-04-18 05:17:09 +00:00
List < BlockPos > curr = new ArrayList < > ( knownOreLocations ) ;
2018-11-04 05:11:52 +00:00
if ( mineGoalUpdateInterval ! = 0 & & tickCount + + % mineGoalUpdateInterval = = 0 ) { // big brain
2018-11-26 06:30:37 +00:00
CalculationContext context = new CalculationContext ( baritone , true ) ;
2018-11-23 17:00:52 +00:00
Baritone . getExecutor ( ) . execute ( ( ) - > rescan ( curr , context ) ) ;
2018-09-15 17:34:02 +00:00
}
2019-03-05 05:30:04 +00:00
if ( Baritone . settings ( ) . legitMine . value ) {
2018-10-26 04:21:42 +00:00
addNearby ( ) ;
}
2019-04-18 05:17:09 +00:00
Optional < BlockPos > shaft = curr . stream ( )
2019-09-07 00:46:26 +00:00
. filter ( pos - > pos . getX ( ) = = ctx . playerFeet ( ) . getX ( ) & & pos . getZ ( ) = = ctx . playerFeet ( ) . getZ ( ) )
. filter ( pos - > pos . getY ( ) > = ctx . playerFeet ( ) . getY ( ) )
. filter ( pos - > ! ( BlockStateInterface . get ( ctx , pos ) . getBlock ( ) instanceof BlockAir ) ) // after breaking a block, it takes mineGoalUpdateInterval ticks for it to actually update this list =(
. min ( Comparator . comparingDouble ( ctx . player ( ) : : getDistanceSq ) ) ;
2019-04-18 05:17:09 +00:00
baritone . getInputOverrideHandler ( ) . clearAllKeys ( ) ;
2019-06-11 06:12:37 +00:00
if ( shaft . isPresent ( ) & & ctx . player ( ) . onGround ) {
2019-04-18 05:17:09 +00:00
BlockPos pos = shaft . get ( ) ;
IBlockState state = baritone . bsi . get0 ( pos ) ;
if ( ! MovementHelper . avoidBreaking ( baritone . bsi , pos . getX ( ) , pos . getY ( ) , pos . getZ ( ) , state ) ) {
Optional < Rotation > rot = RotationUtils . reachable ( ctx , pos ) ;
if ( rot . isPresent ( ) & & isSafeToCancel ) {
baritone . getLookBehavior ( ) . updateTarget ( rot . get ( ) , true ) ;
MovementHelper . switchToBestToolFor ( ctx , ctx . world ( ) . getBlockState ( pos ) ) ;
if ( ctx . isLookingAt ( pos ) | | ctx . playerRotations ( ) . isReallyCloseTo ( rot . get ( ) ) ) {
baritone . getInputOverrideHandler ( ) . setInputForceState ( Input . CLICK_LEFT , true ) ;
}
return new PathingCommand ( null , PathingCommandType . REQUEST_PAUSE ) ;
}
}
}
2019-01-29 23:22:48 +00:00
PathingCommand command = updateGoal ( ) ;
if ( command = = null ) {
2018-11-04 05:11:52 +00:00
// none in range
// maybe say something in chat? (ahem impact)
cancel ( ) ;
return null ;
}
2019-01-29 23:22:48 +00:00
return command ;
2018-09-04 22:33:38 +00:00
}
2018-11-04 05:11:52 +00:00
@Override
public void onLostControl ( ) {
2019-08-30 22:38:15 +00:00
mine ( 0 , ( BlockOptionalMetaLookup ) null ) ;
2018-11-04 05:11:52 +00:00
}
2018-11-04 18:29:22 +00:00
@Override
2019-03-13 16:17:25 +00:00
public String displayName0 ( ) {
2019-08-30 18:55:25 +00:00
return " Mine " + filter ;
2018-11-04 18:29:22 +00:00
}
2019-01-29 23:22:48 +00:00
private PathingCommand updateGoal ( ) {
2019-03-05 05:30:04 +00:00
boolean legit = Baritone . settings ( ) . legitMine . value ;
2018-10-26 03:08:52 +00:00
List < BlockPos > locs = knownOreLocations ;
2018-10-10 23:40:33 +00:00
if ( ! locs . isEmpty ( ) ) {
2019-08-30 18:55:25 +00:00
List < BlockPos > locs2 = prune ( new CalculationContext ( baritone ) , new ArrayList < > ( locs ) , filter , ORE_LOCATIONS_COUNT , blacklist ) ;
2018-10-26 04:21:42 +00:00
// can't reassign locs, gotta make a new var locs2, because we use it in a lambda right here, and variables you use in a lambda must be effectively final
2019-04-25 17:49:54 +00:00
Goal goal = new GoalComposite ( locs2 . stream ( ) . map ( loc - > coalesce ( loc , locs2 ) ) . toArray ( Goal [ ] : : new ) ) ;
2018-11-04 03:25:09 +00:00
knownOreLocations = locs2 ;
2019-01-29 23:22:48 +00:00
return new PathingCommand ( goal , legit ? PathingCommandType . FORCE_REVALIDATE_GOAL_AND_PATH : PathingCommandType . REVALIDATE_GOAL_AND_PATH ) ;
2018-10-26 04:21:42 +00:00
}
// we don't know any ore locations at the moment
2019-01-29 23:22:48 +00:00
if ( ! legit ) {
2018-11-04 05:11:52 +00:00
return null ;
2018-10-26 04:21:42 +00:00
}
// only in non-Xray mode (aka legit mode) do we do this
2019-03-05 05:30:04 +00:00
int y = Baritone . settings ( ) . legitMineYLevel . value ;
2018-10-26 04:21:42 +00:00
if ( branchPoint = = null ) {
2018-11-12 01:59:13 +00:00
/ * if ( ! baritone . getPathingBehavior ( ) . isPathing ( ) & & playerFeet ( ) . y = = y ) {
2018-10-26 04:21:42 +00:00
// cool, path is over and we are at desired y
branchPoint = playerFeet ( ) ;
2018-11-08 01:27:57 +00:00
branchPointRunaway = null ;
2018-10-26 04:21:42 +00:00
} else {
2018-11-04 05:11:52 +00:00
return new GoalYLevel ( y ) ;
2018-11-12 01:59:13 +00:00
} * /
2018-11-13 17:50:29 +00:00
branchPoint = ctx . playerFeet ( ) ;
2018-10-26 04:21:42 +00:00
}
2018-11-08 22:58:18 +00:00
// TODO shaft mode, mine 1x1 shafts to either side
// TODO also, see if the GoalRunAway with maintain Y at 11 works even from the surface
2018-11-08 01:27:57 +00:00
if ( branchPointRunaway = = null ) {
2018-11-17 17:18:55 +00:00
branchPointRunaway = new GoalRunAway ( 1 , y , branchPoint ) {
2018-11-08 01:27:57 +00:00
@Override
public boolean isInGoal ( int x , int y , int z ) {
return false ;
}
} ;
}
2019-01-29 23:22:48 +00:00
return new PathingCommand ( branchPointRunaway , PathingCommandType . REVALIDATE_GOAL_AND_PATH ) ;
2018-10-10 23:40:33 +00:00
}
2018-11-23 17:00:52 +00:00
private void rescan ( List < BlockPos > already , CalculationContext context ) {
2019-08-30 18:55:25 +00:00
if ( filter = = null ) {
2018-10-10 23:40:33 +00:00
return ;
2018-09-15 19:56:35 +00:00
}
2019-03-05 05:30:04 +00:00
if ( Baritone . settings ( ) . legitMine . value ) {
2018-10-26 04:21:42 +00:00
return ;
}
2019-08-30 18:55:25 +00:00
List < BlockPos > locs = searchWorld ( context , filter , ORE_LOCATIONS_COUNT , already , blacklist ) ;
locs . addAll ( droppedItemsScan ( filter , ctx . world ( ) ) ) ;
2018-09-04 22:03:59 +00:00
if ( locs . isEmpty ( ) ) {
2019-08-30 18:55:25 +00:00
logDirect ( " No locations for " + filter + " known, cancelling " ) ;
2018-11-04 05:11:52 +00:00
cancel ( ) ;
2018-09-04 22:03:59 +00:00
return ;
}
2018-10-26 03:08:52 +00:00
knownOreLocations = locs ;
2018-09-04 22:03:59 +00:00
}
2019-05-02 06:07:20 +00:00
private boolean internalMiningGoal ( BlockPos pos , IPlayerContext ctx , List < BlockPos > locs ) {
2019-04-18 17:36:20 +00:00
// Here, BlockStateInterface is used because the position may be in a cached chunk (the targeted block is one that is kept track of)
2019-05-02 06:07:20 +00:00
if ( locs . contains ( pos ) ) {
return true ;
}
2019-08-30 18:55:25 +00:00
IBlockState state = BlockStateInterface . get ( ctx , pos ) ;
if ( Baritone . settings ( ) . internalMiningAirException . value & & state . getBlock ( ) instanceof BlockAir ) {
2019-05-02 06:07:20 +00:00
return true ;
}
2019-08-30 22:38:15 +00:00
return filter . has ( state ) ;
2019-04-18 05:17:09 +00:00
}
2019-04-25 17:49:54 +00:00
private Goal coalesce ( BlockPos loc , List < BlockPos > locs ) {
boolean assumeVerticalShaftMine = ! ( baritone . bsi . get0 ( loc . up ( ) ) . getBlock ( ) instanceof BlockFalling ) ;
2019-03-05 05:30:04 +00:00
if ( ! Baritone . settings ( ) . forceInternalMining . value ) {
2019-04-25 17:49:54 +00:00
if ( assumeVerticalShaftMine ) {
// we can get directly below the block
return new GoalThreeBlocks ( loc ) ;
} else {
// we need to get feet or head into the block
return new GoalTwoBlocks ( loc ) ;
}
2018-10-12 03:36:18 +00:00
}
2019-04-18 05:17:09 +00:00
boolean upwardGoal = internalMiningGoal ( loc . up ( ) , ctx , locs ) ;
boolean downwardGoal = internalMiningGoal ( loc . down ( ) , ctx , locs ) ;
boolean doubleDownwardGoal = internalMiningGoal ( loc . down ( 2 ) , ctx , locs ) ;
2019-04-18 17:36:20 +00:00
if ( upwardGoal = = downwardGoal ) { // symmetric
2019-04-25 17:49:54 +00:00
if ( doubleDownwardGoal & & assumeVerticalShaftMine ) {
2019-04-18 17:36:20 +00:00
// we have a checkerboard like pattern
// this one, and the one two below it
// therefore it's fine to path to immediately below this one, since your feet will be in the doubleDownwardGoal
2019-04-25 17:49:54 +00:00
// but only if assumeVerticalShaftMine
2019-04-18 17:36:20 +00:00
return new GoalThreeBlocks ( loc ) ;
} else {
// this block has nothing interesting two below, but is symmetric vertically so we can get either feet or head into it
return new GoalTwoBlocks ( loc ) ;
}
}
if ( upwardGoal ) {
// downwardGoal known to be false
// ignore the gap then potential doubleDownward, because we want to path feet into this one and head into upwardGoal
return new GoalBlock ( loc ) ;
}
// upwardGoal known to be false, downwardGoal known to be true
2019-04-25 17:49:54 +00:00
if ( doubleDownwardGoal & & assumeVerticalShaftMine ) {
2019-04-18 17:36:20 +00:00
// this block and two below it are goals
// path into the center of the one below, because that includes directly below this one
return new GoalTwoBlocks ( loc . down ( ) ) ;
}
// upwardGoal false, downwardGoal true, doubleDownwardGoal false
// just this block and the one immediately below, no others
return new GoalBlock ( loc . down ( ) ) ;
2019-04-18 05:17:09 +00:00
}
private static class GoalThreeBlocks extends GoalTwoBlocks {
public GoalThreeBlocks ( BlockPos pos ) {
super ( pos ) ;
}
@Override
public boolean isInGoal ( int x , int y , int z ) {
return x = = this . x & & ( y = = this . y | | y = = this . y - 1 | | y = = this . y - 2 ) & & z = = this . z ;
}
@Override
public double heuristic ( int x , int y , int z ) {
int xDiff = x - this . x ;
int yDiff = y - this . y ;
int zDiff = z - this . z ;
return GoalBlock . calculate ( xDiff , yDiff < - 1 ? yDiff + 2 : yDiff = = - 1 ? 0 : yDiff , zDiff ) ;
}
2018-10-12 03:36:18 +00:00
}
2019-08-30 22:38:15 +00:00
public static List < BlockPos > droppedItemsScan ( BlockOptionalMetaLookup filter , World world ) {
2019-03-05 05:30:04 +00:00
if ( ! Baritone . settings ( ) . mineScanDroppedItems . value ) {
2019-06-01 17:56:24 +00:00
return Collections . emptyList ( ) ;
2018-11-06 02:31:59 +00:00
}
List < BlockPos > ret = new ArrayList < > ( ) ;
for ( Entity entity : world . loadedEntityList ) {
if ( entity instanceof EntityItem ) {
EntityItem ei = ( EntityItem ) entity ;
2019-09-01 03:43:03 +00:00
if ( filter . has ( ei . getItem ( ) ) ) {
2018-11-06 03:31:05 +00:00
ret . add ( new BlockPos ( entity ) ) ;
2018-11-06 02:31:59 +00:00
}
}
}
return ret ;
}
2019-08-30 22:38:15 +00:00
public static List < BlockPos > searchWorld ( CalculationContext ctx , BlockOptionalMetaLookup filter , int max , List < BlockPos > alreadyKnown , List < BlockPos > blacklist ) {
2018-09-04 15:50:42 +00:00
List < BlockPos > locs = new ArrayList < > ( ) ;
2019-08-31 00:12:05 +00:00
List < Block > untracked = new ArrayList < > ( ) ;
for ( BlockOptionalMeta bom : filter . blocks ( ) ) {
Block block = bom . getBlock ( ) ;
2019-08-31 00:13:09 +00:00
if ( CachedChunk . BLOCKS_TO_KEEP_TRACK_OF . contains ( block ) ) {
2019-08-31 00:12:05 +00:00
BetterBlockPos pf = ctx . baritone . getPlayerContext ( ) . playerFeet ( ) ;
2019-09-06 10:59:10 +00:00
// maxRegionDistanceSq 2 means adjacent directly or adjacent diagonally; nothing further than that
2019-08-31 00:12:05 +00:00
locs . addAll ( ctx . worldData . getCachedWorld ( ) . getLocationsOf (
2019-09-07 00:46:26 +00:00
BlockUtils . blockToString ( block ) ,
Baritone . settings ( ) . maxCachedWorldScanCount . value ,
pf . x ,
pf . z ,
2
2019-08-31 00:12:05 +00:00
) ) ;
} else {
untracked . add ( block ) ;
}
}
2019-08-31 00:20:20 +00:00
locs = prune ( ctx , locs , filter , max , blacklist ) ;
2019-08-31 00:19:44 +00:00
if ( ! untracked . isEmpty ( ) | | ( Baritone . settings ( ) . extendCacheOnThreshold . value & & locs . size ( ) < max ) ) {
2019-08-31 00:12:05 +00:00
locs . addAll ( WorldScanner . INSTANCE . scanChunkRadius (
2019-09-07 00:46:26 +00:00
ctx . getBaritone ( ) . getPlayerContext ( ) ,
filter ,
max ,
10 ,
32
2019-08-31 00:12:05 +00:00
) ) ; // maxSearchRadius is NOT sq
}
2018-11-07 22:09:23 +00:00
locs . addAll ( alreadyKnown ) ;
2019-08-31 00:12:05 +00:00
2019-08-30 18:55:25 +00:00
return prune ( ctx , locs , filter , max , blacklist ) ;
2018-09-15 19:56:35 +00:00
}
2019-02-11 00:44:09 +00:00
private void addNearby ( ) {
2019-08-30 18:55:25 +00:00
knownOreLocations . addAll ( droppedItemsScan ( filter , ctx . world ( ) ) ) ;
2018-11-13 17:50:29 +00:00
BlockPos playerFeet = ctx . playerFeet ( ) ;
2018-11-21 00:32:44 +00:00
BlockStateInterface bsi = new BlockStateInterface ( ctx ) ;
int searchDist = 10 ;
double fakedBlockReachDistance = 20 ; // at least 10 * sqrt(3) with some extra space to account for positioning within the block
2018-10-26 04:21:42 +00:00
for ( int x = playerFeet . getX ( ) - searchDist ; x < = playerFeet . getX ( ) + searchDist ; x + + ) {
for ( int y = playerFeet . getY ( ) - searchDist ; y < = playerFeet . getY ( ) + searchDist ; y + + ) {
for ( int z = playerFeet . getZ ( ) - searchDist ; z < = playerFeet . getZ ( ) + searchDist ; z + + ) {
2018-11-13 21:14:29 +00:00
// crucial to only add blocks we can see because otherwise this
// is an x-ray and it'll get caught
2019-08-30 22:38:15 +00:00
if ( filter . has ( bsi . get0 ( x , y , z ) ) ) {
2019-02-11 00:44:09 +00:00
BlockPos pos = new BlockPos ( x , y , z ) ;
2019-03-05 05:30:04 +00:00
if ( ( Baritone . settings ( ) . legitMineIncludeDiagonals . value & & knownOreLocations . stream ( ) . anyMatch ( ore - > ore . distanceSq ( pos ) < = 2 /* sq means this is pytha dist <= sqrt(2) */ ) ) | | RotationUtils . reachable ( ctx . player ( ) , pos , fakedBlockReachDistance ) . isPresent ( ) ) {
2019-02-11 00:44:09 +00:00
knownOreLocations . add ( pos ) ;
}
2018-10-26 04:21:42 +00:00
}
}
}
}
2019-08-30 18:55:25 +00:00
knownOreLocations = prune ( new CalculationContext ( baritone ) , knownOreLocations , filter , ORE_LOCATIONS_COUNT , blacklist ) ;
2018-10-26 04:21:42 +00:00
}
2019-08-30 22:38:15 +00:00
private static List < BlockPos > prune ( CalculationContext ctx , List < BlockPos > locs2 , BlockOptionalMetaLookup filter , int max , List < BlockPos > blacklist ) {
2019-08-30 18:55:25 +00:00
List < BlockPos > dropped = droppedItemsScan ( filter , ctx . world ) ;
2019-02-08 20:08:34 +00:00
dropped . removeIf ( drop - > {
for ( BlockPos pos : locs2 ) {
2019-08-30 22:38:15 +00:00
if ( pos . distanceSq ( drop ) < = 9 & & filter . has ( ctx . get ( pos . getX ( ) , pos . getY ( ) , pos . getZ ( ) ) ) & & MineProcess . plausibleToBreak ( ctx , pos ) ) { // TODO maybe drop also has to be supported? no lava below?
2019-02-08 20:08:34 +00:00
return true ;
}
}
return false ;
} ) ;
2018-10-26 04:21:42 +00:00
List < BlockPos > locs = locs2
2019-09-07 00:46:26 +00:00
. stream ( )
. distinct ( )
2018-10-26 04:21:42 +00:00
2019-09-07 00:46:26 +00:00
// remove any that are within loaded chunks that aren't actually what we want
. filter ( pos - > ! ctx . bsi . worldContainsLoadedChunk ( pos . getX ( ) , pos . getZ ( ) ) | | filter . has ( ctx . get ( pos . getX ( ) , pos . getY ( ) , pos . getZ ( ) ) ) | | dropped . contains ( pos ) )
2018-10-26 04:21:42 +00:00
2019-09-07 00:46:26 +00:00
// remove any that are implausible to mine (encased in bedrock, or touching lava)
. filter ( pos - > MineProcess . plausibleToBreak ( ctx , pos ) )
2018-10-26 04:21:42 +00:00
2019-09-07 00:46:26 +00:00
. filter ( pos - > ! blacklist . contains ( pos ) )
2019-03-12 03:06:19 +00:00
2019-09-07 00:46:26 +00:00
. sorted ( Comparator . comparingDouble ( ctx . getBaritone ( ) . getPlayerContext ( ) . player ( ) : : getDistanceSq ) )
. collect ( Collectors . toList ( ) ) ;
2018-08-28 18:43:28 +00:00
2018-09-04 22:03:59 +00:00
if ( locs . size ( ) > max ) {
2018-09-17 00:49:19 +00:00
return locs . subList ( 0 , max ) ;
2018-09-01 19:16:55 +00:00
}
2018-09-04 22:03:59 +00:00
return locs ;
2018-08-28 18:43:28 +00:00
}
2019-04-25 06:10:41 +00:00
public static boolean plausibleToBreak ( CalculationContext ctx , BlockPos pos ) {
if ( MovementHelper . getMiningDurationTicks ( ctx , pos . getX ( ) , pos . getY ( ) , pos . getZ ( ) , ctx . bsi . get0 ( pos ) , true ) > = COST_INF ) {
2018-10-26 04:21:42 +00:00
return false ;
}
2018-11-23 17:00:52 +00:00
2018-10-26 04:21:42 +00:00
// bedrock above and below makes it implausible, otherwise we're good
2019-04-25 06:10:41 +00:00
return ! ( ctx . bsi . get0 ( pos . up ( ) ) . getBlock ( ) = = Blocks . BEDROCK & & ctx . bsi . get0 ( pos . down ( ) ) . getBlock ( ) = = Blocks . BEDROCK ) ;
2018-10-26 04:21:42 +00:00
}
2018-09-23 21:44:35 +00:00
@Override
2018-11-04 05:11:52 +00:00
public void mineByName ( int quantity , String . . . blocks ) {
2019-09-06 10:59:10 +00:00
mine ( quantity , new BlockOptionalMetaLookup ( blocks ) ) ;
2018-09-12 22:12:06 +00:00
}
2018-09-23 21:44:35 +00:00
@Override
2019-08-30 22:38:15 +00:00
public void mine ( int quantity , BlockOptionalMetaLookup filter ) {
2019-08-30 18:55:25 +00:00
this . filter = filter ;
if ( filter ! = null & & ! Baritone . settings ( ) . allowBreak . value ) {
2019-07-11 17:41:24 +00:00
logDirect ( " Unable to mine when allowBreak is false! " ) ;
2019-08-30 18:55:25 +00:00
filter = null ;
2019-07-11 17:41:24 +00:00
}
2018-10-26 03:08:52 +00:00
this . desiredQuantity = quantity ;
this . knownOreLocations = new ArrayList < > ( ) ;
2019-03-12 03:06:19 +00:00
this . blacklist = new ArrayList < > ( ) ;
2018-10-26 04:21:42 +00:00
this . branchPoint = null ;
2018-11-08 01:27:57 +00:00
this . branchPointRunaway = null ;
2019-08-30 18:55:25 +00:00
if ( filter ! = null ) {
2018-11-23 17:00:52 +00:00
rescan ( new ArrayList < > ( ) , new CalculationContext ( baritone ) ) ;
}
2018-08-28 18:43:28 +00:00
}
2018-08-28 18:28:36 +00:00
}