Merge pull request #4742 from Murat65536/magma-block-detection

Magma block detection
This commit is contained in:
leijurv
2025-07-23 20:58:03 +02:00
committed by GitHub
10 changed files with 68 additions and 19 deletions

View File

@@ -1550,6 +1550,11 @@ public final class Settings {
*/
public final Setting<Boolean> elytraChatSpam = new Setting<>(false);
/**
* Sneak when magma blocks are under feet
*/
public final Setting<Boolean> allowWalkOnMagmaBlocks = new Setting<>(false);
/**
* A map of lowercase setting field names to their respective setting
*/

View File

@@ -79,6 +79,7 @@ public class CalculationContext {
public double backtrackCostFavoringCoefficient;
public double jumpPenalty;
public final double walkOnWaterOnePenalty;
public final boolean allowWalkOnMagmaBlocks;
public final BetterWorldBorder worldBorder;
public final PrecomputedData precomputedData;
@@ -125,6 +126,7 @@ public class CalculationContext {
this.backtrackCostFavoringCoefficient = Baritone.settings().backtrackCostFavoringCoefficient.value;
this.jumpPenalty = Baritone.settings().jumpPenalty.value;
this.walkOnWaterOnePenalty = Baritone.settings().walkOnWaterOnePenalty.value;
this.allowWalkOnMagmaBlocks = Baritone.settings().allowWalkOnMagmaBlocks.value;
// why cache these things here, why not let the movements just get directly from settings?
// because if some movements are calculated one way and others are calculated another way,
// then you get a wildly inconsistent path that isn't optimal for either scenario.

View File

@@ -50,6 +50,7 @@ import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.HitResult;
import net.minecraft.world.phys.Vec3;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
@@ -384,7 +385,7 @@ public interface MovementHelper extends ActionCosts, Helper {
static boolean avoidWalkingInto(BlockState state) {
Block block = state.getBlock();
return !state.getFluidState().isEmpty()
|| block == Blocks.MAGMA_BLOCK
|| (block == Blocks.MAGMA_BLOCK && !Baritone.settings().allowWalkOnMagmaBlocks.value)
|| block == Blocks.CACTUS
|| block == Blocks.SWEET_BERRY_BUSH
|| block instanceof BaseFireBlock
@@ -420,7 +421,7 @@ public interface MovementHelper extends ActionCosts, Helper {
static Ternary canWalkOnBlockState(BlockState state) {
Block block = state.getBlock();
if (isBlockNormalCube(state) && block != Blocks.MAGMA_BLOCK && block != Blocks.BUBBLE_COLUMN && block != Blocks.HONEY_BLOCK) {
if (isBlockNormalCube(state) && (block != Blocks.MAGMA_BLOCK || Baritone.settings().allowWalkOnMagmaBlocks.value) && block != Blocks.BUBBLE_COLUMN && block != Blocks.HONEY_BLOCK) {
return YES;
}
if (block instanceof AzaleaBlock) {
@@ -806,4 +807,16 @@ public interface MovementHelper extends ActionCosts, Helper {
b == Blocks.LAVA ||
b == Blocks.WATER;
}
static List<BetterBlockPos> steppingOnBlocks(IPlayerContext ctx) {
List<BetterBlockPos> blocks = new ArrayList<>();
for (byte x = -1; x <= 1; x++) {
for (byte z = -1; z <= 1; z++) {
if (ctx.player().getBoundingBox().intersects(Vec3.atLowerCornerOf(ctx.player().blockPosition()).add(x, 0, z), Vec3.atLowerCornerOf(ctx.player().blockPosition()).add(x + 1, 1, z + 1))) {
blocks.add(new BetterBlockPos(ctx.player().getBlockX() + x, ctx.player().getBlockY() - 1, ctx.player().getBlockZ() + z));
}
}
}
return blocks;
}
}

View File

@@ -131,8 +131,10 @@ public class MovementAscend extends Movement {
}
} else {
// jumpingFromBottomSlab must be false
if (toPlace.getBlock() == Blocks.SOUL_SAND) {
if (toPlace.is(Blocks.SOUL_SAND)) {
walk = WALK_ONE_OVER_SOUL_SAND_COST;
} else if (toPlace.is(Blocks.MAGMA_BLOCK)) {
walk = SNEAK_ONE_BLOCK_COST;
} else {
walk = Math.max(JUMP_ONE_BLOCK_COST, WALK_ONE_BLOCK_COST);
}
@@ -188,6 +190,9 @@ public class MovementAscend extends Movement {
return state;
}
MovementHelper.moveTowards(ctx, state, dest);
state.setInput(Input.SNEAK, Baritone.settings().allowWalkOnMagmaBlocks.value && jumpingOnto.is(Blocks.MAGMA_BLOCK));
if (MovementHelper.isBottomSlab(jumpingOnto) && !MovementHelper.isBottomSlab(BlockStateInterface.get(ctx, src.below()))) {
return state; // don't jump while walking from a non double slab into a bottom slab
}

View File

@@ -17,6 +17,7 @@
package baritone.pathing.movement.movements;
import baritone.Baritone;
import baritone.api.IBaritone;
import baritone.api.pathing.movement.MovementStatus;
import baritone.api.utils.BetterBlockPos;
@@ -255,6 +256,9 @@ public class MovementDescend extends Movement {
double x = ctx.player().position().x - (src.getX() + 0.5);
double z = ctx.player().position().z - (src.getZ() + 0.5);
double fromStart = Math.sqrt(x * x + z * z);
state.setInput(Input.SNEAK, Baritone.settings().allowWalkOnMagmaBlocks.value && ctx.world().getBlockState(ctx.player().blockPosition().below()).is(Blocks.MAGMA_BLOCK));
if (!playerFeet.equals(dest) || ab > 0.25) {
if (numTicks++ < 20 && fromStart < 1.25) {
MovementHelper.moveTowards(ctx, state, fakeDest);

View File

@@ -118,6 +118,7 @@ public class MovementDiagonal extends Movement {
BlockState destWalkOn;
boolean descend = false;
boolean frostWalker = false;
boolean sneaking = false;
if (!MovementHelper.canWalkThrough(context, destX, y, destZ, destInto)) {
ascend = true;
if (!context.allowDiagonalAscend || !MovementHelper.canWalkThrough(context, x, y + 2, z) || !MovementHelper.canWalkOn(context, destX, y, destZ, destInto) || !MovementHelper.canWalkThrough(context, destX, y + 2, destZ)) {
@@ -140,8 +141,11 @@ public class MovementDiagonal extends Movement {
}
double multiplier = WALK_ONE_BLOCK_COST;
// For either possible soul sand, that affects half of our walking
if (destWalkOn.getBlock() == Blocks.SOUL_SAND) {
if (destWalkOn.is(Blocks.SOUL_SAND)) {
multiplier += (WALK_ONE_OVER_SOUL_SAND_COST - WALK_ONE_BLOCK_COST) / 2;
} else if (context.allowWalkOnMagmaBlocks && destWalkOn.is(Blocks.MAGMA_BLOCK)) {
multiplier += (SNEAK_ONE_BLOCK_COST - WALK_ONE_BLOCK_COST) / 2;
sneaking = true;
} else if (frostWalker) {
// frostwalker lets us walk on water without the penalty
} else if (destWalkOn.getBlock() == Blocks.WATER) {
@@ -153,13 +157,16 @@ public class MovementDiagonal extends Movement {
}
if (fromDownBlock == Blocks.SOUL_SAND) {
multiplier += (WALK_ONE_OVER_SOUL_SAND_COST - WALK_ONE_BLOCK_COST) / 2;
} else if (context.allowWalkOnMagmaBlocks && fromDownBlock.equals(Blocks.MAGMA_BLOCK)) {
multiplier += (SNEAK_ONE_BLOCK_COST - WALK_ONE_BLOCK_COST) / 2;
sneaking = true;
}
BlockState cuttingOver1 = context.get(x, y - 1, destZ);
if (cuttingOver1.getBlock() == Blocks.MAGMA_BLOCK || MovementHelper.isLava(cuttingOver1)) {
if ((!context.allowWalkOnMagmaBlocks && cuttingOver1.is(Blocks.MAGMA_BLOCK)) || MovementHelper.isLava(cuttingOver1)) {
return;
}
BlockState cuttingOver2 = context.get(destX, y - 1, z);
if (cuttingOver2.getBlock() == Blocks.MAGMA_BLOCK || MovementHelper.isLava(cuttingOver2)) {
if ((!context.allowWalkOnMagmaBlocks && cuttingOver1.is(Blocks.MAGMA_BLOCK)) || MovementHelper.isLava(cuttingOver2)) {
return;
}
boolean water = false;
@@ -234,7 +241,7 @@ public class MovementDiagonal extends Movement {
}
} else {
// only can sprint if not edging around
if (context.canSprint && !water) {
if (context.canSprint && !water && !sneaking) {
// If we aren't edging around anything, and we aren't in water
// We can sprint =D
// Don't check for soul sand, since we can sprint on that too
@@ -270,6 +277,7 @@ public class MovementDiagonal extends Movement {
if (sprint()) {
state.setInput(Input.SPRINT, true);
}
state.setInput(Input.SNEAK, Baritone.settings().allowWalkOnMagmaBlocks.value && MovementHelper.steppingOnBlocks(ctx).stream().anyMatch(block -> ctx.world().getBlockState(block).is(Blocks.MAGMA_BLOCK)));
MovementHelper.moveTowards(ctx, state, dest);
return state;
}

View File

@@ -94,6 +94,11 @@ public class MovementFall extends Movement {
Rotation targetRotation = null;
BlockState destState = ctx.world().getBlockState(dest);
Block destBlock = destState.getBlock();
if (ctx.world().getBlockState(dest.below()).is(Blocks.MAGMA_BLOCK) && MovementHelper.steppingOnBlocks(ctx).stream().allMatch(block -> MovementHelper.canWalkThrough(ctx, block))) {
state.setInput(Input.SNEAK, true);
}
boolean isWater = destState.getFluidState().getType() instanceof WaterFluid;
if (!isWater && willPlaceBucket() && !playerFeet.equals(dest)) {
if (!Inventory.isHotbarSlot(ctx.player().getInventory().findSlotMatchingItem(STACK_BUCKET_WATER)) || ctx.world().dimension() == Level.NETHER) {

View File

@@ -102,15 +102,15 @@ public class MovementParkour extends Movement {
return; // can't jump out of water
}
int maxJump;
if (standingOn.getBlock() == Blocks.SOUL_SAND) {
if (context.allowWalkOnMagmaBlocks && standingOn.is(Blocks.MAGMA_BLOCK)) {
maxJump = 2;
} else if (standingOn.getBlock() == Blocks.SOUL_SAND) {
maxJump = 2; // 1 block gap
} else {
if (context.canSprint) {
} else if (context.canSprint) {
maxJump = 4;
} else {
maxJump = 3;
}
}
// check parkour jumps from smallest to largest for obstacles/walls and landing positions
int verifiedMaxJump = 1; // i - 1 (when i = 2)
@@ -262,6 +262,10 @@ public class MovementParkour extends Movement {
if (dist >= 4 || ascend) {
state.setInput(Input.SPRINT, true);
}
if (Baritone.settings().allowWalkOnMagmaBlocks.value && ctx.world().getBlockState(ctx.playerFeet().below()).is(Blocks.MAGMA_BLOCK)) {
state.setInput(Input.SNEAK, true);
}
MovementHelper.moveTowards(ctx, state, dest);
if (ctx.playerFeet().equals(dest)) {
Block d = BlockStateInterface.getBlock(ctx, dest);

View File

@@ -229,8 +229,7 @@ public class MovementPillar extends Movement {
return state.setStatus(MovementStatus.UNREACHABLE);
}
state.setInput(Input.SNEAK, ctx.player().position().y > dest.getY() || ctx.player().position().y < src.getY() + 0.2D); // delay placement by 1 tick for ncp compatibility
state.setInput(Input.SNEAK, true);
// since (lower down) we only right click once player.isSneaking, and that happens the tick after we request to sneak
double diffX = ctx.player().position().x - (dest.getX() + 0.5);

View File

@@ -85,6 +85,7 @@ public class MovementTraverse extends Movement {
if (frostWalker || MovementHelper.canWalkOn(context, destX, y - 1, destZ, destOn)) { //this is a walk, not a bridge
double WC = WALK_ONE_BLOCK_COST;
boolean water = false;
boolean sneaking = false;
if (MovementHelper.isWater(pb0) || MovementHelper.isWater(pb1)) {
WC = context.waterWalkSpeed;
water = true;
@@ -98,6 +99,9 @@ public class MovementTraverse extends Movement {
}
if (srcDownBlock == Blocks.SOUL_SAND) {
WC += (WALK_ONE_OVER_SOUL_SAND_COST - WALK_ONE_BLOCK_COST) / 2;
} else if (context.allowWalkOnMagmaBlocks && srcDownBlock.equals(Blocks.MAGMA_BLOCK)) {
sneaking = true;
WC += (SNEAK_ONE_BLOCK_COST - WALK_ONE_BLOCK_COST) / 2;
}
}
double hardness1 = MovementHelper.getMiningDurationTicks(context, destX, y, destZ, pb1, false);
@@ -106,7 +110,7 @@ public class MovementTraverse extends Movement {
}
double hardness2 = MovementHelper.getMiningDurationTicks(context, destX, y + 1, destZ, pb0, true); // only include falling on the upper block to break
if (hardness1 == 0 && hardness2 == 0) {
if (!water && context.canSprint) {
if (!water && !sneaking && context.canSprint) {
// If there's nothing in the way, and this isn't water, and we aren't sneak placing
// We can sprint =D
// Don't check for soul sand, since we can sprint on that too
@@ -213,12 +217,12 @@ public class MovementTraverse extends Movement {
.setInput(Input.SPRINT, true);
}
//sneak may have been set to true in the PREPPING state while mining an adjacent block
state.setInput(Input.SNEAK, false);
Block fd = BlockStateInterface.get(ctx, src.below()).getBlock();
boolean ladder = fd == Blocks.LADDER || fd == Blocks.VINE;
//sneak may have been set to true in the PREPPING state while mining an adjacent block, but we still want it to be true if the player is about to go on magma
state.setInput(Input.SNEAK, Baritone.settings().allowWalkOnMagmaBlocks.value && MovementHelper.steppingOnBlocks(ctx).stream().anyMatch(block -> ctx.world().getBlockState(block).is(Blocks.MAGMA_BLOCK)));
if (pb0.getBlock() instanceof DoorBlock || pb1.getBlock() instanceof DoorBlock) {
boolean notPassable = pb0.getBlock() instanceof DoorBlock && !MovementHelper.isDoorPassable(ctx, src, dest) || pb1.getBlock() instanceof DoorBlock && !MovementHelper.isDoorPassable(ctx, dest, src);
boolean canOpen = !(Blocks.IRON_DOOR.equals(pb0.getBlock()) || Blocks.IRON_DOOR.equals(pb1.getBlock()));