diff --git a/src/main/java/baritone/process/BuilderProcess.java b/src/main/java/baritone/process/BuilderProcess.java index 00d3831ce..deccf5041 100644 --- a/src/main/java/baritone/process/BuilderProcess.java +++ b/src/main/java/baritone/process/BuilderProcess.java @@ -58,6 +58,7 @@ import net.minecraft.util.math.*; import java.io.File; import java.io.FileInputStream; import java.util.*; +import java.util.stream.Collectors; import static baritone.api.pathing.movement.ActionCosts.COST_INF; @@ -482,7 +483,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil Goal goal = assemble(bcc, approxPlaceable.subList(0, 9)); if (goal == null) { - goal = assemble(bcc, approxPlaceable); // we're far away, so assume that we have our whole inventory to recalculate placeable properly + goal = assemble(bcc, approxPlaceable, true); // we're far away, so assume that we have our whole inventory to recalculate placeable properly if (goal == null) { if (Baritone.settings().skipFailedLayers.value && Baritone.settings().buildInLayers.value && layer < realSchematic.heightY()) { logDirect("Skipping layer that I cannot construct! Layer #" + layer); @@ -586,14 +587,23 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil } private Goal assemble(BuilderCalculationContext bcc, List approxPlaceable) { + return assemble(bcc, approxPlaceable, false); + } + + private Goal assemble(BuilderCalculationContext bcc, List approxPlaceable, boolean logMissing) { List placeable = new ArrayList<>(); List breakable = new ArrayList<>(); List sourceLiquids = new ArrayList<>(); + List flowingLiquids = new ArrayList<>(); + Map missing = new HashMap<>(); incorrectPositions.forEach(pos -> { IBlockState state = bcc.bsi.get0(pos); if (state.getBlock() instanceof BlockAir) { if (approxPlaceable.contains(bcc.getSchematic(pos.x, pos.y, pos.z, state))) { placeable.add(pos); + } else { + IBlockState desired = bcc.getSchematic(pos.x, pos.y, pos.z, state); + missing.put(desired, 1 + missing.getOrDefault(desired, 0)); } } else { if (state.getBlock() instanceof BlockLiquid) { @@ -602,6 +612,8 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil if (!MovementHelper.possiblyFlowing(state)) { // if it's a source block then we want to replace it with a throwaway sourceLiquids.add(pos); + } else { + flowingLiquids.add(pos); } } else { breakable.add(pos); @@ -622,6 +634,18 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil return new JankyGoalComposite(new GoalComposite(toPlace.toArray(new Goal[0])), new GoalComposite(toBreak.toArray(new Goal[0]))); } if (toBreak.isEmpty()) { + if (logMissing && !missing.isEmpty()) { + logDirect("Missing materials for at least:"); + logDirect(missing.entrySet().stream() + .map(e -> String.format("%sx %s", e.getValue(), e.getKey())) + .collect(Collectors.joining("\n"))); + } + if (logMissing && !flowingLiquids.isEmpty()) { + logDirect("Unreplaceable liquids at at least:"); + logDirect(flowingLiquids.stream() + .map(p -> String.format("%s %s %s", p.x, p.y, p.z)) + .collect(Collectors.joining("\n"))); + } return null; } return new GoalComposite(toBreak.toArray(new Goal[0]));