action to movement
This commit is contained in:
parent
49cc61d2ca
commit
71d4379316
@ -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) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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");
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
});
|
});
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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",
|
||||||
|
Loading…
Reference in New Issue
Block a user