454 lines
18 KiB
Java
454 lines
18 KiB
Java
/*
|
|
* To change this license header, choose License Headers in Project Properties.
|
|
* To change this template file, choose Tools | Templates
|
|
* and open the template in the editor.
|
|
*/
|
|
package baritone;
|
|
|
|
import baritone.movement.Combat;
|
|
import baritone.movement.MovementManager;
|
|
import baritone.pathfinding.Path;
|
|
import baritone.pathfinding.PathFinder;
|
|
import baritone.pathfinding.actions.Action;
|
|
import baritone.pathfinding.actions.ActionPlaceOrBreak;
|
|
import baritone.pathfinding.goals.Goal;
|
|
import baritone.pathfinding.goals.GoalComposite;
|
|
import baritone.schematic.SchematicBuilder;
|
|
import baritone.ui.LookManager;
|
|
import baritone.util.Autorun;
|
|
import baritone.util.Manager;
|
|
import baritone.util.ManagerTick;
|
|
import baritone.util.Memory;
|
|
import baritone.util.Out;
|
|
import baritone.util.ToolSet;
|
|
import java.io.IOException;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.logging.Level;
|
|
import java.util.logging.Logger;
|
|
import net.minecraft.block.Block;
|
|
import net.minecraft.block.state.IBlockState;
|
|
import net.minecraft.client.Minecraft;
|
|
import net.minecraft.client.entity.EntityPlayerSP;
|
|
import net.minecraft.entity.Entity;
|
|
import net.minecraft.util.math.BlockPos;
|
|
import net.minecraft.world.World;
|
|
|
|
/**
|
|
*
|
|
* @author leijurv
|
|
*/
|
|
public class Baritone {
|
|
|
|
public static BlockPos playerFeet = null;
|
|
public static World world = null;
|
|
|
|
public static boolean allowDiagonal = true;
|
|
public static boolean farf5 = false;
|
|
public static boolean slowPath = false;
|
|
public static boolean pause = false;
|
|
public static boolean overrideF3 = false;
|
|
public static boolean sketchytracer = false;
|
|
public static boolean allowVerticalMotion = true;
|
|
public static boolean actuallyPutMessagesInChat = false;
|
|
public static boolean isThereAnythingInProgress = false;
|
|
public static boolean fullBright = true;
|
|
public static boolean plsCancel = false;
|
|
public static int tickNumber = 0;
|
|
public static boolean ticktimer = false;
|
|
public static boolean allowBreakOrPlace = true;
|
|
public static boolean hasThrowaway = true;
|
|
public static Path currentPath = null;
|
|
public static Path nextPath = null;
|
|
public static boolean calculatingNext = false;
|
|
public static Goal goal = null;
|
|
static int numTicksInInventoryOrCrafting = 0;
|
|
public static BlockPos death;
|
|
public static long lastDeath = 0;
|
|
public static SchematicBuilder currentBuilder = null;
|
|
|
|
public static void main(String[] args) throws IOException, InterruptedException {
|
|
String s = Autorun.class.getProtectionDomain().getCodeSource().getLocation().toString().substring(5) + "../../autorun/runmc.command";
|
|
if (s.contains("jar")) {
|
|
Autorun.start(args);
|
|
return;
|
|
}
|
|
Autorun.runprocess("/usr/local/bin/ant jar");
|
|
Autorun.runprocess("java -Djava.library.path=jars/versions/1.12.2/1.12.2-natives/ -jar dist/Baritone.jar");
|
|
}
|
|
|
|
public static IBlockState get(BlockPos pos) { // wrappers for future 1.13 compat
|
|
return world.getBlockState(pos);
|
|
}
|
|
|
|
public static Block getBlock(BlockPos pos) {
|
|
return get(pos).getBlock();
|
|
}
|
|
|
|
/**
|
|
* Called by minecraft.java
|
|
*/
|
|
public static void onTick() {
|
|
try {
|
|
long start = System.currentTimeMillis();
|
|
onTick1();
|
|
long end = System.currentTimeMillis();
|
|
long time = end - start;
|
|
if (ticktimer && time > 3) {
|
|
Out.gui("Tick took " + time + "ms", Out.Mode.Debug);
|
|
Out.log("Tick took " + time + "ms");
|
|
}
|
|
} catch (Exception ex) {
|
|
Out.log("Exception");
|
|
Logger.getLogger(Baritone.class.getName()).log(Level.SEVERE, null, ex);
|
|
}
|
|
}
|
|
|
|
public static void onTick1() {
|
|
if (pause) {
|
|
Manager.tick(LookManager.class, true);
|
|
MovementManager.clearMovement();
|
|
return;
|
|
}
|
|
world = Minecraft.getMinecraft().world;
|
|
if (world == null || Minecraft.getMinecraft().player == null) {
|
|
Baritone.cancelPath();
|
|
Baritone.plsCancel = true;
|
|
return;
|
|
}
|
|
MovementManager.leftPressTime = 0;
|
|
MovementManager.rightPressTime = 0;
|
|
if (MovementManager.isLeftClick) {
|
|
MovementManager.leftPressTime = 5;
|
|
}
|
|
if (MovementManager.isRightClick) {
|
|
MovementManager.rightPressTime = 5;
|
|
}
|
|
Manager.tick(LookManager.class, true);
|
|
|
|
/*MovementManager.isLeftClick = false;
|
|
MovementManager.isRightClick = false;
|
|
MovementManager.jumping = false;
|
|
MovementManager.sneak = false;*/
|
|
MovementManager.clearMovement();
|
|
EntityPlayerSP thePlayer = Minecraft.getMinecraft().player;
|
|
World theWorld = Minecraft.getMinecraft().world;
|
|
playerFeet = new BlockPos(thePlayer.posX, thePlayer.posY, thePlayer.posZ);
|
|
if (thePlayer.isDead && System.currentTimeMillis() > lastDeath + 10000) {
|
|
death = playerFeet;
|
|
lastDeath = System.currentTimeMillis();
|
|
Out.gui("Saved death position (" + death + "). do /death to set goal.", Out.Mode.Minimal);
|
|
//impact handles this
|
|
//thePlayer.respawnPlayer();
|
|
//Minecraft.getMinecraft().displayGuiScreen(null);
|
|
}
|
|
tickNumber++;
|
|
hasThrowaway = ActionPlaceOrBreak.hasthrowaway();
|
|
ManagerTick.tickPath = true;
|
|
Manager.tick(LookManager.class);
|
|
|
|
BlockPos ts = whatAreYouLookingAt();
|
|
if (ts != null) {
|
|
Memory.scanBlock(ts);
|
|
}
|
|
if (currentBuilder != null) {
|
|
currentBuilder.tick();
|
|
}
|
|
if (currentPath != null && ManagerTick.tickPath) {
|
|
if (currentPath.tick()) {
|
|
Goal currentPathGoal = currentPath == null ? null : currentPath.goal;
|
|
if (currentPath != null && currentPath.failed) {
|
|
clearPath();
|
|
Out.gui("Recalculating because path failed", Out.Mode.Standard);
|
|
nextPath = null;
|
|
if (isAir(playerFeet.down())) {//sometimes we are jumping and we make a path that starts in the air and then jumps up, which is impossible
|
|
Out.gui("DOING THE JANKY THING, WARNING", Out.Mode.Debug);
|
|
findPathInNewThread(playerFeet.down(), true);
|
|
} else {
|
|
findPathInNewThread(playerFeet, true);
|
|
}
|
|
return;
|
|
} else {
|
|
clearPath();
|
|
}
|
|
currentPath = null;
|
|
if (goal.isInGoal(playerFeet)) {
|
|
Out.gui("All done. At goal", Out.Mode.Standard);
|
|
nextPath = null;
|
|
} else {
|
|
Out.gui("Done with segment", Out.Mode.Debug);
|
|
if (nextPath != null || calculatingNext) {
|
|
if (calculatingNext) {
|
|
calculatingNext = false;
|
|
Out.gui("Patiently waiting to finish", Out.Mode.Debug);
|
|
} else {
|
|
currentPath = nextPath;
|
|
nextPath = null;
|
|
if (!currentPath.start.equals(playerFeet)) {
|
|
//Out.gui("The next path starts at " + currentPath.start + " but I'm at " + playerFeet + ". not doing it", true);
|
|
currentPath = null;
|
|
findPathInNewThread(playerFeet, true);
|
|
} else {
|
|
Out.gui("Going onto next", Out.Mode.Debug);
|
|
if (!currentPath.goal.isInGoal(currentPath.end)) {
|
|
planAhead();
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
Out.gui("Hmm. I'm not actually at the goal. Recalculating.", Out.Mode.Debug);
|
|
findPathInNewThread(playerFeet, (currentPathGoal != null && goal != null) ? !(currentPathGoal instanceof GoalComposite) && currentPathGoal.toString().equals(goal.toString()) : true);
|
|
}
|
|
}
|
|
} else {
|
|
if (Action.isWater(theWorld.getBlockState(playerFeet).getBlock())) {
|
|
//if (Action.isWater(theWorld.getBlockState(playerFeet.down()).getBlock()) || !Action.canWalkOn(playerFeet.down()) || Action.isWater(theWorld.getBlockState(playerFeet.up()).getBlock())) {
|
|
//if water is deeper than one block, or we can't walk on what's below the water, or our head is in water, jump
|
|
Out.log("Jumping because in water");
|
|
MovementManager.jumping = true;
|
|
//}
|
|
}
|
|
if (nextPath != null) {
|
|
for (int i = 1; i < 20 && i < nextPath.path.size(); i++) {
|
|
if (playerFeet.equals(nextPath.path.get(i))) {
|
|
Out.gui("Jumping to position " + i + " in nextpath", Out.Mode.Debug);
|
|
currentPath = nextPath;
|
|
currentPath.calculatePathPosition();
|
|
nextPath = null;
|
|
if (!currentPath.goal.isInGoal(currentPath.end)) {
|
|
planAhead();
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
LookManager.nudgeToLevel();
|
|
}
|
|
}
|
|
/*if (Minecraft.getMinecraft().currentScreen != null && (Minecraft.getMinecraft().currentScreen instanceof GuiCrafting || Minecraft.getMinecraft().currentScreen instanceof GuiInventory || Minecraft.getMinecraft().currentScreen instanceof GuiFurnace)) {
|
|
MovementManager.isLeftClick = false;
|
|
MovementManager.leftPressTime = -5;
|
|
numTicksInInventoryOrCrafting++;
|
|
if (numTicksInInventoryOrCrafting > 20 * 20) {
|
|
Minecraft.getMinecraft().player.closeScreen();
|
|
numTicksInInventoryOrCrafting = 0;
|
|
}
|
|
} else {
|
|
numTicksInInventoryOrCrafting = 0;
|
|
}*/ // impact does this
|
|
if (isThereAnythingInProgress && Action.isWater(theWorld.getBlockState(playerFeet).getBlock())) {
|
|
if (Action.isWater(theWorld.getBlockState(playerFeet.down()).getBlock()) || !Action.canWalkOn(playerFeet.down()) || Action.isWater(theWorld.getBlockState(playerFeet.up()).getBlock())) {
|
|
//if water is deeper than one block, or we can't walk on what's below the water, or our head is in water, jump
|
|
Out.log("Jumping because in water and pathfinding");
|
|
MovementManager.jumping = true;
|
|
}
|
|
}
|
|
Manager.tick(LookManager.class, false);
|
|
}
|
|
|
|
public static boolean isPathFinding() {
|
|
return isThereAnythingInProgress;
|
|
}
|
|
|
|
/**
|
|
* Clears movement, clears the current path, and lets go of left click. It
|
|
* purposefully does NOT clear nextPath.
|
|
*/
|
|
public static void clearPath() {
|
|
currentPath = null;
|
|
MovementManager.letGoOfLeftClick();
|
|
MovementManager.clearMovement();
|
|
}
|
|
|
|
public static String info(BlockPos bp) {
|
|
IBlockState state = get(bp);
|
|
Block block = state.getBlock();
|
|
return bp + " " + block + " can walk on: " + Action.canWalkOn(bp) + " can walk through: " + Action.canWalkThrough(bp) + " is full block: " + block.isFullBlock(state) + " is full cube: " + block.isFullCube(state) + " is liquid: " + Action.isLiquid(block) + " is flow: " + Action.isFlowing(bp, state);
|
|
}
|
|
|
|
/**
|
|
* Cancel the path
|
|
*
|
|
*/
|
|
public static void cancelPath() {
|
|
nextPath = null;
|
|
Combat.target = null;
|
|
currentBuilder = null;
|
|
clearPath();
|
|
}
|
|
|
|
public static boolean isAir(BlockPos pos) {
|
|
return Minecraft.getMinecraft().world.getBlockState(pos).getBlock().equals(Block.getBlockById(0));
|
|
}
|
|
|
|
public static void findPathInNewThread(final boolean talkAboutIt) {
|
|
findPathInNewThread(playerFeet, talkAboutIt);
|
|
}
|
|
|
|
/**
|
|
* In a new thread, pathfind to target blockpos
|
|
*
|
|
* @param start
|
|
* @param talkAboutIt
|
|
*/
|
|
public static void findPathInNewThread(final BlockPos start, final boolean talkAboutIt) {
|
|
if (isThereAnythingInProgress) {
|
|
return;
|
|
}
|
|
isThereAnythingInProgress = true;
|
|
new Thread() {
|
|
@Override
|
|
public void run() {
|
|
if (talkAboutIt) {
|
|
Out.gui("Starting to search for path from " + start + " to " + goal, Out.Mode.Debug);
|
|
}
|
|
try {
|
|
currentPath = findPath(start);
|
|
} catch (Exception e) {
|
|
}
|
|
isThereAnythingInProgress = false;
|
|
if (!currentPath.goal.isInGoal(currentPath.end)) {
|
|
if (talkAboutIt) {
|
|
Out.gui("I couldn't get all the way to " + goal + ", but I'm going to get as close as I can. " + currentPath.numNodes + " nodes considered", Out.Mode.Standard);
|
|
}
|
|
planAhead();
|
|
} else if (talkAboutIt) {
|
|
Out.gui("Finished finding a path from " + start + " to " + goal + ". " + currentPath.numNodes + " nodes considered", Out.Mode.Debug);
|
|
}
|
|
}
|
|
}.start();
|
|
}
|
|
|
|
/**
|
|
* In a new thread, pathfind from currentPath.end to goal. Store resulting
|
|
* path in nextPath (or in currentPath if calculatingNext was set to false
|
|
* in the meantime).
|
|
*/
|
|
public static void planAhead() {
|
|
if (isThereAnythingInProgress) {
|
|
return;
|
|
}
|
|
isThereAnythingInProgress = true;
|
|
new Thread() {
|
|
@Override
|
|
public void run() {
|
|
Out.gui("Planning ahead", Out.Mode.Debug);
|
|
calculatingNext = true;
|
|
Path path = findPath(currentPath.end);
|
|
isThereAnythingInProgress = false;
|
|
Out.gui("Done planning ahead " + calculatingNext, Out.Mode.Debug);
|
|
if (calculatingNext) {
|
|
nextPath = path;
|
|
} else {
|
|
currentPath = path;
|
|
if (!plsCancel) {
|
|
planAhead();
|
|
}
|
|
}
|
|
calculatingNext = false;
|
|
Out.gui(path.numNodes + " nodes considered, calculated " + path.start + " to " + path.end, Out.Mode.Debug);
|
|
}
|
|
}.start();
|
|
}
|
|
|
|
/**
|
|
* Actually do the pathfinding
|
|
*
|
|
* @param start
|
|
* @return
|
|
*/
|
|
private static Path findPath(BlockPos start) {
|
|
if (goal == null) {
|
|
Out.gui("babe, please. there is no goal", Out.Mode.Minimal);
|
|
return null;
|
|
}
|
|
try {
|
|
PathFinder pf = new PathFinder(start, goal);
|
|
Path path = pf.calculatePath();
|
|
return path;
|
|
} catch (Exception e) {
|
|
Logger.getLogger(Baritone.class.getName()).log(Level.SEVERE, null, e);
|
|
isThereAnythingInProgress = false;
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* What block is the player looking at
|
|
*
|
|
* @return the position of it
|
|
*/
|
|
public static BlockPos whatAreYouLookingAt() {
|
|
/*Minecraft mc = Minecraft.getMinecraft();
|
|
if (mc.objectMouseOver != null && mc.objectMouseOver.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK) {
|
|
return mc.objectMouseOver.getBlockPos();
|
|
}
|
|
return null;*/
|
|
throw new UnsupportedOperationException("need to figure out what MovingObjectPosition is in 1.12.2");
|
|
}
|
|
|
|
public static void switchToBestTool() {
|
|
BlockPos pos = whatAreYouLookingAt();
|
|
if (pos == null) {
|
|
return;
|
|
}
|
|
Block block = Minecraft.getMinecraft().world.getBlockState(pos).getBlock();
|
|
if (block.equals(Block.getBlockById(0))) {
|
|
return;
|
|
}
|
|
switchtotool(block);
|
|
}
|
|
|
|
public static void switchtotool(Block b) {
|
|
Baritone.switchtotool(b, new ToolSet());
|
|
}
|
|
|
|
public static void switchtotool(Block b, ToolSet ts) {
|
|
Minecraft.getMinecraft().player.inventory.currentItem = ts.getBestSlot(b);
|
|
}
|
|
|
|
public static Entity whatEntityAreYouLookingAt() {
|
|
/*Minecraft mc = Minecraft.getMinecraft();
|
|
if (mc.objectMouseOver != null && mc.objectMouseOver.typeOfHit == MovingObjectPosition.MovingObjectType.ENTITY) {
|
|
return mc.objectMouseOver.entityHit;
|
|
}*/
|
|
throw new UnsupportedOperationException("need to figure out what MovingObjectPosition is in 1.12.2");
|
|
//return null;
|
|
}
|
|
|
|
public static List<String> getDebugGui() {
|
|
if (!overrideF3) {
|
|
return null;
|
|
}
|
|
List<String> list = new ArrayList<String>();
|
|
list.add("§5[§dBaritone§5]§f");
|
|
Class<LookManager> c = LookManager.class;
|
|
list.add("§r[§" + (Manager.enabled(c) ? "a" : "c") + c.getSimpleName() + "§r]");
|
|
|
|
list.add("");
|
|
list.add("Current goal: " + goal);
|
|
list.add("");
|
|
if (currentPath != null) {
|
|
list.add("Current path start: " + currentPath.start);
|
|
list.add("Current path end: " + currentPath.end);
|
|
list.add("Current path ends in current goal: " + (goal == null ? null : goal.isInGoal(currentPath.end)));
|
|
if (!currentPath.goal.equals(goal)) {
|
|
list.add("Current path goal: " + currentPath.goal);
|
|
}
|
|
}
|
|
if (nextPath != null) {
|
|
list.add("");
|
|
list.add("Next path start: " + nextPath.start);
|
|
list.add("Next path end: " + nextPath.end);
|
|
list.add("Next path ends in current goal: " + (goal == null ? null : goal.isInGoal(nextPath.end)));
|
|
}
|
|
return list;
|
|
}
|
|
|
|
public boolean isNull() throws NullPointerException {
|
|
NullPointerException up = new NullPointerException("You are disgusting");
|
|
throw up;
|
|
//To use this surround the call to this message with a try-catch then compare the length of the NullPointerException.getMessage()
|
|
}
|
|
}
|