Merge branch '1.15.2' into 1.16.5

This commit is contained in:
ZacSharp 2023-01-10 01:40:36 +01:00
commit 0e1fee352f
No known key found for this signature in database
GPG Key ID: 9453647B005083A3
28 changed files with 358 additions and 182 deletions

View File

@ -13,12 +13,12 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
- name: Set up JDK 8 - name: Set up JDK 8
uses: actions/setup-java@v2 uses: actions/setup-java@v3
with: with:
java-version: '8' java-version: '8'
distribution: 'adopt' distribution: 'temurin'
- name: Grant execute permission for gradlew - name: Grant execute permission for gradlew
run: chmod +x gradlew run: chmod +x gradlew
@ -33,13 +33,13 @@ jobs:
run: ./gradlew build -Pbaritone.forge_build run: ./gradlew build -Pbaritone.forge_build
- name: Archive Artifacts - name: Archive Artifacts
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v3
with: with:
name: Artifacts name: Artifacts
path: dist/ path: dist/
- name: Archive mapping.txt - name: Archive mapping.txt
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v3
with: with:
name: Mappings name: Mappings
path: build/tmp/proguard/mapping.txt path: build/tmp/proguard/mapping.txt

View File

@ -11,12 +11,12 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
- name: Set up JDK 9 - name: Set up JDK 8
uses: actions/setup-java@v2 uses: actions/setup-java@v3
with: with:
java-version: '8' java-version: '8'
distribution: 'adopt' distribution: 'temurin'
- name: Grant execute permission for gradlew - name: Grant execute permission for gradlew
run: chmod +x gradlew run: chmod +x gradlew

View File

@ -201,8 +201,8 @@ public class ProguardTask extends BaritoneGradleTask {
// Setup the template that will be used to derive the API and Standalone configs // Setup the template that will be used to derive the API and Standalone configs
List<String> template = Files.readAllLines(getTemporaryFile(PROGUARD_CONFIG_DEST)); List<String> template = Files.readAllLines(getTemporaryFile(PROGUARD_CONFIG_DEST));
template.add(0, "-injars " + this.artifactPath.toString()); template.add(0, "-injars '" + this.artifactPath.toString() + "'");
template.add(1, "-outjars " + this.getTemporaryFile(PROGUARD_EXPORT_PATH)); template.add(1, "-outjars '" + this.getTemporaryFile(PROGUARD_EXPORT_PATH) + "'");
// Acquire the RT jar using "java -verbose". This doesn't work on Java 9+ // Acquire the RT jar using "java -verbose". This doesn't work on Java 9+
Process p = new ProcessBuilder(this.getJavaBinPathForProguard(), "-verbose").start(); Process p = new ProcessBuilder(this.getJavaBinPathForProguard(), "-verbose").start();
@ -283,9 +283,15 @@ public class ProguardTask extends BaritoneGradleTask {
Files.delete(this.proguardOut); Files.delete(this.proguardOut);
} }
Path proguardJar = getTemporaryFile(PROGUARD_JAR); // Make paths relative to work directory; fixes spaces in path to config, @"" doesn't work
Path workingDirectory = getTemporaryFile("");
Path proguardJar = workingDirectory.relativize(getTemporaryFile(PROGUARD_JAR));
config = workingDirectory.relativize(config);
// Honestly, if you still have spaces in your path at this point, you're SOL.
Process p = new ProcessBuilder("java", "-jar", proguardJar.toString(), "@" + config.toString()) Process p = new ProcessBuilder("java", "-jar", proguardJar.toString(), "@" + config.toString())
.directory(getTemporaryFile("").toFile()) // Set the working directory to the temporary folder] .directory(workingDirectory.toFile()) // Set the working directory to the temporary folder]
.start(); .start();
// We can't do output inherit process I/O with gradle for some reason and have it work, so we have to do this // We can't do output inherit process I/O with gradle for some reason and have it work, so we have to do this

View File

@ -34,8 +34,8 @@ import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.List; import java.util.List;
import java.util.*; import java.util.*;
import java.util.function.Consumer;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.Consumer;
/** /**
* Baritone's settings. Settings apply to all Baritone instances. * Baritone's settings. Settings apply to all Baritone instances.
@ -196,7 +196,7 @@ public final class Settings {
* Blocks that Baritone is not allowed to break * Blocks that Baritone is not allowed to break
*/ */
public final Setting<List<Block>> blocksToDisallowBreaking = new Setting<>(new ArrayList<>( public final Setting<List<Block>> blocksToDisallowBreaking = new Setting<>(new ArrayList<>(
// Leave Empty by Default // Leave Empty by Default
)); ));
/** /**
@ -276,6 +276,12 @@ public final class Settings {
*/ */
public final Setting<Boolean> buildIgnoreDirection = new Setting<>(false); public final Setting<Boolean> buildIgnoreDirection = new Setting<>(false);
/**
* A list of names of block properties the builder will ignore.
*/
public final Setting<List<String>> buildIgnoreProperties = new Setting<>(new ArrayList<>(Arrays.asList(
)));
/** /**
* If this setting is true, Baritone will never break a block that is adjacent to an unsupported falling block. * If this setting is true, Baritone will never break a block that is adjacent to an unsupported falling block.
* <p> * <p>
@ -914,7 +920,7 @@ public final class Settings {
/** /**
* Only build the selected part of schematics * Only build the selected part of schematics
*/ */
public final Setting<Boolean> buildOnlySelection = new Setting<>(false); public final Setting<Boolean> buildOnlySelection = new Setting<>(false);
/** /**
* How far to move before repeating the build. 0 to disable repeating on a certain axis, 0,0,0 to disable entirely * How far to move before repeating the build. 0 to disable repeating on a certain axis, 0,0,0 to disable entirely

View File

@ -26,7 +26,8 @@ import java.util.stream.Stream;
public enum RelativeCoordinate implements IDatatypePost<Double, Double> { public enum RelativeCoordinate implements IDatatypePost<Double, Double> {
INSTANCE; INSTANCE;
private static Pattern PATTERN = Pattern.compile("^(~?)([+-]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)([k-k]?)|)$"); private static String ScalesAliasRegex = "[kKmM]";
private static Pattern PATTERN = Pattern.compile("^(~?)([+-]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)("+ScalesAliasRegex+"?)|)$");
@Override @Override
public Double apply(IDatatypeContext ctx, Double origin) throws CommandException { public Double apply(IDatatypeContext ctx, Double origin) throws CommandException {
@ -41,11 +42,15 @@ public enum RelativeCoordinate implements IDatatypePost<Double, Double> {
boolean isRelative = !matcher.group(1).isEmpty(); boolean isRelative = !matcher.group(1).isEmpty();
double offset = matcher.group(2).isEmpty() ? 0 : Double.parseDouble(matcher.group(2).replaceAll("k", "")); double offset = matcher.group(2).isEmpty() ? 0 : Double.parseDouble(matcher.group(2).replaceAll(ScalesAliasRegex, ""));
if (matcher.group(2).contains("k")) { if (matcher.group(2).toLowerCase().contains("k")) {
offset *= 1000; offset *= 1000;
} }
if (matcher.group(2).toLowerCase().contains("m")) {
offset *= 1000000;
}
if (isRelative) { if (isRelative) {
return origin + offset; return origin + offset;

View File

@ -84,7 +84,7 @@ public class Registry<V> {
* @param entry The entry to unregister. * @param entry The entry to unregister.
*/ */
public void unregister(V entry) { public void unregister(V entry) {
if (registered(entry)) { if (!registered(entry)) {
return; return;
} }
_entries.remove(entry); _entries.remove(entry);

View File

@ -179,7 +179,7 @@ public class SettingsUtil {
/** /**
* This should always be the same as whether the setting can be parsed from or serialized to a string * This should always be the same as whether the setting can be parsed from or serialized to a string
* *
* @param the setting * @param setting The Setting
* @return true if the setting can not be set or read by the user * @return true if the setting can not be set or read by the user
*/ */
public static boolean javaOnlySetting(Settings.Setting setting) { public static boolean javaOnlySetting(Settings.Setting setting) {

View File

@ -1,35 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* 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
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.launch.mixins;
import baritone.utils.accessor.ILongArrayNBT;
import net.minecraft.nbt.LongArrayNBT;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
/**
* @author rycbar
* @since 26.09.2022
*/
@Mixin(LongArrayNBT.class)
public abstract class MixinLongArrayNBT implements ILongArrayNBT {
@Accessor("data")
@Override
public abstract long[] getLongArray();
}

View File

@ -19,7 +19,6 @@
"MixinLivingEntity", "MixinLivingEntity",
"MixinLootContext", "MixinLootContext",
"MixinMinecraft", "MixinMinecraft",
"MixinLongArrayNBT",
"MixinNetworkManager", "MixinNetworkManager",
"MixinPlayerController", "MixinPlayerController",
"MixinScreen", "MixinScreen",

View File

@ -99,6 +99,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
baritone.getPathingControlManager().cancelEverything(); baritone.getPathingControlManager().cancelEverything();
return; return;
} }
expectedSegmentStart = pathStart(); expectedSegmentStart = pathStart();
baritone.getPathingControlManager().preTick(); baritone.getPathingControlManager().preTick();
tickPath(); tickPath();

View File

@ -56,6 +56,7 @@ public class ExecutionControlCommands {
@Override @Override
public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) {
baritone.getInputOverrideHandler().clearAllKeys();
return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE); return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE);
} }

