Merge pull request #949 from LoganDark/commands

Commands
This commit is contained in:
Leijurv
2019-09-19 12:51:21 -07:00
committed by GitHub
149 changed files with 10660 additions and 1162 deletions

View File

@@ -21,14 +21,17 @@ import baritone.api.BaritoneAPI;
import baritone.api.IBaritone;
import baritone.api.Settings;
import baritone.api.event.listener.IEventBus;
import baritone.api.utils.ExampleBaritoneControl;
import baritone.api.utils.command.BaritoneChatControl;
import baritone.api.utils.Helper;
import baritone.api.utils.IPlayerContext;
import baritone.api.utils.command.manager.CommandManager;
import baritone.behavior.*;
import baritone.cache.WorldProvider;
import baritone.event.GameEventHandler;
import baritone.process.*;
import baritone.selection.SelectionManager;
import baritone.utils.*;
import baritone.utils.command.defaults.DefaultCommands;
import baritone.utils.player.PrimaryPlayerContext;
import net.minecraft.client.Minecraft;
@@ -83,6 +86,7 @@ public class Baritone implements IBaritone {
private FarmProcess farmProcess;
private PathingControlManager pathingControlManager;
private SelectionManager selectionManager;
private IPlayerContext playerContext;
private WorldProvider worldProvider;
@@ -109,7 +113,6 @@ public class Baritone implements IBaritone {
memoryBehavior = new MemoryBehavior(this);
inventoryBehavior = new InventoryBehavior(this);
inputOverrideHandler = new InputOverrideHandler(this);
new ExampleBaritoneControl(this);
}
this.pathingControlManager = new PathingControlManager(this);
@@ -125,6 +128,7 @@ public class Baritone implements IBaritone {
}
this.worldProvider = new WorldProvider();
this.selectionManager = new SelectionManager();
if (BaritoneAutoTest.ENABLE_AUTO_TEST) {
this.gameEventHandler.registerEventListener(BaritoneAutoTest.INSTANCE);
@@ -203,6 +207,11 @@ public class Baritone implements IBaritone {
return this.pathingBehavior;
}
@Override
public SelectionManager getSelectionManager() {
return selectionManager;
}
@Override
public WorldProvider getWorldProvider() {
return this.worldProvider;

View File

@@ -20,7 +20,10 @@ package baritone;
import baritone.api.IBaritone;
import baritone.api.IBaritoneProvider;
import baritone.api.cache.IWorldScanner;
import baritone.api.utils.command.BaritoneChatControl;
import baritone.api.utils.command.manager.CommandManager;
import baritone.cache.WorldScanner;
import baritone.utils.command.defaults.DefaultCommands;
import java.util.Collections;
import java.util.List;
@@ -34,6 +37,11 @@ public final class BaritoneProvider implements IBaritoneProvider {
private final Baritone primary = new Baritone();
private final List<IBaritone> all = Collections.singletonList(primary);
{
DefaultCommands.COMMANDS.forEach(CommandManager.REGISTRY::register);
new BaritoneChatControl(primary);
}
@Override
public IBaritone getPrimaryBaritone() {
return primary;

View File

@@ -28,6 +28,7 @@ import net.minecraft.inventory.ClickType;
import net.minecraft.item.*;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.NonNullList;
import net.minecraft.util.math.BlockPos;
import java.util.ArrayList;
import java.util.OptionalInt;
@@ -132,7 +133,7 @@ public final class InventoryBehavior extends Behavior {
}
public boolean selectThrowawayForLocation(boolean select, int x, int y, int z) {
IBlockState maybe = baritone.getBuilderProcess().placeAt(x, y, z);
IBlockState maybe = baritone.getBuilderProcess().placeAt(x, y, z, baritone.bsi.get0(x, y, z));
if (maybe != null && throwaway(select, stack -> stack.getItem() instanceof ItemBlock && maybe.equals(((ItemBlock) stack.getItem()).getBlock().getStateForPlacement(ctx.world(), ctx.playerFeet(), EnumFacing.UP, (float) ctx.player().posX, (float) ctx.player().posY, (float) ctx.player().posZ, stack.getItem().getMetadata(stack.getMetadata()), ctx.player())))) {
return true; // gotem
}

View File

@@ -160,7 +160,7 @@ public final class MemoryBehavior extends Behavior {
@Override
public void onBlockInteract(BlockInteractEvent event) {
if (event.getType() == BlockInteractEvent.Type.USE && BlockStateInterface.getBlock(ctx, event.getPos()) instanceof BlockBed) {
baritone.getWorldProvider().getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("bed", Waypoint.Tag.BED, event.getPos()));
baritone.getWorldProvider().getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("bed", Waypoint.Tag.BED, BetterBlockPos.from(event.getPos())));
}
}

View File

@@ -19,7 +19,11 @@ package baritone.behavior;
import baritone.Baritone;
import baritone.api.behavior.IPathingBehavior;
import baritone.api.event.events.*;
import baritone.api.event.events.PathEvent;
import baritone.api.event.events.PlayerUpdateEvent;
import baritone.api.event.events.RenderEvent;
import baritone.api.event.events.SprintStateEvent;
import baritone.api.event.events.TickEvent;
import baritone.api.pathing.calc.IPath;
import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.goals.GoalXZ;
@@ -55,6 +59,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
private boolean safeToCancel;
private boolean pauseRequestedLastTick;
private boolean unpausedLastTick;
private boolean pausedThisTick;
private boolean cancelRequested;
private boolean calcFailedLastTick;
@@ -108,6 +113,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
}
private void tickPath() {
pausedThisTick = false;
if (pauseRequestedLastTick && safeToCancel) {
pauseRequestedLastTick = false;
if (unpausedLastTick) {
@@ -115,6 +121,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
baritone.getInputOverrideHandler().getBlockBreakHelper().stopBreakingBlock();
}
unpausedLastTick = false;
pausedThisTick = true;
return;
}
unpausedLastTick = true;
@@ -130,8 +137,8 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
BetterBlockPos calcFrom = inProgress.getStart();
Optional<IPath> currentBest = inProgress.bestPathSoFar();
if ((current == null || !current.getPath().getDest().equals(calcFrom)) // if current ends in inProgress's start, then we're ok
&& !calcFrom.equals(ctx.playerFeet()) && !calcFrom.equals(expectedSegmentStart) // if current starts in our playerFeet or pathStart, then we're ok
&& (!currentBest.isPresent() || (!currentBest.get().positions().contains(ctx.playerFeet()) && !currentBest.get().positions().contains(expectedSegmentStart))) // if
&& !calcFrom.equals(ctx.playerFeet()) && !calcFrom.equals(expectedSegmentStart) // if current starts in our playerFeet or pathStart, then we're ok
&& (!currentBest.isPresent() || (!currentBest.get().positions().contains(ctx.playerFeet()) && !currentBest.get().positions().contains(expectedSegmentStart))) // if
) {
// when it was *just* started, currentBest will be empty so we need to also check calcFrom since that's always present
inProgress.cancel(); // cancellation doesn't dispatch any events
@@ -279,6 +286,11 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
return goal;
}
@Override
public boolean isPathing() {
return hasPath() && !pausedThisTick;
}
@Override
public PathExecutor getCurrent() {
return current;

View File

@@ -20,6 +20,7 @@ package baritone.cache;
import baritone.api.cache.IWaypoint;
import baritone.api.cache.IWaypointCollection;
import baritone.api.cache.Waypoint;
import baritone.api.utils.BetterBlockPos;
import net.minecraft.util.math.BlockPos;
import java.io.*;
@@ -86,7 +87,7 @@ public class WaypointCollection implements IWaypointCollection {
int x = in.readInt();
int y = in.readInt();
int z = in.readInt();
this.waypoints.get(tag).add(new Waypoint(name, tag, new BlockPos(x, y, z), creationTimestamp));
this.waypoints.get(tag).add(new Waypoint(name, tag, new BetterBlockPos(x, y, z), creationTimestamp));
}
} catch (IOException ignored) {}
}

View File

@@ -17,20 +17,29 @@
package baritone.cache;
import baritone.api.cache.ICachedWorld;
import baritone.api.cache.IWorldScanner;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.BlockOptionalMetaLookup;
import baritone.api.utils.IPlayerContext;
import net.minecraft.block.Block;
import baritone.utils.accessor.IBlockStateContainer;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.multiplayer.ChunkProviderClient;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.world.chunk.BlockStateContainer;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.IChunkProvider;
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
import java.util.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.stream.IntStream;
import static java.util.Objects.nonNull;
public enum WorldScanner implements IWorldScanner {
INSTANCE;
@@ -38,14 +47,13 @@ public enum WorldScanner implements IWorldScanner {
private static final int[] DEFAULT_COORDINATE_ITERATION_ORDER = IntStream.range(0, 16).toArray();
@Override
public List<BlockPos> scanChunkRadius(IPlayerContext ctx, List<Block> blocks, int max, int yLevelThreshold, int maxSearchRadius) {
if (blocks.contains(null)) {
throw new IllegalStateException("Invalid block name should have been caught earlier: " + blocks.toString());
}
public List<BlockPos> scanChunkRadius(IPlayerContext ctx, BlockOptionalMetaLookup filter, int max, int yLevelThreshold, int maxSearchRadius) {
ArrayList<BlockPos> res = new ArrayList<>();
if (blocks.isEmpty()) {
if (filter.blocks().isEmpty()) {
return res;
}
ChunkProviderClient chunkProvider = (ChunkProviderClient) ctx.world().getChunkProvider();
int maxSearchRadiusSq = maxSearchRadius * maxSearchRadius;
@@ -75,14 +83,14 @@ public enum WorldScanner implements IWorldScanner {
continue;
}
allUnloaded = false;
if (scanChunkInto(chunkX << 4, chunkZ << 4, chunk, blocks, res, max, yLevelThreshold, playerY, coordinateIterationOrder)) {
if (scanChunkInto(chunkX << 4, chunkZ << 4, chunk, filter, res, max, yLevelThreshold, playerY, coordinateIterationOrder)) {
foundWithinY = true;
}
}
}
if ((allUnloaded && foundChunks)
|| (res.size() >= max
&& (searchRadiusSq > maxSearchRadiusSq || (searchRadiusSq > 1 && foundWithinY)))
|| (res.size() >= max
&& (searchRadiusSq > maxSearchRadiusSq || (searchRadiusSq > 1 && foundWithinY)))
) {
return res;
}
@@ -91,8 +99,8 @@ public enum WorldScanner implements IWorldScanner {
}
@Override
public List<BlockPos> scanChunk(IPlayerContext ctx, List<Block> blocks, ChunkPos pos, int max, int yLevelThreshold) {
if (blocks.isEmpty()) {
public List<BlockPos> scanChunk(IPlayerContext ctx, BlockOptionalMetaLookup filter, ChunkPos pos, int max, int yLevelThreshold) {
if (filter.blocks().isEmpty()) {
return Collections.emptyList();
}
@@ -105,11 +113,11 @@ public enum WorldScanner implements IWorldScanner {
}
ArrayList<BlockPos> res = new ArrayList<>();
scanChunkInto(pos.x << 4, pos.z << 4, chunk, blocks, res, max, yLevelThreshold, playerY, DEFAULT_COORDINATE_ITERATION_ORDER);
scanChunkInto(pos.x << 4, pos.z << 4, chunk, filter, res, max, yLevelThreshold, playerY, DEFAULT_COORDINATE_ITERATION_ORDER);
return res;
}
private boolean scanChunkInto(int chunkX, int chunkZ, Chunk chunk, List<Block> search, Collection<BlockPos> result, int max, int yLevelThreshold, int playerY, int[] coordinateIterationOrder) {
private boolean scanChunkInto(int chunkX, int chunkZ, Chunk chunk, BlockOptionalMetaLookup filter, Collection<BlockPos> result, int max, int yLevelThreshold, int playerY, int[] coordinateIterationOrder) {
ExtendedBlockStorage[] chunkInternalStorageArray = chunk.getBlockStorageArray();
boolean foundWithinY = false;
for (int yIndex = 0; yIndex < 16; yIndex++) {
@@ -119,32 +127,52 @@ public enum WorldScanner implements IWorldScanner {
continue;
}
int yReal = y0 << 4;
BlockStateContainer bsc = extendedblockstorage.getData();
// the mapping of BlockStateContainer.getIndex from xyz to index is y << 8 | z << 4 | x;
// for better cache locality, iterate in that order
for (int y = 0; y < 16; y++) {
for (int z = 0; z < 16; z++) {
for (int x = 0; x < 16; x++) {
IBlockState state = bsc.get(x, y, z);
if (search.contains(state.getBlock())) {
int yy = yReal | y;
if (result.size() >= max) {
if (Math.abs(yy - playerY) < yLevelThreshold) {
foundWithinY = true;
} else {
if (foundWithinY) {
// have found within Y in this chunk, so don't need to consider outside Y
// TODO continue iteration to one more sorted Y coordinate block
return true;
}
}
IBlockStateContainer bsc = (IBlockStateContainer) extendedblockstorage.getData();
// storageArray uses an optimized algorithm that's faster than getAt
// creating this array and then using getAtPalette is faster than even getFast(int index)
int[] storage = bsc.storageArray();
final int imax = 1 << 12;
for (int i = 0; i < imax; i++) {
IBlockState state = bsc.getAtPalette(storage[i]);
if (filter.has(state)) {
int y = yReal | ((i >> 8) & 15);
if (result.size() >= max) {
if (Math.abs(y - playerY) < yLevelThreshold) {
foundWithinY = true;
} else {
if (foundWithinY) {
// have found within Y in this chunk, so don't need to consider outside Y
// TODO continue iteration to one more sorted Y coordinate block
return true;
}
result.add(new BlockPos(chunkX | x, yy, chunkZ | z));
}
}
result.add(new BlockPos(chunkX | (i & 15), y, chunkZ | ((i >> 4) & 15)));
}
}
}
return foundWithinY;
}
public int repack(IPlayerContext ctx) {
IChunkProvider chunkProvider = ctx.world().getChunkProvider();
ICachedWorld cachedWorld = ctx.worldData().getCachedWorld();
BetterBlockPos playerPos = ctx.playerFeet();
int playerChunkX = playerPos.getX() >> 4;
int playerChunkZ = playerPos.getZ() >> 4;
int queued = 0;
for (int x = playerChunkX - 40; x <= playerChunkX + 40; x++) {
for (int z = playerChunkZ - 40; z <= playerChunkZ + 40; z++) {
Chunk chunk = chunkProvider.getLoadedChunk(x, z);
if (nonNull(chunk) && !chunk.isEmpty()) {
queued++;
cachedWorld.queueForPacking(chunk);
}
}
}
return queued;
}
}

View File

@@ -69,6 +69,16 @@ public final class GameEventHandler implements IEventBus, Helper {
listeners.forEach(l -> l.onSendChatMessage(event));
}
@Override
public void onPreTabComplete(TabCompleteEvent.Pre event) {
listeners.forEach(l -> l.onPreTabComplete(event));
}
@Override
public void onPostTabComplete(TabCompleteEvent.Post event) {
listeners.forEach(l -> l.onPostTabComplete(event));
}
@Override
public final void onChunkEvent(ChunkEvent event) {
EventState state = event.getState();

View File

@@ -177,7 +177,7 @@ public interface MovementHelper extends ActionCosts, Helper {
return block.isPassable(null, null);
}
static boolean isReplacable(int x, int y, int z, IBlockState state, BlockStateInterface bsi) {
static boolean isReplaceable(int x, int y, int z, IBlockState state, BlockStateInterface bsi) {
// for MovementTraverse and MovementAscend
// block double plant defaults to true when the block doesn't match, so don't need to check that case
// all other overrides just return true or false
@@ -207,6 +207,11 @@ public interface MovementHelper extends ActionCosts, Helper {
return state.getMaterial().isReplaceable();
}
@Deprecated
static boolean isReplacable(int x, int y, int z, IBlockState state, BlockStateInterface bsi) {
return isReplaceable(x, y, z, state, bsi);
}
static boolean isDoorPassable(IPlayerContext ctx, BlockPos doorPos, BlockPos playerPos) {
if (playerPos.equals(doorPos)) {
return false;

View File

@@ -73,7 +73,7 @@ public class MovementAscend extends Movement {
if (additionalPlacementCost >= COST_INF) {
return COST_INF;
}
if (!MovementHelper.isReplacable(destX, y, destZ, toPlace, context.bsi)) {
if (!MovementHelper.isReplaceable(destX, y, destZ, toPlace, context.bsi)) {
return COST_INF;
}
boolean foundPlaceOption = false;

View File

@@ -152,7 +152,7 @@ public class MovementParkour extends Movement {
return;
}
IBlockState toReplace = context.get(destX, y - 1, destZ);
if (!MovementHelper.isReplacable(destX, y - 1, destZ, toReplace, context.bsi)) {
if (!MovementHelper.isReplaceable(destX, y - 1, destZ, toReplace, context.bsi)) {
return;
}
if (!checkOvershootSafety(context.bsi, destX + xDiff, y, destZ + zDiff)) {

View File

@@ -111,7 +111,7 @@ public class MovementTraverse extends Movement {
if (srcDown == Blocks.LADDER || srcDown == Blocks.VINE) {
return COST_INF;
}
if (MovementHelper.isReplacable(destX, y - 1, destZ, destOn, context.bsi)) {
if (MovementHelper.isReplaceable(destX, y - 1, destZ, destOn, context.bsi)) {
boolean throughWater = MovementHelper.isWater(pb0.getBlock()) || MovementHelper.isWater(pb1.getBlock());
if (MovementHelper.isWater(destOn.getBlock()) && throughWater) {
// this happens when assume walk on water is true and this is a traverse in water, which isn't allowed

View File

@@ -33,7 +33,7 @@ import baritone.pathing.movement.MovementHelper;
import baritone.utils.BaritoneProcessHelper;
import baritone.utils.BlockStateInterface;
import baritone.utils.PathingCommandContext;
import baritone.utils.schematic.AirSchematic;
import baritone.utils.schematic.FillSchematic;
import baritone.utils.schematic.MapArtSchematic;
import baritone.utils.schematic.Schematic;
import baritone.utils.schematic.schematica.SchematicaHelper;
@@ -58,7 +58,6 @@ import java.util.*;
import static baritone.api.pathing.movement.ActionCosts.COST_INF;
public final class BuilderProcess extends BaritoneProcessHelper implements IBuilderProcess {
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;
@@ -68,6 +67,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
private int ticks;
private boolean paused;
private int layer;
private List<IBlockState> approxPlaceable;
public BuilderProcess(Baritone baritone) {
super(baritone);
@@ -104,6 +104,11 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
paused = true;
}
@Override
public boolean isPaused() {
return paused;
}
@Override
public boolean build(String name, File schematic, Vec3i origin) {
NBTTagCompound tag;
@@ -113,6 +118,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
e.printStackTrace();
return false;
}
//noinspection ConstantConditions
if (tag == null) {
return false;
}
@@ -139,7 +145,12 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
int widthX = Math.abs(corner1.getX() - corner2.getX()) + 1;
int heightY = Math.abs(corner1.getY() - corner2.getY()) + 1;
int lengthZ = Math.abs(corner1.getZ() - corner2.getZ()) + 1;
build("clear area", new AirSchematic(widthX, heightY, lengthZ), origin);
build("clear area", new FillSchematic(widthX, heightY, lengthZ, Blocks.AIR.getDefaultState()), origin);
}
@Override
public List<IBlockState> getApproxPlaceable() {
return new ArrayList<>(approxPlaceable);
}
private static ISchematic parse(NBTTagCompound schematic) {
@@ -151,14 +162,14 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
return schematic != null;
}
public IBlockState placeAt(int x, int y, int z) {
public IBlockState placeAt(int x, int y, int z, IBlockState current) {
if (!isActive()) {
return null;
}
if (!schematic.inSchematic(x - origin.getX(), y - origin.getY(), z - origin.getZ())) {
if (!schematic.inSchematic(x - origin.getX(), y - origin.getY(), z - origin.getZ(), current)) {
return null;
}
IBlockState state = schematic.desiredState(x - origin.getX(), y - origin.getY(), z - origin.getZ());
IBlockState state = schematic.desiredState(x - origin.getX(), y - origin.getY(), z - origin.getZ(), current, this.approxPlaceable);
if (state.getBlock() == Blocks.AIR) {
return null;
}
@@ -177,7 +188,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
if (dy == -1 && x == pathStart.x && z == pathStart.z) {
continue; // dont mine what we're supported by, but not directly standing on
}
IBlockState desired = bcc.getSchematic(x, y, z);
IBlockState desired = bcc.getSchematic(x, y, z, bcc.bsi.get0(x, y, z));
if (desired == null) {
continue; // irrelevant
}
@@ -195,7 +206,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
return Optional.empty();
}
public class Placement {
public static class Placement {
private final int hotbarSelection;
private final BlockPos placeAgainst;
private final EnumFacing side;
@@ -209,7 +220,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
}
}
private Optional<Placement> searchForPlacables(BuilderCalculationContext bcc, List<IBlockState> desirableOnHotbar) {
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++) {
@@ -217,12 +228,12 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
int x = center.x + dx;
int y = center.y + dy;
int z = center.z + dz;
IBlockState desired = bcc.getSchematic(x, y, z);
IBlockState desired = bcc.getSchematic(x, y, z, bcc.bsi.get0(x, y, z));
if (desired == null) {
continue; // irrelevant
}
IBlockState curr = bcc.bsi.get0(x, y, z);
if (MovementHelper.isReplacable(x, y, z, curr, bcc.bsi) && !valid(curr, desired)) {
if (MovementHelper.isReplaceable(x, y, z, curr, bcc.bsi) && !valid(curr, desired)) {
if (dy == 1 && bcc.bsi.get0(x, y + 1, z).getBlock() == Blocks.AIR) {
continue;
}
@@ -242,7 +253,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
for (EnumFacing against : EnumFacing.values()) {
BetterBlockPos placeAgainstPos = new BetterBlockPos(x, y, z).offset(against);
IBlockState placeAgainstState = bsi.get0(placeAgainstPos);
if (MovementHelper.isReplacable(placeAgainstPos.x, placeAgainstPos.y, placeAgainstPos.z, placeAgainstState, bsi)) {
if (MovementHelper.isReplaceable(placeAgainstPos.x, placeAgainstPos.y, placeAgainstPos.z, placeAgainstState, bsi)) {
continue;
}
if (!ctx.world().mayPlace(toPlace.getBlock(), new BetterBlockPos(x, y, z), false, against, null)) {
@@ -316,6 +327,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
@Override
public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) {
approxPlaceable = approxPlaceable(36);
if (baritone.getInputOverrideHandler().isInputForcedDown(Input.CLICK_LEFT)) {
ticks = 5;
} else {
@@ -343,13 +355,13 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
}
schematic = new ISchematic() {
@Override
public IBlockState desiredState(int x, int y, int z) {
return realSchematic.desiredState(x, y, z);
public IBlockState desiredState(int x, int y, int z, IBlockState current, List<IBlockState> approxPlaceable) {
return realSchematic.desiredState(x, y, z, current, BuilderProcess.this.approxPlaceable);
}
@Override
public boolean inSchematic(int x, int y, int z) {
return ISchematic.super.inSchematic(x, y, z) && y >= minYInclusive && y <= maxYInclusive;
public boolean inSchematic(int x, int y, int z, IBlockState currentState) {
return ISchematic.super.inSchematic(x, y, z, currentState) && y >= minYInclusive && y <= maxYInclusive;
}
@Override
@@ -411,7 +423,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL);
}
List<IBlockState> desirableOnHotbar = new ArrayList<>();
Optional<Placement> toPlace = searchForPlacables(bcc, desirableOnHotbar);
Optional<Placement> toPlace = searchForPlaceables(bcc, desirableOnHotbar);
if (toPlace.isPresent() && isSafeToCancel && ctx.player().onGround && ticks <= 0) {
Rotation rot = toPlace.get().rot;
baritone.getLookBehavior().updateTarget(rot, true);
@@ -423,14 +435,13 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL);
}
List<IBlockState> approxPlacable = placable(36);
if (Baritone.settings().allowInventory.value) {
ArrayList<Integer> usefulSlots = new ArrayList<>();
List<IBlockState> noValidHotbarOption = new ArrayList<>();
outer:
for (IBlockState desired : desirableOnHotbar) {
for (int i = 0; i < 9; i++) {
if (valid(approxPlacable.get(i), desired)) {
if (valid(approxPlaceable.get(i), desired)) {
usefulSlots.add(i);
continue outer;
}
@@ -441,7 +452,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
outer:
for (int i = 9; i < 36; i++) {
for (IBlockState desired : noValidHotbarOption) {
if (valid(approxPlacable.get(i), desired)) {
if (valid(approxPlaceable.get(i), desired)) {
baritone.getInventoryBehavior().attemptToPutOnHotbar(i, usefulSlots::contains);
break outer;
}
@@ -449,9 +460,9 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
}
}
Goal goal = assemble(bcc, approxPlacable.subList(0, 9));
Goal goal = assemble(bcc, approxPlaceable.subList(0, 9));
if (goal == null) {
goal = assemble(bcc, approxPlacable); // we're far away, so assume that we have our whole inventory to recalculate placable properly
goal = assemble(bcc, approxPlaceable); // we're far away, so assume that we have our whole inventory to recalculate placeable properly
if (goal == null) {
logDirect("Unable to do it. Pausing. resume to resume, cancel to cancel");
paused = true;
@@ -493,7 +504,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
int x = center.x + dx;
int y = center.y + dy;
int z = center.z + dz;
IBlockState desired = bcc.getSchematic(x, y, z);
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);
@@ -515,15 +526,16 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
for (int y = 0; y < schematic.heightY(); y++) {
for (int z = 0; z < schematic.lengthZ(); z++) {
for (int x = 0; x < schematic.widthX(); x++) {
if (!schematic.inSchematic(x, y, z)) {
continue;
}
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)) { // check if its in render distance, not if its in cache
// we can directly observe this block, it is in render distance
if (valid(bcc.bsi.get0(blockX, blockY, blockZ), schematic.desiredState(x, y, z))) {
if (valid(bcc.bsi.get0(blockX, blockY, blockZ), schematic.desiredState(x, y, z, current, this.approxPlaceable))) {
observedCompleted.add(BetterBlockPos.longHash(blockX, blockY, blockZ));
} else {
incorrectPositions.add(new BetterBlockPos(blockX, blockY, blockZ));
@@ -548,15 +560,15 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
}
}
private Goal assemble(BuilderCalculationContext bcc, List<IBlockState> approxPlacable) {
List<BetterBlockPos> placable = new ArrayList<>();
private Goal assemble(BuilderCalculationContext bcc, List<IBlockState> approxPlaceable) {
List<BetterBlockPos> placeable = new ArrayList<>();
List<BetterBlockPos> breakable = new ArrayList<>();
List<BetterBlockPos> 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);
if (approxPlaceable.contains(bcc.getSchematic(pos.x, pos.y, pos.z, state))) {
placeable.add(pos);
}
} else {
if (state.getBlock() instanceof BlockLiquid) {
@@ -574,8 +586,8 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
List<Goal> toBreak = new ArrayList<>();
breakable.forEach(pos -> toBreak.add(breakGoal(pos, bcc)));
List<Goal> toPlace = new ArrayList<>();
placable.forEach(pos -> {
if (!placable.contains(pos.down()) && !placable.contains(pos.down(2))) {
placeable.forEach(pos -> {
if (!placeable.contains(pos.down()) && !placeable.contains(pos.down(2))) {
toPlace.add(placementGoal(pos, bcc));
}
});
@@ -638,8 +650,10 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
return new GoalPlace(pos);
}
boolean allowSameLevel = ctx.world().getBlockState(pos.up()).getBlock() != Blocks.AIR;
IBlockState current = ctx.world().getBlockState(pos);
for (EnumFacing facing : Movement.HORIZONTALS_BUT_ALSO_DOWN_____SO_EVERY_DIRECTION_EXCEPT_UP) {
if (MovementHelper.canPlaceAgainst(ctx, pos.offset(facing)) && ctx.world().mayPlace(bcc.getSchematic(pos.getX(), pos.getY(), pos.getZ()).getBlock(), pos, false, facing, null)) {
//noinspection ConstantConditions
if (MovementHelper.canPlaceAgainst(ctx, pos.offset(facing)) && ctx.world().mayPlace(bcc.getSchematic(pos.getX(), pos.getY(), pos.getZ(), current).getBlock(), pos, false, facing, null)) {
return new GoalAdjacent(pos, pos.offset(facing), allowSameLevel);
}
}
@@ -720,7 +734,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
return paused ? "Builder Paused" : "Building " + name;
}
private List<IBlockState> placable(int size) {
private List<IBlockState> approxPlaceable(int size) {
List<IBlockState> result = new ArrayList<>();
for (int i = 0; i < size; i++) {
ItemStack stack = ctx.player().inventory.mainInventory.get(i);
@@ -744,7 +758,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
}
public class BuilderCalculationContext extends CalculationContext {
private final List<IBlockState> placable;
private final List<IBlockState> placeable;
private final ISchematic schematic;
private final int originX;
private final int originY;
@@ -752,7 +766,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
public BuilderCalculationContext() {
super(BuilderProcess.this.baritone, true); // wew lad
this.placable = placable(9);
this.placeable = approxPlaceable(9);
this.schematic = BuilderProcess.this.schematic;
this.originX = origin.getX();
this.originY = origin.getY();
@@ -762,9 +776,9 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
this.backtrackCostFavoringCoefficient = 1;
}
private IBlockState getSchematic(int x, int y, int z) {
if (schematic.inSchematic(x - originX, y - originY, z - originZ)) {
return schematic.desiredState(x - originX, y - originY, z - originZ);
private IBlockState getSchematic(int x, int y, int z, IBlockState current) {
if (schematic.inSchematic(x - originX, y - originY, z - originZ, current)) {
return schematic.desiredState(x - originX, y - originY, z - originZ, current, BuilderProcess.this.approxPlaceable);
} else {
return null;
}
@@ -775,7 +789,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
if (isPossiblyProtected(x, y, z) || !worldBorder.canPlaceAt(x, z)) { // make calculation fail properly if we can't build
return COST_INF;
}
IBlockState sch = getSchematic(x, y, z);
IBlockState sch = getSchematic(x, y, z, bsi.get0(x, y, z));
if (sch != null) {
// TODO this can return true even when allowPlace is off.... is that an issue?
if (sch.getBlock() == Blocks.AIR) {
@@ -783,7 +797,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
// this won't be a schematic block, this will be a throwaway
return placeBlockCost * 2; // we're going to have to break it eventually
}
if (placable.contains(sch)) {
if (placeable.contains(sch)) {
return 0; // thats right we gonna make it FREE to place a block where it should go in a structure
// no place block penalty at all 😎
// i'm such an idiot that i just tried to copy and paste the epic gamer moment emoji too
@@ -809,7 +823,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
if (!allowBreak || isPossiblyProtected(x, y, z)) {
return COST_INF;
}
IBlockState sch = getSchematic(x, y, z);
IBlockState sch = getSchematic(x, y, z, bsi.get0(x, y, z));
if (sch != null) {
if (sch.getBlock() == Blocks.AIR) {
// it should be air

View File

@@ -87,7 +87,7 @@ public final class FollowProcess extends BaritoneProcessHelper implements IFollo
.filter(this::followable)
.filter(this.filter)
.distinct()
.collect(Collectors.toCollection(ArrayList::new));
.collect(Collectors.toList());
}
@Override

View File

@@ -22,6 +22,7 @@ import baritone.api.pathing.goals.*;
import baritone.api.process.IGetToBlockProcess;
import baritone.api.process.PathingCommand;
import baritone.api.process.PathingCommandType;
import baritone.api.utils.BlockOptionalMetaLookup;
import baritone.api.utils.Rotation;
import baritone.api.utils.RotationUtils;
import baritone.api.utils.input.Input;
@@ -171,7 +172,7 @@ public final class GetToBlockProcess extends BaritoneProcessHelper implements IG
}
private synchronized void rescan(List<BlockPos> known, CalculationContext context) {
List<BlockPos> positions = MineProcess.searchWorld(context, Collections.singletonList(gettingTo), 64, known, blacklist);
List<BlockPos> positions = MineProcess.searchWorld(context, new BlockOptionalMetaLookup(gettingTo), 64, known, blacklist);
positions.removeIf(blacklist::contains);
knownLocations = positions;
}

View File

@@ -22,10 +22,7 @@ import baritone.api.pathing.goals.*;
import baritone.api.process.IMineProcess;
import baritone.api.process.PathingCommand;
import baritone.api.process.PathingCommandType;
import baritone.api.utils.BlockUtils;
import baritone.api.utils.IPlayerContext;
import baritone.api.utils.Rotation;
import baritone.api.utils.RotationUtils;
import baritone.api.utils.*;
import baritone.api.utils.input.Input;
import baritone.cache.CachedChunk;
import baritone.cache.WorldScanner;
@@ -40,7 +37,6 @@ import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.init.Blocks;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
@@ -56,10 +52,9 @@ import static baritone.api.pathing.movement.ActionCosts.COST_INF;
* @author leijurv
*/
public final class MineProcess extends BaritoneProcessHelper implements IMineProcess {
private static final int ORE_LOCATIONS_COUNT = 64;
private List<Block> mining;
private BlockOptionalMetaLookup filter;
private List<BlockPos> knownOreLocations;
private List<BlockPos> blacklist; // inaccessible
private BlockPos branchPoint;
@@ -73,28 +68,29 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
@Override
public boolean isActive() {
return mining != null;
return filter != null;
}
@Override
public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) {
if (desiredQuantity > 0) {
Item item = mining.get(0).getItemDropped(mining.get(0).getDefaultState(), new Random(), 0);
int curr = ctx.player().inventory.mainInventory.stream().filter(stack -> item.equals(stack.getItem())).mapToInt(ItemStack::getCount).sum();
System.out.println("Currently have " + curr + " " + item);
int curr = ctx.player().inventory.mainInventory.stream()
.filter(stack -> filter.has(stack))
.mapToInt(ItemStack::getCount).sum();
System.out.println("Currently have " + curr + " valid items");
if (curr >= desiredQuantity) {
logDirect("Have " + curr + " " + item.getItemStackDisplayName(new ItemStack(item, 1)));
logDirect("Have " + curr + " valid items");
cancel();
return null;
}
}
if (calcFailed) {
if (!knownOreLocations.isEmpty() && Baritone.settings().blacklistClosestOnFailure.value) {
logDirect("Unable to find any path to " + mining + ", blacklisting presumably unreachable closest instance...");
logDirect("Unable to find any path to " + filter + ", blacklisting presumably unreachable closest instance...");
knownOreLocations.stream().min(Comparator.comparingDouble(ctx.player()::getDistanceSq)).ifPresent(blacklist::add);
knownOreLocations.removeIf(blacklist::contains);
} else {
logDirect("Unable to find any path to " + mining + ", canceling Mine");
logDirect("Unable to find any path to " + filter + ", canceling mine");
cancel();
return null;
}
@@ -146,19 +142,19 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
@Override
public void onLostControl() {
mine(0, (Block[]) null);
mine(0, (BlockOptionalMetaLookup) null);
}
@Override
public String displayName0() {
return "Mine " + mining;
return "Mine " + filter;
}
private PathingCommand updateGoal() {
boolean legit = Baritone.settings().legitMine.value;
List<BlockPos> locs = knownOreLocations;
if (!locs.isEmpty()) {
List<BlockPos> locs2 = prune(new CalculationContext(baritone), new ArrayList<>(locs), mining, ORE_LOCATIONS_COUNT, blacklist);
List<BlockPos> locs2 = prune(new CalculationContext(baritone), new ArrayList<>(locs), filter, ORE_LOCATIONS_COUNT, blacklist);
// can't reassign locs, gotta make a new var locs2, because we use it in a lambda right here, and variables you use in a lambda must be effectively final
Goal goal = new GoalComposite(locs2.stream().map(loc -> coalesce(loc, locs2)).toArray(Goal[]::new));
knownOreLocations = locs2;
@@ -194,16 +190,16 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
}
private void rescan(List<BlockPos> already, CalculationContext context) {
if (mining == null) {
if (filter == null) {
return;
}
if (Baritone.settings().legitMine.value) {
return;
}
List<BlockPos> locs = searchWorld(context, mining, ORE_LOCATIONS_COUNT, already, blacklist);
locs.addAll(droppedItemsScan(mining, ctx.world()));
List<BlockPos> locs = searchWorld(context, filter, ORE_LOCATIONS_COUNT, already, blacklist);
locs.addAll(droppedItemsScan(filter, ctx.world()));
if (locs.isEmpty()) {
logDirect("No locations for " + mining + " known, cancelling");
logDirect("No locations for " + filter + " known, cancelling");
cancel();
return;
}
@@ -215,11 +211,11 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
if (locs.contains(pos)) {
return true;
}
Block block = BlockStateInterface.getBlock(ctx, pos);
if (Baritone.settings().internalMiningAirException.value && block instanceof BlockAir) {
IBlockState state = BlockStateInterface.get(ctx, pos);
if (Baritone.settings().internalMiningAirException.value && state.getBlock() instanceof BlockAir) {
return true;
}
return mining.contains(block);
return filter.has(state);
}
private Goal coalesce(BlockPos loc, List<BlockPos> locs) {
@@ -284,22 +280,15 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
}
}
public static List<BlockPos> droppedItemsScan(List<Block> mining, World world) {
public static List<BlockPos> droppedItemsScan(BlockOptionalMetaLookup filter, World world) {
if (!Baritone.settings().mineScanDroppedItems.value) {
return Collections.emptyList();
}
Set<Item> searchingFor = new HashSet<>();
for (Block block : mining) {
Item drop = block.getItemDropped(block.getDefaultState(), new Random(), 0);
Item ore = Item.getItemFromBlock(block);
searchingFor.add(drop);
searchingFor.add(ore);
}
List<BlockPos> ret = new ArrayList<>();
for (Entity entity : world.loadedEntityList) {
if (entity instanceof EntityItem) {
EntityItem ei = (EntityItem) entity;
if (searchingFor.contains(ei.getItem().getItem())) {
if (filter.has(ei.getItem())) {
ret.add(new BlockPos(entity));
}
}
@@ -307,30 +296,46 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
return ret;
}
public static List<BlockPos> searchWorld(CalculationContext ctx, List<Block> mining, int max, List<BlockPos> alreadyKnown, List<BlockPos> blacklist) {
public static List<BlockPos> searchWorld(CalculationContext ctx, BlockOptionalMetaLookup filter, int max, List<BlockPos> alreadyKnown, List<BlockPos> blacklist) {
List<BlockPos> locs = new ArrayList<>();
List<Block> uninteresting = new ArrayList<>();
for (Block m : mining) {
if (CachedChunk.BLOCKS_TO_KEEP_TRACK_OF.contains(m)) {
List<Block> untracked = new ArrayList<>();
for (BlockOptionalMeta bom : filter.blocks()) {
Block block = bom.getBlock();
if (CachedChunk.BLOCKS_TO_KEEP_TRACK_OF.contains(block)) {
BetterBlockPos pf = ctx.baritone.getPlayerContext().playerFeet();
// maxRegionDistanceSq 2 means adjacent directly or adjacent diagonally; nothing further than that
locs.addAll(ctx.worldData.getCachedWorld().getLocationsOf(BlockUtils.blockToString(m), Baritone.settings().maxCachedWorldScanCount.value, ctx.getBaritone().getPlayerContext().playerFeet().getX(), ctx.getBaritone().getPlayerContext().playerFeet().getZ(), 2));
locs.addAll(ctx.worldData.getCachedWorld().getLocationsOf(
BlockUtils.blockToString(block),
Baritone.settings().maxCachedWorldScanCount.value,
pf.x,
pf.z,
2
));
} else {
uninteresting.add(m);
untracked.add(block);
}
}
locs = prune(ctx, locs, mining, max, blacklist);
if (locs.isEmpty() || (Baritone.settings().extendCacheOnThreshold.value && locs.size() < max)) {
uninteresting = mining;
}
if (!uninteresting.isEmpty()) {
locs.addAll(WorldScanner.INSTANCE.scanChunkRadius(ctx.getBaritone().getPlayerContext(), uninteresting, max, 10, 32)); // maxSearchRadius is NOT sq
locs = prune(ctx, locs, filter, max, blacklist);
if (!untracked.isEmpty() || (Baritone.settings().extendCacheOnThreshold.value && locs.size() < max)) {
locs.addAll(WorldScanner.INSTANCE.scanChunkRadius(
ctx.getBaritone().getPlayerContext(),
filter,
max,
10,
32
)); // maxSearchRadius is NOT sq
}
locs.addAll(alreadyKnown);
return prune(ctx, locs, mining, max, blacklist);
return prune(ctx, locs, filter, max, blacklist);
}
private void addNearby() {
knownOreLocations.addAll(droppedItemsScan(mining, ctx.world()));
knownOreLocations.addAll(droppedItemsScan(filter, ctx.world()));
BlockPos playerFeet = ctx.playerFeet();
BlockStateInterface bsi = new BlockStateInterface(ctx);
int searchDist = 10;
@@ -340,7 +345,7 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
for (int z = playerFeet.getZ() - searchDist; z <= playerFeet.getZ() + searchDist; z++) {
// crucial to only add blocks we can see because otherwise this
// is an x-ray and it'll get caught
if (mining.contains(bsi.get0(x, y, z).getBlock())) {
if (filter.has(bsi.get0(x, y, z))) {
BlockPos pos = new BlockPos(x, y, z);
if ((Baritone.settings().legitMineIncludeDiagonals.value && knownOreLocations.stream().anyMatch(ore -> ore.distanceSq(pos) <= 2 /* sq means this is pytha dist <= sqrt(2) */)) || RotationUtils.reachable(ctx.player(), pos, fakedBlockReachDistance).isPresent()) {
knownOreLocations.add(pos);
@@ -349,14 +354,14 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
}
}
}
knownOreLocations = prune(new CalculationContext(baritone), knownOreLocations, mining, ORE_LOCATIONS_COUNT, blacklist);
knownOreLocations = prune(new CalculationContext(baritone), knownOreLocations, filter, ORE_LOCATIONS_COUNT, blacklist);
}
private static List<BlockPos> prune(CalculationContext ctx, List<BlockPos> locs2, List<Block> mining, int max, List<BlockPos> blacklist) {
List<BlockPos> dropped = droppedItemsScan(mining, ctx.world);
private static List<BlockPos> prune(CalculationContext ctx, List<BlockPos> locs2, BlockOptionalMetaLookup filter, int max, List<BlockPos> blacklist) {
List<BlockPos> dropped = droppedItemsScan(filter, ctx.world);
dropped.removeIf(drop -> {
for (BlockPos pos : locs2) {
if (pos.distanceSq(drop) <= 9 && mining.contains(ctx.getBlock(pos.getX(), pos.getY(), pos.getZ())) && MineProcess.plausibleToBreak(ctx, pos)) { // TODO maybe drop also has to be supported? no lava below?
if (pos.distanceSq(drop) <= 9 && filter.has(ctx.get(pos.getX(), pos.getY(), pos.getZ())) && MineProcess.plausibleToBreak(ctx, pos)) { // TODO maybe drop also has to be supported? no lava below?
return true;
}
}
@@ -367,7 +372,7 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
.distinct()
// remove any that are within loaded chunks that aren't actually what we want
.filter(pos -> !ctx.bsi.worldContainsLoadedChunk(pos.getX(), pos.getZ()) || mining.contains(ctx.getBlock(pos.getX(), pos.getY(), pos.getZ())) || dropped.contains(pos))
.filter(pos -> !ctx.bsi.worldContainsLoadedChunk(pos.getX(), pos.getZ()) || filter.has(ctx.get(pos.getX(), pos.getY(), pos.getZ())) || dropped.contains(pos))
// remove any that are implausible to mine (encased in bedrock, or touching lava)
.filter(pos -> MineProcess.plausibleToBreak(ctx, pos))
@@ -394,22 +399,22 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
@Override
public void mineByName(int quantity, String... blocks) {
mine(quantity, blocks == null || blocks.length == 0 ? null : Arrays.stream(blocks).map(BlockUtils::stringToBlockRequired).toArray(Block[]::new));
mine(quantity, new BlockOptionalMetaLookup(blocks));
}
@Override
public void mine(int quantity, Block... blocks) {
this.mining = blocks == null || blocks.length == 0 ? null : Arrays.asList(blocks);
if (mining != null && !Baritone.settings().allowBreak.value) {
public void mine(int quantity, BlockOptionalMetaLookup filter) {
this.filter = filter;
if (filter != null && !Baritone.settings().allowBreak.value) {
logDirect("Unable to mine when allowBreak is false!");
mining = null;
filter = null;
}
this.desiredQuantity = quantity;
this.knownOreLocations = new ArrayList<>();
this.blacklist = new ArrayList<>();
this.branchPoint = null;
this.branchPointRunaway = null;
if (mining != null) {
if (filter != null) {
rescan(new ArrayList<>(), new CalculationContext(baritone));
}
}

View File

@@ -0,0 +1,129 @@
package baritone.selection;
import baritone.api.selection.ISelection;
import baritone.api.utils.BetterBlockPos;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.Vec3i;
public class Selection implements ISelection {
private final BetterBlockPos pos1;
private final BetterBlockPos pos2;
private final BetterBlockPos min;
private final BetterBlockPos max;
private final Vec3i size;
private final AxisAlignedBB aabb;
public Selection(BetterBlockPos pos1, BetterBlockPos pos2) {
this.pos1 = pos1;
this.pos2 = pos2;
this.min = new BetterBlockPos(
Math.min(pos1.x, pos2.x),
Math.min(pos1.y, pos2.y),
Math.min(pos1.z, pos2.z)
);
this.max = new BetterBlockPos(
Math.max(pos1.x, pos2.x),
Math.max(pos1.y, pos2.y),
Math.max(pos1.z, pos2.z)
);
this.size = new Vec3i(
max.x - min.x + 1,
max.y - min.y + 1,
max.z - min.z + 1
);
this.aabb = new AxisAlignedBB(this.min, this.max.add(1, 1, 1));
}
@Override
public BetterBlockPos pos1() {
return pos1;
}
@Override
public BetterBlockPos pos2() {
return pos2;
}
@Override
public BetterBlockPos min() {
return min;
}
@Override
public BetterBlockPos max() {
return max;
}
@Override
public Vec3i size() {
return size;
}
@Override
public AxisAlignedBB aabb() {
return aabb;
}
@Override
public int hashCode() {
return pos1.hashCode() ^ pos2.hashCode();
}
@Override
public String toString() {
return String.format("Selection{pos1=%s,pos2=%s}", pos1, pos2);
}
/**
* Since it might not be immediately obvious what this does, let me explain.
*
* Let's say you specify EnumFacing.UP, this functions returns if pos2 is the highest BlockPos.
* If you specify EnumFacing.DOWN, it returns if pos2 is the lowest BlockPos.
*
* @param facing The direction to check.
* @return {@code true} if pos2 is further in that direction than pos1, {@code false} if it isn't, and something
* else if they're both at the same position on that axis (it really doesn't matter)
*/
private boolean isPos2(EnumFacing facing) {
boolean negative = facing.getAxisDirection().getOffset() < 0;
switch (facing.getAxis()) {
case X:
return (pos2.x > pos1.x) ^ negative;
case Y:
return (pos2.y > pos1.y) ^ negative;
case Z:
return (pos2.z > pos1.z) ^ negative;
default:
throw new IllegalStateException("Bad EnumFacing.Axis");
}
}
@Override
public ISelection expand(EnumFacing direction, int blocks) {
if (isPos2(direction)) {
return new Selection(pos1, pos2.offset(direction, blocks));
} else {
return new Selection(pos1.offset(direction, blocks), pos2);
}
}
@Override
public ISelection contract(EnumFacing direction, int blocks) {
if (isPos2(direction)) {
return new Selection(pos1.offset(direction, blocks), pos2);
} else {
return new Selection(pos1, pos2.offset(direction, blocks));
}
}
@Override
public ISelection shift(EnumFacing direction, int blocks) {
return new Selection(pos1.offset(direction, blocks), pos2.offset(direction, blocks));
}
}

View File

@@ -0,0 +1,116 @@
package baritone.selection;
import baritone.api.selection.ISelection;
import baritone.api.selection.ISelectionManager;
import baritone.api.utils.BetterBlockPos;
import net.minecraft.util.EnumFacing;
import java.util.LinkedList;
import java.util.ListIterator;
public class SelectionManager implements ISelectionManager {
private final LinkedList<ISelection> selections = new LinkedList<>();
private ISelection[] selectionsArr = new ISelection[0];
public SelectionManager() {
new SelectionRenderer(this);
}
private void resetSelectionsArr() {
selectionsArr = selections.toArray(new ISelection[0]);
}
@Override
public synchronized ISelection addSelection(ISelection selection) {
selections.add(selection);
resetSelectionsArr();
return selection;
}
@Override
public ISelection addSelection(BetterBlockPos pos1, BetterBlockPos pos2) {
return addSelection(new Selection(pos1, pos2));
}
@Override
public synchronized ISelection removeSelection(ISelection selection) {
selections.remove(selection);
resetSelectionsArr();
return selection;
}
@Override
public synchronized ISelection[] removeAllSelections() {
ISelection[] selectionsArr = getSelections();
selections.clear();
resetSelectionsArr();
return selectionsArr;
}
@Override
public ISelection[] getSelections() {
return selectionsArr;
}
@Override
public synchronized ISelection getOnlySelection() {
if (selections.size() == 1) {
return selections.peekFirst();
}
return null;
}
@Override
public ISelection getLastSelection() {
return selections.peekLast();
}
@Override
public synchronized ISelection expand(ISelection selection, EnumFacing direction, int blocks) {
for (ListIterator<ISelection> it = selections.listIterator(); it.hasNext(); ) {
ISelection current = it.next();
if (current == selection) {
it.remove();
it.add(current.expand(direction, blocks));
resetSelectionsArr();
return it.previous();
}
}
return null;
}
@Override
public synchronized ISelection contract(ISelection selection, EnumFacing direction, int blocks) {
for (ListIterator<ISelection> it = selections.listIterator(); it.hasNext(); ) {
ISelection current = it.next();
if (current == selection) {
it.remove();
it.add(current.contract(direction, blocks));
resetSelectionsArr();
return it.previous();
}
}
return null;
}
@Override
public synchronized ISelection shift(ISelection selection, EnumFacing direction, int blocks) {
for (ListIterator<ISelection> it = selections.listIterator(); it.hasNext(); ) {
ISelection current = it.next();
if (current == selection) {
it.remove();
it.add(current.shift(direction, blocks));
resetSelectionsArr();
return it.previous();
}
}
return null;
}
}

View File

@@ -0,0 +1,55 @@
package baritone.selection;
import baritone.api.event.events.RenderEvent;
import baritone.api.event.listener.AbstractGameEventListener;
import baritone.api.selection.ISelection;
import baritone.utils.IRenderer;
import net.minecraft.util.math.AxisAlignedBB;
public class SelectionRenderer implements IRenderer, AbstractGameEventListener {
public static final double SELECTION_BOX_EXPANSION = .005D;
private final SelectionManager manager;
SelectionRenderer(SelectionManager manager) {
this.manager = manager;
baritone.getGameEventHandler().registerEventListener(this);
}
public static void renderSelections(ISelection[] selections) {
float opacity = settings.selectionOpacity.value;
boolean ignoreDepth = settings.renderSelectionIgnoreDepth.value;
float lineWidth = settings.selectionLineWidth.value;
if (!settings.renderSelection.value) {
return;
}
IRenderer.startLines(settings.colorSelection.value, opacity, lineWidth, ignoreDepth);
for (ISelection selection : selections) {
IRenderer.drawAABB(selection.aabb(), SELECTION_BOX_EXPANSION);
}
if (settings.renderSelectionCorners.value) {
IRenderer.glColor(settings.colorSelectionPos1.value, opacity);
for (ISelection selection : selections) {
IRenderer.drawAABB(new AxisAlignedBB(selection.pos1(), selection.pos1().add(1, 1, 1)));
}
IRenderer.glColor(settings.colorSelectionPos2.value, opacity);
for (ISelection selection : selections) {
IRenderer.drawAABB(new AxisAlignedBB(selection.pos2(), selection.pos2().add(1, 1, 1)));
}
}
IRenderer.endLines(ignoreDepth);
}
@Override
public void onRenderPass(RenderEvent event) {
renderSelections(manager.getSelections());
}
}

View File

@@ -110,7 +110,7 @@ public class GuiClick extends GuiScreen {
GlStateManager.disableDepth();
BetterBlockPos a = new BetterBlockPos(currentMouseOver);
BetterBlockPos b = new BetterBlockPos(clickStart);
PathRenderer.drawAABB(new AxisAlignedBB(Math.min(a.x, b.x), Math.min(a.y, b.y), Math.min(a.z, b.z), Math.max(a.x, b.x) + 1, Math.max(a.y, b.y) + 1, Math.max(a.z, b.z) + 1));
IRenderer.drawAABB(new AxisAlignedBB(Math.min(a.x, b.x), Math.min(a.y, b.y), Math.min(a.z, b.z), Math.max(a.x, b.x) + 1, Math.max(a.y, b.y) + 1, Math.max(a.z, b.z) + 1));
GlStateManager.enableDepth();
GlStateManager.depthMask(true);

View File

@@ -0,0 +1,113 @@
/*
* 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;
import baritone.api.BaritoneAPI;
import baritone.api.IBaritone;
import baritone.api.Settings;
import baritone.api.utils.Helper;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.util.math.AxisAlignedBB;
import java.awt.Color;
import static org.lwjgl.opengl.GL11.*;
public interface IRenderer {
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer();
RenderManager renderManager = Helper.mc.getRenderManager();
IBaritone baritone = BaritoneAPI.getProvider().getPrimaryBaritone();
Settings settings = BaritoneAPI.getSettings();
static void glColor(Color color, float alpha) {
float[] colorComponents = color.getColorComponents(null);
GlStateManager.color(colorComponents[0], colorComponents[1], colorComponents[2], alpha);
}
static void startLines(Color color, float alpha, float lineWidth, boolean ignoreDepth) {
GlStateManager.enableBlend();
GlStateManager.disableLighting();
GlStateManager.tryBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
glColor(color, alpha);
GlStateManager.glLineWidth(lineWidth);
GlStateManager.disableTexture2D();
GlStateManager.depthMask(false);
if (ignoreDepth) {
GlStateManager.disableDepth();
}
}
static void startLines(Color color, float lineWidth, boolean ignoreDepth) {
startLines(color, .4f, lineWidth, ignoreDepth);
}
static void endLines(boolean ignoredDepth) {
if (ignoredDepth) {
GlStateManager.enableDepth();
}
GlStateManager.depthMask(true);
GlStateManager.enableTexture2D();
GlStateManager.enableLighting();
GlStateManager.disableBlend();
}
static void drawAABB(AxisAlignedBB aabb) {
AxisAlignedBB toDraw = aabb.offset(-renderManager.viewerPosX, -renderManager.viewerPosY, -renderManager.viewerPosZ);
buffer.begin(GL_LINES, DefaultVertexFormats.POSITION);
// bottom
buffer.pos(toDraw.minX, toDraw.minY, toDraw.minZ).endVertex();
buffer.pos(toDraw.maxX, toDraw.minY, toDraw.minZ).endVertex();
buffer.pos(toDraw.maxX, toDraw.minY, toDraw.minZ).endVertex();
buffer.pos(toDraw.maxX, toDraw.minY, toDraw.maxZ).endVertex();
buffer.pos(toDraw.maxX, toDraw.minY, toDraw.maxZ).endVertex();
buffer.pos(toDraw.minX, toDraw.minY, toDraw.maxZ).endVertex();
buffer.pos(toDraw.minX, toDraw.minY, toDraw.maxZ).endVertex();
buffer.pos(toDraw.minX, toDraw.minY, toDraw.minZ).endVertex();
// top
buffer.pos(toDraw.minX, toDraw.maxY, toDraw.minZ).endVertex();
buffer.pos(toDraw.maxX, toDraw.maxY, toDraw.minZ).endVertex();
buffer.pos(toDraw.maxX, toDraw.maxY, toDraw.minZ).endVertex();
buffer.pos(toDraw.maxX, toDraw.maxY, toDraw.maxZ).endVertex();
buffer.pos(toDraw.maxX, toDraw.maxY, toDraw.maxZ).endVertex();
buffer.pos(toDraw.minX, toDraw.maxY, toDraw.maxZ).endVertex();
buffer.pos(toDraw.minX, toDraw.maxY, toDraw.maxZ).endVertex();
buffer.pos(toDraw.minX, toDraw.maxY, toDraw.minZ).endVertex();
// corners
buffer.pos(toDraw.minX, toDraw.minY, toDraw.minZ).endVertex();
buffer.pos(toDraw.minX, toDraw.maxY, toDraw.minZ).endVertex();
buffer.pos(toDraw.maxX, toDraw.minY, toDraw.minZ).endVertex();
buffer.pos(toDraw.maxX, toDraw.maxY, toDraw.minZ).endVertex();
buffer.pos(toDraw.maxX, toDraw.minY, toDraw.maxZ).endVertex();
buffer.pos(toDraw.maxX, toDraw.maxY, toDraw.maxZ).endVertex();
buffer.pos(toDraw.minX, toDraw.minY, toDraw.maxZ).endVertex();
buffer.pos(toDraw.minX, toDraw.maxY, toDraw.maxZ).endVertex();
tessellator.draw();
}
static void drawAABB(AxisAlignedBB aabb, double expand) {
drawAABB(aabb.grow(expand, expand, expand));
}
}

View File

@@ -17,7 +17,6 @@
package baritone.utils;
import baritone.Baritone;
import baritone.api.BaritoneAPI;
import baritone.api.event.events.RenderEvent;
import baritone.api.pathing.calc.IPath;
@@ -28,9 +27,7 @@ import baritone.api.utils.interfaces.IGoalRenderPos;
import baritone.behavior.PathingBehavior;
import baritone.pathing.path.PathExecutor;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.tileentity.TileEntityBeaconRenderer;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.entity.Entity;
@@ -39,7 +36,7 @@ import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import java.awt.*;
import java.awt.Color;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@@ -50,18 +47,14 @@ import static org.lwjgl.opengl.GL11.*;
* @author Brady
* @since 8/9/2018
*/
public final class PathRenderer implements Helper {
private static final Tessellator TESSELLATOR = Tessellator.getInstance();
private static final BufferBuilder BUFFER = TESSELLATOR.getBuffer();
public final class PathRenderer implements IRenderer {
private PathRenderer() {}
public static void render(RenderEvent event, PathingBehavior behavior) {
float partialTicks = event.getPartialTicks();
Goal goal = behavior.getGoal();
if (mc.currentScreen instanceof GuiClick) {
((GuiClick) mc.currentScreen).onRender();
if (Helper.mc.currentScreen instanceof GuiClick) {
((GuiClick) Helper.mc.currentScreen).onRender();
}
int thisPlayerDimension = behavior.baritone.getPlayerContext().world().provider.getDimensionType().getId();
@@ -72,7 +65,7 @@ public final class PathRenderer implements Helper {
return;
}
Entity renderView = mc.getRenderViewEntity();
Entity renderView = Helper.mc.getRenderViewEntity();
if (renderView.world != BaritoneAPI.getProvider().getPrimaryBaritone().getPlayerContext().world()) {
System.out.println("I have no idea what's going on");
@@ -81,19 +74,20 @@ public final class PathRenderer implements Helper {
return;
}
if (goal != null && Baritone.settings().renderGoal.value) {
drawDankLitGoalBox(renderView, goal, partialTicks, Baritone.settings().colorGoalBox.value);
if (goal != null && settings.renderGoal.value) {
drawDankLitGoalBox(renderView, goal, partialTicks, settings.colorGoalBox.value);
}
if (!Baritone.settings().renderPath.value) {
if (!settings.renderPath.value) {
return;
}
PathExecutor current = behavior.getCurrent(); // this should prevent most race conditions?
PathExecutor next = behavior.getNext(); // like, now it's not possible for current!=null to be true, then suddenly false because of another thread
if (current != null && Baritone.settings().renderSelectionBoxes.value) {
drawManySelectionBoxes(renderView, current.toBreak(), Baritone.settings().colorBlocksToBreak.value);
drawManySelectionBoxes(renderView, current.toPlace(), Baritone.settings().colorBlocksToPlace.value);
drawManySelectionBoxes(renderView, current.toWalkInto(), Baritone.settings().colorBlocksToWalkInto.value);
if (current != null && settings.renderSelectionBoxes.value) {
drawManySelectionBoxes(renderView, current.toBreak(), settings.colorBlocksToBreak.value);
drawManySelectionBoxes(renderView, current.toPlace(), settings.colorBlocksToPlace.value);
drawManySelectionBoxes(renderView, current.toWalkInto(), settings.colorBlocksToWalkInto.value);
}
//drawManySelectionBoxes(player, Collections.singletonList(behavior.pathStart()), partialTicks, Color.WHITE);
@@ -101,63 +95,51 @@ public final class PathRenderer implements Helper {
// Render the current path, if there is one
if (current != null && current.getPath() != null) {
int renderBegin = Math.max(current.getPosition() - 3, 0);
drawPath(current.getPath(), renderBegin, renderView, partialTicks, Baritone.settings().colorCurrentPath.value, Baritone.settings().fadePath.value, 10, 20);
drawPath(current.getPath(), renderBegin, settings.colorCurrentPath.value, settings.fadePath.value, 10, 20);
}
if (next != null && next.getPath() != null) {
drawPath(next.getPath(), 0, renderView, partialTicks, Baritone.settings().colorNextPath.value, Baritone.settings().fadePath.value, 10, 20);
drawPath(next.getPath(), 0, settings.colorNextPath.value, settings.fadePath.value, 10, 20);
}
// If there is a path calculation currently running, render the path calculation process
behavior.getInProgress().ifPresent(currentlyRunning -> {
currentlyRunning.bestPathSoFar().ifPresent(p -> {
drawPath(p, 0, renderView, partialTicks, Baritone.settings().colorBestPathSoFar.value, Baritone.settings().fadePath.value, 10, 20);
drawPath(p, 0, settings.colorBestPathSoFar.value, settings.fadePath.value, 10, 20);
});
currentlyRunning.pathToMostRecentNodeConsidered().ifPresent(mr -> {
drawPath(mr, 0, renderView, partialTicks, Baritone.settings().colorMostRecentConsidered.value, Baritone.settings().fadePath.value, 10, 20);
drawManySelectionBoxes(renderView, Collections.singletonList(mr.getDest()), Baritone.settings().colorMostRecentConsidered.value);
currentlyRunning.pathToMostRecentNodeConsidered().ifPresent(mr -> {
drawPath(mr, 0, settings.colorMostRecentConsidered.value, settings.fadePath.value, 10, 20);
drawManySelectionBoxes(renderView, Collections.singletonList(mr.getDest()), settings.colorMostRecentConsidered.value);
});
});
}
public static void drawPath(IPath path, int startIndex, Entity player, float partialTicks, Color color, boolean fadeOut, int fadeStart0, int fadeEnd0) {
GlStateManager.enableBlend();
GlStateManager.disableLighting();
GlStateManager.tryBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
GlStateManager.color(color.getColorComponents(null)[0], color.getColorComponents(null)[1], color.getColorComponents(null)[2], 0.4F);
GlStateManager.glLineWidth(Baritone.settings().pathRenderLineWidthPixels.value);
GlStateManager.disableTexture2D();
GlStateManager.depthMask(false);
if (Baritone.settings().renderPathIgnoreDepth.value) {
GlStateManager.disableDepth();
}
List<BetterBlockPos> positions = path.positions();
int next;
Tessellator tessellator = Tessellator.getInstance();
public static void drawPath(IPath path, int startIndex, Color color, boolean fadeOut, int fadeStart0, int fadeEnd0) {
IRenderer.startLines(color, settings.pathRenderLineWidthPixels.value, settings.renderPathIgnoreDepth.value);
int fadeStart = fadeStart0 + startIndex;
int fadeEnd = fadeEnd0 + startIndex;
for (int i = startIndex; i < positions.size() - 1; i = next) {
BetterBlockPos start = positions.get(i);
next = i + 1;
BetterBlockPos end = positions.get(next);
List<BetterBlockPos> positions = path.positions();
for (int i = startIndex, next; i < positions.size() - 1; i = next) {
BetterBlockPos start = positions.get(i);
BetterBlockPos end = positions.get(next = i + 1);
int dirX = end.x - start.x;
int dirY = end.y - start.y;
int dirZ = end.z - start.z;
while (next + 1 < positions.size() && (!fadeOut || next + 1 < fadeStart) && (dirX == positions.get(next + 1).x - end.x && dirY == positions.get(next + 1).y - end.y && dirZ == positions.get(next + 1).z - end.z)) {
next++;
end = positions.get(next);
}
double x1 = start.x;
double y1 = start.y;
double z1 = start.z;
double x2 = end.x;
double y2 = end.y;
double z2 = end.z;
if (fadeOut) {
while (next + 1 < positions.size() && (!fadeOut || next + 1 < fadeStart) &&
(dirX == positions.get(next + 1).x - end.x &&
dirY == positions.get(next + 1).y - end.y &&
dirZ == positions.get(next + 1).z - end.z)) {
end = positions.get(++next);
}
if (fadeOut) {
float alpha;
if (i <= fadeStart) {
alpha = 0.4F;
} else {
@@ -166,109 +148,65 @@ public final class PathRenderer implements Helper {
}
alpha = 0.4F * (1.0F - (float) (i - fadeStart) / (float) (fadeEnd - fadeStart));
}
GlStateManager.color(color.getColorComponents(null)[0], color.getColorComponents(null)[1], color.getColorComponents(null)[2], alpha);
IRenderer.glColor(color, alpha);
}
drawLine(x1, y1, z1, x2, y2, z2);
drawLine(start.x, start.y, start.z, end.x, end.y, end.z);
tessellator.draw();
}
if (Baritone.settings().renderPathIgnoreDepth.value) {
GlStateManager.enableDepth();
}
//GlStateManager.color(0.0f, 0.0f, 0.0f, 0.4f);
GlStateManager.depthMask(true);
GlStateManager.enableTexture2D();
GlStateManager.enableLighting();
GlStateManager.disableBlend();
IRenderer.endLines(settings.renderPathIgnoreDepth.value);
}
public static void drawLine(double bp1x, double bp1y, double bp1z, double bp2x, double bp2y, double bp2z) {
double d0 = mc.getRenderManager().viewerPosX;
double d1 = mc.getRenderManager().viewerPosY;
double d2 = mc.getRenderManager().viewerPosZ;
BUFFER.begin(GL_LINE_STRIP, DefaultVertexFormats.POSITION);
BUFFER.pos(bp1x + 0.5D - d0, bp1y + 0.5D - d1, bp1z + 0.5D - d2).endVertex();
BUFFER.pos(bp2x + 0.5D - d0, bp2y + 0.5D - d1, bp2z + 0.5D - d2).endVertex();
BUFFER.pos(bp2x + 0.5D - d0, bp2y + 0.53D - d1, bp2z + 0.5D - d2).endVertex();
BUFFER.pos(bp1x + 0.5D - d0, bp1y + 0.53D - d1, bp1z + 0.5D - d2).endVertex();
BUFFER.pos(bp1x + 0.5D - d0, bp1y + 0.5D - d1, bp1z + 0.5D - d2).endVertex();
public static void drawLine(double x1, double y1, double z1, double x2, double y2, double z2) {
double vpX = renderManager.viewerPosX;
double vpY = renderManager.viewerPosY;
double vpZ = renderManager.viewerPosZ;
boolean renderPathAsFrickinThingy = !settings.renderPathAsLine.value;
buffer.begin(renderPathAsFrickinThingy ? GL_LINE_STRIP : GL_LINES, DefaultVertexFormats.POSITION);
buffer.pos(x1 + 0.5D - vpX, y1 + 0.5D - vpY, z1 + 0.5D - vpZ).endVertex();
buffer.pos(x2 + 0.5D - vpX, y2 + 0.5D - vpY, z2 + 0.5D - vpZ).endVertex();
if (renderPathAsFrickinThingy) {
buffer.pos(x2 + 0.5D - vpX, y2 + 0.53D - vpY, z2 + 0.5D - vpZ).endVertex();
buffer.pos(x1 + 0.5D - vpX, y1 + 0.53D - vpY, z1 + 0.5D - vpZ).endVertex();
buffer.pos(x1 + 0.5D - vpX, y1 + 0.5D - vpY, z1 + 0.5D - vpZ).endVertex();
}
}
public static void drawManySelectionBoxes(Entity player, Collection<BlockPos> positions, Color color) {
GlStateManager.enableBlend();
GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0);
GlStateManager.color(color.getColorComponents(null)[0], color.getColorComponents(null)[1], color.getColorComponents(null)[2], 0.4F);
GlStateManager.glLineWidth(Baritone.settings().pathRenderLineWidthPixels.value);
GlStateManager.disableTexture2D();
GlStateManager.depthMask(false);
if (Baritone.settings().renderSelectionBoxesIgnoreDepth.value) {
GlStateManager.disableDepth();
}
IRenderer.startLines(color, settings.pathRenderLineWidthPixels.value, settings.renderSelectionBoxesIgnoreDepth.value);
//BlockPos blockpos = movingObjectPositionIn.getBlockPos();
BlockStateInterface bsi = new BlockStateInterface(BaritoneAPI.getProvider().getPrimaryBaritone().getPlayerContext()); // TODO this assumes same dimension between primary baritone and render view? is this safe?
positions.forEach(pos -> {
IBlockState state = bsi.get0(pos);
AxisAlignedBB toDraw;
if (state.getBlock().equals(Blocks.AIR)) {
toDraw = Blocks.DIRT.getDefaultState().getSelectedBoundingBox(player.world, pos);
} else {
toDraw = state.getSelectedBoundingBox(player.world, pos);
}
drawAABB(toDraw);
IRenderer.drawAABB(toDraw, .002D);
});
if (Baritone.settings().renderSelectionBoxesIgnoreDepth.value) {
GlStateManager.enableDepth();
}
GlStateManager.depthMask(true);
GlStateManager.enableTexture2D();
GlStateManager.disableBlend();
}
public static void drawAABB(AxisAlignedBB aabb) {
float expand = 0.002F;
AxisAlignedBB toDraw = aabb.expand(expand, expand, expand).offset(-mc.getRenderManager().viewerPosX, -mc.getRenderManager().viewerPosY, -mc.getRenderManager().viewerPosZ);
BUFFER.begin(GL_LINE_STRIP, DefaultVertexFormats.POSITION);
BUFFER.pos(toDraw.minX, toDraw.minY, toDraw.minZ).endVertex();
BUFFER.pos(toDraw.maxX, toDraw.minY, toDraw.minZ).endVertex();
BUFFER.pos(toDraw.maxX, toDraw.minY, toDraw.maxZ).endVertex();
BUFFER.pos(toDraw.minX, toDraw.minY, toDraw.maxZ).endVertex();
BUFFER.pos(toDraw.minX, toDraw.minY, toDraw.minZ).endVertex();
TESSELLATOR.draw();
BUFFER.begin(GL_LINE_STRIP, DefaultVertexFormats.POSITION);
BUFFER.pos(toDraw.minX, toDraw.maxY, toDraw.minZ).endVertex();
BUFFER.pos(toDraw.maxX, toDraw.maxY, toDraw.minZ).endVertex();
BUFFER.pos(toDraw.maxX, toDraw.maxY, toDraw.maxZ).endVertex();
BUFFER.pos(toDraw.minX, toDraw.maxY, toDraw.maxZ).endVertex();
BUFFER.pos(toDraw.minX, toDraw.maxY, toDraw.minZ).endVertex();
TESSELLATOR.draw();
BUFFER.begin(GL_LINES, DefaultVertexFormats.POSITION);
BUFFER.pos(toDraw.minX, toDraw.minY, toDraw.minZ).endVertex();
BUFFER.pos(toDraw.minX, toDraw.maxY, toDraw.minZ).endVertex();
BUFFER.pos(toDraw.maxX, toDraw.minY, toDraw.minZ).endVertex();
BUFFER.pos(toDraw.maxX, toDraw.maxY, toDraw.minZ).endVertex();
BUFFER.pos(toDraw.maxX, toDraw.minY, toDraw.maxZ).endVertex();
BUFFER.pos(toDraw.maxX, toDraw.maxY, toDraw.maxZ).endVertex();
BUFFER.pos(toDraw.minX, toDraw.minY, toDraw.maxZ).endVertex();
BUFFER.pos(toDraw.minX, toDraw.maxY, toDraw.maxZ).endVertex();
TESSELLATOR.draw();
IRenderer.endLines(settings.renderSelectionBoxesIgnoreDepth.value);
}
public static void drawDankLitGoalBox(Entity player, Goal goal, float partialTicks, Color color) {
double renderPosX = mc.getRenderManager().viewerPosX;
double renderPosY = mc.getRenderManager().viewerPosY;
double renderPosZ = mc.getRenderManager().viewerPosZ;
double minX;
double maxX;
double minZ;
double maxZ;
double minY;
double maxY;
double y1;
double y2;
double renderPosX = renderManager.viewerPosX;
double renderPosY = renderManager.viewerPosY;
double renderPosZ = renderManager.viewerPosZ;
double minX, maxX;
double minZ, maxZ;
double minY, maxY;
double y1, y2;
double y = MathHelper.cos((float) (((float) ((System.nanoTime() / 100000L) % 20000L)) / 20000F * Math.PI * 2));
if (goal instanceof IGoalRenderPos) {
BlockPos goalPos = ((IGoalRenderPos) goal).getGoalPos();
@@ -291,12 +229,12 @@ public final class PathRenderer implements Helper {
} else if (goal instanceof GoalXZ) {
GoalXZ goalPos = (GoalXZ) goal;
if (Baritone.settings().renderGoalXZBeacon.value) {
if (settings.renderGoalXZBeacon.value) {
glPushAttrib(GL_LIGHTING_BIT);
mc.getTextureManager().bindTexture(TileEntityBeaconRenderer.TEXTURE_BEACON_BEAM);
Helper.mc.getTextureManager().bindTexture(TileEntityBeaconRenderer.TEXTURE_BEACON_BEAM);
if (Baritone.settings().renderGoalIgnoreDepth.value) {
if (settings.renderGoalIgnoreDepth.value) {
GlStateManager.disableDepth();
}
@@ -312,7 +250,7 @@ public final class PathRenderer implements Helper {
color.getColorComponents(null)
);
if (Baritone.settings().renderGoalIgnoreDepth.value) {
if (settings.renderGoalIgnoreDepth.value) {
GlStateManager.enableDepth();
}
@@ -334,12 +272,15 @@ public final class PathRenderer implements Helper {
drawDankLitGoalBox(player, g, partialTicks, color);
}
return;
} else if (goal instanceof GoalInverted) {
drawDankLitGoalBox(player, ((GoalInverted) goal).origin, partialTicks, settings.colorInvertedGoalBox.value);
return;
} else if (goal instanceof GoalYLevel) {
GoalYLevel goalpos = (GoalYLevel) goal;
minX = player.posX - Baritone.settings().yLevelBoxSize.value - renderPosX;
minZ = player.posZ - Baritone.settings().yLevelBoxSize.value - renderPosZ;
maxX = player.posX + Baritone.settings().yLevelBoxSize.value - renderPosX;
maxZ = player.posZ + Baritone.settings().yLevelBoxSize.value - renderPosZ;
minX = player.posX - settings.yLevelBoxSize.value - renderPosX;
minZ = player.posZ - settings.yLevelBoxSize.value - renderPosZ;
maxX = player.posX + settings.yLevelBoxSize.value - renderPosX;
maxZ = player.posZ + settings.yLevelBoxSize.value - renderPosZ;
minY = ((GoalYLevel) goal).level - renderPosY;
maxY = minY + 2;
y1 = 1 + y + goalpos.level - renderPosY;
@@ -348,46 +289,33 @@ public final class PathRenderer implements Helper {
return;
}
GlStateManager.enableBlend();
GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0);
GlStateManager.color(color.getColorComponents(null)[0], color.getColorComponents(null)[1], color.getColorComponents(null)[2], 0.6F);
GlStateManager.glLineWidth(Baritone.settings().goalRenderLineWidthPixels.value);
GlStateManager.disableTexture2D();
GlStateManager.depthMask(false);
if (Baritone.settings().renderGoalIgnoreDepth.value) {
GlStateManager.disableDepth();
}
IRenderer.startLines(color, settings.goalRenderLineWidthPixels.value, settings.renderGoalIgnoreDepth.value);
renderHorizontalQuad(minX, maxX, minZ, maxZ, y1);
renderHorizontalQuad(minX, maxX, minZ, maxZ, y2);
BUFFER.begin(GL_LINES, DefaultVertexFormats.POSITION);
BUFFER.pos(minX, minY, minZ).endVertex();
BUFFER.pos(minX, maxY, minZ).endVertex();
BUFFER.pos(maxX, minY, minZ).endVertex();
BUFFER.pos(maxX, maxY, minZ).endVertex();
BUFFER.pos(maxX, minY, maxZ).endVertex();
BUFFER.pos(maxX, maxY, maxZ).endVertex();
BUFFER.pos(minX, minY, maxZ).endVertex();
BUFFER.pos(minX, maxY, maxZ).endVertex();
TESSELLATOR.draw();
buffer.begin(GL_LINES, DefaultVertexFormats.POSITION);
buffer.pos(minX, minY, minZ).endVertex();
buffer.pos(minX, maxY, minZ).endVertex();
buffer.pos(maxX, minY, minZ).endVertex();
buffer.pos(maxX, maxY, minZ).endVertex();
buffer.pos(maxX, minY, maxZ).endVertex();
buffer.pos(maxX, maxY, maxZ).endVertex();
buffer.pos(minX, minY, maxZ).endVertex();
buffer.pos(minX, maxY, maxZ).endVertex();
tessellator.draw();
if (Baritone.settings().renderGoalIgnoreDepth.value) {
GlStateManager.enableDepth();
}
GlStateManager.depthMask(true);
GlStateManager.enableTexture2D();
GlStateManager.disableBlend();
IRenderer.endLines(settings.renderGoalIgnoreDepth.value);
}
private static void renderHorizontalQuad(double minX, double maxX, double minZ, double maxZ, double y) {
if (y != 0) {
BUFFER.begin(GL_LINE_LOOP, DefaultVertexFormats.POSITION);
BUFFER.pos(minX, y, minZ).endVertex();
BUFFER.pos(maxX, y, minZ).endVertex();
BUFFER.pos(maxX, y, maxZ).endVertex();
BUFFER.pos(minX, y, maxZ).endVertex();
TESSELLATOR.draw();
buffer.begin(GL_LINE_LOOP, DefaultVertexFormats.POSITION);
buffer.pos(minX, y, minZ).endVertex();
buffer.pos(maxX, y, minZ).endVertex();
buffer.pos(maxX, y, maxZ).endVertex();
buffer.pos(minX, y, maxZ).endVertex();
tessellator.draw();
}
}
}

View File

@@ -0,0 +1,7 @@
package baritone.utils.accessor;
public interface IBitArray {
int getAtFast(int index);
int[] toArray();
}

View File

@@ -0,0 +1,17 @@
package baritone.utils.accessor;
import net.minecraft.block.state.IBlockState;
import net.minecraft.util.BitArray;
import net.minecraft.world.chunk.IBlockStatePalette;
public interface IBlockStateContainer {
IBlockStatePalette getPalette();
BitArray getStorage();
IBlockState getFast(int index);
IBlockState getAtPalette(int index);
int[] storageArray();
}

View File

@@ -0,0 +1,9 @@
package baritone.utils.accessor;
public interface ITabCompleter {
String getPrefix();
void setPrefix(String prefix);
boolean onGuiChatSetCompletions(String[] newCompl);
}

View File

@@ -0,0 +1,63 @@
/*
* 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.command.defaults;
import baritone.api.Settings;
import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.goals.GoalAxis;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import java.util.List;
import java.util.stream.Stream;
import static java.util.Arrays.asList;
public class AxisCommand extends Command {
public AxisCommand() {
super(asList("axis", "highway"));
}
@Override
protected void executed(String label, ArgConsumer args, Settings settings) {
args.requireMax(0);
Goal goal = new GoalAxis();
baritone.getCustomGoalProcess().setGoal(goal);
logDirect(String.format("Goal: %s", goal.toString()));
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args, Settings settings) {
return Stream.empty();
}
@Override
public String getShortDesc() {
return "Set a goal to the axes";
}
@Override
public List<String> getLongDesc() {
return asList(
"The axis command sets a goal that tells Baritone to head towards the nearest axis. That is, X=0 or Z=0.",
"",
"Usage:",
"> axis"
);
}
}

View File

@@ -0,0 +1,71 @@
/*
* 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.command.defaults;
import baritone.api.Settings;
import baritone.api.process.IGetToBlockProcess;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.exception.CommandInvalidStateException;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import java.util.List;
import java.util.stream.Stream;
import static java.util.Arrays.asList;
public class BlacklistCommand extends Command {
public BlacklistCommand() {
super("blacklist");
}
@Override
protected void executed(String label, ArgConsumer args, Settings settings) {
args.requireMax(0);
IGetToBlockProcess proc = baritone.getGetToBlockProcess();
if (!proc.isActive()) {
throw new CommandInvalidStateException("GetToBlockProcess is not currently active");
}
if (proc.blacklistClosest()) {
logDirect("Blacklisted closest instances");
} else {
throw new CommandInvalidStateException("No known locations, unable to blacklist");
}
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args, Settings settings) {
return Stream.empty();
}
@Override
public String getShortDesc() {
return "Blacklist closest block";
}
@Override
public List<String> getLongDesc() {
return asList(
"While, for example, mining, this command blacklists the closest block so that Baritone won't attempt to get to it.",
"",
"Usage:",
"> blacklist"
);
}
}

View File

@@ -0,0 +1,99 @@
/*
* 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.command.defaults;
import baritone.api.Settings;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.datatypes.RelativeBlockPos;
import baritone.api.utils.command.datatypes.RelativeFile;
import baritone.api.utils.command.exception.CommandInvalidStateException;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import net.minecraft.client.Minecraft;
import java.io.File;
import java.util.List;
import java.util.Locale;
import java.util.stream.Stream;
import static java.util.Arrays.asList;
public class BuildCommand extends Command {
private static final File schematicsDir = new File(Minecraft.getMinecraft().gameDir, "schematics");
public BuildCommand() {
super("build");
}
@Override
protected void executed(String label, ArgConsumer args, Settings settings) {
File file = args.getDatatypePost(RelativeFile.class, schematicsDir).getAbsoluteFile();
if (!file.getName().toLowerCase(Locale.US).endsWith(".schematic")) {
file = new File(file.getAbsolutePath() + ".schematic");
}
BetterBlockPos origin = ctx.playerFeet();
BetterBlockPos buildOrigin;
if (args.has()) {
args.requireMax(3);
buildOrigin = args.getDatatype(RelativeBlockPos.class).apply(origin);
} else {
args.requireMax(0);
buildOrigin = origin;
}
boolean success = baritone.getBuilderProcess().build(file.getName(), file, buildOrigin);
if (!success) {
throw new CommandInvalidStateException("Couldn't load the schematic");
}
logDirect(String.format("Successfully loaded schematic for building\nOrigin: %s", buildOrigin));
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args, Settings settings) {
if (args.hasExactlyOne()) {
return RelativeFile.tabComplete(args, schematicsDir);
} else if (args.has(2)) {
args.get();
return args.tabCompleteDatatype(RelativeBlockPos.class);
}
return Stream.empty();
}
@Override
public String getShortDesc() {
return "Build a schematic";
}
@Override
public List<String> getLongDesc() {
return asList(
"Build a schematic from a file.",
"",
"Usage:",
"> build <filename> - Loads and builds '<filename>.schematic'",
"> build <filename> <x> <y> <z> - Custom position"
);
}
}

View File

@@ -0,0 +1,60 @@
/*
* 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.command.defaults;
import baritone.api.Settings;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import java.util.List;
import java.util.stream.Stream;
import static java.util.Arrays.asList;
public class CancelCommand extends Command {
public CancelCommand() {
super(asList("cancel", "stop"));
}
@Override
protected void executed(String label, ArgConsumer args, Settings settings) {
args.requireMax(0);
baritone.getPathingBehavior().cancelEverything();
logDirect("ok canceled");
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args, Settings settings) {
return Stream.empty();
}
@Override
public String getShortDesc() {
return "Cancel what Baritone is currently doing";
}
@Override
public List<String> getLongDesc() {
return asList(
"The cancel command tells Baritons to stop whatever it's currently doing.",
"",
"Usage:",
"> cancel"
);
}
}

View File

@@ -0,0 +1,86 @@
/*
* 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.command.defaults;
import baritone.api.Settings;
import baritone.api.cache.IRememberedInventory;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.exception.CommandInvalidStateException;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.ITextComponent;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Stream;
import static java.util.Arrays.asList;
public class ChestsCommand extends Command {
public ChestsCommand() {
super("chests");
}
@Override
protected void executed(String label, ArgConsumer args, Settings settings) {
args.requireMax(0);
Set<Map.Entry<BlockPos, IRememberedInventory>> entries =
ctx.worldData().getContainerMemory().getRememberedInventories().entrySet();
if (entries.isEmpty()) {
throw new CommandInvalidStateException("No remembered inventories");
}
for (Map.Entry<BlockPos, IRememberedInventory> entry : entries) {
// betterblockpos has censoring
BetterBlockPos pos = new BetterBlockPos(entry.getKey());
IRememberedInventory inv = entry.getValue();
logDirect(pos.toString());
for (ItemStack item : inv.getContents()) {
ITextComponent component = item.getTextComponent();
component.appendText(String.format(" x %d", item.getCount()));
logDirect(component);
}
}
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args, Settings settings) {
return Stream.empty();
}
@Override
public String getShortDesc() {
return "Display remembered inventories";
}
@Override
public List<String> getLongDesc() {
return asList(
"The chests command lists remembered inventories, I guess?",
"",
"Usage:",
"> chests"
);
}
}

View File

@@ -0,0 +1,83 @@
/*
* 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.command.defaults;
import baritone.api.Settings;
import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.goals.GoalBlock;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.datatypes.RelativeBlockPos;
import baritone.api.utils.command.exception.CommandInvalidStateException;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import java.util.List;
import java.util.stream.Stream;
import static java.util.Arrays.asList;
public class ClearareaCommand extends Command {
public ClearareaCommand() {
super("cleararea");
}
@Override
protected void executed(String label, ArgConsumer args, Settings settings) {
BetterBlockPos pos1 = ctx.playerFeet();
BetterBlockPos pos2;
if (args.has()) {
args.requireMax(3);
pos2 = args.getDatatype(RelativeBlockPos.class).apply(pos1);
} else {
args.requireMax(0);
Goal goal = baritone.getCustomGoalProcess().getGoal();
if (!(goal instanceof GoalBlock)) {
throw new CommandInvalidStateException("Goal is not a GoalBlock");
} else {
pos2 = new BetterBlockPos(((GoalBlock) goal).getGoalPos());
}
}
baritone.getBuilderProcess().clearArea(pos1, pos2);
logDirect("Success");
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args, Settings settings) {
return args.tabCompleteDatatype(RelativeBlockPos.class);
}
@Override
public String getShortDesc() {
return "Clear an area of all blocks";
}
@Override
public List<String> getLongDesc() {
return asList(
"Clear an area of all blocks.",
"",
"Usage:",
"> cleararea - Clears the area marked by your current position and the current GoalBlock",
"> cleararea <x> <y> <z> - Custom second corner rather than your goal"
);
}
}

View File

@@ -0,0 +1,60 @@
/*
* 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.command.defaults;
import baritone.api.Settings;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import java.util.List;
import java.util.stream.Stream;
import static java.util.Arrays.asList;
public class ClickCommand extends Command {
public ClickCommand() {
super("click");
}
@Override
protected void executed(String label, ArgConsumer args, Settings settings) {
args.requireMax(0);
baritone.openClick();
logDirect("aight dude");
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args, Settings settings) {
return Stream.empty();
}
@Override
public String getShortDesc() {
return "Open click";
}
@Override
public List<String> getLongDesc() {
return asList(
"Opens click dude",
"",
"Usage:",
"> click"
);
}
}

View File

@@ -0,0 +1,73 @@
/*
* 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.command.defaults;
import baritone.api.Settings;
import baritone.api.pathing.goals.GoalBlock;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.exception.CommandInvalidStateException;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.BlockPos;
import java.util.List;
import java.util.stream.Stream;
import static java.util.Arrays.asList;
import static java.util.Objects.isNull;
public class ComeCommand extends Command {
public ComeCommand() {
super("come");
}
@Override
protected void executed(String label, ArgConsumer args, Settings settings) {
args.requireMax(0);
Entity entity = MC.getRenderViewEntity();
if (isNull(entity)) {
throw new CommandInvalidStateException("render view entity is null");
}
baritone.getCustomGoalProcess().setGoalAndPath(new GoalBlock(new BlockPos(entity)));
logDirect("Coming");
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args, Settings settings) {
return Stream.empty();
}
@Override
public String getShortDesc() {
return "Start heading towards your camera";
}
@Override
public List<String> getLongDesc() {
return asList(
"The come command tells Baritone to head towards your camera.",
"",
"This can be useful in hacked clients where freecam doesn't move your player position.",
"",
"Usage:",
"> come"
);
}
}

View File

@@ -0,0 +1,64 @@
/*
* 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.command.defaults;
import baritone.api.Settings;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import baritone.api.utils.command.manager.CommandManager;
import java.util.Collections;
import java.util.List;
import java.util.stream.Stream;
public class CommandAlias extends Command {
private final String shortDesc;
public final String target;
public CommandAlias(List<String> names, String shortDesc, String target) {
super(names);
this.shortDesc = shortDesc;
this.target = target;
}
public CommandAlias(String name, String shortDesc, String target) {
super(name);
this.shortDesc = shortDesc;
this.target = target;
}
@Override
protected void executed(String label, ArgConsumer args, Settings settings) {
CommandManager.execute(String.format("%s %s", target, args.rawRest()));
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args, Settings settings) {
return CommandManager.tabComplete(String.format("%s %s", target, args.rawRest()));
}
@Override
public String getShortDesc() {
return shortDesc;
}
@Override
public List<String> getLongDesc() {
return Collections.singletonList(String.format("This command is an alias, for: %s ...", target));
}
}

View File

@@ -0,0 +1,69 @@
/*
* 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.command.defaults;
import baritone.api.utils.command.Command;
import java.util.Collections;
import java.util.List;
import static java.util.Arrays.asList;
public class DefaultCommands {
public static final List<Command> COMMANDS = Collections.unmodifiableList(asList(
new HelpCommand(),
new SetCommand(),
new CommandAlias(asList("modified", "mod", "baritone", "modifiedsettings"), "List modified settings", "set modified"),
new CommandAlias("reset", "Reset all settings or just one", "set reset"),
new GoalCommand(),
new PathCommand(),
new ProcCommand(),
new VersionCommand(),
new RepackCommand(),
new BuildCommand(),
new SchematicaCommand(),
new ComeCommand(),
new AxisCommand(),
new CancelCommand(),
new ForceCancelCommand(),
new GcCommand(),
new InvertCommand(),
new ClearareaCommand(),
PauseResumeCommands.pauseCommand,
PauseResumeCommands.resumeCommand,
PauseResumeCommands.pausedCommand,
new TunnelCommand(),
new RenderCommand(),
new FarmCommand(),
new ChestsCommand(),
new FollowCommand(),
new ExploreFilterCommand(),
new ReloadAllCommand(),
new SaveAllCommand(),
new ExploreCommand(),
new BlacklistCommand(),
new FindCommand(),
new MineCommand(),
new ClickCommand(),
new ThisWayCommand(),
new WaypointsCommand(),
new CommandAlias("sethome", "Sets your home waypoint", "waypoints save home"),
new CommandAlias("home", "Set goal to your home waypoint", "waypoints goal home"),
new SelCommand()
));
}

View File

@@ -0,0 +1,58 @@
/*
* 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.command.defaults;
import baritone.api.Settings;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import java.util.List;
import java.util.stream.Stream;
import static java.util.Arrays.asList;
public class EmptyCommand extends Command {
public EmptyCommand() {
super(asList("name1", "name2"));
}
@Override
protected void executed(String label, ArgConsumer args, Settings settings) {
;
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args, Settings settings) {
return Stream.empty();
}
@Override
public String getShortDesc() {
return "Short description";
}
@Override
public List<String> getLongDesc() {
return asList(
"",
"",
"Usage:",
"> "
);
}
}

View File

@@ -0,0 +1,76 @@
/*
* 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.command.defaults;
import baritone.api.Settings;
import baritone.api.pathing.goals.GoalXZ;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.datatypes.RelativeGoalXZ;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import java.util.List;
import java.util.stream.Stream;
import static java.util.Arrays.asList;
public class ExploreCommand extends Command {
public ExploreCommand() {
super("explore");
}
@Override
protected void executed(String label, ArgConsumer args, Settings settings) {
if (args.has()) {
args.requireExactly(2);
} else {
args.requireMax(0);
}
GoalXZ goal = args.has()
? args.getDatatypePost(RelativeGoalXZ.class, ctx.playerFeet())
: new GoalXZ(ctx.playerFeet());
baritone.getExploreProcess().explore(goal.getX(), goal.getZ());
logDirect(String.format("Exploring from %s", goal.toString()));
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args, Settings settings) {
if (args.hasAtMost(2)) {
return args.tabCompleteDatatype(RelativeGoalXZ.class);
}
return Stream.empty();
}
@Override
public String getShortDesc() {
return "Explore things";
}
@Override
public List<String> getLongDesc() {
return asList(
"Tell Baritone to explore randomly. If you used explorefilter before this, it will be applied.",
"",
"Usage:",
"> explore - Explore from your current position.",
"> explore <x> <z> - Explore from the specified X and Z position."
);
}
}

View File

@@ -0,0 +1,94 @@
/*
* 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.command.defaults;
import baritone.api.Settings;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.datatypes.RelativeFile;
import baritone.api.utils.command.exception.CommandInvalidStateException;
import baritone.api.utils.command.exception.CommandInvalidTypeException;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import com.google.gson.JsonSyntaxException;
import java.io.File;
import java.nio.file.NoSuchFileException;
import java.util.List;
import java.util.stream.Stream;
import static java.util.Arrays.asList;
public class ExploreFilterCommand extends Command {
public ExploreFilterCommand() {
super("explorefilter");
}
@Override
protected void executed(String label, ArgConsumer args, Settings settings) {
args.requireMax(2);
File file = args.getDatatypePost(RelativeFile.class, MC.gameDir.getAbsoluteFile().getParentFile());
boolean invert = false;
if (args.has()) {
if (args.getString().equalsIgnoreCase("invert")) {
invert = true;
} else {
throw new CommandInvalidTypeException(args.consumed(), "either \"invert\" or nothing");
}
}
try {
baritone.getExploreProcess().applyJsonFilter(file.toPath().toAbsolutePath(), invert);
} catch (NoSuchFileException e) {
throw new CommandInvalidStateException("File not found");
} catch (JsonSyntaxException e) {
throw new CommandInvalidStateException("Invalid JSON syntax");
} catch (Exception e) {
throw new RuntimeException(e);
}
logDirect(String.format("Explore filter applied. Inverted: %s", Boolean.toString(invert)));
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args, Settings settings) {
if (args.hasExactlyOne()) {
return RelativeFile.tabComplete(args, RelativeFile.gameDir());
}
return Stream.empty();
}
@Override
public String getShortDesc() {
return "Explore chunks from a json";
}
@Override
public List<String> getLongDesc() {
return asList(
"Apply an explore filter before using explore, which tells the explore process which chunks have been explored/not explored.",
"",
"The JSON file will follow this format: [{\"x\":0,\"z\":0},...]",
"",
"If 'invert' is specified, the chunks listed will be considered NOT explored, rather than explored.",
"",
"Usage:",
"> explorefilter <path> [invert] - Load the JSON file referenced by the specified path. If invert is specified, it must be the literal word 'invert'."
);
}
}

View File

@@ -0,0 +1,60 @@
/*
* 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.command.defaults;
import baritone.api.Settings;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import java.util.List;
import java.util.stream.Stream;
import static java.util.Arrays.asList;
public class FarmCommand extends Command {
public FarmCommand() {
super("farm");
}
@Override
protected void executed(String label, ArgConsumer args, Settings settings) {
args.requireMax(0);
baritone.getFarmProcess().farm();
logDirect("Farming");
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args, Settings settings) {
return Stream.empty();
}
@Override
public String getShortDesc() {
return "Farm nearby crops";
}
@Override
public List<String> getLongDesc() {
return asList(
"The farm command starts farming nearby plants. It harvests mature crops and plants new ones.",
"",
"Usage:",
"> farm"
);
}
}

View File

@@ -0,0 +1,82 @@
/*
* 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.command.defaults;
import baritone.api.Settings;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.datatypes.BlockById;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import net.minecraft.block.Block;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
import static java.util.Arrays.asList;
public class FindCommand extends Command {
public FindCommand() {
super("find");
}
@Override
protected void executed(String label, ArgConsumer args, Settings settings) {
List<Block> toFind = new ArrayList<>();
while (args.has()) {
toFind.add(args.getDatatypeFor(BlockById.class));
}
BetterBlockPos origin = ctx.playerFeet();
toFind.stream()
.flatMap(block ->
ctx.worldData().getCachedWorld().getLocationsOf(
Block.REGISTRY.getNameForObject(block).getPath(),
Integer.MAX_VALUE,
origin.x,
origin.y,
4
).stream()
)
.map(BetterBlockPos::new)
.map(BetterBlockPos::toString)
.forEach(this::logDirect);
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args, Settings settings) {
return args.tabCompleteDatatype(BlockById.class);
}
@Override
public String getShortDesc() {
return "Find positions of a certain block";
}
@Override
public List<String> getLongDesc() {
return asList(
"",
"",
"Usage:",
"> "
);
}
}

View File

@@ -0,0 +1,175 @@
/*
* 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.command.defaults;
import baritone.api.Settings;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.datatypes.EntityClassById;
import baritone.api.utils.command.datatypes.IDatatype;
import baritone.api.utils.command.datatypes.IDatatypeFor;
import baritone.api.utils.command.datatypes.PlayerByUsername;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import baritone.api.utils.command.helpers.tabcomplete.TabCompleteHelper;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityList;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.ResourceLocation;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.function.Predicate;
import java.util.stream.Stream;
import static java.util.Arrays.asList;
import static java.util.Objects.isNull;
import static java.util.Objects.nonNull;
public class FollowCommand extends Command {
public FollowCommand() {
super("follow");
}
@Override
protected void executed(String label, ArgConsumer args, Settings settings) {
args.requireMin(1);
FollowGroup group;
FollowList list;
List<Entity> entities = new ArrayList<>();
List<Class<? extends Entity>> classes = new ArrayList<>();
if (args.hasExactlyOne()) {
baritone.getFollowProcess().follow((group = args.getEnum(FollowGroup.class)).filter);
} else {
args.requireMin(2);
group = null;
list = args.getEnum(FollowList.class);
while (args.has()) {
//noinspection unchecked
Object gotten = args.getDatatypeFor(list.datatype);
if (gotten instanceof Class) {
//noinspection unchecked
classes.add((Class<? extends Entity>) gotten);
} else {
entities.add((Entity) gotten);
}
}
baritone.getFollowProcess().follow(
classes.isEmpty()
? entities::contains
: e -> classes.stream().anyMatch(c -> c.isInstance(e))
);
}
if (nonNull(group)) {
logDirect(String.format("Following all %s", group.name().toLowerCase(Locale.US)));
} else {
logDirect("Following these types of entities:");
if (classes.isEmpty()) {
entities.stream()
.map(Entity::toString)
.forEach(this::logDirect);
} else {
classes.stream()
.map(EntityList::getKey)
.map(Objects::requireNonNull)
.map(ResourceLocation::toString)
.forEach(this::logDirect);
}
}
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args, Settings settings) {
if (args.hasExactlyOne()) {
return new TabCompleteHelper()
.append(FollowGroup.class)
.append(FollowList.class)
.filterPrefix(args.getString())
.stream();
} else {
Class<? extends IDatatype> followType;
try {
followType = args.getEnum(FollowList.class).datatype;
} catch (NullPointerException e) {
return Stream.empty();
}
while (args.has(2)) {
if (isNull(args.peekDatatypeOrNull(followType))) {
return Stream.empty();
}
args.get();
}
return args.tabCompleteDatatype(followType);
}
}
@Override
public String getShortDesc() {
return "Follow entity things";
}
@Override
public List<String> getLongDesc() {
return asList(
"The follow command tells Baritone to follow certain kinds of entities.",
"",
"Usage:",
"> follow entities - Follows all entities.",
"> follow entity <entity1> <entity2> <...> - Follow certain entities (for example 'skeleton', 'horse' etc.)",
"> follow players - Follow players",
"> follow player <username1> <username2> <...> - Follow certain players"
);
}
private enum FollowGroup {
ENTITIES(EntityLiving.class::isInstance),
PLAYERS(EntityPlayer.class::isInstance); /* ,
FRIENDLY(entity -> entity.getAttackTarget() != HELPER.mc.player),
HOSTILE(FRIENDLY.filter.negate()); */
final Predicate<Entity> filter;
FollowGroup(Predicate<Entity> filter) {
this.filter = filter;
}
}
private enum FollowList {
ENTITY(EntityClassById.class),
PLAYER(PlayerByUsername.class);
final Class<? extends IDatatypeFor> datatype;
FollowList(Class<? extends IDatatypeFor> datatype) {
this.datatype = datatype;
}
}
}

View File

@@ -0,0 +1,63 @@
/*
* 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.command.defaults;
import baritone.api.Settings;
import baritone.api.behavior.IPathingBehavior;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import java.util.List;
import java.util.stream.Stream;
import static java.util.Arrays.asList;
public class ForceCancelCommand extends Command {
public ForceCancelCommand() {
super("forcecancel");
}
@Override
protected void executed(String label, ArgConsumer args, Settings settings) {
args.requireMax(0);
IPathingBehavior pathingBehavior = baritone.getPathingBehavior();
pathingBehavior.cancelEverything();
pathingBehavior.forceCancel();
logDirect("ok force canceled");
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args, Settings settings) {
return Stream.empty();
}
@Override
public String getShortDesc() {
return "Force cancel";
}
@Override
public List<String> getLongDesc() {
return asList(
"Like cancel, but more forceful.",
"",
"Usage:",
"> forcecancel"
);
}
}

View File

@@ -0,0 +1,62 @@
/*
* 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.command.defaults;
import baritone.api.Settings;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import java.util.List;
import java.util.stream.Stream;
import static java.util.Arrays.asList;
public class GcCommand extends Command {
public GcCommand() {
super("gc");
}
@Override
protected void executed(String label, ArgConsumer args, Settings settings) {
args.requireMax(0);
System.gc();
logDirect("ok called System.gc()");
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args, Settings settings) {
return Stream.empty();
}
@Override
public String getShortDesc() {
return "Call System.gc()";
}
@Override
public List<String> getLongDesc() {
return asList(
"Calls System.gc().",
"",
"Usage:",
"> gc"
);
}
}

View File

@@ -0,0 +1,109 @@
/*
* 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.command.defaults;
import baritone.api.Settings;
import baritone.api.pathing.goals.Goal;
import baritone.api.process.ICustomGoalProcess;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.datatypes.RelativeCoordinate;
import baritone.api.utils.command.datatypes.RelativeGoal;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import baritone.api.utils.command.helpers.tabcomplete.TabCompleteHelper;
import java.util.List;
import java.util.stream.Stream;
import static java.util.Arrays.asList;
import static java.util.Objects.isNull;
import static java.util.Objects.nonNull;
public class GoalCommand extends Command {
public GoalCommand() {
super("goal");
}
@Override
protected void executed(String label, ArgConsumer args, Settings settings) {
ICustomGoalProcess goalProcess = baritone.getCustomGoalProcess();
if (args.has() && asList("reset", "clear", "none").contains(args.peekString())) {
args.requireMax(1);
if (nonNull(goalProcess.getGoal())) {
goalProcess.setGoal(null);
logDirect("Cleared goal");
} else {
logDirect("There was no goal to clear");
}
} else {
args.requireMax(3);
BetterBlockPos origin = baritone.getPlayerContext().playerFeet();
Goal goal = args.getDatatype(RelativeGoal.class).apply(origin);
goalProcess.setGoal(goal);
logDirect(String.format("Goal: %s", goal.toString()));
}
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args, Settings settings) {
TabCompleteHelper helper = new TabCompleteHelper();
if (args.hasExactlyOne()) {
helper.append(Stream.of("reset", "clear", "none", "~"));
} else {
if (args.hasAtMost(3)) {
while (args.has(2)) {
if (isNull(args.peekDatatypeOrNull(RelativeCoordinate.class))) {
break;
}
args.get();
if (!args.has(2)) {
helper.append("~");
}
}
}
}
return helper.filterPrefix(args.getString()).stream();
}
@Override
public String getShortDesc() {
return "Set or clear the goal";
}
@Override
public List<String> getLongDesc() {
return asList(
"The goal command allows you to set or clear Baritone's goal.",
"",
"Wherever a coordinate is expected, you can use ~ just like in regular Minecraft commands. Or, you can just use regular numbers.",
"",
"Usage:",
"> goal - Set the goal to your current position",
"> goal <reset/clear/none> - Erase the goal",
"> goal <y> - Set the goal to a Y level",
"> goal <x> <z> - Set the goal to an X,Z position",
"> goal <x> <y> <z> - Set the goal to an X,Y,Z position"
);
}
}

View File

@@ -0,0 +1,133 @@
/*
* 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.command.defaults;
import baritone.api.Settings;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.exception.CommandNotFoundException;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import baritone.api.utils.command.helpers.pagination.Paginator;
import baritone.api.utils.command.helpers.tabcomplete.TabCompleteHelper;
import baritone.api.utils.command.manager.CommandManager;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.util.text.event.ClickEvent;
import net.minecraft.util.text.event.HoverEvent;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static baritone.api.utils.command.BaritoneChatControl.FORCE_COMMAND_PREFIX;
import static baritone.api.utils.command.manager.CommandManager.getCommand;
import static java.util.Arrays.asList;
import static java.util.Objects.isNull;
public class HelpCommand extends Command {
public HelpCommand() {
super(asList("help", "?"));
}
@Override
protected void executed(String label, ArgConsumer args, Settings settings) {
args.requireMax(1);
if (!args.has() || args.is(Integer.class)) {
Paginator.paginate(
args, new Paginator<>(
CommandManager.REGISTRY.descendingStream()
.filter(command -> !command.hiddenFromHelp())
.collect(Collectors.toList())
),
() -> logDirect("All Baritone commands (clickable):"),
command -> {
String names = String.join("/", command.names);
String name = command.names.get(0);
ITextComponent shortDescComponent = new TextComponentString(" - " + command.getShortDesc());
shortDescComponent.getStyle().setColor(TextFormatting.DARK_GRAY);
ITextComponent namesComponent = new TextComponentString(names);
namesComponent.getStyle().setColor(TextFormatting.WHITE);
ITextComponent hoverComponent = new TextComponentString("");
hoverComponent.getStyle().setColor(TextFormatting.GRAY);
hoverComponent.appendSibling(namesComponent);
hoverComponent.appendText("\n" + command.getShortDesc());
hoverComponent.appendText("\n\nClick to view full help");
String clickCommand = FORCE_COMMAND_PREFIX + String.format("%s %s", label, command.names.get(0));
ITextComponent component = new TextComponentString(name);
component.getStyle().setColor(TextFormatting.GRAY);
component.appendSibling(shortDescComponent);
component.getStyle()
.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, hoverComponent))
.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, clickCommand));
return component;
},
FORCE_COMMAND_PREFIX + label
);
} else {
String commandName = args.getString().toLowerCase();
Command command = getCommand(commandName);
if (isNull(command)) {
throw new CommandNotFoundException(commandName);
}
logDirect(String.format("%s - %s", String.join(" / ", command.names), command.getShortDesc()));
logDirect("");
command.getLongDesc().forEach(this::logDirect);
logDirect("");
ITextComponent returnComponent = new TextComponentString("Click to return to the help menu");
returnComponent.getStyle().setClickEvent(new ClickEvent(
ClickEvent.Action.RUN_COMMAND,
FORCE_COMMAND_PREFIX + label
));
logDirect(returnComponent);
}
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args, Settings settings) {
if (args.hasExactlyOne()) {
return new TabCompleteHelper().addCommands().filterPrefix(args.getString()).stream();
}
return Stream.empty();
}
@Override
public String getShortDesc() {
return "View all commands or help on specific ones";
}
@Override
public List<String> getLongDesc() {
return asList(
"Using this command, you can view detailed help information on how to use certain commands of Baritone.",
"",
"Usage:",
"> help - Lists all commands and their short descriptions.",
"> help <command> - Displays help information on a specific command."
);
}
}

View File

@@ -0,0 +1,79 @@
/*
* 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.command.defaults;
import baritone.api.Settings;
import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.goals.GoalInverted;
import baritone.api.process.ICustomGoalProcess;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.exception.CommandInvalidStateException;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import java.util.List;
import java.util.stream.Stream;
import static java.util.Arrays.asList;
import static java.util.Objects.isNull;
public class InvertCommand extends Command {
public InvertCommand() {
super("invert");
}
@Override
protected void executed(String label, ArgConsumer args, Settings settings) {
args.requireMax(0);
ICustomGoalProcess customGoalProcess = baritone.getCustomGoalProcess();
Goal goal;
if (isNull(goal = customGoalProcess.getGoal())) {
throw new CommandInvalidStateException("No goal");
}
if (goal instanceof GoalInverted) {
goal = ((GoalInverted) goal).origin;
} else {
goal = new GoalInverted(goal);
}
customGoalProcess.setGoal(goal);
logDirect(String.format("Goal: %s", goal.toString()));
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args, Settings settings) {
return Stream.empty();
}
@Override
public String getShortDesc() {
return "Run away from the current goal";
}
@Override
public List<String> getLongDesc() {
return asList(
"The invert command tells Baritone to head away from the current goal rather than towards it.",
"",
"Usage:",
"> invert - Invert the current goal."
);
}
}

View File

@@ -0,0 +1,79 @@
/*
* 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.command.defaults;
import baritone.api.Settings;
import baritone.api.utils.BlockOptionalMeta;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.datatypes.BlockById;
import baritone.api.utils.command.datatypes.ForBlockOptionalMeta;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import baritone.cache.WorldScanner;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
import static java.util.Arrays.asList;
public class MineCommand extends Command {
public MineCommand() {
super("mine");
}
@Override
protected void executed(String label, ArgConsumer args, Settings settings) {
int quantity = args.getAsOrDefault(Integer.class, 0);
args.requireMin(1);
List<BlockOptionalMeta> boms = new ArrayList<>();
while (args.has()) {
boms.add(args.getDatatypeFor(ForBlockOptionalMeta.class));
}
WorldScanner.INSTANCE.repack(ctx);
baritone.getMineProcess().mine(quantity, boms.toArray(new BlockOptionalMeta[0]));
logDirect(String.format("Mining %s", boms.toString()));
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args, Settings settings) {
return args.tabCompleteDatatype(BlockById.class);
}
@Override
public String getShortDesc() {
return "Mine some blocks";
}
@Override
public List<String> getLongDesc() {
return asList(
"The mine command allows you to tell Baritone to search for and mine individual blocks.",
"",
"The specified blocks can be ores (which are commonly cached), or any other block.",
"",
"Also see the legitMine settings (see #set l legitMine).",
"",
"Usage:",
"> mine diamond_ore - Mines all diamonds it can find.",
"> mine redstone_ore lit_redstone_ore - Mines redstone ore.",
"> mine log:0 - Mines only oak logs."
);
}
}

View File

@@ -0,0 +1,99 @@
/*
* 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.command.defaults;
import baritone.api.Settings;
import baritone.api.pathing.goals.Goal;
import baritone.api.process.ICustomGoalProcess;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.datatypes.RelativeCoordinate;
import baritone.api.utils.command.datatypes.RelativeGoal;
import baritone.api.utils.command.exception.CommandInvalidStateException;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import baritone.api.utils.command.helpers.tabcomplete.TabCompleteHelper;
import baritone.cache.WorldScanner;
import java.util.List;
import java.util.stream.Stream;
import static java.util.Arrays.asList;
import static java.util.Objects.isNull;
public class PathCommand extends Command {
public PathCommand() {
super(asList("path", "goto"));
}
@Override
protected void executed(String label, ArgConsumer args, Settings settings) {
ICustomGoalProcess customGoalProcess = baritone.getCustomGoalProcess();
Goal goal;
if (args.has()) {
args.requireMax(3);
goal = args.getDatatype(RelativeGoal.class).apply(ctx.playerFeet());
} else if (isNull(goal = customGoalProcess.getGoal())) {
throw new CommandInvalidStateException("No goal");
}
args.requireMax(0);
WorldScanner.INSTANCE.repack(ctx);
customGoalProcess.setGoalAndPath(goal);
logDirect("Now pathing");
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args, Settings settings) {
if (args.has() && !args.has(4)) {
while (args.has(2)) {
if (isNull(args.peekDatatypeOrNull(RelativeCoordinate.class))) {
break;
}
args.get();
if (!args.has(2)) {
return new TabCompleteHelper()
.append("~")
.filterPrefix(args.getString())
.stream();
}
}
}
return Stream.empty();
}
@Override
public String getShortDesc() {
return "Start heading towards a goal";
}
@Override
public List<String> getLongDesc() {
return asList(
"The path command tells Baritone to head towards the current goal.",
"",
"Usage:",
"> path - Start the pathing.",
"> path <y>",
"> path <x> <z>",
"> path <x> <y> <z> - Define the goal here"
);
}
}

View File

@@ -0,0 +1,181 @@
/*
* 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.command.defaults;
import baritone.api.BaritoneAPI;
import baritone.api.Settings;
import baritone.api.process.IBaritoneProcess;
import baritone.api.process.PathingCommand;
import baritone.api.process.PathingCommandType;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.exception.CommandInvalidStateException;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import java.util.List;
import java.util.stream.Stream;
import static java.util.Arrays.asList;
/**
* Contains the pause, resume, and paused commands.
*
* This thing is scoped to hell, private so far you can't even access it using reflection, because you AREN'T SUPPOSED
* TO USE THIS to pause and resume Baritone. Make your own process that returns {@link PathingCommandType#REQUEST_PAUSE
* REQUEST_PAUSE} as needed.
*/
public class PauseResumeCommands {
public static Command pauseCommand;
public static Command resumeCommand;
public static Command pausedCommand;
static {
// array for mutability, non-field so reflection can't touch it
final boolean[] paused = {false};
BaritoneAPI.getProvider().getPrimaryBaritone().getPathingControlManager().registerProcess(
new IBaritoneProcess() {
@Override
public boolean isActive() {
return paused[0];
}
@Override
public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) {
return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE);
}
@Override
public boolean isTemporary() {
return true;
}
@Override
public void onLostControl() {}
@Override
public double priority() {
return DEFAULT_PRIORITY + 1;
}
@Override
public String displayName0() {
return "Pause/Resume Commands";
}
}
);
pauseCommand = new Command("pause") {
@Override
protected void executed(String label, ArgConsumer args, Settings settings) {
args.requireMax(0);
if (paused[0]) {
throw new CommandInvalidStateException("Already paused");
}
paused[0] = true;
logDirect("Paused");
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args, Settings settings) {
return Stream.empty();
}
@Override
public String getShortDesc() {
return "Pauses Baritone until you use resume";
}
@Override
public List<String> getLongDesc() {
return asList(
"The pause command tells Baritone to temporarily stop whatever it's doing.",
"",
"This can be used to pause pathing, building, following, whatever. A single use of the resume command will start it right back up again!",
"",
"Usage:",
"> pause"
);
}
};
resumeCommand = new Command("resume") {
@Override
protected void executed(String label, ArgConsumer args, Settings settings) {
args.requireMax(0);
if (!paused[0]) {
throw new CommandInvalidStateException("Not paused");
}
paused[0] = false;
logDirect("Resumed");
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args, Settings settings) {
return Stream.empty();
}
@Override
public String getShortDesc() {
return "Resumes Baritone after a pause";
}
@Override
public List<String> getLongDesc() {
return asList(
"The resume command tells Baritone to resume whatever it was doing when you last used pause.",
"",
"Usage:",
"> resume"
);
}
};
pausedCommand = new Command("paused") {
@Override
protected void executed(String label, ArgConsumer args, Settings settings) {
args.requireMax(0);
logDirect(String.format("Baritone is %spaused", paused[0] ? "" : "not "));
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args, Settings settings) {
return Stream.empty();
}
@Override
public String getShortDesc() {
return "Tells you if Baritone is paused";
}
@Override
public List<String> getLongDesc() {
return asList(
"The paused command tells you if Baritone is currently paused by use of the pause command.",
"",
"Usage:",
"> paused"
);
}
};
}
}

View File

@@ -0,0 +1,88 @@
/*
* 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.command.defaults;
import baritone.api.Settings;
import baritone.api.pathing.calc.IPathingControlManager;
import baritone.api.process.IBaritoneProcess;
import baritone.api.process.PathingCommand;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.exception.CommandInvalidStateException;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import java.util.List;
import java.util.stream.Stream;
import static java.util.Arrays.asList;
import static java.util.Objects.isNull;
public class ProcCommand extends Command {
public ProcCommand() {
super("proc");
}
@Override
protected void executed(String label, ArgConsumer args, Settings settings) {
args.requireMax(0);
IPathingControlManager pathingControlManager = baritone.getPathingControlManager();
IBaritoneProcess process = pathingControlManager.mostRecentInControl().orElse(null);
if (isNull(process)) {
throw new CommandInvalidStateException("No process in control");
}
logDirect(String.format(
"Class: %s\n" +
"Priority: %f\n" +
"Temporary: %b\n" +
"Display name: %s\n" +
"Last command: %s",
process.getClass().getTypeName(),
process.priority(),
process.isTemporary(),
process.displayName(),
pathingControlManager
.mostRecentCommand()
.map(PathingCommand::toString)
.orElse("None")
));
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args, Settings settings) {
return Stream.empty();
}
@Override
public String getShortDesc() {
return "View process state information";
}
@Override
public List<String> getLongDesc() {
return asList(
"The proc command provides miscellaneous information about the process currently controlling Baritone.",
"",
"You are not expected to understand this if you aren't familiar with how Baritone works.",
"",
"Usage:",
"> proc - View process information, if present"
);
}
}

View File

@@ -0,0 +1,60 @@
/*
* 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.command.defaults;
import baritone.api.Settings;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import java.util.List;
import java.util.stream.Stream;
import static java.util.Arrays.asList;
public class ReloadAllCommand extends Command {
public ReloadAllCommand() {
super("reloadall");
}
@Override
protected void executed(String label, ArgConsumer args, Settings settings) {
args.requireMax(0);
ctx.worldData().getCachedWorld().reloadAllFromDisk();
logDirect("Reloaded");
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args, Settings settings) {
return Stream.empty();
}
@Override
public String getShortDesc() {
return "Reloads Baritone's cache for this world";
}
@Override
public List<String> getLongDesc() {
return asList(
"The reloadall command reloads Baritone's world cache.",
"",
"Usage:",
"> reloadall"
);
}
}

View File

@@ -0,0 +1,72 @@
/*
* 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.command.defaults;
import baritone.api.Settings;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import java.util.List;
import java.util.stream.Stream;
import static java.util.Arrays.asList;
public class RenderCommand extends Command {
public RenderCommand() {
super("render");
}
@Override
protected void executed(String label, ArgConsumer args, Settings settings) {
args.requireMax(0);
BetterBlockPos origin = ctx.playerFeet();
int renderDistance = (MC.gameSettings.renderDistanceChunks + 1) * 16;
MC.renderGlobal.markBlockRangeForRenderUpdate(
origin.x - renderDistance,
0,
origin.z - renderDistance,
origin.x + renderDistance,
255,
origin.z + renderDistance
);
logDirect("Done");
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args, Settings settings) {
return Stream.empty();
}
@Override
public String getShortDesc() {
return "Fix glitched chunks";
}
@Override
public List<String> getLongDesc() {
return asList(
"The render command fixes glitched chunk rendering without having to reload all of them.",
"",
"Usage:",
"> render"
);
}
}

View File

@@ -0,0 +1,60 @@
/*
* 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.command.defaults;
import baritone.api.Settings;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import baritone.cache.WorldScanner;
import java.util.List;
import java.util.stream.Stream;
import static java.util.Arrays.asList;
public class RepackCommand extends Command {
public RepackCommand() {
super(asList("repack", "rescan"));
}
@Override
protected void executed(String label, ArgConsumer args, Settings settings) {
args.requireMax(0);
logDirect(String.format("Queued %d chunks for repacking", WorldScanner.INSTANCE.repack(ctx)));
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args, Settings settings) {
return Stream.empty();
}
@Override
public String getShortDesc() {
return "Re-cache chunks";
}
@Override
public List<String> getLongDesc() {
return asList(
"Repack chunks around you. This basically re-caches them.",
"",
"Usage:",
"> repack - Repack chunks."
);
}
}

View File

@@ -0,0 +1,60 @@
/*
* 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.command.defaults;
import baritone.api.Settings;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import java.util.List;
import java.util.stream.Stream;
import static java.util.Arrays.asList;
public class SaveAllCommand extends Command {
public SaveAllCommand() {
super("saveall");
}
@Override
protected void executed(String label, ArgConsumer args, Settings settings) {
args.requireMax(0);
ctx.worldData().getCachedWorld().save();
logDirect("Saved");
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args, Settings settings) {
return Stream.empty();
}
@Override
public String getShortDesc() {
return "Saves Baritone's cache for this world";
}
@Override
public List<String> getLongDesc() {
return asList(
"The saveall command saves Baritone's world cache.",
"",
"Usage:",
"> saveall"
);
}
}

View File

@@ -0,0 +1,59 @@
/*
* 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.command.defaults;
import baritone.api.Settings;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import java.util.List;
import java.util.stream.Stream;
import static java.util.Arrays.asList;
public class SchematicaCommand extends Command {
public SchematicaCommand() {
super("schematica");
}
@Override
protected void executed(String label, ArgConsumer args, Settings settings) {
args.requireMax(0);
baritone.getBuilderProcess().buildOpenSchematic();
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args, Settings settings) {
return Stream.empty();
}
@Override
public String getShortDesc() {
return "Builds the loaded schematic";
}
@Override
public List<String> getLongDesc() {
return asList(
"Builds the schematica currently open in Schematica.",
"",
"Usage:",
"> schematica"
);
}
}

View File

@@ -0,0 +1,383 @@
/*
* 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.command.defaults;
import baritone.api.Settings;
import baritone.api.event.events.RenderEvent;
import baritone.api.schematic.CompositeSchematic;
import baritone.api.schematic.FillSchematic;
import baritone.api.schematic.ReplaceSchematic;
import baritone.api.schematic.ShellSchematic;
import baritone.api.schematic.WallsSchematic;
import baritone.api.selection.ISelection;
import baritone.api.selection.ISelectionManager;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.BlockOptionalMeta;
import baritone.api.utils.BlockOptionalMetaLookup;
import baritone.api.utils.ISchematic;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.datatypes.ForBlockOptionalMeta;
import baritone.api.utils.command.datatypes.ForEnumFacing;
import baritone.api.utils.command.datatypes.RelativeBlockPos;
import baritone.api.utils.command.exception.CommandInvalidStateException;
import baritone.api.utils.command.exception.CommandInvalidTypeException;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import baritone.api.utils.command.helpers.tabcomplete.TabCompleteHelper;
import baritone.utils.IRenderer;
import net.minecraft.init.Blocks;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.Vec3i;
import java.awt.Color;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Stream;
import static java.util.Arrays.asList;
public class SelCommand extends Command {
private ISelectionManager manager = baritone.getSelectionManager();
private BetterBlockPos pos1 = null;
public SelCommand() {
super(asList("sel", "selection", "s"));
}
@Override
protected void executed(String label, ArgConsumer args, Settings settings) {
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 = ctx.playerFeet();
BetterBlockPos pos = args.has() ? args.getDatatypePost(RelativeBlockPos.class, 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.class);
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.class));
}
type = args.getDatatypeFor(ForBlockOptionalMeta.class);
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.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.class);
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));
}
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args, Settings settings) {
if (args.hasExactlyOne()) {
return new TabCompleteHelper()
.append(Action.getAllNames())
.filterPrefix(args.getString())
.sortAlphabetically()
.stream();
} else {
Action action = Action.getByName(args.getString());
if (action != null) {
if (action == Action.POS1 || action == Action.POS2) {
if (args.hasAtMost(3)) {
return args.tabCompleteDatatype(RelativeBlockPos.class);
}
} else if (action == Action.SET || action == Action.WALLS || action == Action.CLEARAREA || action == Action.REPLACE) {
if (args.hasExactlyOne() || action == Action.REPLACE) {
while (args.has(2)) {
args.get();
}
return args.tabCompleteDatatype(ForBlockOptionalMeta.class);
}
} else if (action == Action.EXPAND || action == Action.CONTRACT || action == Action.SHIFT) {
if (args.hasExactlyOne()) {
return new TabCompleteHelper()
.append(TransformTarget.getAllNames())
.filterPrefix(args.getString())
.sortAlphabetically()
.stream();
} else {
TransformTarget target = TransformTarget.getByName(args.getString());
if (target != null && args.hasExactlyOne()) {
return args.tabCompleteDatatype(ForEnumFacing.class);
}
}
}
}
}
return Stream.empty();
}
@Override
public String getShortDesc() {
return "WorldEdit-like commands";
}
@Override
public List<String> getLongDesc() {
return asList(
"The sel command allows you to manipulate Baritone's selections, similarly to WorldEdit.",
"",
"Using these selections, you can clear areas, fill them with blocks, or something else.",
"",
"The expand/contract/shift commands use a kind of selector to choose which selections to target. Supported ones are a/all, n/newest, and o/oldest.",
"",
"Usage:",
"> sel pos1/p1/1 - Set position 1 to your current position.",
"> sel pos1/p1/1 <x> <y> <z> - Set position 1 to a relative position.",
"> sel pos2/p2/2 - Set position 2 to your current position.",
"> sel pos2/p2/2 <x> <y> <z> - Set position 2 to a relative position.",
"",
"> sel clear/c - Clear the selection.",
"> sel undo/u - Undo the last action (setting positions, creating selections, etc.)",
"> sel set/fill/s/f [block] - Completely fill all selections with a block.",
"> sel walls/w [block] - Fill in the walls of the selection with a specified block.",
"> sel shell/shl [block] - The same as walls, but fills in a ceiling and floor too.",
"> sel cleararea/ca - Basically 'set air'.",
"> sel replace/r <blocks...> <with> - Replaces blocks with another block.",
"",
"> sel expand <target> <direction> <blocks> - Expand the targets.",
"> sel contract <target> <direction> <blocks> - Contract the targets.",
"> sel shift <target> <direction> <blocks> - Shift the targets (does not resize)."
);
}
enum Action {
POS1("pos1", "p1", "1"),
POS2("pos2", "p2", "2"),
CLEAR("clear", "c"),
UNDO("undo", "u"),
SET("set", "fill", "s", "f"),
WALLS("walls", "w"),
SHELL("shell", "shl"),
CLEARAREA("cleararea", "ca"),
REPLACE("replace", "r"),
EXPAND("expand", "ex"),
CONTRACT("contract", "ct"),
SHIFT("shift", "sh");
private final String[] names;
Action(String... names) {
this.names = names;
}
public static Action getByName(String name) {
for (Action action : Action.values()) {
for (String alias : action.names) {
if (alias.equalsIgnoreCase(name)) {
return action;
}
}
}
return null;
}
public static String[] getAllNames() {
Set<String> names = new HashSet<>();
for (Action action : Action.values()) {
names.addAll(asList(action.names));
}
return names.toArray(new String[0]);
}
}
enum TransformTarget {
ALL(sels -> sels, "all", "a"),
NEWEST(sels -> new ISelection[] {sels[sels.length - 1]}, "newest", "n"),
OLDEST(sels -> new ISelection[] {sels[0]}, "oldest", "o");
private final Function<ISelection[], ISelection[]> transform;
private final String[] names;
TransformTarget(Function<ISelection[], ISelection[]> transform, String... names) {
this.transform = transform;
this.names = names;
}
public ISelection[] transform(ISelection[] selections) {
return transform.apply(selections);
}
public static TransformTarget getByName(String name) {
for (TransformTarget target : TransformTarget.values()) {
for (String alias : target.names) {
if (alias.equalsIgnoreCase(name)) {
return target;
}
}
}
return null;
}
public static String[] getAllNames() {
Set<String> names = new HashSet<>();
for (TransformTarget target : TransformTarget.values()) {
names.addAll(asList(target.names));
}
return names.toArray(new String[0]);
}
}
@Override
public void onRenderPass(RenderEvent event) {
if (!settings.renderSelectionCorners.value || pos1 == null) {
return;
}
Color color = settings.colorSelectionPos1.value;
float opacity = settings.selectionOpacity.value;
float lineWidth = settings.selectionLineWidth.value;
boolean ignoreDepth = settings.renderSelectionIgnoreDepth.value;
IRenderer.startLines(color, opacity, lineWidth, ignoreDepth);
IRenderer.drawAABB(new AxisAlignedBB(pos1, pos1.add(1, 1, 1)));
IRenderer.endLines(ignoreDepth);
}
}

View File

@@ -0,0 +1,283 @@
/*
* 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.command.defaults;
import baritone.api.Settings;
import baritone.api.utils.SettingsUtil;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.exception.CommandInvalidTypeException;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import baritone.api.utils.command.helpers.pagination.Paginator;
import baritone.api.utils.command.helpers.tabcomplete.TabCompleteHelper;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.util.text.event.ClickEvent;
import net.minecraft.util.text.event.HoverEvent;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static baritone.api.utils.SettingsUtil.settingTypeToString;
import static baritone.api.utils.SettingsUtil.settingValueToString;
import static baritone.api.utils.command.BaritoneChatControl.FORCE_COMMAND_PREFIX;
import static java.util.Arrays.asList;
import static java.util.Objects.isNull;
import static java.util.Objects.nonNull;
import static java.util.stream.Stream.of;
public class SetCommand extends Command {
public SetCommand() {
super(asList("set", "setting", "settings"));
}
@Override
protected void executed(String label, ArgConsumer args, Settings settings) {
String arg = args.has() ? args.getString().toLowerCase(Locale.US) : "list";
if (asList("s", "save").contains(arg)) {
SettingsUtil.save(settings);
logDirect("Settings saved");
return;
}
boolean viewModified = asList("m", "mod", "modified").contains(arg);
boolean viewAll = asList("all", "l", "list").contains(arg);
boolean paginate = viewModified || viewAll;
if (paginate) {
String search = args.has() && args.peekAsOrNull(Integer.class) == null ? args.getString() : "";
args.requireMax(1);
List<? extends Settings.Setting> toPaginate =
(viewModified ? SettingsUtil.modifiedSettings(settings) : settings.allSettings).stream()
.filter(s -> !s.getName().equals("logger"))
.filter(s -> s.getName().toLowerCase(Locale.US).contains(search.toLowerCase(Locale.US)))
.sorted((s1, s2) -> String.CASE_INSENSITIVE_ORDER.compare(s1.getName(), s2.getName()))
.collect(Collectors.toList());
Paginator.paginate(
args,
new Paginator<>(toPaginate),
() -> logDirect(
!search.isEmpty()
? String.format("All %ssettings containing the string '%s':", viewModified ? "modified " : "", search)
: String.format("All %ssettings:", viewModified ? "modified " : "")
),
setting -> {
ITextComponent typeComponent = new TextComponentString(String.format(
" (%s)",
settingTypeToString(setting)
));
typeComponent.getStyle().setColor(TextFormatting.DARK_GRAY);
ITextComponent hoverComponent = new TextComponentString("");
hoverComponent.getStyle().setColor(TextFormatting.GRAY);
hoverComponent.appendText(setting.getName());
hoverComponent.appendText(String.format("\nType: %s", settingTypeToString(setting)));
hoverComponent.appendText(String.format("\n\nValue:\n%s", settingValueToString(setting)));
String commandSuggestion = settings.prefix.value + String.format("set %s ", setting.getName());
ITextComponent component = new TextComponentString(setting.getName());
component.getStyle().setColor(TextFormatting.GRAY);
component.appendSibling(typeComponent);
component.getStyle()
.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, hoverComponent))
.setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, commandSuggestion));
return component;
},
FORCE_COMMAND_PREFIX + "set " + arg + " " + search
);
return;
}
args.requireMax(1);
boolean resetting = arg.equalsIgnoreCase("reset");
boolean toggling = arg.equalsIgnoreCase("toggle");
boolean doingSomething = resetting || toggling;
if (resetting) {
if (!args.has()) {
logDirect("Please specify 'all' as an argument to reset to confirm you'd really like to do this");
logDirect("ALL settings will be reset. Use the 'set modified' or 'modified' commands to see what will be reset.");
logDirect("Specify a setting name instead of 'all' to only reset one setting");
} else if (args.peekString().equalsIgnoreCase("all")) {
SettingsUtil.modifiedSettings(settings).forEach(Settings.Setting::reset);
logDirect("All settings have been reset to their default values");
SettingsUtil.save(settings);
return;
}
}
if (toggling) {
args.requireMin(1);
}
String settingName = doingSomething ? args.getString() : arg;
Settings.Setting<?> setting = settings.allSettings.stream()
.filter(s -> s.getName().equalsIgnoreCase(settingName))
.findFirst()
.orElse(null);
if (isNull(setting)) {
throw new CommandInvalidTypeException(args.consumed(), "a valid setting");
}
if (!doingSomething && !args.has()) {
logDirect(String.format("Value of setting %s:", setting.getName()));
logDirect(settingValueToString(setting));
} else {
String oldValue = settingValueToString(setting);
if (resetting) {
setting.reset();
} else if (toggling) {
if (setting.getValueClass() != Boolean.class) {
throw new CommandInvalidTypeException(args.consumed(), "a toggleable setting", "some other setting");
}
//noinspection unchecked
((Settings.Setting<Boolean>) setting).value ^= true;
logDirect(String.format(
"Toggled setting %s to %s",
setting.getName(),
Boolean.toString((Boolean) setting.value)
));
} else {
String newValue = args.getString();
try {
SettingsUtil.parseAndApply(settings, arg, newValue);
} catch (Throwable t) {
t.printStackTrace();
throw new CommandInvalidTypeException(args.consumed(), "a valid value", t);
}
}
if (!toggling) {
logDirect(String.format(
"Successfully %s %s to %s",
resetting ? "reset" : "set",
setting.getName(),
settingValueToString(setting)
));
}
ITextComponent oldValueComponent = new TextComponentString(String.format("Old value: %s", oldValue));
oldValueComponent.getStyle()
.setColor(TextFormatting.GRAY)
.setHoverEvent(new HoverEvent(
HoverEvent.Action.SHOW_TEXT,
new TextComponentString("Click to set the setting back to this value")
))
.setClickEvent(new ClickEvent(
ClickEvent.Action.RUN_COMMAND,
FORCE_COMMAND_PREFIX + String.format("set %s %s", setting.getName(), oldValue)
));
logDirect(oldValueComponent);
if ((setting.getName().equals("chatControl") && !(Boolean) setting.value && !settings.chatControlAnyway.value) ||
setting.getName().equals("chatControlAnyway") && !(Boolean) setting.value && !settings.chatControl.value) {
logDirect("Warning: Chat commands will no longer work. If you want to revert this change, use prefix control (if enabled) or click the old value listed above.", TextFormatting.RED);
} else if (setting.getName().equals("prefixControl") && !(Boolean) setting.value) {
logDirect("Warning: Prefixed commands will no longer work. If you want to revert this change, use chat control (if enabled) or click the old value listed above.", TextFormatting.RED);
}
}
SettingsUtil.save(settings);
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args, Settings settings) {
if (args.has()) {
String arg = args.getString();
if (args.hasExactlyOne() && !asList("s", "save").contains(args.peekString().toLowerCase(Locale.US))) {
if (arg.equalsIgnoreCase("reset")) {
return new TabCompleteHelper()
.addModifiedSettings()
.prepend("all")
.filterPrefix(args.getString())
.stream();
} else if (arg.equalsIgnoreCase("toggle")) {
return new TabCompleteHelper()
.addToggleableSettings()
.filterPrefix(args.getString())
.stream();
}
Settings.Setting setting = settings.byLowerName.get(arg.toLowerCase(Locale.US));
if (nonNull(setting)) {
if (setting.getType() == Boolean.class) {
TabCompleteHelper helper = new TabCompleteHelper();
if ((Boolean) setting.value) {
helper.append(of("true", "false"));
} else {
helper.append(of("false", "true"));
}
return helper.filterPrefix(args.getString()).stream();
} else {
return Stream.of(settingValueToString(setting));
}
}
} else if (!args.has()) {
return new TabCompleteHelper()
.addSettings()
.sortAlphabetically()
.prepend("list", "modified", "reset", "toggle", "save")
.filterPrefix(arg)
.stream();
}
}
return Stream.empty();
}
@Override
public String getShortDesc() {
return "View or change settings";
}
@Override
public List<String> getLongDesc() {
return asList(
"Using the set command, you can manage all of Baritone's settings. Almost every aspect is controlled by these settings - go wild!",
"",
"Usage:",
"> set - Same as `set list`",
"> set list [page] - View all settings",
"> set modified [page] - View modified settings",
"> set <setting> - View the current value of a setting",
"> set <setting> <value> - Set the value of a setting",
"> set reset all - Reset ALL SETTINGS to their defaults",
"> set reset <setting> - Reset a setting to its default",
"> set toggle <setting> - Toggle a boolean setting",
"> set save - Save all settings (this is automatic tho)"
);
}
}

View File

@@ -0,0 +1,68 @@
/*
* 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.command.defaults;
import baritone.api.Settings;
import baritone.api.pathing.goals.GoalXZ;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import java.util.List;
import java.util.stream.Stream;
import static java.util.Arrays.asList;
public class ThisWayCommand extends Command {
public ThisWayCommand() {
super(asList("thisway", "forward"));
}
@Override
protected void executed(String label, ArgConsumer args, Settings settings) {
args.requireExactly(1);
GoalXZ goal = GoalXZ.fromDirection(
ctx.playerFeetAsVec(),
ctx.player().rotationYawHead,
args.getAs(Double.class)
);
baritone.getCustomGoalProcess().setGoal(goal);
logDirect(String.format("Goal: %s", goal));
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args, Settings settings) {
return Stream.empty();
}
@Override
public String getShortDesc() {
return "Travel in your current direction";
}
@Override
public List<String> getLongDesc() {
return asList(
"Creates a GoalXZ some amount of blocks in the direction you're currently looking",
"",
"Usage:",
"> thisway <distance> - makes a GoalXZ distance blocks in front of you"
);
}
}

View File

@@ -0,0 +1,68 @@
/*
* 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.command.defaults;
import baritone.api.Settings;
import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.goals.GoalStrictDirection;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import java.util.List;
import java.util.stream.Stream;
import static java.util.Arrays.asList;
public class TunnelCommand extends Command {
public TunnelCommand() {
super("tunnel");
}
@Override
protected void executed(String label, ArgConsumer args, Settings settings) {
args.requireMax(0);
Goal goal = new GoalStrictDirection(
ctx.playerFeet(),
ctx.player().getHorizontalFacing()
);
baritone.getCustomGoalProcess().setGoal(goal);
logDirect(String.format("Goal: %s", goal.toString()));
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args, Settings settings) {
return Stream.empty();
}
@Override
public String getShortDesc() {
return "Set a goal to tunnel in your current direction";
}
@Override
public List<String> getLongDesc() {
return asList(
"The tunnel command sets a goal that tells Baritone to mine completely straight in the direction that you're facing.",
"",
"Usage:",
"> tunnel"
);
}
}

View File

@@ -0,0 +1,68 @@
/*
* 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.command.defaults;
import baritone.api.Settings;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.exception.CommandInvalidStateException;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import java.util.List;
import java.util.stream.Stream;
import static java.util.Arrays.asList;
import static java.util.Objects.isNull;
public class VersionCommand extends Command {
public VersionCommand() {
super("version");
}
@Override
protected void executed(String label, ArgConsumer args, Settings settings) {
args.requireMax(0);
String version = getClass().getPackage().getImplementationVersion();
if (isNull(version)) {
throw new CommandInvalidStateException("Null version (this is normal in a dev environment)");
} else {
logDirect(String.format("You are running Baritone v%s", version));
}
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args, Settings settings) {
return Stream.empty();
}
@Override
public String getShortDesc() {
return "View the Baritone version";
}
@Override
public List<String> getLongDesc() {
return asList(
"The version command prints the version of Baritone you're currently running.",
"",
"Usage:",
"> version - View version information, if present"
);
}
}

View File

@@ -0,0 +1,357 @@
/*
* 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.command.defaults;
import baritone.api.Settings;
import baritone.api.cache.IWaypoint;
import baritone.api.cache.Waypoint;
import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.goals.GoalBlock;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.datatypes.ForWaypoints;
import baritone.api.utils.command.datatypes.RelativeBlockPos;
import baritone.api.utils.command.exception.CommandInvalidStateException;
import baritone.api.utils.command.exception.CommandInvalidTypeException;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import baritone.api.utils.command.helpers.pagination.Paginator;
import baritone.api.utils.command.helpers.tabcomplete.TabCompleteHelper;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.util.text.event.ClickEvent;
import net.minecraft.util.text.event.HoverEvent;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.Stream;
import static baritone.api.utils.command.BaritoneChatControl.FORCE_COMMAND_PREFIX;
import static java.util.Arrays.asList;
public class WaypointsCommand extends Command {
public WaypointsCommand() {
super(asList("waypoints", "waypoint", "wp"));
}
@Override
protected void executed(String label, ArgConsumer args, Settings settings) {
Action action = args.has() ? Action.getByName(args.getString()) : Action.LIST;
if (action == null) {
throw new CommandInvalidTypeException(args.consumed(), "an action");
}
BiFunction<IWaypoint, Action, ITextComponent> toComponent = (waypoint, _action) -> {
ITextComponent component = new TextComponentString("");
ITextComponent tagComponent = new TextComponentString(waypoint.getTag().name() + " ");
tagComponent.getStyle().setColor(TextFormatting.GRAY);
String name = waypoint.getName();
ITextComponent nameComponent = new TextComponentString(!name.isEmpty() ? name : "<empty>");
nameComponent.getStyle().setColor(!name.isEmpty() ? TextFormatting.GRAY : TextFormatting.DARK_GRAY);
ITextComponent timestamp = new TextComponentString(" @ " + new Date(waypoint.getCreationTimestamp()));
timestamp.getStyle().setColor(TextFormatting.DARK_GRAY);
component.appendSibling(tagComponent);
component.appendSibling(nameComponent);
component.appendSibling(timestamp);
component.getStyle()
.setHoverEvent(new HoverEvent(
HoverEvent.Action.SHOW_TEXT,
new TextComponentString("Click to select")
))
.setClickEvent(new ClickEvent(
ClickEvent.Action.RUN_COMMAND,
String.format(
"%s%s %s %s @ %d",
FORCE_COMMAND_PREFIX,
label,
_action.names[0],
waypoint.getTag().getName(),
waypoint.getCreationTimestamp()
))
);
return component;
};
Function<IWaypoint, ITextComponent> transform = waypoint ->
toComponent.apply(waypoint, action == Action.LIST ? Action.INFO : action);
if (action == Action.LIST) {
IWaypoint.Tag tag = args.has() ? IWaypoint.Tag.getByName(args.peekString()) : null;
if (tag != null) {
args.get();
}
IWaypoint[] waypoints = tag != null
? ForWaypoints.getWaypointsByTag(tag)
: ForWaypoints.getWaypoints();
if (waypoints.length > 0) {
args.requireMax(1);
Paginator.paginate(
args,
waypoints,
() -> logDirect(
tag != null
? String.format("All waypoints by tag %s:", tag.name())
: "All waypoints:"
),
transform,
String.format(
"%s%s %s%s",
FORCE_COMMAND_PREFIX,
label,
action.names[0],
tag != null ? " " + tag.getName() : ""
)
);
} else {
args.requireMax(0);
throw new CommandInvalidStateException(
tag != null
? "No waypoints found by that tag"
: "No waypoints found"
);
}
} else if (action == Action.SAVE) {
IWaypoint.Tag tag = IWaypoint.Tag.getByName(args.getString());
if (tag == null) {
throw new CommandInvalidStateException(String.format("'%s' is not a tag ", args.consumedString()));
}
String name = args.has() ? args.getString() : "";
BetterBlockPos pos = args.has()
? args.getDatatypePost(RelativeBlockPos.class, ctx.playerFeet())
: ctx.playerFeet();
args.requireMax(0);
IWaypoint waypoint = new Waypoint(name, tag, pos);
ForWaypoints.waypoints().addWaypoint(waypoint);
ITextComponent component = new TextComponentString("Waypoint added: ");
component.getStyle().setColor(TextFormatting.GRAY);
component.appendSibling(toComponent.apply(waypoint, Action.INFO));
logDirect(component);
} else if (action == Action.CLEAR) {
args.requireMax(1);
IWaypoint.Tag tag = IWaypoint.Tag.getByName(args.getString());
IWaypoint[] waypoints = ForWaypoints.getWaypointsByTag(tag);
for (IWaypoint waypoint : waypoints) {
ForWaypoints.waypoints().removeWaypoint(waypoint);
}
logDirect(String.format("Cleared %d waypoints", waypoints.length));
} else {
IWaypoint[] waypoints = args.getDatatypeFor(ForWaypoints.class);
IWaypoint waypoint = null;
if (args.has() && args.peekString().equals("@")) {
args.requireExactly(2);
args.get();
long timestamp = args.getAs(Long.class);
for (IWaypoint iWaypoint : waypoints) {
if (iWaypoint.getCreationTimestamp() == timestamp) {
waypoint = iWaypoint;
break;
}
}
if (waypoint == null) {
throw new CommandInvalidStateException("Timestamp was specified but no waypoint was found");
}
} else {
switch (waypoints.length) {
case 0:
throw new CommandInvalidStateException("No waypoints found");
case 1:
waypoint = waypoints[0];
}
}
if (waypoint == null) {
args.requireMax(1);
Paginator.paginate(
args,
waypoints,
() -> logDirect("Multiple waypoints were found:"),
transform,
String.format(
"%s%s %s %s",
FORCE_COMMAND_PREFIX,
label,
action.names[0],
args.consumedString()
)
);
} else {
if (action == Action.INFO) {
logDirect(transform.apply(waypoint));
logDirect(String.format("Position: %s", waypoint.getLocation()));
ITextComponent deleteComponent = new TextComponentString("Click to delete this waypoint");
deleteComponent.getStyle().setClickEvent(new ClickEvent(
ClickEvent.Action.RUN_COMMAND,
String.format(
"%s%s delete %s @ %d",
FORCE_COMMAND_PREFIX,
label,
waypoint.getTag().getName(),
waypoint.getCreationTimestamp()
)
));
ITextComponent goalComponent = new TextComponentString("Click to set goal to this waypoint");
goalComponent.getStyle().setClickEvent(new ClickEvent(
ClickEvent.Action.RUN_COMMAND,
String.format(
"%s%s goal %s @ %d",
FORCE_COMMAND_PREFIX,
label,
waypoint.getTag().getName(),
waypoint.getCreationTimestamp()
)
));
ITextComponent backComponent = new TextComponentString("Click to return to the waypoints list");
backComponent.getStyle().setClickEvent(new ClickEvent(
ClickEvent.Action.RUN_COMMAND,
String.format(
"%s%s list",
FORCE_COMMAND_PREFIX,
label
)
));
logDirect(deleteComponent);
logDirect(goalComponent);
logDirect(backComponent);
} else if (action == Action.DELETE) {
ForWaypoints.waypoints().removeWaypoint(waypoint);
logDirect("That waypoint has successfully been deleted");
} else if (action == Action.GOAL) {
Goal goal = new GoalBlock(waypoint.getLocation());
baritone.getCustomGoalProcess().setGoal(goal);
logDirect(String.format("Goal: %s", goal));
}
}
}
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args, Settings settings) {
if (args.has()) {
if (args.hasExactlyOne()) {
return new TabCompleteHelper()
.append(Action.getAllNames())
.sortAlphabetically()
.filterPrefix(args.getString())
.stream();
} else {
Action action = Action.getByName(args.getString());
if (args.hasExactlyOne()) {
if (action == Action.LIST || action == Action.SAVE || action == Action.CLEAR) {
return new TabCompleteHelper()
.append(IWaypoint.Tag.getAllNames())
.sortAlphabetically()
.filterPrefix(args.getString())
.stream();
} else {
return args.tabCompleteDatatype(ForWaypoints.class);
}
} else if (args.has(3) && action == Action.SAVE) {
args.get();
args.get();
return args.tabCompleteDatatype(RelativeBlockPos.class);
}
}
}
return Stream.empty();
}
@Override
public String getShortDesc() {
return "Manage waypoints";
}
@Override
public List<String> getLongDesc() {
return asList(
"The waypoint command allows you to manage Baritone's waypoints.",
"",
"Waypoints can be used to mark positions for later. Waypoints are each given a tag and an optional name.",
"",
"Note that the info, delete, and goal commands let you specify a waypoint by tag. If there is more than one waypoint with a certain tag, then they will let you select which waypoint you mean.",
"",
"Usage:",
"> wp [l/list] - List all waypoints.",
"> wp <s/save> <tag> - Save your current position as an unnamed waypoint with the specified tag.",
"> wp <s/save> <tag> <name> - Save the waypoint with the specified name.",
"> wp <s/save> <tag> <name> <pos> - Save the waypoint with the specified name and position.",
"> wp <i/info/show> <tag> - Show info on a waypoint by tag.",
"> wp <d/delete> <tag> - Delete a waypoint by tag.",
"> wp <g/goal/goto> <tag> - Set a goal to a waypoint by tag."
);
}
private enum Action {
LIST("list", "get", "l"),
CLEAR("clear", "c"),
SAVE("save", "s"),
INFO("info", "show", "i"),
DELETE("delete", "d"),
GOAL("goal", "goto", "g");
private final String[] names;
Action(String... names) {
this.names = names;
}
public static Action getByName(String name) {
for (Action action : Action.values()) {
for (String alias : action.names) {
if (alias.equalsIgnoreCase(name)) {
return action;
}
}
}
return null;
}
public static String[] getAllNames() {
Set<String> names = new HashSet<>();
for (Action action : Action.values()) {
names.addAll(asList(action.names));
}
return names.toArray(new String[0]);
}
}
}

View File

@@ -19,23 +19,25 @@ package baritone.utils.schematic;
import baritone.api.utils.ISchematic;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
public class AirSchematic implements ISchematic {
import java.util.List;
public class FillSchematic implements ISchematic {
private final int widthX;
private final int heightY;
private final int lengthZ;
private final IBlockState state;
public AirSchematic(int widthX, int heightY, int lengthZ) {
public FillSchematic(int widthX, int heightY, int lengthZ, IBlockState state) {
this.widthX = widthX;
this.heightY = heightY;
this.lengthZ = lengthZ;
this.state = state;
}
@Override
public IBlockState desiredState(int x, int y, int z) {
return Blocks.AIR.getDefaultState();
public IBlockState desiredState(int x, int y, int z, IBlockState current, List<IBlockState> approxPlaceable) {
return state;
}
@Override

View File

@@ -59,8 +59,8 @@ public class MapArtSchematic extends Schematic {
}
@Override
public boolean inSchematic(int x, int y, int z) {
public boolean inSchematic(int x, int y, int z, IBlockState currentState) {
// in map art, we only care about coordinates in or above the art
return super.inSchematic(x, y, z) && y >= heightMap[x][z];
return super.inSchematic(x, y, z, currentState) && y >= heightMap[x][z];
}
}

View File

@@ -22,6 +22,8 @@ import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.nbt.NBTTagCompound;
import java.util.List;
public class Schematic implements ISchematic {
public final int widthX;
public final int heightY;
@@ -68,7 +70,7 @@ public class Schematic implements ISchematic {
}
@Override
public IBlockState desiredState(int x, int y, int z) {
public IBlockState desiredState(int x, int y, int z, IBlockState current, List<IBlockState> approxPlaceable) {
return states[x][z][y];
}

View File

@@ -23,6 +23,8 @@ import com.github.lunatrius.schematica.client.world.SchematicWorld;
import net.minecraft.block.state.IBlockState;
import net.minecraft.util.math.BlockPos;
import java.util.List;
public final class SchematicAdapter implements ISchematic {
private final SchematicWorld schematic;
@@ -31,7 +33,7 @@ public final class SchematicAdapter implements ISchematic {
}
@Override
public IBlockState desiredState(int x, int y, int z) {
public IBlockState desiredState(int x, int y, int z, IBlockState current, List<IBlockState> approxPlaceable) {
return schematic.getSchematic().getBlockState(new BlockPos(x, y, z));
}