use of baritone.api.utils.BetterBlockPos in project baritone by cabaletta.
the class BuilderProcess method assemble.
private Goal assemble(BuilderCalculationContext bcc, List<IBlockState> approxPlaceable, boolean logMissing) {
List<BetterBlockPos> placeable = new ArrayList<>();
List<BetterBlockPos> breakable = new ArrayList<>();
List<BetterBlockPos> sourceLiquids = new ArrayList<>();
List<BetterBlockPos> flowingLiquids = new ArrayList<>();
Map<IBlockState, Integer> 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) {
// 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 {
flowingLiquids.add(pos);
}
} else {
breakable.add(pos);
}
}
});
List<Goal> toBreak = new ArrayList<>();
breakable.forEach(pos -> toBreak.add(breakGoal(pos, bcc)));
List<Goal> toPlace = new ArrayList<>();
placeable.forEach(pos -> {
if (!placeable.contains(pos.down()) && !placeable.contains(pos.down(2))) {
toPlace.add(placementGoal(pos, bcc));
}
});
sourceLiquids.forEach(pos -> toPlace.add(new GoalBlock(pos.up())));
if (!toPlace.isEmpty()) {
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]));
}
use of baritone.api.utils.BetterBlockPos in project baritone by cabaletta.
the class BuilderProcess method fullRecalc.
private void fullRecalc(BuilderCalculationContext bcc) {
incorrectPositions = new HashSet<>();
for (int y = 0; y < schematic.heightY(); y++) {
for (int z = 0; z < schematic.lengthZ(); z++) {
for (int x = 0; x < schematic.widthX(); x++) {
int blockX = x + origin.getX();
int blockY = y + origin.getY();
int blockZ = z + origin.getZ();
IBlockState current = bcc.bsi.get0(blockX, blockY, blockZ);
if (!schematic.inSchematic(x, y, z, current)) {
continue;
}
if (bcc.bsi.worldContainsLoadedChunk(blockX, blockZ)) {
// we can directly observe this block, it is in render distance
if (valid(bcc.bsi.get0(blockX, blockY, blockZ), schematic.desiredState(x, y, z, current, this.approxPlaceable), false)) {
observedCompleted.add(BetterBlockPos.longHash(blockX, blockY, blockZ));
} else {
incorrectPositions.add(new BetterBlockPos(blockX, blockY, blockZ));
observedCompleted.remove(BetterBlockPos.longHash(blockX, blockY, blockZ));
if (incorrectPositions.size() > Baritone.settings().incorrectSize.value) {
return;
}
}
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())) {
// and we've never seen this position be correct
// therefore mark as incorrect
incorrectPositions.add(new BetterBlockPos(blockX, blockY, blockZ));
if (incorrectPositions.size() > Baritone.settings().incorrectSize.value) {
return;
}
}
}
}
}
}
use of baritone.api.utils.BetterBlockPos in project baritone by cabaletta.
the class BuilderProcess method searchForPlaceables.
private Optional<Placement> searchForPlaceables(BuilderCalculationContext bcc, List<IBlockState> desirableOnHotbar) {
BetterBlockPos center = ctx.playerFeet();
for (int dx = -5; dx <= 5; dx++) {
for (int dy = -5; dy <= 1; dy++) {
for (int dz = -5; dz <= 5; dz++) {
int x = center.x + dx;
int y = center.y + dy;
int z = center.z + dz;
IBlockState desired = bcc.getSchematic(x, y, z, bcc.bsi.get0(x, y, z));
if (desired == null) {
// irrelevant
continue;
}
IBlockState curr = bcc.bsi.get0(x, y, z);
if (MovementHelper.isReplaceable(x, y, z, curr, bcc.bsi) && !valid(curr, desired, false)) {
if (dy == 1 && bcc.bsi.get0(x, y + 1, z).getBlock() == Blocks.AIR) {
continue;
}
desirableOnHotbar.add(desired);
Optional<Placement> opt = possibleToPlace(desired, x, y, z, bcc.bsi);
if (opt.isPresent()) {
return opt;
}
}
}
}
}
return Optional.empty();
}
use of baritone.api.utils.BetterBlockPos in project baritone by cabaletta.
the class BuilderProcess method recalcNearby.
private void recalcNearby(BuilderCalculationContext bcc) {
BetterBlockPos center = ctx.playerFeet();
int radius = Baritone.settings().builderTickScanRadius.value;
for (int dx = -radius; dx <= radius; dx++) {
for (int dy = -radius; dy <= radius; dy++) {
for (int dz = -radius; dz <= radius; dz++) {
int x = center.x + dx;
int y = center.y + dy;
int z = center.z + dz;
IBlockState desired = bcc.getSchematic(x, y, z, bcc.bsi.get0(x, y, z));
if (desired != null) {
// we care about this position
BetterBlockPos pos = new BetterBlockPos(x, y, z);
if (valid(bcc.bsi.get0(x, y, z), desired, false)) {
incorrectPositions.remove(pos);
observedCompleted.add(BetterBlockPos.longHash(pos));
} else {
incorrectPositions.add(pos);
observedCompleted.remove(BetterBlockPos.longHash(pos));
}
}
}
}
}
}
use of baritone.api.utils.BetterBlockPos in project baritone by cabaletta.
the class SelCommand method execute.
@Override
public void execute(String label, IArgConsumer args) throws CommandException {
Action action = Action.getByName(args.getString());
if (action == null) {
throw new CommandInvalidTypeException(args.consumed(), "an action");
}
if (action == Action.POS1 || action == Action.POS2) {
if (action == Action.POS2 && pos1 == null) {
throw new CommandInvalidStateException("Set pos1 first before using pos2");
}
BetterBlockPos playerPos = mc.getRenderViewEntity() != null ? BetterBlockPos.from(new BlockPos(mc.getRenderViewEntity())) : ctx.playerFeet();
BetterBlockPos pos = args.hasAny() ? args.getDatatypePost(RelativeBlockPos.INSTANCE, playerPos) : playerPos;
args.requireMax(0);
if (action == Action.POS1) {
pos1 = pos;
logDirect("Position 1 has been set");
} else {
manager.addSelection(pos1, pos);
pos1 = null;
logDirect("Selection added");
}
} else if (action == Action.CLEAR) {
args.requireMax(0);
pos1 = null;
logDirect(String.format("Removed %d selections", manager.removeAllSelections().length));
} else if (action == Action.UNDO) {
args.requireMax(0);
if (pos1 != null) {
pos1 = null;
logDirect("Undid pos1");
} else {
ISelection[] selections = manager.getSelections();
if (selections.length < 1) {
throw new CommandInvalidStateException("Nothing to undo!");
} else {
pos1 = manager.removeSelection(selections[selections.length - 1]).pos1();
logDirect("Undid pos2");
}
}
} else if (action == Action.SET || action == Action.WALLS || action == Action.SHELL || action == Action.CLEARAREA || action == Action.REPLACE) {
BlockOptionalMeta type = action == Action.CLEARAREA ? new BlockOptionalMeta(Blocks.AIR) : args.getDatatypeFor(ForBlockOptionalMeta.INSTANCE);
BlockOptionalMetaLookup replaces = null;
if (action == Action.REPLACE) {
args.requireMin(1);
List<BlockOptionalMeta> replacesList = new ArrayList<>();
replacesList.add(type);
while (args.has(2)) {
replacesList.add(args.getDatatypeFor(ForBlockOptionalMeta.INSTANCE));
}
type = args.getDatatypeFor(ForBlockOptionalMeta.INSTANCE);
replaces = new BlockOptionalMetaLookup(replacesList.toArray(new BlockOptionalMeta[0]));
} else {
args.requireMax(0);
}
ISelection[] selections = manager.getSelections();
if (selections.length == 0) {
throw new CommandInvalidStateException("No selections");
}
BetterBlockPos origin = selections[0].min();
CompositeSchematic composite = new CompositeSchematic(0, 0, 0);
for (ISelection selection : selections) {
BetterBlockPos min = selection.min();
origin = new BetterBlockPos(Math.min(origin.x, min.x), Math.min(origin.y, min.y), Math.min(origin.z, min.z));
}
for (ISelection selection : selections) {
Vec3i size = selection.size();
BetterBlockPos min = selection.min();
ISchematic schematic = new FillSchematic(size.getX(), size.getY(), size.getZ(), type);
if (action == Action.WALLS) {
schematic = new WallsSchematic(schematic);
} else if (action == Action.SHELL) {
schematic = new ShellSchematic(schematic);
} else if (action == Action.REPLACE) {
schematic = new ReplaceSchematic(schematic, replaces);
}
composite.put(schematic, min.x - origin.x, min.y - origin.y, min.z - origin.z);
}
baritone.getBuilderProcess().build("Fill", composite, origin);
logDirect("Filling now");
} else if (action == Action.COPY) {
BetterBlockPos playerPos = mc.getRenderViewEntity() != null ? BetterBlockPos.from(new BlockPos(mc.getRenderViewEntity())) : ctx.playerFeet();
BetterBlockPos pos = args.hasAny() ? args.getDatatypePost(RelativeBlockPos.INSTANCE, playerPos) : playerPos;
args.requireMax(0);
ISelection[] selections = manager.getSelections();
if (selections.length < 1) {
throw new CommandInvalidStateException("No selections");
}
BlockStateInterface bsi = new BlockStateInterface(ctx);
BetterBlockPos origin = selections[0].min();
CompositeSchematic composite = new CompositeSchematic(0, 0, 0);
for (ISelection selection : selections) {
BetterBlockPos min = selection.min();
origin = new BetterBlockPos(Math.min(origin.x, min.x), Math.min(origin.y, min.y), Math.min(origin.z, min.z));
}
for (ISelection selection : selections) {
Vec3i size = selection.size();
BetterBlockPos min = selection.min();
IBlockState[][][] blockstates = new IBlockState[size.getX()][size.getZ()][size.getY()];
for (int x = 0; x < size.getX(); x++) {
for (int y = 0; y < size.getY(); y++) {
for (int z = 0; z < size.getZ(); z++) {
blockstates[x][z][y] = bsi.get0(min.x + x, min.y + y, min.z + z);
}
}
}
ISchematic schematic = new StaticSchematic() {
{
states = blockstates;
x = size.getX();
y = size.getY();
z = size.getZ();
}
};
composite.put(schematic, min.x - origin.x, min.y - origin.y, min.z - origin.z);
}
clipboard = composite;
clipboardOffset = origin.subtract(pos);
logDirect("Selection copied");
} else if (action == Action.PASTE) {
BetterBlockPos playerPos = mc.getRenderViewEntity() != null ? BetterBlockPos.from(new BlockPos(mc.getRenderViewEntity())) : ctx.playerFeet();
BetterBlockPos pos = args.hasAny() ? args.getDatatypePost(RelativeBlockPos.INSTANCE, playerPos) : playerPos;
args.requireMax(0);
if (clipboard == null) {
throw new CommandInvalidStateException("You need to copy a selection first");
}
baritone.getBuilderProcess().build("Fill", clipboard, pos.add(clipboardOffset));
logDirect("Building now");
} else if (action == Action.EXPAND || action == Action.CONTRACT || action == Action.SHIFT) {
args.requireExactly(3);
TransformTarget transformTarget = TransformTarget.getByName(args.getString());
if (transformTarget == null) {
throw new CommandInvalidStateException("Invalid transform type");
}
EnumFacing direction = args.getDatatypeFor(ForEnumFacing.INSTANCE);
int blocks = args.getAs(Integer.class);
ISelection[] selections = manager.getSelections();
if (selections.length < 1) {
throw new CommandInvalidStateException("No selections found");
}
selections = transformTarget.transform(selections);
for (ISelection selection : selections) {
if (action == Action.EXPAND) {
manager.expand(selection, direction, blocks);
} else if (action == Action.CONTRACT) {
manager.contract(selection, direction, blocks);
} else {
manager.shift(selection, direction, blocks);
}
}
logDirect(String.format("Transformed %d selections", selections.length));
}
}
Aggregations