action to movement

This commit is contained in:
Leijurv 2018-08-02 18:35:36 -04:00
parent 49cc61d2ca
commit 71d4379316
No known key found for this signature in database
GPG Key ID: 44A3EA646EADAC6A
12 changed files with 90 additions and 62 deletions

View File

@ -9,7 +9,9 @@ import net.minecraft.util.math.BlockPos;
*/ */
public final class GameActionHandler { public final class GameActionHandler {
GameActionHandler() {} GameActionHandler() {
}
public final void onPlacedBlock(ItemStack stack, BlockPos pos) {} public final void onPlacedBlock(ItemStack stack, BlockPos pos) {
}
} }

View File

@ -55,4 +55,4 @@ public final class GameEventHandler implements IGameEventListener {
private void dispatch(Consumer<Behavior> dispatchFunction) { private void dispatch(Consumer<Behavior> dispatchFunction) {
Baritone.INSTANCE.getBehaviors().stream().filter(Behavior::isEnabled).forEach(dispatchFunction); Baritone.INSTANCE.getBehaviors().stream().filter(Behavior::isEnabled).forEach(dispatchFunction);
} }
} }

View File

@ -1,6 +1,6 @@
package baritone.bot.pathing.calc; package baritone.bot.pathing.calc;
import baritone.bot.pathing.action.Action; import baritone.bot.pathing.movement.Movement;
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<Action> actions(); List<Movement> movements();
/** /**
* 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 Action subsequentAction(BlockPos currentPosition) { default Movement subsequentMovement(BlockPos currentPosition) {
List<BlockPos> pos = positions(); List<BlockPos> pos = positions();
List<Action> actions = actions(); List<Movement> movements = movements();
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 actions.get(i); return movements.get(i);
} }
} }
throw new UnsupportedOperationException(currentPosition + " not in path"); throw new UnsupportedOperationException(currentPosition + " not in path");

View File

@ -1,6 +1,6 @@
package baritone.bot.pathing.calc; package baritone.bot.pathing.calc;
import baritone.bot.pathing.action.Action; import baritone.bot.pathing.movement.Movement;
import baritone.bot.pathing.goals.Goal; import baritone.bot.pathing.goals.Goal;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
@ -20,28 +20,28 @@ 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<Action> actions; final ArrayList<Movement> movements;
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.actions = new ArrayList<>(); this.movements = new ArrayList<>();
assemblePath(start, end); assemblePath(start, end);
sanityCheck(); sanityCheck();
} }
private final void assemblePath(PathNode start, PathNode end) { private final void assemblePath(PathNode start, PathNode end) {
if (!path.isEmpty() || !actions.isEmpty()) { if (!path.isEmpty() || !movements.isEmpty()) {
throw new IllegalStateException(); throw new IllegalStateException();
} }
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<Action> tempActions = new LinkedList<>();//instead, do it into a linked list, then convert at the end LinkedList<Movement> tempMovements = 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);
tempActions.addFirst(current.previousAction); tempMovements.addFirst(current.previousMovement);
current = current.previous; current = current.previous;
} }
tempPath.addFirst(start.pos); tempPath.addFirst(start.pos);
@ -49,7 +49,7 @@ class Path implements IPath {
//inserting into a LinkedList<E> keeps track of length, then when we addall (which calls .toArray) it's able //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. //to performantly do that conversion since it knows the length.
path.addAll(tempPath); path.addAll(tempPath);
actions.addAll(tempActions); movements.addAll(tempMovements);
} }
public void sanityCheck() { public void sanityCheck() {
@ -59,25 +59,25 @@ class Path implements IPath {
if (!end.equals(path.get(path.size() - 1))) { if (!end.equals(path.get(path.size() - 1))) {
throw new IllegalStateException(); throw new IllegalStateException();
} }
if (path.size() != actions.size() + 1) { if (path.size() != movements.size() + 1) {
throw new IllegalStateException(); throw new IllegalStateException();
} }
for (int i = 0; i < path.size(); i++) { for (int i = 0; i < path.size(); i++) {
BlockPos src = path.get(i); BlockPos src = path.get(i);
BlockPos dest = path.get(i + 1); BlockPos dest = path.get(i + 1);
Action action = actions.get(i); Movement movement = movements.get(i);
if (!src.equals(action.getSrc())) { if (!src.equals(movement.getSrc())) {
throw new IllegalStateException(); throw new IllegalStateException();
} }
if (!dest.equals(action.getDest())) { if (!dest.equals(movement.getDest())) {
throw new IllegalStateException(); throw new IllegalStateException();
} }
} }
} }
@Override @Override
public List<Action> actions() { public List<Movement> movements() {
return Collections.unmodifiableList(actions); return Collections.unmodifiableList(movements);
} }
@Override @Override
@ -94,4 +94,4 @@ class Path implements IPath {
public Collection<BlockPos> getBlocksToPlace() { public Collection<BlockPos> getBlocksToPlace() {
return null; return null;
} }
} }

View File

@ -1,6 +1,6 @@
package baritone.bot.pathing.calc; package baritone.bot.pathing.calc;
import baritone.bot.pathing.action.Action; import baritone.bot.pathing.movement.Movement;
import baritone.bot.pathing.goals.Goal; import baritone.bot.pathing.goals.Goal;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
@ -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;
Action previousAction; Movement previousMovement;
/** /**
* 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.previousAction = null; this.previousMovement = null;
this.isOpen = false; this.isOpen = false;
} }

View File

@ -1,10 +1,11 @@
package baritone.bot.pathing.goals; package baritone.bot.pathing.goals;
import baritone.bot.pathing.action.ActionCosts; import baritone.bot.pathing.movement.ActionCosts;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
/** /**
* An abstract Goal for pathing, can be anything from a specific block to just a Y coordinate. * An abstract Goal for pathing, can be anything from a specific block to just a Y coordinate.
*
* @author leijurv * @author leijurv
*/ */
public interface Goal extends ActionCosts { public interface Goal extends ActionCosts {

View File

@ -37,9 +37,9 @@ public class GoalXZ implements Goal {
} }
public static double calculateOld(double xDiff, double zDiff, double pythaDist) { public static double calculateOld(double xDiff, double zDiff, double pythaDist) {
double heuristic = 0; double heuristic = 0;
heuristic += Math.abs(xDiff) * Action.WALK_ONE_BLOCK_COST * 1.1;//overestimate heuristic += Math.abs(xDiff) * Movement.WALK_ONE_BLOCK_COST * 1.1;//overestimate
heuristic += Math.abs(zDiff) * Action.WALK_ONE_BLOCK_COST * 1.1; heuristic += Math.abs(zDiff) * Movement.WALK_ONE_BLOCK_COST * 1.1;
heuristic += pythaDist / 10 * Action.WALK_ONE_BLOCK_COST; heuristic += pythaDist / 10 * Movement.WALK_ONE_BLOCK_COST;
return heuristic; return heuristic;
} }
*/ */

View File

@ -16,11 +16,11 @@ public interface ActionCosts {
/** /**
* Doesn't include walking forwards, just the falling * Doesn't include walking forwards, just the falling
* * <p>
* Based on a sketchy formula from minecraftwiki * Based on a sketchy formula from minecraftwiki
* * <p>
* d(t) = 3.92 × (99 - 49.50×(0.98^t+1) - t) * d(t) = 3.92 × (99 - 49.50×(0.98^t+1) - t)
* * <p>
* Solved in mathematica * Solved in mathematica
*/ */
double FALL_ONE_BLOCK_COST = 5.11354; double FALL_ONE_BLOCK_COST = 5.11354;

View File

@ -4,11 +4,14 @@ import baritone.bot.Baritone;
import baritone.bot.event.AbstractGameEventListener; import baritone.bot.event.AbstractGameEventListener;
import baritone.bot.pathing.movement.MovementState.MovementStatus; import baritone.bot.pathing.movement.MovementState.MovementStatus;
import baritone.bot.utils.Helper; import baritone.bot.utils.Helper;
import baritone.bot.utils.ToolSet;
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 net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import java.util.Optional;
public abstract class Movement implements AbstractGameEventListener, Helper, MovementHelper { public abstract class Movement implements AbstractGameEventListener, Helper, MovementHelper {
protected MovementState currentState; protected MovementState currentState;
@ -16,35 +19,30 @@ public abstract class Movement implements AbstractGameEventListener, Helper, Mov
protected final BlockPos dest; protected final BlockPos dest;
protected Movement(BlockPos src, BlockPos dest) { protected Movement(BlockPos src, BlockPos dest) {
this(src, dest, Utils.calcCenterFromCoords(dest, mc.world));
}
protected Movement(BlockPos src, BlockPos dest, Vec3d rotationTarget) {
this.src = src; this.src = src;
this.dest = dest; this.dest = dest;
}
protected Movement(BlockPos src, BlockPos dest, Vec3d rotationTarget) {
this(src, dest);
currentState = new MovementState() currentState = new MovementState()
.setGoal(new MovementState.MovementGoal(dest, rotationTarget)) .setLookDirection(rotationTarget)
.setStatus(MovementStatus.WAITING); .setStatus(MovementStatus.WAITING);
} }
/** public abstract double calculateCost(ToolSet ts); // TODO pass in information like whether it's allowed to place throwaway blocks
* Lowest denominator of the dynamic costs.
* TODO: Investigate performant ways to assign costs to movement
*
* @return Cost
*/
public double cost() {
return 0;
}
@Override @Override
public void onTick() { public void onTick() {
MovementState latestState = calcState(); MovementState latestState = calcState();
Tuple<Float, Float> rotation = Utils.calcRotationFromVec3d(mc.player.getPositionEyes(1.0F), Optional<Vec3d> orientation = latestState.getGoal().rotation;
latestState.getGoal().rotation); if (orientation.isPresent()) {
mc.player.setPositionAndRotation(mc.player.posX, mc.player.posY, mc.player.posZ, Tuple<Float, Float> rotation = Utils.calcRotationFromVec3d(mc.player.getPositionEyes(1.0F),
rotation.getFirst(), rotation.getSecond()); orientation.get());
mc.player.setPositionAndRotation(mc.player.posX, mc.player.posY, mc.player.posZ,
rotation.getFirst(), rotation.getSecond());
}
//TODO calculate movement inputs from latestState.getGoal().position
latestState.inputState.forEach((input, forced) -> { latestState.inputState.forEach((input, forced) -> {
Baritone.INSTANCE.getInputOverrideHandler().setInputForceState(input, forced); Baritone.INSTANCE.getInputOverrideHandler().setInputForceState(input, forced);
}); });

View File

@ -1,16 +1,16 @@
package baritone.bot.pathing.movement; package baritone.bot.pathing.movement;
import baritone.bot.InputOverrideHandler.Input; import baritone.bot.InputOverrideHandler.Input;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Optional;
public class MovementState { public class MovementState {
protected MovementStatus status; protected MovementStatus status;
public MovementGoal goal; public MovementGoal goal = new MovementGoal();
protected final Map<Input, Boolean> inputState = new HashMap<>(); protected final Map<Input, Boolean> inputState = new HashMap<>();
public MovementState setStatus(MovementStatus status) { public MovementState setStatus(MovementStatus status) {
@ -28,18 +28,18 @@ public class MovementState {
* <p> * <p>
* TODO: Decide desiredMovement type * TODO: Decide desiredMovement type
*/ */
public BlockPos position; public Optional<Vec3d> position;
/** /**
* Yaw and pitch angles that must be matched * Yaw and pitch angles that must be matched
* <p> * <p>
* getFirst() -> YAW * getFirst() -> YAW
* getSecond() -> PITCH * getSecond() -> PITCH
*/ */
public Vec3d rotation; public Optional<Vec3d> rotation;
public MovementGoal(BlockPos position, Vec3d rotation) { public MovementGoal() {
this.position = position; this.position = Optional.empty();
this.rotation = rotation; this.rotation = Optional.empty();
} }
} }
@ -47,8 +47,23 @@ public class MovementState {
return goal; return goal;
} }
public MovementState setGoal(MovementGoal goal) { public MovementState setPosition(Vec3d posGoal) {
this.goal = goal; this.goal.position = Optional.of(posGoal);
return this;
}
public MovementState clearPosition() {
this.goal.position = Optional.empty();
return this;
}
public MovementState setLookDirection(Vec3d rotGoal) {
this.goal.rotation = Optional.of(rotGoal);
return this;
}
public MovementState clearLookDirection() {
this.goal.rotation = Optional.empty();
return this; return this;
} }

View File

@ -3,6 +3,7 @@ package baritone.bot.pathing.movement.movements;
import baritone.bot.InputOverrideHandler; import baritone.bot.InputOverrideHandler;
import baritone.bot.pathing.movement.Movement; import baritone.bot.pathing.movement.Movement;
import baritone.bot.pathing.movement.MovementState; import baritone.bot.pathing.movement.MovementState;
import baritone.bot.utils.ToolSet;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
public class MovementAscend extends Movement { public class MovementAscend extends Movement {
@ -11,10 +12,20 @@ public class MovementAscend extends Movement {
super(src, dest); super(src, dest);
} }
@Override
public double calculateCost(ToolSet ts) {
throw new UnsupportedOperationException();
}
//my suggestion: public MovementAscend(BlockPos src, BlockPos dest){
// super(src, dest, new BlockPos[]{dest, src.up(2), dest.up()}, new BlockPos[]{dest.down()});
// This basically says that dest, src.up3 and dest.up need to be passable before this movement can start
// and that dest.down needs to be stand-on-able
@Override @Override
public MovementState calcState() { public MovementState calcState() {
MovementState latestState = currentState.setInput(InputOverrideHandler.Input.JUMP, true).setInput(InputOverrideHandler.Input.MOVE_FORWARD, true); MovementState latestState = currentState.setInput(InputOverrideHandler.Input.JUMP, true).setInput(InputOverrideHandler.Input.MOVE_FORWARD, true);
if (mc.player.getPosition().equals(latestState.getGoal().position)) if (playerFeet().equals(dest))
latestState.setStatus(MovementState.MovementStatus.SUCCESS); latestState.setStatus(MovementState.MovementStatus.SUCCESS);
return latestState; return latestState;
} }

View File

@ -21,7 +21,8 @@ import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
@Mixin(Minecraft.class) @Mixin(Minecraft.class)
public class MixinMinecraft { public class MixinMinecraft {
@Shadow private int leftClickCounter; @Shadow
private int leftClickCounter;
@Inject( @Inject(
method = "init", method = "init",