Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a placeIncorrectBlockPenaltyMultiplier setting #4303

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/api/java/baritone/api/Settings.java
Original file line number Diff line number Diff line change
Expand Up @@ -1058,6 +1058,11 @@ public final class Settings {
*/
public final Setting<Double> breakCorrectBlockPenaltyMultiplier = new Setting<>(10d);

/**
* Multiply the cost of placing a block that's incorrect in the builder's schematic by this coefficient
*/
public final Setting<Double> placeIncorrectBlockPenaltyMultiplier = new Setting<>(2d);

/**
* When this setting is true, build a schematic with the highest X coordinate being the origin, instead of the lowest
*/
Expand Down
70 changes: 34 additions & 36 deletions src/main/java/baritone/process/BuilderProcess.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import baritone.api.schematic.FillSchematic;
import baritone.api.schematic.ISchematic;
import baritone.api.schematic.IStaticSchematic;
import baritone.api.schematic.MaskSchematic;
import baritone.api.schematic.SubstituteSchematic;
import baritone.api.schematic.format.ISchematicFormat;
import baritone.api.utils.*;
Expand Down Expand Up @@ -84,6 +85,14 @@

public final class BuilderProcess extends BaritoneProcessHelper implements IBuilderProcess {

private static final Set<Property<?>> ORIENTATION_PROPS =
ImmutableSet.of(
RotatedPillarBlock.AXIS, HorizontalDirectionalBlock.FACING,
StairBlock.FACING, StairBlock.HALF, StairBlock.SHAPE,
PipeBlock.NORTH, PipeBlock.EAST, PipeBlock.SOUTH, PipeBlock.WEST, PipeBlock.UP,
TrapDoorBlock.OPEN, TrapDoorBlock.HALF
);

private HashSet<BetterBlockPos> incorrectPositions;
private LongOpenHashSet observedCompleted; // positions that are completed even if they're out of render distance and we can't make sure right now
private String name;
Expand All @@ -110,6 +119,14 @@ public void build(String name, ISchematic schematic, Vec3i origin) {
if (!Baritone.settings().buildSubstitutes.value.isEmpty()) {
this.schematic = new SubstituteSchematic(this.schematic, Baritone.settings().buildSubstitutes.value);
}
// TODO this preserves the old behavior, but maybe we should bake the setting value right here
this.schematic = new MaskSchematic(this.schematic) {
@Override
public boolean partOfMask(int x, int y, int z, BlockState current) {
// partOfMask is only called inside the schematic so desiredState is not null
return !Baritone.settings().buildSkipBlocks.value.contains(this.desiredState(x, y, z, current, null).getBlock());
}
};
int x = origin.getX();
int y = origin.getY();
int z = origin.getZ();
Expand Down Expand Up @@ -168,15 +185,15 @@ public boolean build(String name, File schematic, Vec3i origin) {
if (!format.isPresent()) {
return false;
}
ISchematic parsed;
IStaticSchematic parsed;
try {
parsed = format.get().parse(new FileInputStream(schematic));
} catch (Exception e) {
e.printStackTrace();
return false;
}
parsed = applyMapArtAndSelection(origin, (IStaticSchematic) parsed);
build(name, parsed, origin);
ISchematic schem = applyMapArtAndSelection(origin, parsed);
build(name, schem, origin);
return true;
}

Expand All @@ -196,17 +213,10 @@ public void buildOpenSchematic() {
if (SchematicaHelper.isSchematicaPresent()) {
Optional<Tuple<IStaticSchematic, BlockPos>> schematic = SchematicaHelper.getOpenSchematic();
if (schematic.isPresent()) {
IStaticSchematic s = schematic.get().getA();
IStaticSchematic raw = schematic.get().getA();
BlockPos origin = schematic.get().getB();
ISchematic schem = Baritone.settings().mapArtMode.value ? new MapArtSchematic(s) : s;
if (Baritone.settings().buildOnlySelection.value) {
schem = new SelectionSchematic(schem, origin, baritone.getSelectionManager().getSelections());
}
this.build(
schematic.get().getA().toString(),
schem,
origin
);
ISchematic schem = applyMapArtAndSelection(origin, raw);
this.build(raw.toString(), schem, origin);
} else {
logDirect("No schematic currently open");
}
Expand Down Expand Up @@ -438,8 +448,8 @@ public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) {
return onTick(calcFailed, isSafeToCancel, 0);
}

public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel, int recursions) {
if (recursions > 1000) { // onTick calls itself, don't crash
private PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel, int recursions) {
if (recursions > 100) { // onTick calls itself, don't crash
return new PathingCommand(null, PathingCommandType.SET_GOAL_AND_PATH);
}
approxPlaceable = approxPlaceable(36);
Expand Down Expand Up @@ -683,8 +693,7 @@ private void fullRecalc(BuilderCalculationContext bcc) {
continue;
}
// this is not in render distance
if (!observedCompleted.contains(BetterBlockPos.longHash(blockX, blockY, blockZ))
&& !Baritone.settings().buildSkipBlocks.value.contains(schematic.desiredState(x, y, z, current, this.approxPlaceable).getBlock())) {
if (!observedCompleted.contains(BetterBlockPos.longHash(blockX, blockY, blockZ))) {
// and we've never seen this position be correct
// therefore mark as incorrect
incorrectPositions.add(new BetterBlockPos(blockX, blockY, blockZ));
Expand Down Expand Up @@ -1009,15 +1018,7 @@ private List<BlockState> approxPlaceable(int size) {
return result;
}

public static final Set<Property<?>> orientationProps =
ImmutableSet.of(
RotatedPillarBlock.AXIS, HorizontalDirectionalBlock.FACING,
StairBlock.FACING, StairBlock.HALF, StairBlock.SHAPE,
PipeBlock.NORTH, PipeBlock.EAST, PipeBlock.SOUTH, PipeBlock.WEST, PipeBlock.UP,
TrapDoorBlock.OPEN, TrapDoorBlock.HALF
);

private boolean sameBlockstate(BlockState first, BlockState second) {
private static boolean sameBlockstate(BlockState first, BlockState second) {
if (first.getBlock() != second.getBlock()) {
return false;
}
Expand All @@ -1030,15 +1031,15 @@ private boolean sameBlockstate(BlockState first, BlockState second) {
ImmutableMap<Property<?>, Comparable<?>> map2 = second.getValues();
for (Property<?> prop : map1.keySet()) {
if (map1.get(prop) != map2.get(prop)
&& !(ignoreDirection && orientationProps.contains(prop))
&& !(ignoreDirection && ORIENTATION_PROPS.contains(prop))
&& !ignoredProps.contains(prop.getName())) {
return false;
}
}
return true;
}

private boolean containsBlockState(Collection<BlockState> states, BlockState state) {
private static boolean containsBlockState(Collection<BlockState> states, BlockState state) {
for (BlockState testee : states) {
if (sameBlockstate(testee, state)) {
return true;
Expand All @@ -1047,7 +1048,7 @@ private boolean containsBlockState(Collection<BlockState> states, BlockState sta
return false;
}

private boolean valid(BlockState current, BlockState desired, boolean itemVerify) {
private static boolean valid(BlockState current, BlockState desired, boolean itemVerify) {
if (desired == null) {
return true;
}
Expand All @@ -1066,9 +1067,6 @@ private boolean valid(BlockState current, BlockState desired, boolean itemVerify
if (!(current.getBlock() instanceof AirBlock) && Baritone.settings().buildIgnoreExisting.value && !itemVerify) {
return true;
}
if (Baritone.settings().buildSkipBlocks.value.contains(desired.getBlock()) && !itemVerify) {
return true;
}
if (Baritone.settings().buildValidSubstitutes.value.getOrDefault(desired.getBlock(), Collections.emptyList()).contains(current.getBlock()) && !itemVerify) {
return true;
}
Expand Down Expand Up @@ -1112,12 +1110,12 @@ public double costOfPlacingAt(int x, int y, int z, BlockState current) {
return COST_INF;
}
BlockState sch = getSchematic(x, y, z, current);
if (sch != null && !Baritone.settings().buildSkipBlocks.value.contains(sch.getBlock())) {
if (sch != null) {
// TODO this can return true even when allowPlace is off.... is that an issue?
if (sch.getBlock() instanceof AirBlock) {
// we want this to be air, but they're asking if they can place here
// this won't be a schematic block, this will be a throwaway
return placeBlockCost * 2; // we're going to have to break it eventually
return placeBlockCost * Baritone.settings().placeIncorrectBlockPenaltyMultiplier.value; // we're going to have to break it eventually
}
if (placeable.contains(sch)) {
return 0; // thats right we gonna make it FREE to place a block where it should go in a structure
Expand All @@ -1130,7 +1128,7 @@ public double costOfPlacingAt(int x, int y, int z, BlockState current) {
}
// we want it to be something that we don't have
// even more of a pain to place something wrong
return placeBlockCost * 3;
return placeBlockCost * 1.5 * Baritone.settings().placeIncorrectBlockPenaltyMultiplier.value;
} else {
if (hasThrowaway) {
return placeBlockCost;
Expand All @@ -1146,7 +1144,7 @@ public double breakCostMultiplierAt(int x, int y, int z, BlockState current) {
return COST_INF;
}
BlockState sch = getSchematic(x, y, z, current);
if (sch != null && !Baritone.settings().buildSkipBlocks.value.contains(sch.getBlock())) {
if (sch != null) {
if (sch.getBlock() instanceof AirBlock) {
// it should be air
// regardless of current contents, we can break it
Expand Down
9 changes: 6 additions & 3 deletions src/main/java/baritone/utils/schematic/MapArtSchematic.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,19 +41,22 @@ protected boolean partOfMask(int x, int y, int z, BlockState currentState) {
private static int[][] generateHeightMap(IStaticSchematic schematic) {
int[][] heightMap = new int[schematic.widthX()][schematic.lengthZ()];

int missingColumns = 0;
for (int x = 0; x < schematic.widthX(); x++) {
for (int z = 0; z < schematic.lengthZ(); z++) {
BlockState[] column = schematic.getColumn(x, z);
OptionalInt lowestBlockY = lastIndexMatching(column, state -> !(state.getBlock() instanceof AirBlock));
if (lowestBlockY.isPresent()) {
heightMap[x][z] = lowestBlockY.getAsInt();
} else {
System.out.println("Column " + x + "," + z + " has no blocks, but it's apparently map art? wtf");
System.out.println("Letting it be whatever");
heightMap[x][z] = 256;
missingColumns++;
heightMap[x][z] = Integer.MAX_VALUE;
}
}
}
if (missingColumns != 0) {
System.out.println(missingColumns + " columns had no block despite being in a map art, letting them be whatever");
}
return heightMap;
}

Expand Down
Loading