diff --git a/src/main/java/baritone/process/BuilderProcess.java b/src/main/java/baritone/process/BuilderProcess.java index 9f49c595..c08ca8c6 100644 --- a/src/main/java/baritone/process/BuilderProcess.java +++ b/src/main/java/baritone/process/BuilderProcess.java @@ -37,6 +37,7 @@ import baritone.utils.schematic.AirSchematic; import baritone.utils.schematic.Schematic; import it.unimi.dsi.fastutil.longs.LongOpenHashSet; import net.minecraft.block.BlockAir; +import net.minecraft.block.BlockLiquid; import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; import net.minecraft.item.ItemBlock; @@ -51,7 +52,6 @@ import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.*; -import java.util.stream.Collectors; import static baritone.api.pathing.movement.ActionCosts.COST_INF; @@ -500,17 +500,45 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro } private Goal assemble(BuilderCalculationContext bcc, List approxPlacable) { - List placable = incorrectPositions.stream().filter(pos -> bcc.bsi.get0(pos).getBlock() == Blocks.AIR && approxPlacable.contains(bcc.getSchematic(pos.x, pos.y, pos.z))).collect(Collectors.toList()); - Goal[] toBreak = incorrectPositions.stream().filter(pos -> bcc.bsi.get0(pos).getBlock() != Blocks.AIR).map(pos -> breakGoal(pos, bcc)).toArray(Goal[]::new); - Goal[] toPlace = placable.stream().filter(pos -> !placable.contains(pos.down()) && !placable.contains(pos.down(2))).map(pos -> placementGoal(pos, bcc)).toArray(Goal[]::new); + List placable = new ArrayList<>(); + List breakable = new ArrayList<>(); + List sourceLiquids = new ArrayList<>(); + incorrectPositions.forEach(pos -> { + IBlockState state = bcc.bsi.get0(pos); + if (state.getBlock() instanceof BlockAir) { + if (approxPlacable.contains(bcc.getSchematic(pos.x, pos.y, pos.z))) { + placable.add(pos); + } + } else { + if (state.getBlock() instanceof BlockLiquid) { + // if the block itself is JUST a liquid (i.e. not just a waterlogged block), we CANNOT break it + // TODO for 1.13 make sure that this only matches pure water, not waterlogged blocks + if (!MovementHelper.possiblyFlowing(state)) { + // if it's a source block then we want to replace it with a throwaway + sourceLiquids.add(pos); + } + } else { + breakable.add(pos); + } + } + }); + List toBreak = new ArrayList<>(); + breakable.forEach(pos -> toBreak.add(breakGoal(pos, bcc))); + List toPlace = new ArrayList<>(); + placable.forEach(pos -> { + if (!placable.contains(pos.down()) && !placable.contains(pos.down(2))) { + toPlace.add(placementGoal(pos, bcc)); + } + }); + sourceLiquids.forEach(pos -> toPlace.add(new GoalBlock(pos.up()))); - if (toPlace.length != 0) { - return new JankyGoalComposite(new GoalComposite(toPlace), new GoalComposite(toBreak)); + if (!toPlace.isEmpty()) { + return new JankyGoalComposite(new GoalComposite(toPlace.toArray(new Goal[0])), new GoalComposite(toBreak.toArray(new Goal[0]))); } - if (toBreak.length == 0) { + if (toBreak.isEmpty()) { return null; } - return new GoalComposite(toBreak); + return new GoalComposite(toBreak.toArray(new Goal[0])); } public static class JankyGoalComposite implements Goal {