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 {
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) {
Baritone.INSTANCE.getBehaviors().stream().filter(Behavior::isEnabled).forEach(dispatchFunction);
}
}
}

View File

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

View File

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

View File

@ -1,6 +1,6 @@
package baritone.bot.pathing.calc;
import baritone.bot.pathing.action.Action;
import baritone.bot.pathing.movement.Movement;
import baritone.bot.pathing.goals.Goal;
import net.minecraft.util.math.BlockPos;
@ -19,7 +19,7 @@ class PathNode {
// These three fields are mutable and are changed by PathFinder
double cost;
PathNode previous;
Action previousAction;
Movement previousMovement;
/**
* 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.goal = goal;
this.estimatedCostToGoal = goal.heuristic(pos);
this.previousAction = null;
this.previousMovement = null;
this.isOpen = false;
}

View File

@ -1,10 +1,11 @@
package baritone.bot.pathing.goals;
import baritone.bot.pathing.action.ActionCosts;
import baritone.bot.pathing.movement.ActionCosts;
import net.minecraft.util.math.BlockPos;
/**
* An abstract Goal for pathing, can be anything from a specific block to just a Y coordinate.
*
* @author leijurv
*/
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) {
double heuristic = 0;
heuristic += Math.abs(xDiff) * Action.WALK_ONE_BLOCK_COST * 1.1;//overestimate
heuristic += Math.abs(zDiff) * Action.WALK_ONE_BLOCK_COST * 1.1;
heuristic += pythaDist / 10 * Action.WALK_ONE_BLOCK_COST;
heuristic += Math.abs(xDiff) * Movement.WALK_ONE_BLOCK_COST * 1.1;//overestimate
heuristic += Math.abs(zDiff) * Movement.WALK_ONE_BLOCK_COST * 1.1;
heuristic += pythaDist / 10 * Movement.WALK_ONE_BLOCK_COST;
return heuristic;
}
*/

View File

@ -16,11 +16,11 @@ public interface ActionCosts {
/**
* Doesn't include walking forwards, just the falling
*
* <p>
* Based on a sketchy formula from minecraftwiki
*
* <p>
* d(t) = 3.92 × (99 - 49.50×(0.98^t+1) - t)
*
* <p>
* Solved in mathematica
*/
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.pathing.movement.MovementState.MovementStatus;
import baritone.bot.utils.Helper;
import baritone.bot.utils.ToolSet;
import baritone.bot.utils.Utils;
import net.minecraft.util.Tuple;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import java.util.Optional;
public abstract class Movement implements AbstractGameEventListener, Helper, MovementHelper {
protected MovementState currentState;
@ -16,35 +19,30 @@ public abstract class Movement implements AbstractGameEventListener, Helper, Mov
protected final 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.dest = dest;
}
protected Movement(BlockPos src, BlockPos dest, Vec3d rotationTarget) {
this(src, dest);
currentState = new MovementState()
.setGoal(new MovementState.MovementGoal(dest, rotationTarget))
.setLookDirection(rotationTarget)
.setStatus(MovementStatus.WAITING);
}
/**
* Lowest denominator of the dynamic costs.
* TODO: Investigate performant ways to assign costs to movement
*
* @return Cost
*/
public double cost() {
return 0;
}
public abstract double calculateCost(ToolSet ts); // TODO pass in information like whether it's allowed to place throwaway blocks
@Override
public void onTick() {
MovementState latestState = calcState();
Tuple<Float, Float> rotation = Utils.calcRotationFromVec3d(mc.player.getPositionEyes(1.0F),
latestState.getGoal().rotation);
mc.player.setPositionAndRotation(mc.player.posX, mc.player.posY, mc.player.posZ,
rotation.getFirst(), rotation.getSecond());
Optional<Vec3d> orientation = latestState.getGoal().rotation;
if (orientation.isPresent()) {
Tuple<Float, Float> rotation = Utils.calcRotationFromVec3d(mc.player.getPositionEyes(1.0F),
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) -> {
Baritone.INSTANCE.getInputOverrideHandler().setInputForceState(input, forced);
});

View File

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

View File

@ -3,6 +3,7 @@ package baritone.bot.pathing.movement.movements;
import baritone.bot.InputOverrideHandler;
import baritone.bot.pathing.movement.Movement;
import baritone.bot.pathing.movement.MovementState;
import baritone.bot.utils.ToolSet;
import net.minecraft.util.math.BlockPos;
public class MovementAscend extends Movement {
@ -11,10 +12,20 @@ public class MovementAscend extends Movement {
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
public MovementState calcState() {
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);
return latestState;
}

View File

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