action world helper and replacement with actions

This commit is contained in:
Leijurv 2018-08-02 13:25:46 -04:00
parent 38e358b077
commit ee5d382693
No known key found for this signature in database
GPG Key ID: 44A3EA646EADAC6A
10 changed files with 167 additions and 59 deletions

View File

@ -4,6 +4,7 @@ import baritone.bot.behavior.Behavior;
import baritone.bot.event.IGameEventListener; import baritone.bot.event.IGameEventListener;
import baritone.bot.event.events.ChatEvent; import baritone.bot.event.events.ChatEvent;
import baritone.bot.event.events.ChunkEvent; import baritone.bot.event.events.ChunkEvent;
import baritone.bot.pathing.action.ActionWorldHelper;
import net.minecraft.client.settings.KeyBinding; import net.minecraft.client.settings.KeyBinding;
import org.lwjgl.input.Keyboard; import org.lwjgl.input.Keyboard;
@ -15,11 +16,15 @@ import java.util.function.Consumer;
*/ */
public final class GameEventHandler implements IGameEventListener { public final class GameEventHandler implements IGameEventListener {
GameEventHandler() {} GameEventHandler() {
}
@Override @Override
public final void onTick() { public final void onTick() {
dispatch(behavior -> onTick()); dispatch(behavior -> onTick());
while (true) {
System.out.println(ActionWorldHelper.lavaFlowing);
}
} }
@Override @Override

View File

@ -1,7 +1,6 @@
package baritone.bot.behavior; package baritone.bot.behavior;
import baritone.bot.pathing.calc.IPath; import baritone.bot.pathing.calc.IPath;
import baritone.bot.pathing.movements.Movement;
import baritone.bot.utils.Helper; import baritone.bot.utils.Helper;
import net.minecraft.util.Tuple; import net.minecraft.util.Tuple;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
@ -25,8 +24,6 @@ public class PathExecution extends Behavior implements Helper {
// TODO the old Path used to keep track of the index in the path // TODO the old Path used to keep track of the index in the path
// and only increment it when the movement said it was done, not when it detected that the player feet had // and only increment it when the movement said it was done, not when it detected that the player feet had
// moved into the next position // moved into the next position
Movement movement = path.subsequentMovement(playerFeet);
//movement.tick()
} else { } else {
Tuple<Double, BlockPos> closest = path.closestPathPos(player.posX, player.posY, player.posZ); Tuple<Double, BlockPos> closest = path.closestPathPos(player.posX, player.posY, player.posZ);
if (closest.getFirst() > MAX_DIST_FROM_PATH) { if (closest.getFirst() > MAX_DIST_FROM_PATH) {

View File

@ -2,14 +2,14 @@ package baritone.bot.pathing.action;
import baritone.bot.Baritone; import baritone.bot.Baritone;
import baritone.bot.event.AbstractGameEventListener; import baritone.bot.event.AbstractGameEventListener;
import baritone.bot.pathing.action.ActionState.ActionStatus;
import baritone.bot.utils.Helper; import baritone.bot.utils.Helper;
import baritone.bot.utils.Utils; import baritone.bot.utils.Utils;
import net.minecraft.util.Tuple; import net.minecraft.util.Tuple;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import baritone.bot.pathing.action.ActionState.ActionStatus;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
public abstract class Action implements AbstractGameEventListener, Helper { public abstract class Action implements AbstractGameEventListener, Helper, ActionWorldHelper {
protected ActionState currentState; protected ActionState currentState;

View File

@ -0,0 +1,119 @@
package baritone.bot.pathing.action;
import baritone.bot.utils.BlockStateInterface;
import net.minecraft.block.*;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.util.math.BlockPos;
/**
* Static helpers for cost calculation
*
* @author leijurv
*/
public interface ActionWorldHelper {
Block waterFlowing = Block.getBlockById(8);
Block waterStill = Block.getBlockById(9);
Block lavaFlowing = Block.getBlockById(10);
Block lavaStill = Block.getBlockById(11);
/**
* Is this block water? Includes both still and flowing
*
* @param b
* @return
*/
static boolean isWater(Block b) {
return waterFlowing.equals(b) || waterStill.equals(b);
}
static boolean isWater(BlockPos bp) {
return isWater(BlockStateInterface.get(bp).getBlock());
}
static boolean isLiquid(Block b) {
return b instanceof BlockLiquid;
//return b != null && (waterFlowing.equals(b) || waterStill.equals(b) || lavaFlowing.equals(b) || lavaStill.equals(b));
}
static boolean isFlowing(BlockPos pos, IBlockState state) {
Block b = state.getBlock();
if (b instanceof BlockLiquid) {
System.out.println("Need to fix get flow check!!!");
//return BlockLiquid.getFlow(Minecraft.getMinecraft().world, pos, state) != -1000.0D;
}
return false;
}
static boolean isLava(Block b) {
return lavaFlowing.equals(b) || lavaStill.equals(b);
}
static boolean isLiquid(BlockPos p) {
return isLiquid(BlockStateInterface.get(p).getBlock());
}
static boolean avoidBreaking(BlockPos pos) {
Block b = BlockStateInterface.get(pos).getBlock();
Block below = BlockStateInterface.get(new BlockPos(pos.getX(), pos.getY() - 1, pos.getZ())).getBlock();
return Block.getBlockFromName("minecraft:ice").equals(b)//ice becomes water, and water can mess up the path
|| isLiquid(new BlockPos(pos.getX(), pos.getY() + 1, pos.getZ()))//don't break anything touching liquid on any side
|| isLiquid(new BlockPos(pos.getX() + 1, pos.getY(), pos.getZ()))
|| isLiquid(new BlockPos(pos.getX() - 1, pos.getY(), pos.getZ()))
|| isLiquid(new BlockPos(pos.getX(), pos.getY(), pos.getZ() + 1))
|| isLiquid(new BlockPos(pos.getX(), pos.getY(), pos.getZ() - 1))
|| (!(b instanceof BlockLilyPad && isWater(below)) && isLiquid(below));//if it's a lilypad above water, it's ok to break, otherwise don't break if its liquid
}
/**
* Can I walk through this block? e.g. air, saplings, torches, etc
*
* @param pos
* @return
*/
static boolean canWalkThrough(BlockPos pos) {
IBlockState state = BlockStateInterface.get(pos);
Block block = state.getBlock();
if (block instanceof BlockLilyPad || block instanceof BlockFire) {//you can't actually walk through a lilypad from the side, and you shouldn't walk through fire
return false;
}
if (isFlowing(pos, state)) {
return false;//don't walk through flowing liquids
}
if (isLiquid(pos.up())) {
return false;//you could drown
}
return block.isPassable(Minecraft.getMinecraft().world, pos);
}
static boolean avoidWalkingInto(BlockPos pos) {
Block block = BlockStateInterface.get(pos).getBlock();
if (isLava(block)) {
return true;
}
if (block instanceof BlockCactus) {
return true;
}
return block instanceof BlockFire;
}
/**
* Can I walk on this block without anything weird happening like me falling
* through? Includes water because we know that we automatically jump on
* lava
*
* @param pos
* @return
*/
static boolean canWalkOn(BlockPos pos) {
IBlockState state = BlockStateInterface.get(pos);
Block block = state.getBlock();
if (block instanceof BlockLadder || block instanceof BlockVine) {
return true;
}
if (isWater(block)) {
return isWater(pos.up());//you can only walk on water if there is water above it
}
return state.isBlockNormalCube() && !isLava(block);
}
}

View File

@ -1,6 +1,6 @@
package baritone.bot.pathing.calc; package baritone.bot.pathing.calc;
import baritone.bot.pathing.movements.Movement; import baritone.bot.pathing.action.Action;
import baritone.bot.utils.Utils; import baritone.bot.utils.Utils;
import net.minecraft.util.Tuple; import net.minecraft.util.Tuple;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
@ -18,7 +18,7 @@ public interface IPath {
* movements.get(i).getDest() should equal positions.get(i+1) * movements.get(i).getDest() should equal positions.get(i+1)
* movements.size() should equal positions.size()-1 * movements.size() should equal positions.size()-1
*/ */
List<Movement> movements(); List<Action> actions();
/** /**
* All positions along the way. * All positions along the way.
@ -32,12 +32,12 @@ public interface IPath {
* @param currentPosition the current position * @param currentPosition the current position
* @return * @return
*/ */
default Movement subsequentMovement(BlockPos currentPosition) { default Action subsequentAction(BlockPos currentPosition) {
List<BlockPos> pos = positions(); List<BlockPos> pos = positions();
List<Movement> moves = movements(); List<Action> actions = actions();
for (int i = 0; i < pos.size(); i++) { for (int i = 0; i < pos.size(); i++) {
if (currentPosition.equals(pos.get(i))) { if (currentPosition.equals(pos.get(i))) {
return moves.get(i); return actions.get(i);
} }
} }
throw new UnsupportedOperationException(currentPosition + " not in path"); throw new UnsupportedOperationException(currentPosition + " not in path");

View File

@ -1,7 +1,7 @@
package baritone.bot.pathing.calc; package baritone.bot.pathing.calc;
import baritone.bot.pathing.action.Action;
import baritone.bot.pathing.goals.Goal; import baritone.bot.pathing.goals.Goal;
import baritone.bot.pathing.movements.Movement;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import java.util.ArrayList; import java.util.ArrayList;
@ -23,34 +23,41 @@ class Path implements IPath {
* path.get(path.size()-1) equals end * path.get(path.size()-1) equals end
*/ */
public final ArrayList<BlockPos> path; public final ArrayList<BlockPos> path;
final ArrayList<Movement> movements; final ArrayList<Action> actions;
Path(PathNode start, PathNode end, Goal goal) { Path(PathNode start, PathNode end, Goal goal) {
this.start = start.pos; this.start = start.pos;
this.end = end.pos; this.end = end.pos;
this.goal = goal; this.goal = goal;
this.path = new ArrayList<>(); this.path = new ArrayList<>();
this.movements = new ArrayList<>(); this.actions = new ArrayList<>();
assemblePath(start, end); assemblePath(start, end);
} }
private final void assemblePath(PathNode start, PathNode end) { private final void assemblePath(PathNode start, PathNode end) {
PathNode current = end; PathNode current = end;
LinkedList<BlockPos> tempPath = new LinkedList<>();//repeatedly inserting to the beginning of an arraylist is O(n^2) LinkedList<BlockPos> tempPath = new LinkedList<>();//repeatedly inserting to the beginning of an arraylist is O(n^2)
LinkedList<Movement> tempMovements = new LinkedList<>();//instead, do it into a linked list, then convert at the end LinkedList<Action> tempActions = new LinkedList<>();//instead, do it into a linked list, then convert at the end
while (!current.equals(start)) { while (!current.equals(start)) {
tempPath.addFirst(current.pos); tempPath.addFirst(current.pos);
tempMovements.addFirst(current.previousMovement); tempActions.addFirst(current.previousAction);
current = current.previous; current = current.previous;
} }
tempPath.addFirst(start.pos); tempPath.addFirst(start.pos);
//can't directly convert from the PathNode pseudo linked list to an array because we don't know how long it is
//inserting into a LinkedList<E> keeps track of length, then when we addall (which calls .toArray) it's able
//to performantly do that conversion since it knows the length.
path.addAll(tempPath); path.addAll(tempPath);
movements.addAll(tempMovements); actions.addAll(tempActions);
}
protected void sanityCheck() {
} }
@Override @Override
public List<Movement> movements() { public List<Action> actions() {
return movements; return actions;
} }
@Override @Override

View File

@ -1,7 +1,7 @@
package baritone.bot.pathing.calc; package baritone.bot.pathing.calc;
import baritone.bot.pathing.action.Action;
import baritone.bot.pathing.goals.Goal; import baritone.bot.pathing.goals.Goal;
import baritone.bot.pathing.movements.Movement;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import java.util.Objects; import java.util.Objects;
@ -19,7 +19,7 @@ class PathNode {
// These three fields are mutable and are changed by PathFinder // These three fields are mutable and are changed by PathFinder
double cost; double cost;
PathNode previous; PathNode previous;
Movement previousMovement; Action previousAction;
/** /**
* Is this a member of the open set in A*? (only used during pathfinding) * Is this a member of the open set in A*? (only used during pathfinding)
@ -36,7 +36,7 @@ class PathNode {
this.cost = Short.MAX_VALUE; this.cost = Short.MAX_VALUE;
this.goal = goal; this.goal = goal;
this.estimatedCostToGoal = goal.heuristic(pos); this.estimatedCostToGoal = goal.heuristic(pos);
this.previousMovement = null; this.previousAction = null;
this.isOpen = false; this.isOpen = false;
} }
@ -48,7 +48,7 @@ class PathNode {
hash = 3457689 * hash + this.pos.getX(); hash = 3457689 * hash + this.pos.getX();
hash = 8734625 * hash + this.pos.getY(); hash = 8734625 * hash + this.pos.getY();
hash = 2873465 * hash + this.pos.getZ(); hash = 2873465 * hash + this.pos.getZ();
hash = 3241543 * hash + Objects.hashCode(this.goal); hash = 3241543 * hash + Objects.hashCode(this.goal);//don't call goal.hashcode. this calls objects hashcode to verify that the actual goal objects are == identical, which is important for node caching
return hash; return hash;
} }

View File

@ -1,35 +0,0 @@
package baritone.bot.pathing.movements;
import baritone.bot.pathing.action.Action;
import net.minecraft.util.math.BlockPos;
import java.util.List;
public abstract class Movement {
/**
* Flat list of ordered actions
*/
protected List<Action> actions;
/**
* Gets source block position for Movement.
*
* @return Movement's starting block position
*/
public abstract BlockPos getSrc();
/**
* Gets the block position the movement should finish at
*
* @return Movement's final block position
*/
public abstract BlockPos getDest();
/**
* Calculate the movement's cost
*
* @return Cost
*/
public abstract double calcCost();
}

View File

@ -0,0 +1,16 @@
package baritone.bot.utils;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.util.math.BlockPos;
public class BlockStateInterface {
public static IBlockState get(BlockPos pos) { // wrappers for future 1.13 compat
return Minecraft.getMinecraft().world.getBlockState(pos);
}
public static Block getBlock(BlockPos pos) {
return get(pos).getBlock();
}
}

View File

@ -6,7 +6,6 @@ import baritone.util.ToolSet;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
/** /**
*
* @author leijurv * @author leijurv
*/ */
public class ActionDescendThree extends ActionPlaceOrBreak { public class ActionDescendThree extends ActionPlaceOrBreak {