revamp follow and fix some bugs in mine
This commit is contained in:
parent
dc6389c46f
commit
f2dcdda9b3
@ -19,6 +19,9 @@ package baritone.api.process;
|
|||||||
|
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 9/23/2018
|
* @since 9/23/2018
|
||||||
@ -26,16 +29,18 @@ import net.minecraft.entity.Entity;
|
|||||||
public interface IFollowProcess extends IBaritoneProcess {
|
public interface IFollowProcess extends IBaritoneProcess {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the follow target to the specified entity;
|
* Set the follow target to any entities matching this predicate
|
||||||
*
|
*
|
||||||
* @param entity The entity to follow
|
* @param filter the predicate
|
||||||
*/
|
*/
|
||||||
void follow(Entity entity);
|
void follow(Predicate<Entity> filter);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The entity that is currently being followed
|
* @return The entities that are currently being followed. null if not currently following, empty if nothing matches the predicate
|
||||||
*/
|
*/
|
||||||
Entity following();
|
List<Entity> following();
|
||||||
|
|
||||||
|
Predicate<Entity> currentFilter();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cancels the follow behavior, this will clear the current follow target.
|
* Cancels the follow behavior, this will clear the current follow target.
|
||||||
|
@ -55,6 +55,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
|
|
||||||
private boolean safeToCancel;
|
private boolean safeToCancel;
|
||||||
private boolean pauseRequestedLastTick;
|
private boolean pauseRequestedLastTick;
|
||||||
|
private boolean cancelRequested;
|
||||||
private boolean calcFailedLastTick;
|
private boolean calcFailedLastTick;
|
||||||
|
|
||||||
private volatile boolean isPathCalcInProgress;
|
private volatile boolean isPathCalcInProgress;
|
||||||
@ -91,18 +92,22 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
baritone.getPathingControlManager().cancelEverything();
|
baritone.getPathingControlManager().cancelEverything();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
baritone.getPathingControlManager().preTick();
|
||||||
tickPath();
|
tickPath();
|
||||||
dispatchEvents();
|
dispatchEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tickPath() {
|
private void tickPath() {
|
||||||
baritone.getPathingControlManager().doTheThingWithTheStuff();
|
|
||||||
if (pauseRequestedLastTick && safeToCancel) {
|
if (pauseRequestedLastTick && safeToCancel) {
|
||||||
pauseRequestedLastTick = false;
|
pauseRequestedLastTick = false;
|
||||||
baritone.getInputOverrideHandler().clearAllKeys();
|
baritone.getInputOverrideHandler().clearAllKeys();
|
||||||
BlockBreakHelper.stopBreakingBlock();
|
BlockBreakHelper.stopBreakingBlock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (cancelRequested) {
|
||||||
|
cancelRequested = false;
|
||||||
|
baritone.getInputOverrideHandler().clearAllKeys();
|
||||||
|
}
|
||||||
if (current == null) {
|
if (current == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -273,6 +278,17 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
return calcFailedLastTick;
|
return calcFailedLastTick;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void softCancelIfSafe() {
|
||||||
|
if (!isSafeToCancel()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
current = null;
|
||||||
|
next = null;
|
||||||
|
cancelRequested = true;
|
||||||
|
AbstractNodeCostSearch.getCurrentlyRunning().ifPresent(AbstractNodeCostSearch::cancel);
|
||||||
|
// do everything BUT clear keys
|
||||||
|
}
|
||||||
|
|
||||||
// just cancel the current path
|
// just cancel the current path
|
||||||
public void secretInternalSegmentCancel() {
|
public void secretInternalSegmentCancel() {
|
||||||
queuePathEvent(PathEvent.CANCELED);
|
queuePathEvent(PathEvent.CANCELED);
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
package baritone.process;
|
package baritone.process;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
|
import baritone.api.pathing.goals.Goal;
|
||||||
|
import baritone.api.pathing.goals.GoalComposite;
|
||||||
import baritone.api.pathing.goals.GoalNear;
|
import baritone.api.pathing.goals.GoalNear;
|
||||||
import baritone.api.pathing.goals.GoalXZ;
|
import baritone.api.pathing.goals.GoalXZ;
|
||||||
import baritone.api.process.IFollowProcess;
|
import baritone.api.process.IFollowProcess;
|
||||||
@ -27,6 +29,12 @@ import baritone.utils.BaritoneProcessHelper;
|
|||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Follow an entity
|
* Follow an entity
|
||||||
*
|
*
|
||||||
@ -34,7 +42,8 @@ import net.minecraft.util.math.BlockPos;
|
|||||||
*/
|
*/
|
||||||
public final class FollowProcess extends BaritoneProcessHelper implements IFollowProcess {
|
public final class FollowProcess extends BaritoneProcessHelper implements IFollowProcess {
|
||||||
|
|
||||||
private Entity following;
|
private Predicate<Entity> filter;
|
||||||
|
private List<Entity> cache;
|
||||||
|
|
||||||
public FollowProcess(Baritone baritone) {
|
public FollowProcess(Baritone baritone) {
|
||||||
super(baritone, 1);
|
super(baritone, 1);
|
||||||
@ -42,39 +51,76 @@ public final class FollowProcess extends BaritoneProcessHelper implements IFollo
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) {
|
public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) {
|
||||||
|
scanWorld();
|
||||||
|
Goal goal = new GoalComposite(cache.stream().map(this::towards).toArray(Goal[]::new));
|
||||||
|
return new PathingCommand(goal, PathingCommandType.REVALIDATE_GOAL_AND_PATH);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Goal towards(Entity following) {
|
||||||
// lol this is trashy but it works
|
// lol this is trashy but it works
|
||||||
BlockPos pos;
|
BlockPos pos;
|
||||||
if (Baritone.settings().followOffsetDistance.get() == 0) {
|
if (Baritone.settings().followOffsetDistance.get() == 0) {
|
||||||
pos = following.getPosition();
|
pos = new BlockPos(following);
|
||||||
} else {
|
} else {
|
||||||
GoalXZ g = GoalXZ.fromDirection(following.getPositionVector(), Baritone.settings().followOffsetDirection.get(), Baritone.settings().followOffsetDistance.get());
|
GoalXZ g = GoalXZ.fromDirection(following.getPositionVector(), Baritone.settings().followOffsetDirection.get(), Baritone.settings().followOffsetDistance.get());
|
||||||
pos = new BlockPos(g.getX(), following.posY, g.getZ());
|
pos = new BlockPos(g.getX(), following.posY, g.getZ());
|
||||||
}
|
}
|
||||||
return new PathingCommand(new GoalNear(pos, Baritone.settings().followRadius.get()), PathingCommandType.FORCE_REVALIDATE_GOAL_AND_PATH);
|
return new GoalNear(pos, Baritone.settings().followRadius.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private boolean followable(Entity entity) {
|
||||||
|
if (entity == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (entity.isDead) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (entity.equals(player())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!world().loadedEntityList.contains(entity) && !world().playerEntities.contains(entity)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void scanWorld() {
|
||||||
|
cache = Stream.of(world().loadedEntityList, world().playerEntities).flatMap(List::stream).filter(this::followable).filter(this.filter).distinct().collect(Collectors.toCollection(ArrayList::new));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isActive() {
|
public boolean isActive() {
|
||||||
return following != null;
|
if (filter == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
scanWorld();
|
||||||
|
return !cache.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLostControl() {
|
public void onLostControl() {
|
||||||
following = null;
|
filter = null;
|
||||||
|
cache = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String displayName() {
|
public String displayName() {
|
||||||
return "Follow " + following;
|
return "Follow " + cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void follow(Entity entity) {
|
public void follow(Predicate<Entity> filter) {
|
||||||
this.following = entity;
|
this.filter = filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Entity following() {
|
public List<Entity> following() {
|
||||||
return this.following;
|
return cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Predicate<Entity> currentFilter() {
|
||||||
|
return filter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -241,6 +241,7 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void addNearby() {
|
public void addNearby() {
|
||||||
|
knownOreLocations.addAll(droppedItemsScan(mining, world()));
|
||||||
BlockPos playerFeet = playerFeet();
|
BlockPos playerFeet = playerFeet();
|
||||||
int searchDist = 4;//why four? idk
|
int searchDist = 4;//why four? idk
|
||||||
for (int x = playerFeet.getX() - searchDist; x <= playerFeet.getX() + searchDist; x++) {
|
for (int x = playerFeet.getX() - searchDist; x <= playerFeet.getX() + searchDist; x++) {
|
||||||
@ -260,6 +261,7 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
|
|||||||
List<BlockPos> dropped = droppedItemsScan(mining, world);
|
List<BlockPos> dropped = droppedItemsScan(mining, world);
|
||||||
List<BlockPos> locs = locs2
|
List<BlockPos> locs = locs2
|
||||||
.stream()
|
.stream()
|
||||||
|
.distinct()
|
||||||
|
|
||||||
// remove any that are within loaded chunks that aren't actually what we want
|
// remove any that are within loaded chunks that aren't actually what we want
|
||||||
.filter(pos -> world.getChunk(pos) instanceof EmptyChunk || mining.contains(BlockStateInterface.get(pos).getBlock()) || dropped.contains(pos))
|
.filter(pos -> world.getChunk(pos) instanceof EmptyChunk || mining.contains(BlockStateInterface.get(pos).getBlock()) || dropped.contains(pos))
|
||||||
|
@ -262,6 +262,11 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
|||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (msg.startsWith("followplayers")) {
|
||||||
|
baritone.getFollowProcess().follow(EntityPlayer.class::isInstance); // O P P A
|
||||||
|
logDirect("Following any players");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (msg.startsWith("follow")) {
|
if (msg.startsWith("follow")) {
|
||||||
String name = msg.substring(6).trim();
|
String name = msg.substring(6).trim();
|
||||||
Optional<Entity> toFollow = Optional.empty();
|
Optional<Entity> toFollow = Optional.empty();
|
||||||
@ -279,7 +284,8 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
|||||||
logDirect("Not found");
|
logDirect("Not found");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
baritone.getFollowProcess().follow(toFollow.get());
|
Entity effectivelyFinal = toFollow.get();
|
||||||
|
baritone.getFollowProcess().follow(x -> effectivelyFinal.equals(x));
|
||||||
logDirect("Following " + toFollow.get());
|
logDirect("Following " + toFollow.get());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -18,10 +18,13 @@
|
|||||||
package baritone.utils;
|
package baritone.utils;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
|
import baritone.api.event.events.TickEvent;
|
||||||
|
import baritone.api.event.listener.AbstractGameEventListener;
|
||||||
import baritone.api.pathing.goals.Goal;
|
import baritone.api.pathing.goals.Goal;
|
||||||
import baritone.api.process.IBaritoneProcess;
|
import baritone.api.process.IBaritoneProcess;
|
||||||
import baritone.api.process.PathingCommand;
|
import baritone.api.process.PathingCommand;
|
||||||
import baritone.behavior.PathingBehavior;
|
import baritone.behavior.PathingBehavior;
|
||||||
|
import baritone.pathing.calc.AbstractNodeCostSearch;
|
||||||
import baritone.pathing.path.PathExecutor;
|
import baritone.pathing.path.PathExecutor;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
@ -36,10 +39,20 @@ public class PathingControlManager {
|
|||||||
private final HashSet<IBaritoneProcess> processes; // unGh
|
private final HashSet<IBaritoneProcess> processes; // unGh
|
||||||
private IBaritoneProcess inControlLastTick;
|
private IBaritoneProcess inControlLastTick;
|
||||||
private IBaritoneProcess inControlThisTick;
|
private IBaritoneProcess inControlThisTick;
|
||||||
|
private PathingCommand command;
|
||||||
|
|
||||||
public PathingControlManager(Baritone baritone) {
|
public PathingControlManager(Baritone baritone) {
|
||||||
this.baritone = baritone;
|
this.baritone = baritone;
|
||||||
this.processes = new HashSet<>();
|
this.processes = new HashSet<>();
|
||||||
|
baritone.registerEventListener(new AbstractGameEventListener() { // needs to be after all behavior ticks
|
||||||
|
@Override
|
||||||
|
public void onTick(TickEvent event) {
|
||||||
|
if (event.getType() == TickEvent.Type.OUT) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
postTick();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerProcess(IBaritoneProcess process) {
|
public void registerProcess(IBaritoneProcess process) {
|
||||||
@ -61,38 +74,35 @@ public class PathingControlManager {
|
|||||||
return inControlThisTick;
|
return inControlThisTick;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void doTheThingWithTheStuff() {
|
public void preTick() {
|
||||||
inControlLastTick = inControlThisTick;
|
inControlLastTick = inControlThisTick;
|
||||||
PathingCommand cmd = doTheStuff();
|
command = doTheStuff();
|
||||||
if (cmd == null) {
|
if (command == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
PathingBehavior p = baritone.getPathingBehavior();
|
PathingBehavior p = baritone.getPathingBehavior();
|
||||||
switch (cmd.commandType) {
|
switch (command.commandType) {
|
||||||
case REQUEST_PAUSE:
|
case REQUEST_PAUSE:
|
||||||
p.requestPause();
|
p.requestPause();
|
||||||
break;
|
break;
|
||||||
case CANCEL_AND_SET_GOAL:
|
case CANCEL_AND_SET_GOAL:
|
||||||
p.secretInternalSetGoal(cmd.goal);
|
p.secretInternalSetGoal(command.goal);
|
||||||
p.cancelSegmentIfSafe();
|
p.cancelSegmentIfSafe();
|
||||||
break;
|
break;
|
||||||
case FORCE_REVALIDATE_GOAL_AND_PATH:
|
case FORCE_REVALIDATE_GOAL_AND_PATH:
|
||||||
p.secretInternalSetGoalAndPath(cmd.goal);
|
if (!p.isPathing() && !AbstractNodeCostSearch.getCurrentlyRunning().isPresent()) {
|
||||||
if (cmd.goal == null || forceRevalidate(cmd.goal) || revalidateGoal(cmd.goal)) {
|
p.secretInternalSetGoalAndPath(command.goal);
|
||||||
// pwnage
|
|
||||||
p.cancelSegmentIfSafe();
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case REVALIDATE_GOAL_AND_PATH:
|
case REVALIDATE_GOAL_AND_PATH:
|
||||||
p.secretInternalSetGoalAndPath(cmd.goal);
|
if (!p.isPathing() && !AbstractNodeCostSearch.getCurrentlyRunning().isPresent()) {
|
||||||
if (Baritone.settings().cancelOnGoalInvalidation.get() && (cmd.goal == null || revalidateGoal(cmd.goal))) {
|
p.secretInternalSetGoalAndPath(command.goal);
|
||||||
p.cancelSegmentIfSafe();
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SET_GOAL_AND_PATH:
|
case SET_GOAL_AND_PATH:
|
||||||
// now this i can do
|
// now this i can do
|
||||||
if (cmd.goal != null) {
|
if (command.goal != null) {
|
||||||
baritone.getPathingBehavior().secretInternalSetGoalAndPath(cmd.goal);
|
baritone.getPathingBehavior().secretInternalSetGoalAndPath(command.goal);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -100,6 +110,33 @@ public class PathingControlManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void postTick() {
|
||||||
|
// if we did this in pretick, it would suck
|
||||||
|
// we use the time between ticks as calculation time
|
||||||
|
// therefore, we only cancel and recalculate after the tick for the current path has executed
|
||||||
|
// "it would suck" means it would actually execute a path every other tick
|
||||||
|
if (command == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
PathingBehavior p = baritone.getPathingBehavior();
|
||||||
|
switch (command.commandType) {
|
||||||
|
case FORCE_REVALIDATE_GOAL_AND_PATH:
|
||||||
|
if (command.goal == null || forceRevalidate(command.goal) || revalidateGoal(command.goal)) {
|
||||||
|
// pwnage
|
||||||
|
p.softCancelIfSafe();
|
||||||
|
}
|
||||||
|
p.secretInternalSetGoalAndPath(command.goal);
|
||||||
|
break;
|
||||||
|
case REVALIDATE_GOAL_AND_PATH:
|
||||||
|
if (Baritone.settings().cancelOnGoalInvalidation.get() && (command.goal == null || revalidateGoal(command.goal))) {
|
||||||
|
p.softCancelIfSafe();
|
||||||
|
}
|
||||||
|
p.secretInternalSetGoalAndPath(command.goal);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public boolean forceRevalidate(Goal newGoal) {
|
public boolean forceRevalidate(Goal newGoal) {
|
||||||
PathExecutor current = baritone.getPathingBehavior().getCurrent();
|
PathExecutor current = baritone.getPathingBehavior().getCurrent();
|
||||||
if (current != null) {
|
if (current != null) {
|
||||||
|
Loading…
Reference in New Issue
Block a user