View File

@ -147,7 +147,8 @@ public class SetCommand extends Command {
throw new CommandInvalidTypeException(args.consumed(), "a toggleable setting", "some other setting"); throw new CommandInvalidTypeException(args.consumed(), "a toggleable setting", "some other setting");
} }
//noinspection unchecked //noinspection unchecked
((Settings.Setting<Boolean>) setting).value ^= true; Settings.Setting<Boolean> asBoolSetting = (Settings.Setting<Boolean>) setting;
asBoolSetting.value ^= true;
logDirect(String.format( logDirect(String.format(
"Toggled setting %s to %s", "Toggled setting %s to %s",
setting.getName(), setting.getName(),

View File

@ -21,6 +21,7 @@ import baritone.Baritone;
import baritone.api.IBaritone; import baritone.api.IBaritone;
import baritone.api.pathing.movement.ActionCosts; import baritone.api.pathing.movement.ActionCosts;
import baritone.cache.WorldData; import baritone.cache.WorldData;
import baritone.pathing.precompute.PrecomputedData;
import baritone.utils.BlockStateInterface; import baritone.utils.BlockStateInterface;
import baritone.utils.ToolSet; import baritone.utils.ToolSet;
import baritone.utils.pathing.BetterWorldBorder; import baritone.utils.pathing.BetterWorldBorder;
@ -76,11 +77,14 @@ public class CalculationContext {
public final double walkOnWaterOnePenalty; public final double walkOnWaterOnePenalty;
public final BetterWorldBorder worldBorder; public final BetterWorldBorder worldBorder;
public final PrecomputedData precomputedData;
public CalculationContext(IBaritone baritone) { public CalculationContext(IBaritone baritone) {
this(baritone, false); this(baritone, false);
} }
public CalculationContext(IBaritone baritone, boolean forUseOnAnotherThread) { public CalculationContext(IBaritone baritone, boolean forUseOnAnotherThread) {
this.precomputedData = new PrecomputedData();
this.safeForThreadedUse = forUseOnAnotherThread; this.safeForThreadedUse = forUseOnAnotherThread;
this.baritone = baritone; this.baritone = baritone;
ClientPlayerEntity player = baritone.getPlayerContext().player(); ClientPlayerEntity player = baritone.getPlayerContext().player();

View File

@ -25,6 +25,7 @@ import baritone.api.pathing.movement.MovementStatus;
import baritone.api.utils.*; import baritone.api.utils.*;
import baritone.api.utils.input.Input; import baritone.api.utils.input.Input;
import baritone.pathing.movement.MovementState.MovementTarget; import baritone.pathing.movement.MovementState.MovementTarget;
import baritone.pathing.precompute.Ternary;
import baritone.utils.BlockStateInterface; import baritone.utils.BlockStateInterface;
import baritone.utils.ToolSet; import baritone.utils.ToolSet;
import net.minecraft.block.*; import net.minecraft.block.*;
@ -43,6 +44,7 @@ import java.util.List;
import java.util.Optional; import java.util.Optional;
import static baritone.pathing.movement.Movement.HORIZONTALS_BUT_ALSO_DOWN_____SO_EVERY_DIRECTION_EXCEPT_UP; import static baritone.pathing.movement.Movement.HORIZONTALS_BUT_ALSO_DOWN_____SO_EVERY_DIRECTION_EXCEPT_UP;
import static baritone.pathing.precompute.Ternary.*;
/** /**
* Static helpers for cost calculation * Static helpers for cost calculation
@ -91,29 +93,82 @@ public interface MovementHelper extends ActionCosts, Helper {
return canWalkThrough(bsi, x, y, z, bsi.get0(x, y, z)); return canWalkThrough(bsi, x, y, z, bsi.get0(x, y, z));
} }
static boolean canWalkThrough(CalculationContext context, int x, int y, int z, BlockState state) {
return context.precomputedData.canWalkThrough(context.bsi, x, y, z, state);
}
static boolean canWalkThrough(CalculationContext context, int x, int y, int z) {
return context.precomputedData.canWalkThrough(context.bsi, x, y, z, context.get(x, y, z));
}
static boolean canWalkThrough(BlockStateInterface bsi, int x, int y, int z, BlockState state) { static boolean canWalkThrough(BlockStateInterface bsi, int x, int y, int z, BlockState state) {
Block block = state.getBlock(); Ternary canWalkThrough = canWalkThroughBlockState(state);
if (block instanceof AirBlock) { // early return for most common case if (canWalkThrough == YES) {
return true; return true;
} }
if (block instanceof AbstractFireBlock || block == Blocks.TRIPWIRE || block == Blocks.COBWEB || block == Blocks.END_PORTAL || block == Blocks.COCOA || block instanceof AbstractSkullBlock || block == Blocks.BUBBLE_COLUMN || block instanceof ShulkerBoxBlock || block instanceof SlabBlock || block instanceof TrapDoorBlock || block == Blocks.HONEY_BLOCK || block == Blocks.END_ROD || block == Blocks.SWEET_BERRY_BUSH) { if (canWalkThrough == NO) {
return false; return false;
} }
return canWalkThroughPosition(bsi, x, y, z, state);
}
static Ternary canWalkThroughBlockState(BlockState state) {
Block block = state.getBlock();
if (block instanceof AirBlock) {
return YES;
}
if (block instanceof AbstractFireBlock || block == Blocks.TRIPWIRE || block == Blocks.COBWEB || block == Blocks.END_PORTAL || block == Blocks.COCOA || block instanceof AbstractSkullBlock || block == Blocks.BUBBLE_COLUMN || block instanceof ShulkerBoxBlock || block instanceof SlabBlock || block instanceof TrapDoorBlock || block == Blocks.HONEY_BLOCK || block == Blocks.END_ROD || block == Blocks.SWEET_BERRY_BUSH) {
return NO;
}
if (Baritone.settings().blocksToAvoid.value.contains(block)) { if (Baritone.settings().blocksToAvoid.value.contains(block)) {
return false; return NO;
} }
if (block instanceof DoorBlock || block instanceof FenceGateBlock) { if (block instanceof DoorBlock || block instanceof FenceGateBlock) {
// Because there's no nice method in vanilla to check if a door is openable or not, we just have to assume // TODO this assumes that all doors in all mods are openable
// that anything that isn't an iron door isn't openable, ignoring that some doors introduced in mods can't if (block == Blocks.IRON_DOOR) {
// be opened by just interacting. return NO;
return block != Blocks.IRON_DOOR; }
return YES;
} }
if (block instanceof CarpetBlock) {
return MAYBE;
}
if (block instanceof SnowBlock) {
// snow layers cached as the top layer of a packed chunk have no metadata, we can't make a decision based on their depth here
// it would otherwise make long distance pathing through snowy biomes impossible
return MAYBE;
}
FluidState fluidState = state.getFluidState();
if (!fluidState.isEmpty()) {
if (fluidState.getFluid().getLevel(fluidState) != 8) {
return NO;
} else {
return MAYBE;
}
}
if (block instanceof CauldronBlock) {
return NO;
}
try { // A dodgy catch-all at the end, for most blocks with default behaviour this will work, however where blocks are special this will error out, and we can handle it when we have this information
if (state.allowsMovement(null, null, PathType.LAND)) {
return YES;
} else {
return NO;
}
} catch (Throwable exception) {
System.out.println("The block " + state.getBlock().getTranslatedName().getString() + " requires a special case due to the exception " + exception.getMessage());
return MAYBE;
}
}
static boolean canWalkThroughPosition(BlockStateInterface bsi, int x, int y, int z, BlockState state) {
Block block = state.getBlock();
if (block instanceof CarpetBlock) { if (block instanceof CarpetBlock) {
return canWalkOn(bsi, x, y - 1, z); return canWalkOn(bsi, x, y - 1, z);
} }
if (block instanceof SnowBlock) { if (block instanceof SnowBlock) {
// we've already checked doors and fence gates
// so the only remaining dynamic isPassables are snow and trapdoor
// if they're cached as a top block, we don't know their metadata // if they're cached as a top block, we don't know their metadata
// default to true (mostly because it would otherwise make long distance pathing through snowy biomes impossible) // default to true (mostly because it would otherwise make long distance pathing through snowy biomes impossible)
if (!bsi.worldContainsLoadedChunk(x, z)) { if (!bsi.worldContainsLoadedChunk(x, z)) {
@ -127,29 +182,31 @@ public interface MovementHelper extends ActionCosts, Helper {
// ok, it's low enough we could walk through it, but is it supported? // ok, it's low enough we could walk through it, but is it supported?
return canWalkOn(bsi, x, y - 1, z); return canWalkOn(bsi, x, y - 1, z);
} }
if (isFlowing(x, y, z, state, bsi)) {
return false; // Don't walk through flowing liquids
}
FluidState fluidState = state.getFluidState(); FluidState fluidState = state.getFluidState();
if (fluidState.getFluid() instanceof WaterFluid) { if (!fluidState.isEmpty()) {
if (isFlowing(x, y, z, state, bsi)) {
return false;
}
// Everything after this point has to be a special case as it relies on the water not being flowing, which means a special case is needed.
if (Baritone.settings().assumeWalkOnWater.value) { if (Baritone.settings().assumeWalkOnWater.value) {
return false; return false;
} }
BlockState up = bsi.get0(x, y + 1, z); BlockState up = bsi.get0(x, y + 1, z);
if (!up.getFluidState().isEmpty() || up.getBlock() instanceof LilyPadBlock) { if (!up.getFluidState().isEmpty() || up.getBlock() instanceof LilyPadBlock) {
return false; return false;
} }
return true; return fluidState.getFluid() instanceof WaterFluid;
}
if (block instanceof CauldronBlock) {
return false;
} }
// every block that overrides isPassable with anything more complicated than a "return true;" or "return false;" // every block that overrides isPassable with anything more complicated than a "return true;" or "return false;"
// has already been accounted for above // has already been accounted for above
// therefore it's safe to not construct a blockpos from our x, y, z ints and instead just pass null // therefore it's safe to not construct a blockpos from our x, y, z ints and instead just pass null
return state.allowsMovement(bsi.access, BlockPos.ZERO, PathType.LAND); // workaround for future compatibility =P return state.allowsMovement(bsi.access, BlockPos.ZERO, PathType.LAND); // workaround for future compatibility =P
} }
/** /**
* canWalkThrough but also won't impede movement at all. so not including doors or fence gates (we'd have to right click), * canWalkThrough but also won't impede movement at all. so not including doors or fence gates (we'd have to right click),
* not including water, and not including ladders or vines or cobwebs (they slow us down) * not including water, and not including ladders or vines or cobwebs (they slow us down)
@ -294,6 +351,8 @@ public interface MovementHelper extends ActionCosts, Helper {
* Can I walk on this block without anything weird happening like me falling * Can I walk on this block without anything weird happening like me falling
* through? Includes water because we know that we automatically jump on * through? Includes water because we know that we automatically jump on
* water * water
* <p>
* If changing something in this function remember to also change it in precomputed data
* *
* @param bsi Block state provider * @param bsi Block state provider
* @param x The block's x position * @param x The block's x position
@ -303,24 +362,56 @@ public interface MovementHelper extends ActionCosts, Helper {
* @return Whether or not the specified block can be walked on * @return Whether or not the specified block can be walked on
*/ */
static boolean canWalkOn(BlockStateInterface bsi, int x, int y, int z, BlockState state) { static boolean canWalkOn(BlockStateInterface bsi, int x, int y, int z, BlockState state) {
Block block = state.getBlock(); Ternary canWalkOn = canWalkOnBlockState(state);
if (block instanceof AirBlock || block == Blocks.MAGMA_BLOCK || block == Blocks.BUBBLE_COLUMN || block == Blocks.HONEY_BLOCK) { if (canWalkOn == YES) {
// early return for most common case (air) return true;
// plus magma, which is a normal cube but it hurts you }
if (canWalkOn == NO) {
return false; return false;
} }
if (isBlockNormalCube(state)) { return canWalkOnPosition(bsi, x, y, z, state);
return true; }
static Ternary canWalkOnBlockState(BlockState state) {
Block block = state.getBlock();
if (isBlockNormalCube(state) && block != Blocks.MAGMA_BLOCK && block != Blocks.BUBBLE_COLUMN && block != Blocks.HONEY_BLOCK) {
return YES;
} }
if (block == Blocks.LADDER || (block == Blocks.VINE && Baritone.settings().allowVines.value)) { // TODO reconsider this if (block == Blocks.LADDER || (block == Blocks.VINE && Baritone.settings().allowVines.value)) { // TODO reconsider this
return true; return YES;
} }
if (block == Blocks.FARMLAND || block == Blocks.GRASS_PATH) { if (block == Blocks.FARMLAND || block == Blocks.GRASS_PATH) {
return true; return YES;
} }
if (block == Blocks.ENDER_CHEST || block == Blocks.CHEST || block == Blocks.TRAPPED_CHEST) { if (block == Blocks.ENDER_CHEST || block == Blocks.CHEST || block == Blocks.TRAPPED_CHEST) {
return true; return YES;
} }
if (block == Blocks.GLASS || block instanceof StainedGlassBlock) {
return YES;
}
if (block instanceof StairsBlock) {
return YES;
}
if (isWater(state)) {
return MAYBE;
}
if (MovementHelper.isLava(state) && Baritone.settings().assumeWalkOnLava.value) {
return MAYBE;
}
if (block instanceof SlabBlock) {
if (!Baritone.settings().allowWalkOnBottomSlab.value) {
if (state.get(SlabBlock.TYPE) != SlabType.BOTTOM) {
return YES;
}
return NO;
}
return YES;
}
return NO;
}
static boolean canWalkOnPosition(BlockStateInterface bsi, int x, int y, int z, BlockState state) {
Block block = state.getBlock();
if (isWater(state)) { if (isWater(state)) {
// since this is called literally millions of times per second, the benefit of not allocating millions of useless "pos.up()" // since this is called literally millions of times per second, the benefit of not allocating millions of useless "pos.up()"
// BlockPos s that we'd just garbage collect immediately is actually noticeable. I don't even think its a decrease in readability // BlockPos s that we'd just garbage collect immediately is actually noticeable. I don't even think its a decrease in readability
@ -329,7 +420,7 @@ public interface MovementHelper extends ActionCosts, Helper {
if (up == Blocks.LILY_PAD || up instanceof CarpetBlock) { if (up == Blocks.LILY_PAD || up instanceof CarpetBlock) {
return true; return true;
} }
if (isFlowing(x, y, z, state, bsi) || upState.getFluidState().getFluid() == Fluids.FLOWING_WATER) { if (MovementHelper.isFlowing(x, y, z, state, bsi) || upState.getFluidState().getFluid() == Fluids.FLOWING_WATER) {
// the only scenario in which we can walk on flowing water is if it's under still water with jesus off // the only scenario in which we can walk on flowing water is if it's under still water with jesus off
return isWater(upState) && !Baritone.settings().assumeWalkOnWater.value; return isWater(upState) && !Baritone.settings().assumeWalkOnWater.value;
} }
@ -337,19 +428,20 @@ public interface MovementHelper extends ActionCosts, Helper {
// if assumeWalkOnWater is off, we can only walk on water if there is water above it // if assumeWalkOnWater is off, we can only walk on water if there is water above it
return isWater(upState) ^ Baritone.settings().assumeWalkOnWater.value; return isWater(upState) ^ Baritone.settings().assumeWalkOnWater.value;
} }
if (Baritone.settings().assumeWalkOnLava.value && isLava(state) && !isFlowing(x, y, z, state, bsi)) {
if (MovementHelper.isLava(state) && !MovementHelper.isFlowing(x, y, z, state, bsi) && Baritone.settings().assumeWalkOnLava.value) { // if we get here it means that assumeWalkOnLava must be true, so put it last
return true; return true;
} }
if (block == Blocks.GLASS || block instanceof StainedGlassBlock) {
return true; return false; // If we don't recognise it then we want to just return false to be safe.
} }
if (block instanceof SlabBlock) {
if (!Baritone.settings().allowWalkOnBottomSlab.value) { static boolean canWalkOn(CalculationContext context, int x, int y, int z, BlockState state) {
return state.get(SlabBlock.TYPE) != SlabType.BOTTOM; return context.precomputedData.canWalkOn(context.bsi, x, y, z, state);
} }
return true;
} static boolean canWalkOn(CalculationContext context, int x, int y, int z) {
return block instanceof StairsBlock; return canWalkOn(context, x, y, z, context.get(x, y, z));
} }
static boolean canWalkOn(IPlayerContext ctx, BetterBlockPos pos, BlockState state) { static boolean canWalkOn(IPlayerContext ctx, BetterBlockPos pos, BlockState state) {
@ -396,7 +488,7 @@ public interface MovementHelper extends ActionCosts, Helper {
static double getMiningDurationTicks(CalculationContext context, int x, int y, int z, BlockState state, boolean includeFalling) { static double getMiningDurationTicks(CalculationContext context, int x, int y, int z, BlockState state, boolean includeFalling) {
Block block = state.getBlock(); Block block = state.getBlock();
if (!canWalkThrough(context.bsi, x, y, z, state)) { if (!canWalkThrough(context, x, y, z, state)) {
if (!state.getFluidState().isEmpty()) { if (!state.getFluidState().isEmpty()) {
return COST_INF; return COST_INF;
} }

View File

@ -68,7 +68,7 @@ public class MovementAscend extends Movement {
public static double cost(CalculationContext context, int x, int y, int z, int destX, int destZ) { public static double cost(CalculationContext context, int x, int y, int z, int destX, int destZ) {
BlockState toPlace = context.get(destX, y, destZ); BlockState toPlace = context.get(destX, y, destZ);
double additionalPlacementCost = 0; double additionalPlacementCost = 0;
if (!MovementHelper.canWalkOn(context.bsi, destX, y, destZ, toPlace)) { if (!MovementHelper.canWalkOn(context, destX, y, destZ, toPlace)) {
additionalPlacementCost = context.costOfPlacingAt(destX, y, destZ, toPlace); additionalPlacementCost = context.costOfPlacingAt(destX, y, destZ, toPlace);
if (additionalPlacementCost >= COST_INF) { if (additionalPlacementCost >= COST_INF) {
return COST_INF; return COST_INF;
@ -94,7 +94,7 @@ public class MovementAscend extends Movement {
} }
} }
BlockState srcUp2 = context.get(x, y + 2, z); // used lower down anyway BlockState srcUp2 = context.get(x, y + 2, z); // used lower down anyway
if (context.get(x, y + 3, z).getBlock() instanceof FallingBlock && (MovementHelper.canWalkThrough(context.bsi, x, y + 1, z) || !(srcUp2.getBlock() instanceof FallingBlock))) {//it would fall on us and possibly suffocate us if (context.get(x, y + 3, z).getBlock() instanceof FallingBlock && (MovementHelper.canWalkThrough(context, x, y + 1, z) || !(srcUp2.getBlock() instanceof FallingBlock))) {//it would fall on us and possibly suffocate us
// HOWEVER, we assume that we're standing in the start position // HOWEVER, we assume that we're standing in the start position
// that means that src and src.up(1) are both air // that means that src and src.up(1) are both air
// maybe they aren't now, but they will be by the time this starts // maybe they aren't now, but they will be by the time this starts

View File

@ -101,7 +101,7 @@ public class MovementDescend extends Movement {
//C, D, etc determine the length of the fall //C, D, etc determine the length of the fall
BlockState below = context.get(destX, y - 2, destZ); BlockState below = context.get(destX, y - 2, destZ);
if (!MovementHelper.canWalkOn(context.bsi, destX, y - 2, destZ, below)) { if (!MovementHelper.canWalkOn(context, destX, y - 2, destZ, below)) {
dynamicFallCost(context, x, y, z, destX, destZ, totalCost, below, res); dynamicFallCost(context, x, y, z, destX, destZ, totalCost, below, res);
return; return;
} }
@ -130,7 +130,7 @@ public class MovementDescend extends Movement {
// and potentially replace the water we're going to fall into // and potentially replace the water we're going to fall into
return false; return false;
} }
if (!MovementHelper.canWalkThrough(context.bsi, destX, y - 2, destZ, below)) { if (!MovementHelper.canWalkThrough(context, destX, y - 2, destZ, below)) {
return false; return false;
} }
double costSoFar = 0; double costSoFar = 0;
@ -146,7 +146,7 @@ public class MovementDescend extends Movement {
int unprotectedFallHeight = fallHeight - (y - effectiveStartHeight); // equal to fallHeight - y + effectiveFallHeight, which is equal to -newY + effectiveFallHeight, which is equal to effectiveFallHeight - newY int unprotectedFallHeight = fallHeight - (y - effectiveStartHeight); // equal to fallHeight - y + effectiveFallHeight, which is equal to -newY + effectiveFallHeight, which is equal to effectiveFallHeight - newY
double tentativeCost = WALK_OFF_BLOCK_COST + FALL_N_BLOCKS_COST[unprotectedFallHeight] + frontBreak + costSoFar; double tentativeCost = WALK_OFF_BLOCK_COST + FALL_N_BLOCKS_COST[unprotectedFallHeight] + frontBreak + costSoFar;
if (MovementHelper.isWater(ontoBlock)) { if (MovementHelper.isWater(ontoBlock)) {
if (!MovementHelper.canWalkThrough(context.bsi, destX, newY, destZ, ontoBlock)) { if (!MovementHelper.canWalkThrough(context, destX, newY, destZ, ontoBlock)) {
return false; return false;
} }
if (context.assumeWalkOnWater) { if (context.assumeWalkOnWater) {
@ -155,7 +155,7 @@ public class MovementDescend extends Movement {
if (MovementHelper.isFlowing(destX, newY, destZ, ontoBlock, context.bsi)) { if (MovementHelper.isFlowing(destX, newY, destZ, ontoBlock, context.bsi)) {
return false; // TODO flowing check required here? return false; // TODO flowing check required here?
} }
if (!MovementHelper.canWalkOn(context.bsi, destX, newY - 1, destZ)) { if (!MovementHelper.canWalkOn(context, destX, newY - 1, destZ)) {
// we could punch right through the water into something else // we could punch right through the water into something else
return false; return false;
} }
@ -174,10 +174,10 @@ public class MovementDescend extends Movement {
effectiveStartHeight = newY; effectiveStartHeight = newY;
continue; continue;
} }
if (MovementHelper.canWalkThrough(context.bsi, destX, newY, destZ, ontoBlock)) { if (MovementHelper.canWalkThrough(context, destX, newY, destZ, ontoBlock)) {
continue; continue;
} }
if (!MovementHelper.canWalkOn(context.bsi, destX, newY, destZ, ontoBlock)) { if (!MovementHelper.canWalkOn(context, destX, newY, destZ, ontoBlock)) {
return false; return false;
} }
if (MovementHelper.isBottomSlab(ontoBlock)) { if (MovementHelper.isBottomSlab(ontoBlock)) {

View File

@ -60,7 +60,7 @@ public class MovementDiagonal extends Movement {
@Override @Override
protected boolean safeToCancel(MovementState state) { protected boolean safeToCancel(MovementState state) {
//too simple. backfill does not work after cornering with this //too simple. backfill does not work after cornering with this
//return MovementHelper.canWalkOn(ctx, ctx.playerFeet().down()); //return context.precomputedData.canWalkOn(ctx, ctx.playerFeet().down());
ClientPlayerEntity player = ctx.player(); ClientPlayerEntity player = ctx.player();
double offset = 0.25; double offset = 0.25;
double x = player.getPositionVec().x; double x = player.getPositionVec().x;
@ -110,24 +110,24 @@ public class MovementDiagonal extends Movement {
} }
public static void cost(CalculationContext context, int x, int y, int z, int destX, int destZ, MutableMoveResult res) { public static void cost(CalculationContext context, int x, int y, int z, int destX, int destZ, MutableMoveResult res) {
if (!MovementHelper.canWalkThrough(context.bsi, destX, y + 1, destZ)) { if (!MovementHelper.canWalkThrough(context, destX, y + 1, destZ)) {
return; return;
} }
BlockState destInto = context.get(destX, y, destZ); BlockState destInto = context.get(destX, y, destZ);
boolean ascend = false; boolean ascend = false;
BlockState destWalkOn; BlockState destWalkOn;
boolean descend = false; boolean descend = false;
if (!MovementHelper.canWalkThrough(context.bsi, destX, y, destZ, destInto)) { if (!MovementHelper.canWalkThrough(context, destX, y, destZ, destInto)) {
ascend = true; ascend = true;
if (!context.allowDiagonalAscend || !MovementHelper.canWalkThrough(context.bsi, x, y + 2, z) || !MovementHelper.canWalkOn(context.bsi, destX, y, destZ, destInto) || !MovementHelper.canWalkThrough(context.bsi, destX, y + 2, destZ)) { if (!context.allowDiagonalAscend || !MovementHelper.canWalkThrough(context, x, y + 2, z) || !MovementHelper.canWalkOn(context, destX, y, destZ, destInto) || !MovementHelper.canWalkThrough(context, destX, y + 2, destZ)) {
return; return;
} }
destWalkOn = destInto; destWalkOn = destInto;
} else { } else {
destWalkOn = context.get(destX, y - 1, destZ); destWalkOn = context.get(destX, y - 1, destZ);
if (!MovementHelper.canWalkOn(context.bsi, destX, y - 1, destZ, destWalkOn)) { if (!MovementHelper.canWalkOn(context, destX, y - 1, destZ, destWalkOn)) {
descend = true; descend = true;
if (!context.allowDiagonalDescend || !MovementHelper.canWalkOn(context.bsi, destX, y - 2, destZ) || !MovementHelper.canWalkThrough(context.bsi, destX, y - 1, destZ, destWalkOn)) { if (!context.allowDiagonalDescend || !MovementHelper.canWalkOn(context, destX, y - 2, destZ) || !MovementHelper.canWalkThrough(context, destX, y - 1, destZ, destWalkOn)) {
return; return;
} }
} }
@ -170,17 +170,17 @@ public class MovementDiagonal extends Movement {
BlockState pb0 = context.get(x, y, destZ); BlockState pb0 = context.get(x, y, destZ);
BlockState pb2 = context.get(destX, y, z); BlockState pb2 = context.get(destX, y, z);
if (ascend) { if (ascend) {
boolean ATop = MovementHelper.canWalkThrough(context.bsi, x, y + 2, destZ); boolean ATop = MovementHelper.canWalkThrough(context, x, y + 2, destZ);
boolean AMid = MovementHelper.canWalkThrough(context.bsi, x, y + 1, destZ); boolean AMid = MovementHelper.canWalkThrough(context, x, y + 1, destZ);
boolean ALow = MovementHelper.canWalkThrough(context.bsi, x, y, destZ, pb0); boolean ALow = MovementHelper.canWalkThrough(context, x, y, destZ, pb0);
boolean BTop = MovementHelper.canWalkThrough(context.bsi, destX, y + 2, z); boolean BTop = MovementHelper.canWalkThrough(context, destX, y + 2, z);
boolean BMid = MovementHelper.canWalkThrough(context.bsi, destX, y + 1, z); boolean BMid = MovementHelper.canWalkThrough(context, destX, y + 1, z);
boolean BLow = MovementHelper.canWalkThrough(context.bsi, destX, y, z, pb2); boolean BLow = MovementHelper.canWalkThrough(context, destX, y, z, pb2);
if ((!(ATop && AMid && ALow) && !(BTop && BMid && BLow)) // no option if ((!(ATop && AMid && ALow) && !(BTop && BMid && BLow)) // no option
|| MovementHelper.avoidWalkingInto(pb0) // bad || MovementHelper.avoidWalkingInto(pb0) // bad
|| MovementHelper.avoidWalkingInto(pb2) // bad || MovementHelper.avoidWalkingInto(pb2) // bad
|| (ATop && AMid && MovementHelper.canWalkOn(context.bsi, x, y, destZ, pb0)) // we could just ascend || (ATop && AMid && MovementHelper.canWalkOn(context, x, y, destZ, pb0)) // we could just ascend
|| (BTop && BMid && MovementHelper.canWalkOn(context.bsi, destX, y, z, pb2)) // we could just ascend || (BTop && BMid && MovementHelper.canWalkOn(context, destX, y, z, pb2)) // we could just ascend
|| (!ATop && AMid && ALow) // head bonk A || (!ATop && AMid && ALow) // head bonk A
|| (!BTop && BMid && BLow)) { // head bonk B || (!BTop && BMid && BLow)) { // head bonk B
return; return;

View File

@ -59,7 +59,7 @@ public class MovementDownward extends Movement {
if (!context.allowDownward) { if (!context.allowDownward) {
return COST_INF; return COST_INF;
} }
if (!MovementHelper.canWalkOn(context.bsi, x, y - 2, z)) { if (!MovementHelper.canWalkOn(context, x, y - 2, z)) {
return COST_INF; return COST_INF;
} }
BlockState down = context.get(x, y - 1, z); BlockState down = context.get(x, y - 1, z);

View File

@ -75,7 +75,7 @@ public class MovementParkour extends Movement {
return; return;
} }
BlockState adj = context.get(x + xDiff, y - 1, z + zDiff); BlockState adj = context.get(x + xDiff, y - 1, z + zDiff);
if (MovementHelper.canWalkOn(context.bsi, x + xDiff, y - 1, z + zDiff, adj)) { // don't parkour if we could just traverse (for now) if (MovementHelper.canWalkOn(context, x + xDiff, y - 1, z + zDiff, adj)) { // don't parkour if we could just traverse (for now)
// second most common case -- we could just traverse not parkour // second most common case -- we could just traverse not parkour
return; return;
} }
@ -123,7 +123,7 @@ public class MovementParkour extends Movement {
// check for ascend landing position // check for ascend landing position
BlockState destInto = context.bsi.get0(destX, y, destZ); BlockState destInto = context.bsi.get0(destX, y, destZ);
if (!MovementHelper.fullyPassable(context.bsi.access, context.bsi.isPassableBlockPos.setPos(destX, y, destZ), destInto)) { if (!MovementHelper.fullyPassable(context.bsi.access, context.bsi.isPassableBlockPos.setPos(destX, y, destZ), destInto)) {
if (i <= 3 && context.allowParkourAscend && context.canSprint && MovementHelper.canWalkOn(context.bsi, destX, y, destZ, destInto) && checkOvershootSafety(context.bsi, destX + xDiff, y + 1, destZ + zDiff)) { if (i <= 3 && context.allowParkourAscend && context.canSprint && MovementHelper.canWalkOn(context, destX, y, destZ, destInto) && checkOvershootSafety(context.bsi, destX + xDiff, y + 1, destZ + zDiff)) {
res.x = destX; res.x = destX;
res.y = y + 1; res.y = y + 1;
res.z = destZ; res.z = destZ;
@ -136,7 +136,7 @@ public class MovementParkour extends Movement {
// check for flat landing position // check for flat landing position
BlockState landingOn = context.bsi.get0(destX, y - 1, destZ); BlockState landingOn = context.bsi.get0(destX, y - 1, destZ);
// farmland needs to be canWalkOn otherwise farm can never work at all, but we want to specifically disallow ending a jump on farmland haha // farmland needs to be canWalkOn otherwise farm can never work at all, but we want to specifically disallow ending a jump on farmland haha
if (landingOn.getBlock() != Blocks.FARMLAND && MovementHelper.canWalkOn(context.bsi, destX, y - 1, destZ, landingOn)) { if (landingOn.getBlock() != Blocks.FARMLAND && MovementHelper.canWalkOn(context, destX, y - 1, destZ, landingOn)) {
if (checkOvershootSafety(context.bsi, destX + xDiff, y, destZ + zDiff)) { if (checkOvershootSafety(context.bsi, destX + xDiff, y, destZ + zDiff)) {
res.x = destX; res.x = destX;
res.y = y; res.y = y;

View File

@ -118,7 +118,7 @@ public class MovementPillar extends Movement {
} }
} }
// this is commented because it may have had a purpose, but it's very unclear what it was. it's from the minebot era. // this is commented because it may have had a purpose, but it's very unclear what it was. it's from the minebot era.
//if (!MovementHelper.canWalkOn(chkPos, check) || MovementHelper.canWalkThrough(chkPos, check)) {//if the block above where we want to break is not a full block, don't do it //if (!MovementHelper.canWalkOn(context, chkPos, check) || MovementHelper.canWalkThrough(context, chkPos, check)) {//if the block above where we want to break is not a full block, don't do it
// TODO why does canWalkThrough mean this action is COST_INF? // TODO why does canWalkThrough mean this action is COST_INF?
// FallingBlock makes sense, and !canWalkOn deals with weird cases like if it were lava // FallingBlock makes sense, and !canWalkOn deals with weird cases like if it were lava
// but I don't understand why canWalkThrough makes it impossible // but I don't understand why canWalkThrough makes it impossible

View File

@ -73,7 +73,7 @@ public class MovementTraverse extends Movement {
BlockState destOn = context.get(destX, y - 1, destZ); BlockState destOn = context.get(destX, y - 1, destZ);
BlockState down = context.get(x, y - 1, z); BlockState down = context.get(x, y - 1, z);
Block srcDown = down.getBlock(); Block srcDown = down.getBlock();
if (MovementHelper.canWalkOn(context.bsi, destX, y - 1, destZ, destOn)) {//this is a walk, not a bridge if (MovementHelper.canWalkOn(context, destX, y - 1, destZ, destOn)) {//this is a walk, not a bridge
double WC = WALK_ONE_BLOCK_COST; double WC = WALK_ONE_BLOCK_COST;
boolean water = false; boolean water = false;
if (MovementHelper.isWater(pb0) || MovementHelper.isWater(pb1)) { if (MovementHelper.isWater(pb0) || MovementHelper.isWater(pb1)) {

View File

@ -349,7 +349,7 @@ public class PathExecutor implements IPathExecutor, Helper {
behavior.baritone.getInputOverrideHandler().setInputForceState(Input.SPRINT, false); behavior.baritone.getInputOverrideHandler().setInputForceState(Input.SPRINT, false);
// first and foremost, if allowSprint is off, or if we don't have enough hunger, don't try and sprint // first and foremost, if allowSprint is off, or if we don't have enough hunger, don't try and sprint
if (!new CalculationContext(behavior.baritone).canSprint) { if (!new CalculationContext(behavior.baritone, false).canSprint) {
return false; return false;
} }
IMovement current = path.movements().get(pathPosition); IMovement current = path.movements().get(pathPosition);

View File

@ -0,0 +1,92 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* 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
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.pathing.precompute;
import baritone.pathing.movement.MovementHelper;
import baritone.utils.BlockStateInterface;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import static baritone.pathing.precompute.Ternary.MAYBE;
import static baritone.pathing.precompute.Ternary.YES;
public class PrecomputedData { // TODO add isFullyPassable
private final int[] data = new int[Block.BLOCK_STATE_IDS.size()];
private static final int COMPLETED_MASK = 1 << 0;
private static final int CAN_WALK_ON_MASK = 1 << 1;
private static final int CAN_WALK_ON_SPECIAL_MASK = 1 << 2;
private static final int CAN_WALK_THROUGH_MASK = 1 << 3;
private static final int CAN_WALK_THROUGH_SPECIAL_MASK = 1 << 4;
private int fillData(int id, BlockState state) {
int blockData = 0;
Ternary canWalkOnState = MovementHelper.canWalkOnBlockState(state);
if (canWalkOnState == YES) {
blockData |= CAN_WALK_ON_MASK;
}
if (canWalkOnState == MAYBE) {
blockData |= CAN_WALK_ON_SPECIAL_MASK;
}
Ternary canWalkThroughState = MovementHelper.canWalkThroughBlockState(state);
if (canWalkThroughState == YES) {
blockData |= CAN_WALK_THROUGH_MASK;
}
if (canWalkOnState == MAYBE) {
blockData |= CAN_WALK_THROUGH_SPECIAL_MASK;
}
blockData |= COMPLETED_MASK;
data[id] = blockData; // in theory, this is thread "safe" because every thread should compute the exact same int to write?
return blockData;
}
public boolean canWalkOn(BlockStateInterface bsi, int x, int y, int z, BlockState state) {
int id = Block.BLOCK_STATE_IDS.getId(state);
int blockData = data[id];
if ((blockData & COMPLETED_MASK) == 0) { // we need to fill in the data
blockData = fillData(id, state);
}
if ((blockData & CAN_WALK_ON_SPECIAL_MASK) != 0) {
return MovementHelper.canWalkOnPosition(bsi, x, y, z, state);
} else {
return (blockData & CAN_WALK_ON_MASK) != 0;
}
}
public boolean canWalkThrough(BlockStateInterface bsi, int x, int y, int z, BlockState state) {
int id = Block.BLOCK_STATE_IDS.getId(state);
int blockData = data[id];
if ((blockData & COMPLETED_MASK) == 0) { // we need to fill in the data
blockData = fillData(id, state);
}
if ((blockData & CAN_WALK_THROUGH_SPECIAL_MASK) != 0) {
return MovementHelper.canWalkThroughPosition(bsi, x, y, z, state);
} else {
return (blockData & CAN_WALK_THROUGH_MASK) != 0;
}
}
}

View File

@ -15,13 +15,8 @@
* along with Baritone. If not, see <https://www.gnu.org/licenses/>. * along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/ */
package baritone.utils.accessor; package baritone.pathing.precompute;
/** public enum Ternary {
* @author rycbar YES, MAYBE, NO
* @since 26.09.2022 }
*/
public interface ILongArrayNBT {
long[] getLongArray();
}

View File

@ -651,7 +651,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
} }
// this is not in render distance // this is not in render distance
if (!observedCompleted.contains(BetterBlockPos.longHash(blockX, blockY, blockZ)) if (!observedCompleted.contains(BetterBlockPos.longHash(blockX, blockY, blockZ))
&& !Baritone.settings().buildSkipBlocks.value.contains(schematic.desiredState(x, y, z, current, this.approxPlaceable).getBlock())) { && !Baritone.settings().buildSkipBlocks.value.contains(schematic.desiredState(x, y, z, current, this.approxPlaceable).getBlock())) {
// and we've never seen this position be correct // and we've never seen this position be correct
// therefore mark as incorrect // therefore mark as incorrect
incorrectPositions.add(new BetterBlockPos(blockX, blockY, blockZ)); incorrectPositions.add(new BetterBlockPos(blockX, blockY, blockZ));
@ -898,14 +898,21 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
TrapDoorBlock.OPEN, TrapDoorBlock.HALF TrapDoorBlock.OPEN, TrapDoorBlock.HALF
); );
private boolean sameWithoutOrientation(BlockState first, BlockState second) { private boolean sameBlockstate(BlockState first, BlockState second) {
if (first.getBlock() != second.getBlock()) { if (first.getBlock() != second.getBlock()) {
return false; return false;
} }
boolean ignoreDirection = Baritone.settings().buildIgnoreDirection.value;
List<String> ignoredProps = Baritone.settings().buildIgnoreProperties.value;
if (!ignoreDirection && ignoredProps.isEmpty()) {
return first.equals(second); // early return if no properties are being ignored
}
ImmutableMap<Property<?>, Comparable<?>> map1 = first.getValues(); ImmutableMap<Property<?>, Comparable<?>> map1 = first.getValues();
ImmutableMap<Property<?>, Comparable<?>> map2 = second.getValues(); ImmutableMap<Property<?>, Comparable<?>> map2 = second.getValues();
for (Property<?> prop : map1.keySet()) { for (Property<?> prop : map1.keySet()) {
if (map1.get(prop) != map2.get(prop) && !orientationProps.contains(prop)) { if (map1.get(prop) != map2.get(prop)
&& !(ignoreDirection && orientationProps.contains(prop))
&& !ignoredProps.contains(prop.getName())) {
return false; return false;
} }
} }
@ -940,7 +947,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
if (current.equals(desired)) { if (current.equals(desired)) {
return true; return true;
} }
return Baritone.settings().buildIgnoreDirection.value && sameWithoutOrientation(current, desired); return sameBlockstate(current, desired);
} }
public class BuilderCalculationContext extends CalculationContext { public class BuilderCalculationContext extends CalculationContext {

View File

@ -28,6 +28,7 @@ import baritone.cache.CachedChunk;
import baritone.cache.WorldScanner; import baritone.cache.WorldScanner;
import baritone.pathing.movement.CalculationContext; import baritone.pathing.movement.CalculationContext;
import baritone.pathing.movement.MovementHelper; import baritone.pathing.movement.MovementHelper;
import baritone.pathing.precompute.PrecomputedData;
import baritone.utils.BaritoneProcessHelper; import baritone.utils.BaritoneProcessHelper;
import baritone.utils.BlockStateInterface; import baritone.utils.BlockStateInterface;
import net.minecraft.block.AirBlock; import net.minecraft.block.AirBlock;
@ -103,11 +104,7 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
return null; return null;
} }
} }
if (!Baritone.settings().allowBreak.value) {
logDirect("Unable to mine when allowBreak is false!");
cancel();
return null;
}
updateLoucaSystem(); updateLoucaSystem();
int mineGoalUpdateInterval = Baritone.settings().mineGoalUpdateInterval.value; int mineGoalUpdateInterval = Baritone.settings().mineGoalUpdateInterval.value;
List<BlockPos> curr = new ArrayList<>(knownOreLocations); List<BlockPos> curr = new ArrayList<>(knownOreLocations);
@ -116,7 +113,10 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
Baritone.getExecutor().execute(() -> rescan(curr, context)); Baritone.getExecutor().execute(() -> rescan(curr, context));
} }
if (Baritone.settings().legitMine.value) { if (Baritone.settings().legitMine.value) {
addNearby(); if (!addNearby()) {
cancel();
return null;
}
} }
Optional<BlockPos> shaft = curr.stream() Optional<BlockPos> shaft = curr.stream()
.filter(pos -> pos.getX() == ctx.playerFeet().getX() && pos.getZ() == ctx.playerFeet().getZ()) .filter(pos -> pos.getX() == ctx.playerFeet().getX() && pos.getZ() == ctx.playerFeet().getZ())
@ -178,6 +178,11 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
} }
private PathingCommand updateGoal() { private PathingCommand updateGoal() {
BlockOptionalMetaLookup filter = filterFilter();
if (filter == null) {
return null;
}
boolean legit = Baritone.settings().legitMine.value; boolean legit = Baritone.settings().legitMine.value;
List<BlockPos> locs = knownOreLocations; List<BlockPos> locs = knownOreLocations;
if (!locs.isEmpty()) { if (!locs.isEmpty()) {
@ -222,6 +227,7 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
} }
private void rescan(List<BlockPos> already, CalculationContext context) { private void rescan(List<BlockPos> already, CalculationContext context) {
BlockOptionalMetaLookup filter = filterFilter();
if (filter == null) { if (filter == null) {
return; return;
} }
@ -371,11 +377,18 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
return prune(ctx, locs, filter, max, blacklist, dropped); return prune(ctx, locs, filter, max, blacklist, dropped);
} }
private void addNearby() { private boolean addNearby() {
List<BlockPos> dropped = droppedItemsScan(); List<BlockPos> dropped = droppedItemsScan();
knownOreLocations.addAll(dropped); knownOreLocations.addAll(dropped);
BlockPos playerFeet = ctx.playerFeet(); BlockPos playerFeet = ctx.playerFeet();
BlockStateInterface bsi = new BlockStateInterface(ctx); BlockStateInterface bsi = new BlockStateInterface(ctx);
BlockOptionalMetaLookup filter = filterFilter();
if (filter == null) {
return false;
}
int searchDist = 10; int searchDist = 10;
double fakedBlockReachDistance = 20; // at least 10 * sqrt(3) with some extra space to account for positioning within the block double fakedBlockReachDistance = 20; // at least 10 * sqrt(3) with some extra space to account for positioning within the block
for (int x = playerFeet.getX() - searchDist; x <= playerFeet.getX() + searchDist; x++) { for (int x = playerFeet.getX() - searchDist; x <= playerFeet.getX() + searchDist; x++) {
@ -393,6 +406,7 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
} }
} }
knownOreLocations = prune(new CalculationContext(baritone), knownOreLocations, filter, ORE_LOCATIONS_COUNT, blacklist, dropped); knownOreLocations = prune(new CalculationContext(baritone), knownOreLocations, filter, ORE_LOCATIONS_COUNT, blacklist, dropped);
return true;
} }
private static List<BlockPos> prune(CalculationContext ctx, List<BlockPos> locs2, BlockOptionalMetaLookup filter, int max, List<BlockPos> blacklist, List<BlockPos> dropped) { private static List<BlockPos> prune(CalculationContext ctx, List<BlockPos> locs2, BlockOptionalMetaLookup filter, int max, List<BlockPos> blacklist, List<BlockPos> dropped) {
@ -468,10 +482,8 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
@Override @Override
public void mine(int quantity, BlockOptionalMetaLookup filter) { public void mine(int quantity, BlockOptionalMetaLookup filter) {
this.filter = filter; this.filter = filter;
if (filter != null && !Baritone.settings().allowBreak.value) { if (this.filterFilter() == null) {
logDirect("Unable to mine when allowBreak is false!"); this.filter = null;
this.mine(quantity, (BlockOptionalMetaLookup) null);
return;
} }
this.desiredQuantity = quantity; this.desiredQuantity = quantity;
this.knownOreLocations = new ArrayList<>(); this.knownOreLocations = new ArrayList<>();
@ -483,4 +495,22 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
rescan(new ArrayList<>(), new CalculationContext(baritone)); rescan(new ArrayList<>(), new CalculationContext(baritone));
} }
} }
private BlockOptionalMetaLookup filterFilter() {
if (this.filter == null) {
return null;
}
if (!Baritone.settings().allowBreak.value) {
BlockOptionalMetaLookup f = new BlockOptionalMetaLookup(this.filter.blocks()
.stream()
.filter(e -> Baritone.settings().allowBreakAnyway.value.contains(e.getBlock()))
.toArray(BlockOptionalMeta[]::new));
if (f.blocks().isEmpty()) {
logDirect("Unable to mine when allowBreak is false and target block is not in allowBreakAnyway!");
return null;
}
return f;
}
return filter;
}
} }

View File

@ -1,27 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* 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
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.utils.accessor;
/**
* @author rycbar
* @since 26.09.2022
*/
public interface INBTTagLongArray {
long[] getLongArray();
}

View File

@ -17,7 +17,6 @@
package baritone.utils.schematic.format.defaults; package baritone.utils.schematic.format.defaults;
import baritone.utils.accessor.ILongArrayNBT;
import baritone.utils.schematic.StaticSchematic; import baritone.utils.schematic.StaticSchematic;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
@ -137,7 +136,7 @@ public final class LitematicaSchematic extends StaticSchematic {
* @return amount of bits used to encode a block. * @return amount of bits used to encode a block.
*/ */
private static int getBitsPerBlock(int amountOfBlockTypes) { private static int getBitsPerBlock(int amountOfBlockTypes) {
return (int) Math.floor((Math.log(amountOfBlockTypes)) / Math.log(2)) + 1; return (int) Math.max(2,Math.ceil(Math.log(amountOfBlockTypes) / Math.log(2)));
} }
/** /**
@ -157,7 +156,7 @@ public final class LitematicaSchematic extends StaticSchematic {
* @return array of Long values. * @return array of Long values.
*/ */
private static long[] getBlockStates(CompoundNBT nbt, String subReg) { private static long[] getBlockStates(CompoundNBT nbt, String subReg) {
return ((ILongArrayNBT) nbt.getCompound("Regions").getCompound(subReg).get("BlockStates")).getLongArray(); return nbt.getCompound("Regions").getCompound(subReg).getLongArray("BlockStates");
} }
/** /**