Merge branch 'master' into 1.13.2

This commit is contained in:
Leijurv
2019-09-30 17:52:47 -07:00
198 changed files with 10431 additions and 1334 deletions

View File

@@ -21,14 +21,15 @@ 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.Helper;
import baritone.api.utils.IPlayerContext;
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.manager.CommandManager;
import baritone.utils.player.PrimaryPlayerContext;
import net.minecraft.client.Minecraft;
@@ -60,11 +61,6 @@ public class Baritone implements IBaritone {
}
}
/**
* Whether or not {@link Baritone#init()} has been called yet
*/
private boolean initialized;
private GameEventHandler gameEventHandler;
private PathingBehavior pathingBehavior;
@@ -83,6 +79,8 @@ public class Baritone implements IBaritone {
private FarmProcess farmProcess;
private PathingControlManager pathingControlManager;
private SelectionManager selectionManager;
private CommandManager commandManager;
private IPlayerContext playerContext;
private WorldProvider worldProvider;
@@ -91,13 +89,6 @@ public class Baritone implements IBaritone {
Baritone() {
this.gameEventHandler = new GameEventHandler(this);
}
@Override
public synchronized void init() {
if (initialized) {
return;
}
// Define this before behaviors try and get it, or else it will be null and the builds will fail!
this.playerContext = PrimaryPlayerContext.INSTANCE;
@@ -109,7 +100,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,12 +115,12 @@ public class Baritone implements IBaritone {
}
this.worldProvider = new WorldProvider();
this.selectionManager = new SelectionManager(this);
this.commandManager = new CommandManager(this);
if (BaritoneAutoTest.ENABLE_AUTO_TEST) {
this.gameEventHandler.registerEventListener(BaritoneAutoTest.INSTANCE);
}
this.initialized = true;
}
@Override
@@ -203,6 +193,11 @@ public class Baritone implements IBaritone {
return this.pathingBehavior;
}
@Override
public SelectionManager getSelectionManager() {
return selectionManager;
}
@Override
public WorldProvider getWorldProvider() {
return this.worldProvider;
@@ -213,6 +208,11 @@ public class Baritone implements IBaritone {
return this.gameEventHandler;
}
@Override
public CommandManager getCommandManager() {
return this.commandManager;
}
@Override
public void openClick() {
new Thread(() -> {
@@ -234,4 +234,4 @@ public class Baritone implements IBaritone {
public static Executor getExecutor() {
return threadPool;
}
}
}

View File

@@ -20,6 +20,7 @@ package baritone;
import baritone.api.IBaritone;
import baritone.api.IBaritoneProvider;
import baritone.api.cache.IWorldScanner;
import baritone.utils.command.BaritoneChatControl;
import baritone.cache.WorldScanner;
import java.util.Collections;
@@ -31,8 +32,16 @@ import java.util.List;
*/
public final class BaritoneProvider implements IBaritoneProvider {
private final Baritone primary = new Baritone();
private final List<IBaritone> all = Collections.singletonList(primary);
private final Baritone primary;
private final List<IBaritone> all;
{
this.primary = new Baritone();
this.all = Collections.singletonList(this.primary);
// Setup chat control, just for the primary instance
new BaritoneChatControl(this.primary);
}
@Override
public IBaritone getPrimaryBaritone() {

View File

@@ -35,6 +35,7 @@ import java.util.Random;
import java.util.function.Predicate;
public final class InventoryBehavior extends Behavior {
public InventoryBehavior(Baritone baritone) {
super(baritone);
}
@@ -102,7 +103,7 @@ public final class InventoryBehavior extends Behavior {
return -1;
}
private int bestToolAgainst(Block against, Class<? extends ItemTool> klass) {
private int bestToolAgainst(Block against, Class<? extends ItemTool> cla$$) {
NonNullList<ItemStack> invy = ctx.player().inventory.mainInventory;
int bestInd = -1;
double bestSpeed = -1;
@@ -111,7 +112,7 @@ public final class InventoryBehavior extends Behavior {
if (stack.isEmpty()) {
continue;
}
if (klass.isInstance(stack.getItem())) {
if (cla$$.isInstance(stack.getItem())) {
double speed = ToolSet.calculateSpeedVsBlock(stack, against.getDefaultState()); // takes into account enchants
if (speed > bestSpeed) {
bestSpeed = speed;
@@ -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(new BlockItemUseContext(new ItemUseContext(ctx.player(), stack, ctx.playerFeet(), EnumFacing.UP, (float) ctx.player().posX, (float) ctx.player().posY, (float) ctx.player().posZ)))))) {
return true; // gotem
}

View File

@@ -55,7 +55,7 @@ public final class LookBehavior extends Behavior implements ILookBehavior {
if (Math.abs(rand) < 0.1) {
rand *= 4;
}
this.target = new Rotation(this.target.getYaw() + (float) (rand * Baritone.settings().randomLooking.value), this.target.getPitch());
this.target = new Rotation(this.target.getYaw() + (float) (rand * Baritone.settings().randomLooking113.value), this.target.getPitch());
}
this.force = force || !Baritone.settings().freeLook.value;
}
@@ -76,6 +76,8 @@ public final class LookBehavior extends Behavior implements ILookBehavior {
float oldPitch = ctx.player().rotationPitch;
float desiredPitch = this.target.getPitch();
ctx.player().rotationPitch = desiredPitch;
ctx.player().rotationYaw += (Math.random() - 0.5) * Baritone.settings().randomLooking.value;
ctx.player().rotationPitch += (Math.random() - 0.5) * Baritone.settings().randomLooking.value;
if (desiredPitch == oldPitch && !Baritone.settings().freeLook.value) {
nudgeToLevel();
}

View File

@@ -24,6 +24,7 @@ import baritone.api.event.events.PacketEvent;
import baritone.api.event.events.PlayerUpdateEvent;
import baritone.api.event.events.TickEvent;
import baritone.api.event.events.type.EventState;
import baritone.api.utils.BetterBlockPos;
import baritone.cache.ContainerMemory;
import baritone.utils.BlockStateInterface;
import net.minecraft.block.Block;
@@ -99,8 +100,8 @@ public final class MemoryBehavior extends Behavior {
TileEntityLockable lockable = (TileEntityLockable) tileEntity;
int size = lockable.getSizeInventory();
BlockPos position = tileEntity.getPos();
BlockPos adj = neighboringConnectedBlock(position);
BetterBlockPos position = BetterBlockPos.from(tileEntity.getPos());
BetterBlockPos adj = BetterBlockPos.from(neighboringConnectedBlock(position));
System.out.println(position + " " + adj);
if (adj != null) {
size *= 2; // double chest or double trapped chest
@@ -159,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())));
}
}
@@ -239,7 +240,8 @@ public final class MemoryBehavior extends Behavior {
this.slots = slots;
this.type = type;
this.pos = pos;
System.out.println("Future inventory created " + time + " " + slots + " " + type + " " + pos);
// betterblockpos has censoring
System.out.println("Future inventory created " + time + " " + slots + " " + type + " " + BetterBlockPos.from(pos));
}
}
@@ -253,6 +255,7 @@ public final class MemoryBehavior extends Behavior {
}
public static class EnderChestMemory {
private static final Map<Path, EnderChestMemory> memory = new HashMap<>();
private final Path enderChest;
private List<ItemStack> contents;

View File

@@ -55,6 +55,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 +109,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
}
private void tickPath() {
pausedThisTick = false;
if (pauseRequestedLastTick && safeToCancel) {
pauseRequestedLastTick = false;
if (unpausedLastTick) {
@@ -115,6 +117,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
baritone.getInputOverrideHandler().getBlockBreakHelper().stopBreakingBlock();
}
unpausedLastTick = false;
pausedThisTick = true;
return;
}
unpausedLastTick = true;
@@ -279,6 +282,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

@@ -288,6 +288,7 @@ public final class CachedWorld implements ICachedWorld, Helper {
}
private class PackerThread implements Runnable {
public void run() {
while (true) {
// TODO: Add CachedWorld unloading to remove the redundancy of having this

View File

@@ -88,6 +88,7 @@ public final class ChunkPacker {
//System.out.println("Chunk packing took " + (end - start) + "ms for " + chunk.x + "," + chunk.z);
IBlockState[] blocks = new IBlockState[256];
// @formatter:off
for (int z = 0; z < 16; z++) {
https://www.ibm.com/developerworks/library/j-perry-writing-good-java-code/index.html
for (int x = 0; x < 16; x++) {
@@ -101,6 +102,7 @@ public final class ChunkPacker {
blocks[z << 4 | x] = Blocks.AIR.getDefaultState();
}
}
// @formatter:on
return new CachedChunk(chunk.x, chunk.z, bitSet, blocks, specialBlocks, System.currentTimeMillis());
}

View File

@@ -20,7 +20,7 @@ package baritone.cache;
import baritone.api.cache.IWaypoint;
import baritone.api.cache.IWaypointCollection;
import baritone.api.cache.Waypoint;
import net.minecraft.util.math.BlockPos;
import baritone.api.utils.BetterBlockPos;
import java.io.*;
import java.nio.file.Files;
@@ -86,7 +86,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,16 +17,19 @@
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.ChunkSection;
import net.minecraft.world.chunk.IChunkProvider;
import java.util.*;
import java.util.stream.IntStream;
@@ -38,14 +41,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,7 +77,7 @@ 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;
}
}
@@ -91,8 +93,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 +107,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) {
ChunkSection[] chunkInternalStorageArray = chunk.getSections();
boolean foundWithinY = false;
for (int yIndex = 0; yIndex < 16; yIndex++) {
@@ -119,32 +121,52 @@ public enum WorldScanner implements IWorldScanner {
continue;
}
int yReal = y0 << 4;
BlockStateContainer<IBlockState> 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.getChunk(x, z, false, false);
if (chunk != null && !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

@@ -27,6 +27,7 @@ import baritone.pathing.calc.PathNode;
* @author leijurv
*/
class LinkedListOpenSet implements IOpenSet {
private Node first = null;
@Override
@@ -83,6 +84,7 @@ class LinkedListOpenSet implements IOpenSet {
}
public static class Node { //wrapper with next
private Node nextOpen;
private PathNode val;
}

View File

@@ -61,6 +61,7 @@ public class CalculationContext {
public final boolean allowParkourAscend;
public final boolean assumeWalkOnWater;
public final boolean allowDiagonalDescend;
public final boolean allowDiagonalAscend;
public final boolean allowDownward;
public final int maxFallHeightNoWater;
public final int maxFallHeightBucket;
@@ -94,6 +95,7 @@ public class CalculationContext {
this.allowParkourAscend = Baritone.settings().allowParkourAscend.value;
this.assumeWalkOnWater = Baritone.settings().assumeWalkOnWater.value;
this.allowDiagonalDescend = Baritone.settings().allowDiagonalDescend.value;
this.allowDiagonalAscend = Baritone.settings().allowDiagonalAscend.value;
this.allowDownward = Baritone.settings().allowDownward.value;
this.maxFallHeightNoWater = Baritone.settings().maxFallHeightNoWater.value;
this.maxFallHeightBucket = Baritone.settings().maxFallHeightBucket.value;

View File

@@ -18,6 +18,7 @@
package baritone.pathing.movement;
import baritone.Baritone;
import baritone.api.BaritoneAPI;
import baritone.api.IBaritone;
import baritone.api.pathing.movement.ActionCosts;
import baritone.api.pathing.movement.MovementStatus;
@@ -185,7 +186,7 @@ public interface MovementHelper extends ActionCosts, Helper {
return state.allowsMovement(null, null, PathType.LAND);
}
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
@@ -214,6 +215,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;
@@ -415,7 +421,7 @@ public interface MovementHelper extends ActionCosts, Helper {
* @param b the blockstate to mine
*/
static void switchToBestToolFor(IPlayerContext ctx, IBlockState b) {
switchToBestToolFor(ctx, b, new ToolSet(ctx.player()));
switchToBestToolFor(ctx, b, new ToolSet(ctx.player()), BaritoneAPI.getSettings().preferSilkTouch.value);
}
/**
@@ -425,8 +431,8 @@ public interface MovementHelper extends ActionCosts, Helper {
* @param b the blockstate to mine
* @param ts previously calculated ToolSet
*/
static void switchToBestToolFor(IPlayerContext ctx, IBlockState b, ToolSet ts) {
ctx.player().inventory.currentItem = ts.getBestSlot(b.getBlock());
static void switchToBestToolFor(IPlayerContext ctx, IBlockState b, ToolSet ts, boolean preferSilkTouch) {
ctx.player().inventory.currentItem = ts.getBestSlot(b.getBlock(), preferSilkTouch);
}
static void moveTowards(IPlayerContext ctx, MovementState state, BlockPos pos) {

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

@@ -70,24 +70,37 @@ public class MovementDiagonal extends Movement {
protected Set<BetterBlockPos> calculateValidPositions() {
BetterBlockPos diagA = new BetterBlockPos(src.x, src.y, dest.z);
BetterBlockPos diagB = new BetterBlockPos(dest.x, src.y, src.z);
if (dest.y != src.y) { // only if allowDiagonalDescend
if (dest.y < src.y) {
return ImmutableSet.of(src, dest.up(), diagA, diagB, dest, diagA.down(), diagB.down());
}
if (dest.y > src.y) {
return ImmutableSet.of(src, src.up(), diagA, diagB, dest, diagA.up(), diagB.up());
}
return ImmutableSet.of(src, dest, diagA, diagB);
}
public static void cost(CalculationContext context, int x, int y, int z, int destX, int destZ, MutableMoveResult res) {
IBlockState destInto = context.get(destX, y, destZ);
if (!MovementHelper.canWalkThrough(context.bsi, destX, y, destZ, destInto) || !MovementHelper.canWalkThrough(context.bsi, destX, y + 1, destZ)) {
if (!MovementHelper.canWalkThrough(context.bsi, destX, y + 1, destZ)) {
return;
}
IBlockState destWalkOn = context.get(destX, y - 1, destZ);
IBlockState destInto = context.get(destX, y, destZ);
boolean ascend = false;
IBlockState destWalkOn;
boolean descend = false;
if (!MovementHelper.canWalkOn(context.bsi, destX, y - 1, destZ, destWalkOn)) {
descend = true;
if (!context.allowDiagonalDescend || !MovementHelper.canWalkOn(context.bsi, destX, y - 2, destZ) || !MovementHelper.canWalkThrough(context.bsi, destX, y - 1, destZ, destWalkOn)) {
if (!MovementHelper.canWalkThrough(context.bsi, destX, y, destZ, destInto)) {
ascend = true;
if (!context.allowDiagonalAscend || !MovementHelper.canWalkThrough(context.bsi, x, y + 2, z) || !MovementHelper.canWalkOn(context.bsi, destX, y, destZ, destInto) || !MovementHelper.canWalkThrough(context.bsi, destX, y + 2, destZ)) {
return;
}
destWalkOn = destInto;
} else {
destWalkOn = context.get(destX, y - 1, destZ);
if (!MovementHelper.canWalkOn(context.bsi, destX, y - 1, destZ, destWalkOn)) {
descend = true;
if (!context.allowDiagonalDescend || !MovementHelper.canWalkOn(context.bsi, destX, y - 2, destZ) || !MovementHelper.canWalkThrough(context.bsi, destX, y - 1, destZ, destWalkOn)) {
return;
}
}
}
double multiplier = WALK_ONE_BLOCK_COST;
// For either possible soul sand, that affects half of our walking
@@ -111,8 +124,43 @@ public class MovementDiagonal extends Movement {
if (cuttingOver2.getBlock() == Blocks.MAGMA_BLOCK || MovementHelper.isLava(cuttingOver2)) {
return;
}
boolean water = false;
IBlockState startState = context.get(x, y, z);
Block startIn = startState.getBlock();
if (MovementHelper.isWater(startState) || MovementHelper.isWater(destInto)) {
if (ascend) {
return;
}
// Ignore previous multiplier
// Whatever we were walking on (possibly soul sand) doesn't matter as we're actually floating on water
// Not even touching the blocks below
multiplier = context.waterWalkSpeed;
water = true;
}
IBlockState pb0 = context.get(x, y, destZ);
IBlockState pb2 = context.get(destX, y, z);
if (ascend) {
boolean ATop = MovementHelper.canWalkThrough(context.bsi, x, y + 2, destZ);
boolean AMid = MovementHelper.canWalkThrough(context.bsi, x, y + 1, destZ);
boolean ALow = MovementHelper.canWalkThrough(context.bsi, x, y, destZ, pb0);
boolean BTop = MovementHelper.canWalkThrough(context.bsi, destX, y + 2, z);
boolean BMid = MovementHelper.canWalkThrough(context.bsi, destX, y + 1, z);
boolean BLow = MovementHelper.canWalkThrough(context.bsi, destX, y, z, pb2);
if ((!(ATop && AMid && ALow) && !(BTop && BMid && BLow)) // no option
|| MovementHelper.avoidWalkingInto(pb0) // bad
|| MovementHelper.avoidWalkingInto(pb2) // bad
|| (ATop && AMid && MovementHelper.canWalkOn(context.bsi, x, y, destZ, pb0)) // we could just ascend
|| (BTop && BMid && MovementHelper.canWalkOn(context.bsi, destX, y, z, pb2)) // we could just ascend
|| (!ATop && AMid && ALow) // head bonk A
|| (!BTop && BMid && BLow)) { // head bonk B
return;
}
res.cost = multiplier * SQRT_2 + JUMP_ONE_BLOCK_COST;
res.x = destX;
res.z = destZ;
res.y = y + 1;
return;
}
double optionA = MovementHelper.getMiningDurationTicks(context, x, y, destZ, pb0, false);
double optionB = MovementHelper.getMiningDurationTicks(context, destX, y, z, pb2, false);
if (optionA != 0 && optionB != 0) {
@@ -140,16 +188,6 @@ public class MovementDiagonal extends Movement {
// and now that option B is fully calculated, see if we can edge around that way
return;
}
boolean water = false;
IBlockState startState = context.get(x, y, z);
Block startIn = startState.getBlock();
if (MovementHelper.isWater(startState) || MovementHelper.isWater(destInto)) {
// Ignore previous multiplier
// Whatever we were walking on (possibly soul sand) doesn't matter as we're actually floating on water
// Not even touching the blocks below
multiplier = context.waterWalkSpeed;
water = true;
}
if (optionA != 0 || optionB != 0) {
multiplier *= SQRT_2 - 0.001; // TODO tune
if (startIn == Blocks.LADDER || startIn == Blocks.VINE) {
@@ -188,6 +226,9 @@ public class MovementDiagonal extends Movement {
} else if (!playerInValidPosition() && !(MovementHelper.isLiquid(ctx, src) && getValidPositions().contains(ctx.playerFeet().up()))) {
return state.setStatus(MovementStatus.UNREACHABLE);
}
if (dest.y > src.y && ctx.player().posY < src.y + 0.1 && ctx.player().collidedHorizontally) {
state.setInput(Input.JUMP, true);
}
if (sprint()) {
state.setInput(Input.SPRINT, true);
}

View File

@@ -153,7 +153,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

@@ -114,7 +114,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) || MovementHelper.isWater(pb1);
if (MovementHelper.isWater(destOn) && throughWater) {
// this happens when assume walk on water is true and this is a traverse in water, which isn't allowed

View File

@@ -26,6 +26,7 @@ import baritone.utils.pathing.PathBase;
import java.util.*;
public class SplicedPath extends PathBase {
private final List<BetterBlockPos> path;
private final List<IMovement> movements;

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;
@@ -71,6 +71,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);
@@ -81,7 +82,19 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
this.name = name;
this.schematic = schematic;
this.realSchematic = null;
this.origin = origin;
int x = origin.getX();
int y = origin.getY();
int z = origin.getZ();
if (Baritone.settings().schematicOrientationX.value) {
x += schematic.widthX();
}
if (Baritone.settings().schematicOrientationY.value) {
y += schematic.heightY();
}
if (Baritone.settings().schematicOrientationZ.value) {
z += schematic.lengthZ();
}
this.origin = new Vec3i(x, y, z);
this.paused = false;
this.layer = 0;
this.observedCompleted = new LongOpenHashSet();
@@ -95,6 +108,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;
@@ -104,6 +122,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
e.printStackTrace();
return false;
}
//noinspection ConstantConditions
if (tag == null) {
return false;
}
@@ -130,7 +149,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) {
@@ -142,14 +166,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() instanceof BlockAir) {
return null;
}
@@ -168,7 +192,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
}
@@ -186,7 +210,8 @@ 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;
@@ -200,7 +225,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++) {
@@ -208,12 +233,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() instanceof BlockAir) {
continue;
}
@@ -238,7 +263,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 (!toPlace.isValidPosition(ctx.world(), new BetterBlockPos(x, y, z))) {
@@ -321,6 +346,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 {
@@ -348,13 +374,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
@@ -392,7 +418,9 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
logDirect("Repeating build in vector " + repeat + ", new origin is " + origin);
return onTick(calcFailed, isSafeToCancel);
}
trim();
if (Baritone.settings().distanceTrim.value) {
trim();
}
Optional<Tuple<BetterBlockPos, Rotation>> toBreak = toBreakNearPlayer(bcc);
if (toBreak.isPresent() && isSafeToCancel && ctx.player().onGround) {
@@ -414,7 +442,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);
@@ -426,14 +454,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;
}
@@ -444,7 +471,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;
}
@@ -452,9 +479,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;
@@ -489,13 +516,14 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
private void recalcNearby(BuilderCalculationContext bcc) {
BetterBlockPos center = ctx.playerFeet();
for (int dx = -5; dx <= 5; dx++) {
for (int dy = -5; dy <= 5; dy++) {
for (int dz = -5; dz <= 5; dz++) {
int radius = Baritone.settings().builderTickScanRadius.value;
for (int dx = -radius; dx <= radius; dx++) {
for (int dy = -radius; dy <= radius; dy++) {
for (int dz = -radius; dz <= radius; dz++) {
int x = center.x + dx;
int y = center.y + dy;
int z = center.z + dz;
IBlockState desired = bcc.getSchematic(x, y, z);
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);
@@ -517,15 +545,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));
@@ -550,15 +579,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 BlockFlowingFluid) {
@@ -576,8 +605,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));
}
});
@@ -593,6 +622,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
}
public static class JankyGoalComposite implements Goal {
private final Goal primary;
private final Goal fallback;
@@ -640,8 +670,10 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
return new GoalPlace(pos);
}
boolean allowSameLevel = !(ctx.world().getBlockState(pos.up()).getBlock() instanceof BlockAir);
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)) && placementPlausible(pos, bcc.getSchematic(pos.getX(), pos.getY(), pos.getZ()))) {
//noinspection ConstantConditions
if (MovementHelper.canPlaceAgainst(ctx, pos.offset(facing)) && placementPlausible(pos, bcc.getSchematic(pos.getX(), pos.getY(), pos.getZ(), current))) {
return new GoalAdjacent(pos, pos.offset(facing), allowSameLevel);
}
}
@@ -664,6 +696,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
}
public static class GoalAdjacent extends GoalGetToBlock {
private boolean allowSameLevel;
private BlockPos no;
@@ -696,6 +729,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
}
public static class GoalPlace extends GoalBlock {
public GoalPlace(BlockPos placeAt) {
super(placeAt.up());
}
@@ -722,7 +756,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);
@@ -752,7 +786,8 @@ 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;
@@ -760,7 +795,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();
@@ -770,9 +805,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;
}
@@ -783,7 +818,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() instanceof BlockAir) {
@@ -791,7 +826,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
@@ -817,7 +852,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() instanceof BlockAir) {
// it should be air

View File

@@ -173,6 +173,7 @@ public final class ExploreProcess extends BaritoneProcessHelper implements IExpl
}
private interface IChunkFilter {
Status isAlreadyExplored(int chunkX, int chunkZ);
int countRemain();
@@ -205,6 +206,7 @@ public final class ExploreProcess extends BaritoneProcessHelper implements IExpl
}
private class JsonChunkFilter implements IChunkFilter {
private final boolean invert; // if true, the list is interpreted as a list of chunks that are NOT explored, if false, the list is interpreted as a list of chunks that ARE explored
private final LongOpenHashSet inFilter;
private final MyChunkPos[] positions;
@@ -257,6 +259,7 @@ public final class ExploreProcess extends BaritoneProcessHelper implements IExpl
}
private class EitherChunk implements IChunkFilter {
private final IChunkFilter a;
private final IChunkFilter b;

View File

@@ -110,13 +110,19 @@ public final class FarmProcess extends BaritoneProcessHelper implements IFarmPro
SUGARCANE(Blocks.SUGAR_CANE, null) {
@Override
public boolean readyToHarvest(World world, BlockPos pos, IBlockState state) {
return world.getBlockState(pos.down()).getBlock() instanceof BlockReed;
if (Baritone.settings().replantCrops.value) {
return world.getBlockState(pos.down()).getBlock() instanceof BlockReed;
}
return true;
}
},
CACTUS(Blocks.CACTUS, null) {
@Override
public boolean readyToHarvest(World world, BlockPos pos, IBlockState state) {
return world.getBlockState(pos.down()).getBlock() instanceof BlockCactus;
if (Baritone.settings().replantCrops.value) {
return world.getBlockState(pos.down()).getBlock() instanceof BlockCactus;
}
return true;
}
};
public final Block block;
@@ -164,10 +170,13 @@ public final class FarmProcess extends BaritoneProcessHelper implements IFarmPro
for (Harvest harvest : Harvest.values()) {
scan.add(harvest.block);
}
scan.add(Blocks.FARMLAND);
if (Baritone.settings().replantNetherWart.value) {
scan.add(Blocks.SOUL_SAND);
if (Baritone.settings().replantCrops.value) {
scan.add(Blocks.FARMLAND);
if (Baritone.settings().replantNetherWart.value) {
scan.add(Blocks.SOUL_SAND);
}
}
if (Baritone.settings().mineGoalUpdateInterval.value != 0 && tickCount++ % Baritone.settings().mineGoalUpdateInterval.value == 0) {
Baritone.getExecutor().execute(() -> locations = WorldScanner.INSTANCE.scanChunkRadius(ctx, scan, 256, 10, 10));
}

View File

@@ -29,7 +29,6 @@ import baritone.utils.BaritoneProcessHelper;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.BlockPos;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
@@ -83,11 +82,11 @@ public final class FollowProcess extends BaritoneProcessHelper implements IFollo
private void scanWorld() {
cache = Stream.of(ctx.world().loadedEntityList, ctx.world().playerEntities)
.flatMap(List::stream)
.filter(this::followable)
.filter(this.filter)
.distinct()
.collect(Collectors.toCollection(ArrayList::new));
.flatMap(List::stream)
.filter(this::followable)
.filter(this.filter)
.distinct()
.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;
@@ -32,7 +33,10 @@ import net.minecraft.init.Blocks;
import net.minecraft.inventory.ContainerPlayer;
import net.minecraft.util.math.BlockPos;
import java.util.*;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
public final class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBlockProcess {
@@ -171,7 +175,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;
@@ -59,7 +55,7 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
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 +69,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(), ctx.world(), null, 0).asItem();
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.getDisplayName(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 +143,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 +191,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 +212,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 +281,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(), world, null, 0).asItem();
Item ore = block.asItem();
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 +297,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 +346,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 +355,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 +373,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 +400,23 @@ 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;
this.mine(quantity, (BlockOptionalMetaLookup) null);
return;
}
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,130 @@
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.
* <p>
* 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,118 @@
package baritone.selection;
import baritone.Baritone;
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(Baritone baritone) {
new SelectionRenderer(baritone, 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,57 @@
package baritone.selection;
import baritone.Baritone;
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(Baritone baritone, 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

@@ -19,9 +19,7 @@ package baritone.utils;
import baritone.api.utils.Helper;
import baritone.api.utils.IPlayerContext;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
/**
@@ -30,34 +28,43 @@ import net.minecraft.util.math.RayTraceResult;
*/
public final class BlockBreakHelper implements Helper {
private final IPlayerContext ctx;
private boolean didBreakLastTick;
private final IPlayerContext playerContext;
public BlockBreakHelper(IPlayerContext playerContext) {
this.playerContext = playerContext;
}
private void tryBreakBlock(BlockPos pos, EnumFacing side) {
if (playerContext.playerController().onPlayerDamageBlock(pos, side)) {
playerContext.player().swingArm(EnumHand.MAIN_HAND);
}
BlockBreakHelper(IPlayerContext ctx) {
this.ctx = ctx;
}
public void stopBreakingBlock() {
// The player controller will never be null, but the player can be
if (playerContext.player() != null) {
playerContext.playerController().resetBlockRemoving();
if (ctx.player() != null && didBreakLastTick) {
if (!ctx.playerController().hasBrokenBlock()) {
// insane bypass to check breaking succeeded
ctx.playerController().setHittingBlock(true);
}
ctx.playerController().resetBlockRemoving();
didBreakLastTick = false;
}
}
public void tick(boolean isLeftClick) {
RayTraceResult trace = playerContext.objectMouseOver();
RayTraceResult trace = ctx.objectMouseOver();
boolean isBlockTrace = trace != null && trace.type == RayTraceResult.Type.BLOCK;
if (isLeftClick && isBlockTrace) {
tryBreakBlock(trace.getBlockPos(), trace.sideHit);
if (!didBreakLastTick) {
ctx.playerController().syncHeldItem();
ctx.playerController().clickBlock(trace.getBlockPos(), trace.sideHit);
ctx.player().swingArm(EnumHand.MAIN_HAND);
}
// Attempt to break the block
if (ctx.playerController().onPlayerDamageBlock(trace.getBlockPos(), trace.sideHit)) {
ctx.player().swingArm(EnumHand.MAIN_HAND);
}
ctx.playerController().setHittingBlock(false);
didBreakLastTick = true;
} else if (didBreakLastTick) {
stopBreakingBlock();

View File

@@ -25,10 +25,11 @@ import net.minecraft.util.EnumHand;
import net.minecraft.util.math.RayTraceResult;
public class BlockPlaceHelper implements Helper {
private final IPlayerContext ctx;
private int rightClickTimer;
public BlockPlaceHelper(IPlayerContext playerContext) {
BlockPlaceHelper(IPlayerContext playerContext) {
this.ctx = playerContext;
}

View File

@@ -22,10 +22,15 @@ import baritone.api.BaritoneAPI;
import baritone.api.pathing.goals.GoalBlock;
import baritone.api.pathing.goals.GoalTwoBlocks;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.Helper;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.*;
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 org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
@@ -34,6 +39,7 @@ import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.Collections;
import static baritone.api.utils.command.IBaritoneChatControl.FORCE_COMMAND_PREFIX;
import static org.lwjgl.opengl.GL11.*;
public class GuiClick extends GuiScreen {
@@ -74,7 +80,16 @@ public class GuiClick extends GuiScreen {
public boolean mouseReleased(double mouseX, double mouseY, int mouseButton) {
if (mouseButton == 0) {
if (clickStart != null && !clickStart.equals(currentMouseOver)) {
((Baritone) BaritoneAPI.getProvider().getPrimaryBaritone()).getBuilderProcess().clearArea(clickStart, currentMouseOver);
BaritoneAPI.getProvider().getPrimaryBaritone().getSelectionManager().removeAllSelections();
BaritoneAPI.getProvider().getPrimaryBaritone().getSelectionManager().addSelection(BetterBlockPos.from(clickStart), BetterBlockPos.from(currentMouseOver));
ITextComponent component = new TextComponentString("Selection made! For usage: " + Baritone.settings().prefix.value + "help sel");
component.getStyle()
.setColor(TextFormatting.WHITE)
.setClickEvent(new ClickEvent(
ClickEvent.Action.RUN_COMMAND,
FORCE_COMMAND_PREFIX + "help sel"
));
Helper.HELPER.logDirect(component);
clickStart = null;
} else {
BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().setGoalAndPath(new GoalTwoBlocks(currentMouseOver));
@@ -111,7 +126,7 @@ public class GuiClick extends GuiScreen {
GlStateManager.disableDepthTest();
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.enableDepthTest();
GlStateManager.depthMask(true);

View File

@@ -0,0 +1,112 @@
/*
* 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.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.*;
import static org.lwjgl.opengl.GL11.*;
public interface IRenderer {
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer();
RenderManager renderManager = Helper.mc.getRenderManager();
Settings settings = BaritoneAPI.getSettings();
static void glColor(Color color, float alpha) {
float[] colorComponents = color.getColorComponents(null);
GlStateManager.color4f(colorComponents[0], colorComponents[1], colorComponents[2], alpha);
}
static void startLines(Color color, float alpha, float lineWidth, boolean ignoreDepth) {
GlStateManager.enableBlend();
GlStateManager.disableLighting();
GlStateManager.blendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
glColor(color, alpha);
GlStateManager.lineWidth(lineWidth);
GlStateManager.disableTexture2D();
GlStateManager.depthMask(false);
if (ignoreDepth) {
GlStateManager.disableDepthTest();
}
}
static void startLines(Color color, float lineWidth, boolean ignoreDepth) {
startLines(color, .4f, lineWidth, ignoreDepth);
}
static void endLines(boolean ignoredDepth) {
if (ignoredDepth) {
GlStateManager.enableDepthTest();
}
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

@@ -115,4 +115,4 @@ public final class InputOverrideHandler extends Behavior implements IInputOverri
public BlockBreakHelper getBlockBreakHelper() {
return blockBreakHelper;
}
}
}

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;
@@ -52,19 +49,18 @@ import static org.lwjgl.opengl.GL11.*;
* @author Brady
* @since 8/9/2018
*/
public final class PathRenderer implements Helper {
public final class PathRenderer implements IRenderer {
private static final ResourceLocation TEXTURE_BEACON_BEAM = new ResourceLocation("textures/entity/beacon_beam.png");
private static final Tessellator TESSELLATOR = Tessellator.getInstance();
private static final BufferBuilder BUFFER = TESSELLATOR.getBuffer();
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().getDimension().getType().getId();
@@ -75,7 +71,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");
@@ -84,19 +80,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);
@@ -104,60 +101,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.disableTexture2D();
GlStateManager.depthMask(false);
if (Baritone.settings().renderPathIgnoreDepth.value) {
GlStateManager.disableDepthTest();
}
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,106 +154,60 @@ public final class PathRenderer implements Helper {
}
alpha = 0.4F * (1.0F - (float) (i - fadeStart) / (float) (fadeEnd - fadeStart));
}
GlStateManager.color4f(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.enableDepthTest();
}
//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.blendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
GlStateManager.color4f(color.getColorComponents(null)[0], color.getColorComponents(null)[1], color.getColorComponents(null)[2], 0.4F);
GlStateManager.lineWidth(Baritone.settings().pathRenderLineWidthPixels.value);
GlStateManager.disableTexture2D();
GlStateManager.depthMask(false);
if (Baritone.settings().renderSelectionBoxesIgnoreDepth.value) {
GlStateManager.disableDepthTest();
}
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);
VoxelShape shape = state.getShape(player.world, pos);
AxisAlignedBB toDraw = shape.isEmpty() ? VoxelShapes.fullCube().getBoundingBox() : shape.getBoundingBox();
toDraw = toDraw.offset(pos);
drawAABB(toDraw);
IRenderer.drawAABB(toDraw, .002D);
});
if (Baritone.settings().renderSelectionBoxesIgnoreDepth.value) {
GlStateManager.enableDepthTest();
}
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();
@@ -288,12 +230,13 @@ 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(TEXTURE_BEACON_BEAM);
TileEntityBeaconRenderer a;
if (Baritone.settings().renderGoalIgnoreDepth.value) {
Helper.mc.getTextureManager().bindTexture(TEXTURE_BEACON_BEAM);
if (settings.renderGoalIgnoreDepth.value) {
GlStateManager.disableDepthTest();
}
@@ -313,7 +256,7 @@ public final class PathRenderer implements Helper {
0.25D
);
if (Baritone.settings().renderGoalIgnoreDepth.value) {
if (settings.renderGoalIgnoreDepth.value) {
GlStateManager.enableDepthTest();
}
@@ -335,12 +278,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;
@@ -349,46 +295,34 @@ public final class PathRenderer implements Helper {
return;
}
GlStateManager.enableBlend();
GlStateManager.blendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
GlStateManager.color4f(color.getColorComponents(null)[0], color.getColorComponents(null)[1], color.getColorComponents(null)[2], 0.6F);
GlStateManager.lineWidth(Baritone.settings().goalRenderLineWidthPixels.value);
GlStateManager.disableTexture2D();
GlStateManager.depthMask(false);
if (Baritone.settings().renderGoalIgnoreDepth.value) {
GlStateManager.disableDepthTest();
}
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();
if (Baritone.settings().renderGoalIgnoreDepth.value) {
GlStateManager.enableDepthTest();
}
GlStateManager.depthMask(true);
GlStateManager.enableTexture2D();
GlStateManager.disableBlend();
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();
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

@@ -23,6 +23,7 @@ import baritone.api.process.PathingCommandType;
import baritone.pathing.movement.CalculationContext;
public class PathingCommandContext extends PathingCommand {
public final CalculationContext desiredCalcContext;
public PathingCommandContext(Goal goal, PathingCommandType commandType, CalculationContext context) {

View File

@@ -32,6 +32,7 @@ import net.minecraft.util.math.BlockPos;
import java.util.*;
public class PathingControlManager implements IPathingControlManager {
private final Baritone baritone;
private final HashSet<IBaritoneProcess> processes; // unGh
private final List<IBaritoneProcess> active;

View File

@@ -21,6 +21,7 @@ import baritone.api.utils.input.Input;
import net.minecraft.util.MovementInput;
public class PlayerMovementInput extends MovementInput {
private final InputOverrideHandler handler;
PlayerMovementInput(InputOverrideHandler handler) {

View File

@@ -37,6 +37,7 @@ import java.util.function.Function;
* @author Avery, Brady, leijurv
*/
public class ToolSet {
/**
* A cache mapping a {@link Block} to how long it will take to break
* with this toolset, given the optimum tool is used.
@@ -83,30 +84,39 @@ public class ToolSet {
return itemStack.getItem() instanceof ItemTool ? 1 : -1;
}
public boolean hasSilkTouch(ItemStack stack) {
return EnchantmentHelper.getEnchantmentLevel(Enchantments.SILK_TOUCH, stack) > 0;
}
/**
* Calculate which tool on the hotbar is best for mining
*
* @param b the blockstate to be mined
* @return A byte containing the index in the tools array that worked best
*/
public byte getBestSlot(Block b) {
public byte getBestSlot(Block b, boolean preferSilkTouch) {
byte best = 0;
double value = Double.NEGATIVE_INFINITY;
int materialCost = Integer.MIN_VALUE;
double highestSpeed = Double.NEGATIVE_INFINITY;
int lowestCost = Integer.MIN_VALUE;
boolean bestSilkTouch = false;
IBlockState blockState = b.getDefaultState();
for (byte i = 0; i < 9; i++) {
ItemStack itemStack = player.inventory.getStackInSlot(i);
double v = calculateSpeedVsBlock(itemStack, blockState);
if (v > value) {
value = v;
double speed = calculateSpeedVsBlock(itemStack, blockState);
boolean silkTouch = hasSilkTouch(itemStack);
if (speed > highestSpeed) {
highestSpeed = speed;
best = i;
materialCost = getMaterialCost(itemStack);
} else if (v == value) {
int c = getMaterialCost(itemStack);
if (c < materialCost) {
value = v;
lowestCost = getMaterialCost(itemStack);
bestSilkTouch = silkTouch;
} else if (speed == highestSpeed) {
int cost = getMaterialCost(itemStack);
if ((cost < lowestCost && (silkTouch || !bestSilkTouch)) ||
(preferSilkTouch && !bestSilkTouch && silkTouch)) {
highestSpeed = speed;
best = i;
materialCost = c;
lowestCost = cost;
bestSilkTouch = silkTouch;
}
}
}
@@ -120,7 +130,7 @@ public class ToolSet {
* @return A double containing the destruction ticks with the best tool
*/
private double getBestDestructionTime(Block b) {
ItemStack stack = player.inventory.getStackInSlot(getBestSlot(b));
ItemStack stack = player.inventory.getStackInSlot(getBestSlot(b, false));
return calculateSpeedVsBlock(stack, b.getDefaultState()) * avoidanceMultiplier(b);
}

View File

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

View File

@@ -0,0 +1,18 @@
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

@@ -21,5 +21,6 @@ import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import net.minecraft.world.chunk.Chunk;
public interface IChunkProviderClient {
Long2ObjectMap<Chunk> loadedChunks();
}

View File

@@ -0,0 +1,29 @@
/*
* 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.accessor;
import net.minecraft.util.math.BlockPos;
public interface IPlayerControllerMP {
void setIsHittingBlock(boolean isHittingBlock);
BlockPos getCurrentBlock();
void callSyncCurrentPlayItem();
}

View File

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

View File

@@ -0,0 +1,198 @@
/*
* 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;
import baritone.api.BaritoneAPI;
import baritone.api.IBaritone;
import baritone.api.Settings;
import baritone.api.accessor.IGuiScreen;
import baritone.api.event.events.ChatEvent;
import baritone.api.event.events.TabCompleteEvent;
import baritone.api.event.listener.AbstractGameEventListener;
import baritone.api.utils.Helper;
import baritone.api.utils.SettingsUtil;
import baritone.api.utils.command.argument.CommandArgument;
import baritone.api.utils.command.exception.CommandNotEnoughArgumentsException;
import baritone.api.utils.command.exception.CommandNotFoundException;
import baritone.api.utils.command.execution.ICommandExecution;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import baritone.api.utils.command.helpers.tabcomplete.TabCompleteHelper;
import baritone.api.utils.command.manager.ICommandManager;
import net.minecraft.util.Tuple;
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.net.URI;
import java.net.URISyntaxException;
import java.util.List;
import java.util.Locale;
import java.util.stream.Stream;
import static baritone.api.utils.command.IBaritoneChatControl.FORCE_COMMAND_PREFIX;
public class BaritoneChatControl implements Helper, AbstractGameEventListener {
private static final Settings settings = BaritoneAPI.getSettings();
private final ICommandManager manager;
public BaritoneChatControl(IBaritone baritone) {
this.manager = baritone.getCommandManager();
baritone.getGameEventHandler().registerEventListener(this);
}
@Override
public void onSendChatMessage(ChatEvent event) {
String msg = event.getMessage();
String prefix = settings.prefix.value;
boolean forceRun = msg.startsWith(FORCE_COMMAND_PREFIX);
if ((settings.prefixControl.value && msg.startsWith(prefix)) || forceRun) {
event.cancel();
String commandStr = msg.substring(forceRun ? FORCE_COMMAND_PREFIX.length() : prefix.length());
if (!runCommand(commandStr) && !commandStr.trim().isEmpty()) {
new CommandNotFoundException(ICommandExecution.expand(commandStr).getA()).handle(null, null);
}
} else if ((settings.chatControl.value || settings.chatControlAnyway.value) && runCommand(msg)) {
event.cancel();
}
}
private void logRanCommand(String command, String rest) {
if (settings.echoCommands.value) {
String msg = command + rest;
String toDisplay = settings.censorRanCommands.value ? command + " ..." : msg;
ITextComponent component = new TextComponentString(String.format("> %s", toDisplay));
component.getStyle()
.setColor(TextFormatting.WHITE)
.setHoverEvent(new HoverEvent(
HoverEvent.Action.SHOW_TEXT,
new TextComponentString("Click to rerun command")
))
.setClickEvent(new ClickEvent(
ClickEvent.Action.RUN_COMMAND,
FORCE_COMMAND_PREFIX + msg
));
logDirect(component);
}
}
public boolean runCommand(String msg) {
if (msg.trim().equalsIgnoreCase("damn")) {
logDirect("daniel");
return false;
} else if (msg.trim().equalsIgnoreCase("orderpizza")) {
try {
((IGuiScreen) mc.currentScreen).openLink(new URI("https://www.dominos.com/en/pages/order/"));
} catch (NullPointerException | URISyntaxException ignored) {}
return false;
}
if (msg.isEmpty()) {
return this.runCommand("help");
}
Tuple<String, List<CommandArgument>> pair = ICommandExecution.expand(msg);
String command = pair.getA();
String rest = msg.substring(pair.getA().length());
ArgConsumer argc = new ArgConsumer(this.manager, pair.getB());
if (!argc.hasAny()) {
Settings.Setting setting = settings.byLowerName.get(command.toLowerCase(Locale.US));
if (setting != null) {
logRanCommand(command, rest);
if (setting.getValueClass() == Boolean.class) {
this.manager.execute(String.format("set toggle %s", setting.getName()));
} else {
this.manager.execute(String.format("set %s", setting.getName()));
}
return true;
}
} else if (argc.hasExactlyOne()) {
for (Settings.Setting setting : settings.allSettings) {
if (setting.getName().equals("logger")) {
continue;
}
if (setting.getName().equalsIgnoreCase(pair.getA())) {
logRanCommand(command, rest);
try {
this.manager.execute(String.format("set %s %s", setting.getName(), argc.getString()));
} catch (CommandNotEnoughArgumentsException ignored) {} // The operation is safe
return true;
}
}
}
// If the command exists, then handle echoing the input
if (this.manager.getCommand(pair.getA()) != null) {
logRanCommand(command, rest);
}
return this.manager.execute(pair);
}
@Override
public void onPreTabComplete(TabCompleteEvent.Pre event) {
if (!settings.prefixControl.value) {
return;
}
String prefix = event.prefix.get();
String commandPrefix = settings.prefix.value;
if (!prefix.startsWith(commandPrefix)) {
return;
}
String msg = prefix.substring(commandPrefix.length());
List<CommandArgument> args = CommandArgument.from(msg, true);
Stream<String> stream = tabComplete(msg);
if (args.size() == 1) {
stream = stream.map(x -> commandPrefix + x);
}
event.completions.set(stream.toArray(String[]::new));
}
public Stream<String> tabComplete(String msg) {
try {
List<CommandArgument> args = CommandArgument.from(msg, true);
ArgConsumer argc = new ArgConsumer(this.manager, args);
if (argc.hasAtMost(2)) {
if (argc.hasExactly(1)) {
return new TabCompleteHelper()
.addCommands(this.manager)
.addSettings()
.filterPrefix(argc.getString())
.stream();
}
Settings.Setting setting = settings.byLowerName.get(argc.getString().toLowerCase(Locale.US));
if (setting != null) {
if (setting.getValueClass() == Boolean.class) {
TabCompleteHelper helper = new TabCompleteHelper();
if ((Boolean) setting.value) {
helper.append("true", "false");
} else {
helper.append("false", "true");
}
return helper.filterPrefix(argc.getString()).stream();
} else {
return Stream.of(SettingsUtil.settingValueToString(setting));
}
}
}
return this.manager.tabComplete(msg);
} catch (CommandNotEnoughArgumentsException ignored) { // Shouldn't happen, the operation is safe
return Stream.empty();
}
}
}

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.IBaritone;
import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.goals.GoalAxis;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.exception.CommandException;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class AxisCommand extends Command {
public AxisCommand(IBaritone baritone) {
super(baritone, Arrays.asList("axis", "highway"));
}
@Override
protected void executed(String label, ArgConsumer args) throws CommandException {
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) {
return Stream.empty();
}
@Override
public String getShortDesc() {
return "Set a goal to the axes";
}
@Override
public List<String> getLongDesc() {
return Arrays.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,70 @@
/*
* 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.IBaritone;
import baritone.api.process.IGetToBlockProcess;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.exception.CommandException;
import baritone.api.utils.command.exception.CommandInvalidStateException;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class BlacklistCommand extends Command {
public BlacklistCommand(IBaritone baritone) {
super(baritone, "blacklist");
}
@Override
protected void executed(String label, ArgConsumer args) throws CommandException {
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) {
return Stream.empty();
}
@Override
public String getShortDesc() {
return "Blacklist closest block";
}
@Override
public List<String> getLongDesc() {
return Arrays.asList(
"While going to a block this command blacklists the closest block so that Baritone won't attempt to get to it.",
"",
"Usage:",
"> blacklist"
);
}
}

View File

@@ -0,0 +1,92 @@
/*
* 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.IBaritone;
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.CommandException;
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.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.stream.Stream;
public class BuildCommand extends Command {
private static final File schematicsDir = new File(mc.gameDir, "schematics");
public BuildCommand(IBaritone baritone) {
super(baritone, "build");
}
@Override
protected void executed(String label, ArgConsumer args) throws CommandException {
File file = args.getDatatypePost(RelativeFile.INSTANCE, schematicsDir).getAbsoluteFile();
if (!file.getName().toLowerCase(Locale.US).endsWith(".schematic")) {
file = new File(file.getAbsolutePath() + ".schematic");
}
BetterBlockPos origin = ctx.playerFeet();
BetterBlockPos buildOrigin;
if (args.hasAny()) {
args.requireMax(3);
buildOrigin = args.getDatatypePost(RelativeBlockPos.INSTANCE, 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) throws CommandException {
if (args.hasExactlyOne()) {
return RelativeFile.tabComplete(args, schematicsDir);
} else if (args.has(2)) {
args.get();
return args.tabCompleteDatatype(RelativeBlockPos.INSTANCE);
}
return Stream.empty();
}
@Override
public String getShortDesc() {
return "Build a schematic";
}
@Override
public List<String> getLongDesc() {
return Arrays.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,61 @@
/*
* 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.IBaritone;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.exception.CommandException;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class CancelCommand extends Command {
public CancelCommand(IBaritone baritone) {
super(baritone, Arrays.asList("cancel", "stop"));
}
@Override
protected void executed(String label, ArgConsumer args) throws CommandException {
args.requireMax(0);
baritone.getPathingBehavior().cancelEverything();
logDirect("ok canceled");
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args) {
return Stream.empty();
}
@Override
public String getShortDesc() {
return "Cancel what Baritone is currently doing";
}
@Override
public List<String> getLongDesc() {
return Arrays.asList(
"The cancel command tells Baritone to stop whatever it's currently doing.",
"",
"Usage:",
"> cancel"
);
}
}

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.IBaritone;
import baritone.api.cache.IRememberedInventory;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.exception.CommandException;
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.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Stream;
public class ChestsCommand extends Command {
public ChestsCommand(IBaritone baritone) {
super(baritone, "chests");
}
@Override
protected void executed(String label, ArgConsumer args) throws CommandException {
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) {
return Stream.empty();
}
@Override
public String getShortDesc() {
return "Display remembered inventories";
}
@Override
public List<String> getLongDesc() {
return Arrays.asList(
"The chests command lists remembered inventories, I guess?",
"",
"Usage:",
"> chests"
);
}
}

View File

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

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.IBaritone;
import baritone.api.pathing.goals.GoalBlock;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.exception.CommandException;
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.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class ComeCommand extends Command {
public ComeCommand(IBaritone baritone) {
super(baritone, "come");
}
@Override
protected void executed(String label, ArgConsumer args) throws CommandException {
args.requireMax(0);
Entity entity = mc.getRenderViewEntity();
if (entity == null) {
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) {
return Stream.empty();
}
@Override
public String getShortDesc() {
return "Start heading towards your camera";
}
@Override
public List<String> getLongDesc() {
return Arrays.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.IBaritone;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
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(IBaritone baritone, List<String> names, String shortDesc, String target) {
super(baritone, names);
this.shortDesc = shortDesc;
this.target = target;
}
public CommandAlias(IBaritone baritone, String name, String shortDesc, String target) {
super(baritone, name);
this.shortDesc = shortDesc;
this.target = target;
}
@Override
protected void executed(String label, ArgConsumer args) {
this.baritone.getCommandManager().execute(String.format("%s %s", target, args.rawRest()));
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args) {
return this.baritone.getCommandManager().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,74 @@
/*
* 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.IBaritone;
import baritone.api.utils.command.Command;
import java.util.*;
public final class DefaultCommands {
private DefaultCommands() {}
public static List<Command> createAll(IBaritone baritone) {
Objects.requireNonNull(baritone);
List<Command> commands = new ArrayList<>(Arrays.asList(
new HelpCommand(baritone),
new SetCommand(baritone),
new CommandAlias(baritone, Arrays.asList("modified", "mod", "baritone", "modifiedsettings"), "List modified settings", "set modified"),
new CommandAlias(baritone, "reset", "Reset all settings or just one", "set reset"),
new GoalCommand(baritone),
new PathCommand(baritone),
new ProcCommand(baritone),
new VersionCommand(baritone),
new RepackCommand(baritone),
new BuildCommand(baritone),
new SchematicaCommand(baritone),
new ComeCommand(baritone),
new AxisCommand(baritone),
new CancelCommand(baritone),
new ForceCancelCommand(baritone),
new GcCommand(baritone),
new InvertCommand(baritone),
new TunnelCommand(baritone),
new RenderCommand(baritone),
new FarmCommand(baritone),
new ChestsCommand(baritone),
new FollowCommand(baritone),
new ExploreFilterCommand(baritone),
new ReloadAllCommand(baritone),
new SaveAllCommand(baritone),
new ExploreCommand(baritone),
new BlacklistCommand(baritone),
new FindCommand(baritone),
new MineCommand(baritone),
new ClickCommand(baritone),
new ThisWayCommand(baritone),
new WaypointsCommand(baritone),
new CommandAlias(baritone, "sethome", "Sets your home waypoint", "waypoints save home"),
new CommandAlias(baritone, "home", "Set goal to your home waypoint", "waypoints goal home"),
new SelCommand(baritone)
));
PauseResumeCommands prc = new PauseResumeCommands(baritone);
commands.add(prc.pauseCommand);
commands.add(prc.resumeCommand);
commands.add(prc.pausedCommand);
return Collections.unmodifiableList(commands);
}
}

View File

@@ -0,0 +1,74 @@
/*
* 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.IBaritone;
import baritone.api.pathing.goals.GoalXZ;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.datatypes.RelativeGoalXZ;
import baritone.api.utils.command.exception.CommandException;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class ExploreCommand extends Command {
public ExploreCommand(IBaritone baritone) {
super(baritone, "explore");
}
@Override
protected void executed(String label, ArgConsumer args) throws CommandException {
if (args.hasAny()) {
args.requireExactly(2);
} else {
args.requireMax(0);
}
GoalXZ goal = args.hasAny()
? args.getDatatypePost(RelativeGoalXZ.INSTANCE, 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) {
if (args.hasAtMost(2)) {
return args.tabCompleteDatatype(RelativeGoalXZ.INSTANCE);
}
return Stream.empty();
}
@Override
public String getShortDesc() {
return "Explore things";
}
@Override
public List<String> getLongDesc() {
return Arrays.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,91 @@
/*
* 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.IBaritone;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.datatypes.RelativeFile;
import baritone.api.utils.command.exception.CommandException;
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.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class ExploreFilterCommand extends Command {
public ExploreFilterCommand(IBaritone baritone) {
super(baritone, "explorefilter");
}
@Override
protected void executed(String label, ArgConsumer args) throws CommandException {
args.requireMax(2);
File file = args.getDatatypePost(RelativeFile.INSTANCE, mc.gameDir.getAbsoluteFile().getParentFile());
boolean invert = false;
if (args.hasAny()) {
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 IllegalStateException(e);
}
logDirect(String.format("Explore filter applied. Inverted: %s", Boolean.toString(invert)));
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args) throws CommandException {
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 Arrays.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,61 @@
/*
* 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.IBaritone;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.exception.CommandException;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class FarmCommand extends Command {
public FarmCommand(IBaritone baritone) {
super(baritone, "farm");
}
@Override
protected void executed(String label, ArgConsumer args) throws CommandException {
args.requireMax(0);
baritone.getFarmProcess().farm();
logDirect("Farming");
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args) {
return Stream.empty();
}
@Override
public String getShortDesc() {
return "Farm nearby crops";
}
@Override
public List<String> getLongDesc() {
return Arrays.asList(
"The farm command starts farming nearby plants. It harvests mature crops and plants new ones.",
"",
"Usage:",
"> farm"
);
}
}

View File

@@ -0,0 +1,81 @@
/*
* 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.IBaritone;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.datatypes.BlockById;
import baritone.api.utils.command.exception.CommandException;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import net.minecraft.block.Block;
import net.minecraft.util.registry.IRegistry;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class FindCommand extends Command {
public FindCommand(IBaritone baritone) {
super(baritone, "find");
}
@Override
protected void executed(String label, ArgConsumer args) throws CommandException {
List<Block> toFind = new ArrayList<>();
while (args.hasAny()) {
toFind.add(args.getDatatypeFor(BlockById.INSTANCE));
}
BetterBlockPos origin = ctx.playerFeet();
toFind.stream()
.flatMap(block ->
ctx.worldData().getCachedWorld().getLocationsOf(
IRegistry.BLOCK.getKey(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) {
return args.tabCompleteDatatype(BlockById.INSTANCE);
}
@Override
public String getShortDesc() {
return "Find positions of a certain block";
}
@Override
public List<String> getLongDesc() {
return Arrays.asList(
"",
"",
"Usage:",
"> "
);
}
}

View File

@@ -0,0 +1,156 @@
/*
* 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.IBaritone;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.datatypes.EntityClassById;
import baritone.api.utils.command.datatypes.IDatatypeFor;
import baritone.api.utils.command.datatypes.NearbyPlayer;
import baritone.api.utils.command.exception.CommandException;
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.EntityLiving;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.registry.IRegistry;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Stream;
public class FollowCommand extends Command {
public FollowCommand(IBaritone baritone) {
super(baritone, "follow");
}
@Override
protected void executed(String label, ArgConsumer args) throws CommandException {
args.requireMin(1);
FollowGroup group;
FollowList list;
List<Entity> entities = new ArrayList<>();
List<EntityType> 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.hasAny()) {
Object gotten = args.getDatatypeFor(list.datatype);
if (gotten instanceof EntityType) {
//noinspection unchecked
classes.add((EntityType) gotten);
} else {
entities.add((Entity) gotten);
}
}
baritone.getFollowProcess().follow(
classes.isEmpty()
? entities::contains
: e -> classes.stream().anyMatch(c -> c.getEntityClass().isInstance(e))
);
}
if (group != null) {
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(IRegistry.ENTITY_TYPE::getKey)
.map(Objects::requireNonNull)
.map(ResourceLocation::toString)
.forEach(this::logDirect);
}
}
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args) throws CommandException {
if (args.hasExactlyOne()) {
return new TabCompleteHelper()
.append(FollowGroup.class)
.append(FollowList.class)
.filterPrefix(args.getString())
.stream();
} else {
IDatatypeFor followType;
try {
followType = args.getEnum(FollowList.class).datatype;
} catch (NullPointerException e) {
return Stream.empty();
}
while (args.has(2)) {
if (args.peekDatatypeOrNull(followType) == null) {
return Stream.empty();
}
args.get();
}
return args.tabCompleteDatatype(followType);
}
}
@Override
public String getShortDesc() {
return "Follow entity things";
}
@Override
public List<String> getLongDesc() {
return Arrays.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.INSTANCE),
PLAYER(NearbyPlayer.INSTANCE);
final IDatatypeFor datatype;
FollowList(IDatatypeFor datatype) {
this.datatype = datatype;
}
}
}

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

View File

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

View File

@@ -0,0 +1,102 @@
/*
* 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.IBaritone;
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.exception.CommandException;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import baritone.api.utils.command.helpers.tabcomplete.TabCompleteHelper;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class GoalCommand extends Command {
public GoalCommand(IBaritone baritone) {
super(baritone, "goal");
}
@Override
protected void executed(String label, ArgConsumer args) throws CommandException {
ICustomGoalProcess goalProcess = baritone.getCustomGoalProcess();
if (args.hasAny() && Arrays.asList("reset", "clear", "none").contains(args.peekString())) {
args.requireMax(1);
if (goalProcess.getGoal() != null) {
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.getDatatypePost(RelativeGoal.INSTANCE, origin);
goalProcess.setGoal(goal);
logDirect(String.format("Goal: %s", goal.toString()));
}
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args) throws CommandException {
TabCompleteHelper helper = new TabCompleteHelper();
if (args.hasExactlyOne()) {
helper.append("reset", "clear", "none", "~");
} else {
if (args.hasAtMost(3)) {
while (args.has(2)) {
if (args.peekDatatypeOrNull(RelativeCoordinate.INSTANCE) == null) {
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 Arrays.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,125 @@
/*
* 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.IBaritone;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.exception.CommandException;
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 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.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static baritone.api.utils.command.IBaritoneChatControl.FORCE_COMMAND_PREFIX;
public class HelpCommand extends Command {
public HelpCommand(IBaritone baritone) {
super(baritone, Arrays.asList("help", "?"));
}
@Override
protected void executed(String label, ArgConsumer args) throws CommandException {
args.requireMax(1);
if (!args.hasAny() || args.is(Integer.class)) {
Paginator.paginate(
args, new Paginator<>(
this.baritone.getCommandManager().getRegistry().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 = this.baritone.getCommandManager().getCommand(commandName);
if (command == null) {
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) throws CommandException {
if (args.hasExactlyOne()) {
return new TabCompleteHelper()
.addCommands(this.baritone.getCommandManager())
.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 Arrays.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,75 @@
/*
* 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.IBaritone;
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.CommandException;
import baritone.api.utils.command.exception.CommandInvalidStateException;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class InvertCommand extends Command {
public InvertCommand(IBaritone baritone) {
super(baritone, "invert");
}
@Override
protected void executed(String label, ArgConsumer args) throws CommandException {
args.requireMax(0);
ICustomGoalProcess customGoalProcess = baritone.getCustomGoalProcess();
Goal goal;
if ((goal = customGoalProcess.getGoal()) == null) {
throw new CommandInvalidStateException("No goal");
}
if (goal instanceof GoalInverted) {
goal = ((GoalInverted) goal).origin;
} else {
goal = new GoalInverted(goal);
}
customGoalProcess.setGoalAndPath(goal);
logDirect(String.format("Goal: %s", goal.toString()));
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args) {
return Stream.empty();
}
@Override
public String getShortDesc() {
return "Run away from the current goal";
}
@Override
public List<String> getLongDesc() {
return Arrays.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,78 @@
/*
* 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.IBaritone;
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.exception.CommandException;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import baritone.cache.WorldScanner;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class MineCommand extends Command {
public MineCommand(IBaritone baritone) {
super(baritone, "mine");
}
@Override
protected void executed(String label, ArgConsumer args) throws CommandException {
int quantity = args.getAsOrDefault(Integer.class, 0);
args.requireMin(1);
List<BlockOptionalMeta> boms = new ArrayList<>();
while (args.hasAny()) {
boms.add(args.getDatatypeFor(ForBlockOptionalMeta.INSTANCE));
}
WorldScanner.INSTANCE.repack(ctx);
logDirect(String.format("Mining %s", boms.toString()));
baritone.getMineProcess().mine(quantity, boms.toArray(new BlockOptionalMeta[0]));
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args) {
return args.tabCompleteDatatype(BlockById.INSTANCE);
}
@Override
public String getShortDesc() {
return "Mine some blocks";
}
@Override
public List<String> getLongDesc() {
return Arrays.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,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.IBaritone;
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.CommandException;
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.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class PathCommand extends Command {
public PathCommand(IBaritone baritone) {
super(baritone, Arrays.asList("path", "goto"));
}
@Override
protected void executed(String label, ArgConsumer args) throws CommandException {
ICustomGoalProcess customGoalProcess = baritone.getCustomGoalProcess();
Goal goal;
if (args.hasAny()) {
args.requireMax(3);
goal = args.getDatatypePost(RelativeGoal.INSTANCE, ctx.playerFeet());
} else if ((goal = customGoalProcess.getGoal()) == null) {
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) throws CommandException {
if (args.hasAny() && !args.has(4)) {
while (args.has(2)) {
if (args.peekDatatypeOrNull(RelativeCoordinate.INSTANCE) == null) {
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 Arrays.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,172 @@
/*
* 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.IBaritone;
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.CommandException;
import baritone.api.utils.command.exception.CommandInvalidStateException;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
/**
* Contains the pause, resume, and paused commands.
* <p>
* 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 {
Command pauseCommand;
Command resumeCommand;
Command pausedCommand;
public PauseResumeCommands(IBaritone baritone) {
// array for mutability, non-field so reflection can't touch it
final boolean[] paused = {false};
baritone.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(baritone, "pause") {
@Override
protected void executed(String label, ArgConsumer args) throws CommandException {
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) {
return Stream.empty();
}
@Override
public String getShortDesc() {
return "Pauses Baritone until you use resume";
}
@Override
public List<String> getLongDesc() {
return Arrays.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(baritone, "resume") {
@Override
protected void executed(String label, ArgConsumer args) throws CommandException {
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) {
return Stream.empty();
}
@Override
public String getShortDesc() {
return "Resumes Baritone after a pause";
}
@Override
public List<String> getLongDesc() {
return Arrays.asList(
"The resume command tells Baritone to resume whatever it was doing when you last used pause.",
"",
"Usage:",
"> resume"
);
}
};
pausedCommand = new Command(baritone, "paused") {
@Override
protected void executed(String label, ArgConsumer args) throws CommandException {
args.requireMax(0);
logDirect(String.format("Baritone is %spaused", paused[0] ? "" : "not "));
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args) {
return Stream.empty();
}
@Override
public String getShortDesc() {
return "Tells you if Baritone is paused";
}
@Override
public List<String> getLongDesc() {
return Arrays.asList(
"The paused command tells you if Baritone is currently paused by use of the pause command.",
"",
"Usage:",
"> paused"
);
}
};
}
}

View File

@@ -0,0 +1,85 @@
/*
* 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.IBaritone;
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.CommandException;
import baritone.api.utils.command.exception.CommandInvalidStateException;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class ProcCommand extends Command {
public ProcCommand(IBaritone baritone) {
super(baritone, "proc");
}
@Override
protected void executed(String label, ArgConsumer args) throws CommandException {
args.requireMax(0);
IPathingControlManager pathingControlManager = baritone.getPathingControlManager();
IBaritoneProcess process = pathingControlManager.mostRecentInControl().orElse(null);
if (process == null) {
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) {
return Stream.empty();
}
@Override
public String getShortDesc() {
return "View process state information";
}
@Override
public List<String> getLongDesc() {
return Arrays.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,61 @@
/*
* 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.IBaritone;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.exception.CommandException;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class ReloadAllCommand extends Command {
public ReloadAllCommand(IBaritone baritone) {
super(baritone, "reloadall");
}
@Override
protected void executed(String label, ArgConsumer args) throws CommandException {
args.requireMax(0);
ctx.worldData().getCachedWorld().reloadAllFromDisk();
logDirect("Reloaded");
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args) {
return Stream.empty();
}
@Override
public String getShortDesc() {
return "Reloads Baritone's cache for this world";
}
@Override
public List<String> getLongDesc() {
return Arrays.asList(
"The reloadall command reloads Baritone's world cache.",
"",
"Usage:",
"> reloadall"
);
}
}

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.IBaritone;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.exception.CommandException;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class RenderCommand extends Command {
public RenderCommand(IBaritone baritone) {
super(baritone, "render");
}
@Override
protected void executed(String label, ArgConsumer args) throws CommandException {
args.requireMax(0);
BetterBlockPos origin = ctx.playerFeet();
int renderDistance = (mc.gameSettings.renderDistanceChunks + 1) * 16;
mc.worldRenderer.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) {
return Stream.empty();
}
@Override
public String getShortDesc() {
return "Fix glitched chunks";
}
@Override
public List<String> getLongDesc() {
return Arrays.asList(
"The render command fixes glitched chunk rendering without having to reload all of them.",
"",
"Usage:",
"> render"
);
}
}

View File

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

View File

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

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

View File

@@ -0,0 +1,337 @@
/*
* 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.Baritone;
import baritone.api.IBaritone;
import baritone.api.event.events.RenderEvent;
import baritone.api.event.listener.AbstractGameEventListener;
import baritone.api.schematic.*;
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.CommandException;
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.BlockPos;
import net.minecraft.util.math.Vec3i;
import java.awt.*;
import java.util.List;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Stream;
public class SelCommand extends Command {
private ISelectionManager manager = baritone.getSelectionManager();
private BetterBlockPos pos1 = null;
public SelCommand(IBaritone baritone) {
super(baritone, Arrays.asList("sel", "selection", "s"));
baritone.getGameEventHandler().registerEventListener(new AbstractGameEventListener() {
@Override
public void onRenderPass(RenderEvent event) {
if (!Baritone.settings().renderSelectionCorners.value || pos1 == null) {
return;
}
Color color = Baritone.settings().colorSelectionPos1.value;
float opacity = Baritone.settings().selectionOpacity.value;
float lineWidth = Baritone.settings().selectionLineWidth.value;
boolean ignoreDepth = Baritone.settings().renderSelectionIgnoreDepth.value;
IRenderer.startLines(color, opacity, lineWidth, ignoreDepth);
IRenderer.drawAABB(new AxisAlignedBB(pos1, pos1.add(1, 1, 1)));
IRenderer.endLines(ignoreDepth);
}
});
}
@Override
protected void executed(String label, ArgConsumer args) throws CommandException {
Action action = Action.getByName(args.getString());
if (action == null) {
throw new CommandInvalidTypeException(args.consumed(), "an action");
}
if (action == Action.POS1 || action == Action.POS2) {
if (action == Action.POS2 && pos1 == null) {
throw new CommandInvalidStateException("Set pos1 first before using pos2");
}
BetterBlockPos playerPos = mc.getRenderViewEntity() != null ? BetterBlockPos.from(new BlockPos(mc.getRenderViewEntity())) : ctx.playerFeet();
BetterBlockPos pos = args.hasAny() ? args.getDatatypePost(RelativeBlockPos.INSTANCE, playerPos) : playerPos;
args.requireMax(0);
if (action == Action.POS1) {
pos1 = pos;
logDirect("Position 1 has been set");
} else {
manager.addSelection(pos1, pos);
pos1 = null;
logDirect("Selection added");
}
} else if (action == Action.CLEAR) {
args.requireMax(0);
pos1 = null;
logDirect(String.format("Removed %d selections", manager.removeAllSelections().length));
} else if (action == Action.UNDO) {
args.requireMax(0);
if (pos1 != null) {
pos1 = null;
logDirect("Undid pos1");
} else {
ISelection[] selections = manager.getSelections();
if (selections.length < 1) {
throw new CommandInvalidStateException("Nothing to undo!");
} else {
pos1 = manager.removeSelection(selections[selections.length - 1]).pos1();
logDirect("Undid pos2");
}
}
} else if (action == Action.SET || action == Action.WALLS || action == Action.SHELL || action == Action.CLEARAREA || action == Action.REPLACE) {
BlockOptionalMeta type = action == Action.CLEARAREA
? new BlockOptionalMeta(Blocks.AIR)
: args.getDatatypeFor(ForBlockOptionalMeta.INSTANCE);
BlockOptionalMetaLookup replaces = null;
if (action == Action.REPLACE) {
args.requireMin(1);
List<BlockOptionalMeta> replacesList = new ArrayList<>();
replacesList.add(type);
while (args.has(2)) {
replacesList.add(args.getDatatypeFor(ForBlockOptionalMeta.INSTANCE));
}
type = args.getDatatypeFor(ForBlockOptionalMeta.INSTANCE);
replaces = new BlockOptionalMetaLookup(replacesList.toArray(new BlockOptionalMeta[0]));
} else {
args.requireMax(0);
}
ISelection[] selections = manager.getSelections();
if (selections.length == 0) {
throw new CommandInvalidStateException("No selections");
}
BetterBlockPos origin = selections[0].min();
CompositeSchematic composite = new CompositeSchematic(0, 0, 0);
for (ISelection selection : selections) {
BetterBlockPos min = selection.min();
origin = new BetterBlockPos(
Math.min(origin.x, min.x),
Math.min(origin.y, min.y),
Math.min(origin.z, min.z)
);
}
for (ISelection selection : selections) {
Vec3i size = selection.size();
BetterBlockPos min = selection.min();
ISchematic schematic = new FillSchematic(size.getX(), size.getY(), size.getZ(), type);
if (action == Action.WALLS) {
schematic = new WallsSchematic(schematic);
} else if (action == Action.SHELL) {
schematic = new ShellSchematic(schematic);
} else if (action == Action.REPLACE) {
schematic = new ReplaceSchematic(schematic, replaces);
}
composite.put(schematic, min.x - origin.x, min.y - origin.y, min.z - origin.z);
}
baritone.getBuilderProcess().build("Fill", composite, origin);
logDirect("Filling now");
} else if (action == Action.EXPAND || action == Action.CONTRACT || action == Action.SHIFT) {
args.requireExactly(3);
TransformTarget transformTarget = TransformTarget.getByName(args.getString());
if (transformTarget == null) {
throw new CommandInvalidStateException("Invalid transform type");
}
EnumFacing direction = args.getDatatypeFor(ForEnumFacing.INSTANCE);
int blocks = args.getAs(Integer.class);
ISelection[] selections = manager.getSelections();
if (selections.length < 1) {
throw new CommandInvalidStateException("No selections found");
}
selections = transformTarget.transform(selections);
for (ISelection selection : selections) {
if (action == Action.EXPAND) {
manager.expand(selection, direction, blocks);
} else if (action == Action.CONTRACT) {
manager.contract(selection, direction, blocks);
} else {
manager.shift(selection, direction, blocks);
}
}
logDirect(String.format("Transformed %d selections", selections.length));
}
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args) throws CommandException {
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.INSTANCE);
}
} 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.INSTANCE);
}
} 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.INSTANCE);
}
}
}
}
}
return Stream.empty();
}
@Override
public String getShortDesc() {
return "WorldEdit-like commands";
}
@Override
public List<String> getLongDesc() {
return Arrays.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(Arrays.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(Arrays.asList(target.names));
}
return names.toArray(new String[0]);
}
}
}

View File

@@ -0,0 +1,253 @@
/*
* 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.Baritone;
import baritone.api.IBaritone;
import baritone.api.Settings;
import baritone.api.utils.SettingsUtil;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.exception.CommandException;
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.Arrays;
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.IBaritoneChatControl.FORCE_COMMAND_PREFIX;
public class SetCommand extends Command {
public SetCommand(IBaritone baritone) {
super(baritone, Arrays.asList("set", "setting", "settings"));
}
@Override
protected void executed(String label, ArgConsumer args) throws CommandException {
String arg = args.hasAny() ? args.getString().toLowerCase(Locale.US) : "list";
if (Arrays.asList("s", "save").contains(arg)) {
SettingsUtil.save(Baritone.settings());
logDirect("Settings saved");
return;
}
boolean viewModified = Arrays.asList("m", "mod", "modified").contains(arg);
boolean viewAll = Arrays.asList("all", "l", "list").contains(arg);
boolean paginate = viewModified || viewAll;
if (paginate) {
String search = args.hasAny() && args.peekAsOrNull(Integer.class) == null ? args.getString() : "";
args.requireMax(1);
List<? extends Settings.Setting> toPaginate =
(viewModified ? SettingsUtil.modifiedSettings(Baritone.settings()) : Baritone.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 = Baritone.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.hasAny()) {
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(Baritone.settings()).forEach(Settings.Setting::reset);
logDirect("All settings have been reset to their default values");
SettingsUtil.save(Baritone.settings());
return;
}
}
if (toggling) {
args.requireMin(1);
}
String settingName = doingSomething ? args.getString() : arg;
Settings.Setting<?> setting = Baritone.settings().allSettings.stream()
.filter(s -> s.getName().equalsIgnoreCase(settingName))
.findFirst()
.orElse(null);
if (setting == null) {
throw new CommandInvalidTypeException(args.consumed(), "a valid setting");
}
if (!doingSomething && !args.hasAny()) {
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(Baritone.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 && !Baritone.settings().chatControlAnyway.value) ||
setting.getName().equals("chatControlAnyway") && !(Boolean) setting.value && !Baritone.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(Baritone.settings());
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args) throws CommandException {
if (args.hasAny()) {
String arg = args.getString();
if (args.hasExactlyOne() && !Arrays.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 = Baritone.settings().byLowerName.get(arg.toLowerCase(Locale.US));
if (setting != null) {
if (setting.getType() == Boolean.class) {
TabCompleteHelper helper = new TabCompleteHelper();
if ((Boolean) setting.value) {
helper.append("true", "false");
} else {
helper.append("false", "true");
}
return helper.filterPrefix(args.getString()).stream();
} else {
return Stream.of(settingValueToString(setting));
}
}
} else if (!args.hasAny()) {
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 Arrays.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,67 @@
/*
* 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.IBaritone;
import baritone.api.pathing.goals.GoalXZ;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.exception.CommandException;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class ThisWayCommand extends Command {
public ThisWayCommand(IBaritone baritone) {
super(baritone, Arrays.asList("thisway", "forward"));
}
@Override
protected void executed(String label, ArgConsumer args) throws CommandException {
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) {
return Stream.empty();
}
@Override
public String getShortDesc() {
return "Travel in your current direction";
}
@Override
public List<String> getLongDesc() {
return Arrays.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,67 @@
/*
* 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.IBaritone;
import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.goals.GoalStrictDirection;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.exception.CommandException;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class TunnelCommand extends Command {
public TunnelCommand(IBaritone baritone) {
super(baritone, "tunnel");
}
@Override
protected void executed(String label, ArgConsumer args) throws CommandException {
args.requireMax(0);
Goal goal = new GoalStrictDirection(
ctx.playerFeet(),
ctx.player().getHorizontalFacing()
);
baritone.getCustomGoalProcess().setGoalAndPath(goal);
logDirect(String.format("Goal: %s", goal.toString()));
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args) {
return Stream.empty();
}
@Override
public String getShortDesc() {
return "Set a goal to tunnel in your current direction";
}
@Override
public List<String> getLongDesc() {
return Arrays.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,66 @@
/*
* 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.IBaritone;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.exception.CommandException;
import baritone.api.utils.command.exception.CommandInvalidStateException;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class VersionCommand extends Command {
public VersionCommand(IBaritone baritone) {
super(baritone, "version");
}
@Override
protected void executed(String label, ArgConsumer args) throws CommandException {
args.requireMax(0);
String version = getClass().getPackage().getImplementationVersion();
if (version == null) {
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) {
return Stream.empty();
}
@Override
public String getShortDesc() {
return "View the Baritone version";
}
@Override
public List<String> getLongDesc() {
return Arrays.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,331 @@
/*
* 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.IBaritone;
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.CommandException;
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.*;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.Stream;
import static baritone.api.utils.command.IBaritoneChatControl.FORCE_COMMAND_PREFIX;
public class WaypointsCommand extends Command {
public WaypointsCommand(IBaritone baritone) {
super(baritone, Arrays.asList("waypoints", "waypoint", "wp"));
}
@Override
protected void executed(String label, ArgConsumer args) throws CommandException {
Action action = args.hasAny() ? 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.hasAny() ? IWaypoint.Tag.getByName(args.peekString()) : null;
if (tag != null) {
args.get();
}
IWaypoint[] waypoints = tag != null
? ForWaypoints.getWaypointsByTag(this.baritone, tag)
: ForWaypoints.getWaypoints(this.baritone);
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.hasAny() ? args.getString() : "";
BetterBlockPos pos = args.hasAny()
? args.getDatatypePost(RelativeBlockPos.INSTANCE, ctx.playerFeet())
: ctx.playerFeet();
args.requireMax(0);
IWaypoint waypoint = new Waypoint(name, tag, pos);
ForWaypoints.waypoints(this.baritone).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(this.baritone, tag);
for (IWaypoint waypoint : waypoints) {
ForWaypoints.waypoints(this.baritone).removeWaypoint(waypoint);
}
logDirect(String.format("Cleared %d waypoints", waypoints.length));
} else {
IWaypoint[] waypoints = args.getDatatypeFor(ForWaypoints.INSTANCE);
IWaypoint waypoint = null;
if (args.hasAny() && 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];
break;
default:
break;
}
}
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(this.baritone).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) throws CommandException {
if (args.hasAny()) {
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.INSTANCE);
}
} else if (args.has(3) && action == Action.SAVE) {
args.get();
args.get();
return args.tabCompleteDatatype(RelativeBlockPos.INSTANCE);
}
}
}
return Stream.empty();
}
@Override
public String getShortDesc() {
return "Manage waypoints";
}
@Override
public List<String> getLongDesc() {
return Arrays.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(Arrays.asList(action.names));
}
return names.toArray(new String[0]);
}
}
}

View File

@@ -0,0 +1,85 @@
/*
* 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.execution;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.exception.CommandUnhandledException;
import baritone.api.utils.command.exception.ICommandException;
import baritone.api.utils.command.execution.ICommandExecution;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import baritone.utils.command.manager.CommandManager;
import java.util.stream.Stream;
/**
* The default, internal implementation of {@link ICommandExecution}, which is used by {@link CommandManager}
*
* @author LoganDark, Brady
*/
public class CommandExecution implements ICommandExecution {
/**
* The command itself
*/
private final Command command;
/**
* The name this command was called with
*/
private final String label;
/**
* The arg consumer
*/
private final ArgConsumer args;
public CommandExecution(Command command, String label, ArgConsumer args) {
this.command = command;
this.label = label;
this.args = args;
}
@Override
public String getLabel() {
return this.label;
}
@Override
public ArgConsumer getArguments() {
return this.args;
}
@Override
public void execute() {
try {
command.execute(this);
} catch (Throwable t) {
// Create a handleable exception, wrap if needed
ICommandException exception = t instanceof ICommandException
? (ICommandException) t
: new CommandUnhandledException(t);
exception.handle(command, args.args);
}
}
@Override
public Stream<String> tabComplete() {
return command.tabComplete(this);
}
}

View File

@@ -0,0 +1,115 @@
/*
* 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.manager;
import baritone.Baritone;
import baritone.api.IBaritone;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.argument.CommandArgument;
import baritone.api.utils.command.execution.ICommandExecution;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import baritone.api.utils.command.helpers.tabcomplete.TabCompleteHelper;
import baritone.api.utils.command.manager.ICommandManager;
import baritone.api.utils.command.registry.Registry;
import baritone.utils.command.defaults.DefaultCommands;
import baritone.utils.command.execution.CommandExecution;
import net.minecraft.util.Tuple;
import java.util.List;
import java.util.Locale;
import java.util.stream.Stream;
/**
* The default, internal implementation of {@link ICommandManager}
*
* @author Brady
* @since 9/21/2019
*/
public class CommandManager implements ICommandManager {
private final Registry<Command> registry = new Registry<>();
private final Baritone baritone;
public CommandManager(Baritone baritone) {
this.baritone = baritone;
DefaultCommands.createAll(baritone).forEach(this.registry::register);
}
@Override
public IBaritone getBaritone() {
return this.baritone;
}
@Override
public Registry<Command> getRegistry() {
return this.registry;
}
@Override
public Command getCommand(String name) {
for (Command command : this.registry.entries) {
if (command.names.contains(name.toLowerCase(Locale.US))) {
return command;
}
}
return null;
}
@Override
public boolean execute(String string) {
return this.execute(ICommandExecution.expand(string));
}
@Override
public boolean execute(Tuple<String, List<CommandArgument>> expanded) {
ICommandExecution execution = this.from(expanded);
if (execution != null) {
execution.execute();
}
return execution != null;
}
@Override
public Stream<String> tabComplete(Tuple<String, List<CommandArgument>> expanded) {
ICommandExecution execution = this.from(expanded);
return execution == null ? Stream.empty() : execution.tabComplete();
}
@Override
public Stream<String> tabComplete(String prefix) {
Tuple<String, List<CommandArgument>> pair = ICommandExecution.expand(prefix, true);
String label = pair.getA();
List<CommandArgument> args = pair.getB();
if (args.isEmpty()) {
return new TabCompleteHelper()
.addCommands(this.baritone.getCommandManager())
.filterPrefix(label)
.stream();
} else {
return tabComplete(pair);
}
}
private ICommandExecution from(Tuple<String, List<CommandArgument>> expanded) {
String label = expanded.getA();
ArgConsumer args = new ArgConsumer(this, expanded.getB());
Command command = this.getCommand(label);
return command == null ? null : new CommandExecution(command, label, args);
}
}

View File

@@ -32,6 +32,7 @@ import java.util.Collections;
import java.util.List;
public class Avoidance {
private final int centerX;
private final int centerY;
private final int centerZ;

View File

@@ -25,6 +25,7 @@ import baritone.pathing.movement.CalculationContext;
import it.unimi.dsi.fastutil.longs.Long2DoubleOpenHashMap;
public final class Favoring {
private final Long2DoubleOpenHashMap favorings;
public Favoring(IPlayerContext ctx, IPath previous, CalculationContext context) {

View File

@@ -25,6 +25,7 @@ import baritone.api.pathing.movement.ActionCosts;
* @author leijurv
*/
public final class MutableMoveResult {
public int x;
public int y;
public int z;

View File

@@ -26,6 +26,7 @@ import baritone.utils.BlockStateInterface;
import net.minecraft.util.math.BlockPos;
public abstract class PathBase implements IPath {
@Override
public PathBase cutoffAtLoadedChunks(Object bsi0) { // <-- cursed cursed cursed
if (!Baritone.settings().cutoffAtLoadBoundary.value) {

View File

@@ -19,6 +19,7 @@ package baritone.utils.player;
import baritone.api.utils.Helper;
import baritone.api.utils.IPlayerController;
import baritone.utils.accessor.IPlayerControllerMP;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.client.multiplayer.WorldClient;
import net.minecraft.entity.player.EntityPlayer;
@@ -42,6 +43,16 @@ public enum PrimaryPlayerController implements IPlayerController, Helper {
INSTANCE;
@Override
public void syncHeldItem() {
((IPlayerControllerMP) mc.playerController).callSyncCurrentPlayItem();
}
@Override
public boolean hasBrokenBlock() {
return ((IPlayerControllerMP) mc.playerController).getCurrentBlock().getY() == -1;
}
@Override
public boolean onPlayerDamageBlock(BlockPos pos, EnumFacing side) {
return mc.playerController.onPlayerDamageBlock(pos, side);
@@ -57,11 +68,6 @@ public enum PrimaryPlayerController implements IPlayerController, Helper {
return mc.playerController.windowClick(windowId, slotId, mouseButton, type, player);
}
@Override
public void setGameType(GameType type) {
mc.playerController.setGameType(type);
}
@Override
public GameType getGameType() {
return mc.playerController.getCurrentGameType();
@@ -69,7 +75,6 @@ public enum PrimaryPlayerController implements IPlayerController, Helper {
@Override
public EnumActionResult processRightClickBlock(EntityPlayerSP player, World world, BlockPos pos, EnumFacing direction, Vec3d vec, EnumHand hand) {
// primaryplayercontroller is always in a WorldClient so this is ok
return mc.playerController.processRightClickBlock(player, (WorldClient) world, pos, direction, vec, hand);
}
@@ -77,4 +82,14 @@ public enum PrimaryPlayerController implements IPlayerController, Helper {
public EnumActionResult processRightClick(EntityPlayerSP player, World world, EnumHand hand) {
return mc.playerController.processRightClick(player, world, hand);
}
@Override
public boolean clickBlock(BlockPos loc, EnumFacing face) {
return mc.playerController.clickBlock(loc, face);
}
@Override
public void setHittingBlock(boolean hittingBlock) {
((IPlayerControllerMP) mc.playerController).setIsHittingBlock(hittingBlock);
}
}

View File

@@ -19,23 +19,26 @@ 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

@@ -58,8 +58,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

@@ -21,7 +21,10 @@ import baritone.api.utils.ISchematic;
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;
public final int lengthZ;
@@ -68,7 +71,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

@@ -18,12 +18,14 @@
package baritone.utils.schematic.schematica;
import baritone.api.utils.ISchematic;
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;
public SchematicAdapter(SchematicWorld schematicWorld) {
@@ -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));
}

View File

@@ -39,7 +39,7 @@ public enum SchematicaHelper {
public static Optional<Tuple<ISchematic, BlockPos>> getOpenSchematic() {
return Optional.ofNullable(ClientProxy.schematic)
.map(world -> new Tuple<>(new SchematicAdapter(world), world.position));
.map(world -> new Tuple<>(new SchematicAdapter(world), world.position));
}
}