@@ -79,26 +79,30 @@ public void handle(HighwayContext context) {
7979 }
8080
8181 boolean supportNeeded = false ;
82- if (context .getIssueType (context .sourceBlocks ().getFirst ().north ()) != HighwayBlockState .Blocks &&
83- context .getIssueType (context .sourceBlocks ().getFirst ().east ()) != HighwayBlockState .Blocks &&
84- context .getIssueType (context .sourceBlocks ().getFirst ().south ()) != HighwayBlockState .Blocks &&
85- context .getIssueType (context .sourceBlocks ().getFirst ().west ()) != HighwayBlockState .Blocks &&
86- context .getIssueType (context .sourceBlocks ().getFirst ().below ()) != HighwayBlockState .Blocks ) {
87- // Location to place against are not blocks so lets find the closest surrounding block
88- BlockPos tempSourcePos = context .closestAirBlockWithSideBlock (context .sourceBlocks ().getFirst (), 5 , true );
89- if (tempSourcePos == null ) {
90- Helper .HELPER .logDirect ("Error finding support block during lava removal. Restarting." );
82+ BlockPos firstSourceBlock = context .sourceBlocks ().getFirst ();
83+ if (context .getIssueType (firstSourceBlock .north ()) != HighwayBlockState .Blocks &&
84+ context .getIssueType (firstSourceBlock .east ()) != HighwayBlockState .Blocks &&
85+ context .getIssueType (firstSourceBlock .south ()) != HighwayBlockState .Blocks &&
86+ context .getIssueType (firstSourceBlock .west ()) != HighwayBlockState .Blocks &&
87+ context .getIssueType (firstSourceBlock .below ()) != HighwayBlockState .Blocks ) {
88+ BlockPos playerPos = context .playerContext ().playerFeet ();
89+
90+ // Calculate direction from player to lava for non-blocking checks
91+ int dx = firstSourceBlock .getX () - playerPos .getX ();
92+ int dz = firstSourceBlock .getZ () - playerPos .getZ ();
93+ BlockPos supportPos = findSupportBlockRecursive (context , firstSourceBlock , playerPos , dx , dz , 0 , 5 );
94+
95+ if (supportPos != null ) {
96+ // Clear source blocks and add the support position to place
97+ context .clearSourceBlocks ();
98+ context .sourceBlocks ().add (supportPos );
99+ supportNeeded = true ;
100+ Helper .HELPER .logDirect ("Can't place around lava, placing support block at " + supportPos );
101+ } else {
102+ Helper .HELPER .logDirect ("Cannot find valid support block position for lava removal" );
91103 context .transitionTo (HighwayState .Nothing );
92104 return ;
93105 }
94- context .clearSourceBlocks ();
95- context .sourceBlocks ().add (tempSourcePos );
96- supportNeeded = true ;
97- Helper .HELPER .logDirect ("Can't place around lava, placing support block at " + tempSourcePos );
98- //if (sourceBlocks.isEmpty()) {
99- // currentState = State.Nothing;
100- // return;
101- //}
102106 }
103107 Optional <Rotation > lavaReachable = Optional .empty ();
104108
@@ -185,7 +189,6 @@ public void handle(HighwayContext context) {
185189 //ArrayList<Rotation> belowFeetReachableList = new ArrayList<>();
186190 //Optional<Rotation> belowFeetReachable = Optional.empty();
187191 for (BlockPos placeAt : placeAtList ) {
188- //if (placeAt != null) {
189192 // From MovementHelper.attemptToPlaceABlock
190193 for (int i = 0 ; i < 5 ; i ++) {
191194 BlockPos against1 = placeAt .relative (HORIZONTALS_BUT_ALSO_DOWN_____SO_EVERY_DIRECTION_EXCEPT_UP [i ]);
@@ -195,7 +198,11 @@ public void handle(HighwayContext context) {
195198 double faceZ = (placeAt .getZ () + against1 .getZ () + 1.0D ) * 0.5D ;
196199 Rotation place = RotationUtils .calcRotationFromVec3d (context .playerContext ().playerHead (), new Vec3 (faceX , faceY , faceZ ), context .playerContext ().playerRotations ());
197200 HitResult res = RayTraceUtils .rayTraceTowards (context .playerContext ().player (), place , context .playerContext ().playerController ().getBlockReachDistance (), false );
198- if (res .getType () == HitResult .Type .BLOCK && ((BlockHitResult ) res ).getBlockPos ().equals (against1 ) && ((BlockHitResult ) res ).getBlockPos ().relative (((BlockHitResult ) res ).getDirection ()).equals (placeAt )) {
201+
202+ if (res .getType () == HitResult .Type .BLOCK &&
203+ ((BlockHitResult ) res ).getBlockPos ().equals (against1 ) &&
204+ ((BlockHitResult ) res ).getBlockPos ().relative (((BlockHitResult ) res ).getDirection ()).equals (placeAt )) {
205+
199206 context .baritone ().getLookBehavior ().updateTarget (place , true );
200207 context .baritone ().getInputOverrideHandler ().clearAllKeys ();
201208 int netherRackSlot = context .putItemHotbar (Item .getId (Blocks .NETHERRACK .asItem ()));
@@ -221,10 +228,6 @@ public void handle(HighwayContext context) {
221228 context .baritone ().getInputOverrideHandler ().setInputForceState (Input .CLICK_RIGHT , true );
222229 return ;
223230 }
224-
225- //belowFeetReachable = Optional.ofNullable(place);
226- //belowFeetReachableList.add(place);
227- //break;
228231 }
229232 }
230233 }
@@ -268,23 +271,210 @@ public void handle(HighwayContext context) {
268271 return ;
269272 }
270273
271- context .baritone ().getLookBehavior ().updateTarget (lavaRot , true );
274+ // Check if player is under any lava source block and can't reach
275+ BlockPos playerPos = context .playerContext ().playerFeet ();
276+ double reachDistance = context .playerContext ().playerController ().getBlockReachDistance ();
277+ for (BlockPos lavaPos : context .sourceBlocks ()) {
278+ int xDiff = Math .abs (playerPos .getX () - lavaPos .getX ());
279+ int zDiff = Math .abs (playerPos .getZ () - lavaPos .getZ ());
280+ int yDiff = lavaPos .getY () - playerPos .getY ();
281+
282+ if (xDiff <= 1 && zDiff <= 1 && yDiff > 0 && yDiff > reachDistance ) {
283+ Helper .HELPER .logDirect ("Player under lava and can't reach, backing up" );
284+ context .baritone ().getInputOverrideHandler ().clearAllKeys ();
285+ context .transitionTo (HighwayState .LiquidRemovalPathingBack );
286+ context .resetTimer ();
287+ return ;
288+ }
289+ }
290+
272291 context .baritone ().getInputOverrideHandler ().clearAllKeys ();
273292
274- outerLoop :
275- for (int x = -1 ; x <= 1 ; x ++) {
276- for (int z = -1 ; z <= 1 ; z ++) {
277- BlockPos tempLoc = new BlockPos (context .playerContext ().playerFeet ().x + x , context .playerContext ().playerFeet ().y - 1 , context .playerContext ().playerFeet ().z + z );
278- if (context .getIssueType (tempLoc ) != HighwayBlockState .Blocks ) {
279- context .baritone ().getInputOverrideHandler ().setInputForceState (Input .SNEAK , true ); // No blocks under feet to walk to
280- break outerLoop ;
293+ // Check for blocks that might be obstructing our path
294+ BlockPos feetPos = context .playerContext ().playerFeet ();
295+ Direction playerDirection = context .playerContext ().player ().getDirection ();
296+ BlockPos frontPos = feetPos .relative (playerDirection );
297+ BlockPos frontHeadPos = frontPos .above (); // Block at head level
298+ BlockPos bridgePos = frontPos .below ();
299+
300+ // Also check left and right sides in case player is between blocks
301+ Direction leftDir = playerDirection .getCounterClockWise ();
302+ Direction rightDir = playerDirection .getClockWise ();
303+ BlockPos leftPos = feetPos .relative (leftDir );
304+ BlockPos leftHeadPos = leftPos .above ();
305+ BlockPos rightPos = feetPos .relative (rightDir );
306+ BlockPos rightHeadPos = rightPos .above ();
307+
308+ // Check all potential obstructing positions
309+ BlockPos [] checkPositions = {frontPos , frontHeadPos , leftPos , leftHeadPos , rightPos , rightHeadPos };
310+ BlockPos blockToBreak = null ;
311+
312+ // Find the first obstructing block we can break
313+ for (BlockPos checkPos : checkPositions ) {
314+ if (context .getIssueType (checkPos ) == HighwayBlockState .Blocks ) {
315+ Optional <Rotation > breakRotation = RotationUtils .reachable (context .playerContext (), checkPos , context .playerContext ().playerController ().getBlockReachDistance ());
316+ if (breakRotation .isPresent ()) {
317+ blockToBreak = checkPos ;
318+ break ;
281319 }
282320 }
283321 }
322+
323+ // If we found an obstructing block, break it
324+ if (blockToBreak != null ) {
325+ Optional <Rotation > breakRotation = RotationUtils .reachable (context .playerContext (), blockToBreak , context .playerContext ().playerController ().getBlockReachDistance ());
326+ if (breakRotation .isPresent ()) {
327+ // Make sure we have a pickaxe selected
328+ int breakPickSlot = context .putPickaxeHotbar ();
329+ if (breakPickSlot != -1 ) {
330+ ItemStack breakStack = context .playerContext ().player ().getInventory ().items .get (breakPickSlot );
331+ if (HighwayContext .validPicksList .contains (breakStack .getItem ())) {
332+ context .playerContext ().player ().getInventory ().selected = breakPickSlot ;
333+ }
334+
335+ // Look at the block and break it
336+ context .baritone ().getLookBehavior ().updateTarget (breakRotation .get (), true );
337+ context .baritone ().getInputOverrideHandler ().setInputForceState (Input .CLICK_LEFT , true );
338+ Helper .HELPER .logDirect ("Breaking obstructing block at " + blockToBreak );
339+ return ;
340+ }
341+ }
342+ }
343+
344+ // Check if we need to bridge (no block directly in front below feet)
345+ if (context .getIssueType (bridgePos ) != HighwayBlockState .Blocks ) {
346+ double edgeDistance = Math .max (
347+ Math .abs (context .playerContext ().player ().getX () - (feetPos .getX () + 0.5 )),
348+ Math .abs (context .playerContext ().player ().getZ () - (feetPos .getZ () + 0.5 ))
349+ );
350+
351+ if (edgeDistance < 0.1 ) {
352+ // Look at the edge face between current position and bridge position
353+ double edgeFaceX = (feetPos .getX () + bridgePos .getX () + 1.0D ) * 0.5D ;
354+ double edgeFaceY = bridgePos .getY () + 0.5D ;
355+ double edgeFaceZ = (feetPos .getZ () + bridgePos .getZ () + 1.0D ) * 0.5D ;
356+
357+ Rotation edgeRotation = RotationUtils .calcRotationFromVec3d (
358+ context .playerContext ().playerHead (),
359+ new Vec3 (edgeFaceX , edgeFaceY , edgeFaceZ ),
360+ context .playerContext ().playerRotations ()
361+ );
362+ context .baritone ().getLookBehavior ().updateTarget (edgeRotation , true );
363+ }
284364
285- context .baritone ().getInputOverrideHandler ().setInputForceState (Input .MOVE_FORWARD , true );
365+ context .baritone ().getInputOverrideHandler ().setInputForceState (Input .MOVE_FORWARD , true );
366+ context .baritone ().getInputOverrideHandler ().setInputForceState (Input .SNEAK , true );
367+ } else {
368+ // Safe to walk forward
369+ context .baritone ().getLookBehavior ().updateTarget (lavaRot , true );
370+ context .baritone ().getInputOverrideHandler ().setInputForceState (Input .MOVE_FORWARD , true );
371+ }
286372 }
287373
288374 //timer = 0;
289375 }
376+
377+ private BlockPos findSupportBlockRecursive (HighwayContext context , BlockPos targetPos ,
378+ BlockPos playerPos , int dx , int dz ,
379+ int depth , int maxDepth ) {
380+ if (depth >= maxDepth ) {
381+ return null ; // Max recursion depth reached
382+ }
383+
384+ BlockPos bestPos = null ;
385+ double bestScore = Double .MAX_VALUE ;
386+
387+ // First check all directions around the target position
388+ // Prioritize horizontal directions over vertical to avoid building columns
389+ Direction [] directions = {Direction .NORTH , Direction .SOUTH , Direction .EAST , Direction .WEST , Direction .UP , Direction .DOWN };
390+ for (Direction dir : directions ) {
391+ BlockPos checkPos = targetPos .relative (dir );
392+
393+ if (context .getIssueType (checkPos ) == HighwayBlockState .Blocks ) {
394+ continue ;
395+ }
396+
397+ // If this is below the target and at depth 0 (original lava position),
398+ // only accept it if it's directly adjacent to the lava
399+ if (dir == Direction .DOWN && depth == 0 ) {
400+ // Check if placing here would create a pillar situation
401+ // We only want to place below if we can immediately place against the lava from there
402+ boolean directlyUseful = false ;
403+ for (Direction sideDir : Direction .Plane .HORIZONTAL ) {
404+ BlockPos sideOfBelow = checkPos .relative (sideDir );
405+ if (sideOfBelow .equals (targetPos )) {
406+ directlyUseful = true ;
407+ break ;
408+ }
409+ }
410+ if (!directlyUseful ) {
411+ continue ; // Skip positions below lava that aren't directly useful
412+ }
413+ }
414+
415+ // Check if we can place at this position
416+ boolean canPlace = false ;
417+ for (Direction placeDir : Direction .values ()) {
418+ BlockPos against = checkPos .relative (placeDir );
419+ // Don't count the target position itself as something to place against
420+ if (!against .equals (targetPos ) && MovementHelper .canPlaceAgainst (context .playerContext (), against )) {
421+ canPlace = true ;
422+ break ;
423+ }
424+ }
425+
426+ if (canPlace ) {
427+ // Check if this position would block the player's path
428+ int checkDx = checkPos .getX () - playerPos .getX ();
429+ int checkDz = checkPos .getZ () - playerPos .getZ ();
430+ boolean notBlocking = (Math .abs (checkDx ) >= Math .abs (dx ) || Math .abs (checkDz ) >= Math .abs (dz ));
431+
432+ // Calculate a score based on distance and blocking status
433+ // Lower score is better
434+ double distance = Math .sqrt (checkDx * checkDx + checkDz * checkDz );
435+ double score = getScore (dir , notBlocking , distance );
436+
437+ // At depth 0, only consider non-blocking positions
438+ // At higher depths, accept any position but prefer non-blocking ones
439+ if ((notBlocking || depth > 0 ) && score < bestScore ) {
440+ bestPos = checkPos ;
441+ bestScore = score ;
442+ }
443+ }
444+ }
445+
446+ if (bestPos != null ) {
447+ return bestPos ;
448+ }
449+
450+ // If we couldn't find a direct placement position, recurse to find positions
451+ // that we can build from to eventually reach the target
452+ for (Direction dir : directions ) {
453+ BlockPos checkPos = targetPos .relative (dir );
454+
455+ if (context .getIssueType (checkPos ) == HighwayBlockState .Blocks ) {
456+ continue ;
457+ }
458+
459+ BlockPos result = findSupportBlockRecursive (context , checkPos , playerPos , dx , dz , depth + 1 , maxDepth );
460+ if (result != null ) {
461+ return result ;
462+ }
463+ }
464+
465+ return null ; // No valid position found
466+ }
467+
468+ private static double getScore (Direction dir , boolean notBlocking , double distance ) {
469+ double score = notBlocking ? distance : distance + 1000 ; // Penalize blocking positions
470+
471+ // Penalize positions below that would require pillaring up
472+ // But placing from above is fine and even preferred
473+ if (dir == Direction .DOWN ) {
474+ score += 500 ; // Make below positions less preferred as they require pillaring
475+ } else if (dir == Direction .UP ) {
476+ score -= 50 ; // Slightly prefer above positions as they're easy to place from
477+ }
478+ return score ;
479+ }
290480}
0 commit comments