revamp follow and fix some bugs in mine

This commit is contained in:
Leijurv 2018-11-09 14:49:25 -08:00
parent dc6389c46f
commit f2dcdda9b3
No known key found for this signature in database
GPG Key ID: 44A3EA646EADAC6A
6 changed files with 143 additions and 31 deletions

View File

@ -19,6 +19,9 @@ package baritone.api.process;
import net.minecraft.entity.Entity;
import java.util.List;
import java.util.function.Predicate;
/**
* @author Brady
* @since 9/23/2018
@ -26,16 +29,18 @@ import net.minecraft.entity.Entity;
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.

View File

@ -55,6 +55,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
private boolean safeToCancel;
private boolean pauseRequestedLastTick;
private boolean cancelRequested;
private boolean calcFailedLastTick;
private volatile boolean isPathCalcInProgress;
@ -91,18 +92,22 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
baritone.getPathingControlManager().cancelEverything();
return;
}
baritone.getPathingControlManager().preTick();
tickPath();
dispatchEvents();
}
private void tickPath() {
baritone.getPathingControlManager().doTheThingWithTheStuff();
if (pauseRequestedLastTick && safeToCancel) {
pauseRequestedLastTick = false;
baritone.getInputOverrideHandler().clearAllKeys();
BlockBreakHelper.stopBreakingBlock();
return;
}
if (cancelRequested) {
cancelRequested = false;
baritone.getInputOverrideHandler().clearAllKeys();
}
if (current == null) {
return;
}
@ -273,6 +278,17 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
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
public void secretInternalSegmentCancel() {
queuePathEvent(PathEvent.CANCELED);

View File

@ -18,6 +18,8 @@
package baritone.process;
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.GoalXZ;
import baritone.api.process.IFollowProcess;
@ -27,6 +29,12 @@ import baritone.utils.BaritoneProcessHelper;
import net.minecraft.entity.Entity;
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
*
@ -34,7 +42,8 @@ import net.minecraft.util.math.BlockPos;
*/
public final class FollowProcess extends BaritoneProcessHelper implements IFollowProcess {
private Entity following;
private Predicate<Entity> filter;
private List<Entity> cache;
public FollowProcess(Baritone baritone) {
super(baritone, 1);
@ -42,39 +51,76 @@ public final class FollowProcess extends BaritoneProcessHelper implements IFollo
@Override
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
BlockPos pos;
if (Baritone.settings().followOffsetDistance.get() == 0) {
pos = following.getPosition();
pos = new BlockPos(following);
} else {
GoalXZ g = GoalXZ.fromDirection(following.getPositionVector(), Baritone.settings().followOffsetDirection.get(), Baritone.settings().followOffsetDistance.get());
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
public boolean isActive() {
return following != null;
if (filter == null) {
return false;
}
scanWorld();
return !cache.isEmpty();
}
@Override
public void onLostControl() {
following = null;
filter = null;
cache = null;
}
@Override
public String displayName() {
return "Follow " + following;
return "Follow " + cache;
}
@Override
public void follow(Entity entity) {
this.following = entity;
public void follow(Predicate<Entity> filter) {
this.filter = filter;
}
@Override
public Entity following() {
return this.following;
public List<Entity> following() {
return cache;
}
@Override
public Predicate<Entity> currentFilter() {
return filter;
}
}

View File

@ -241,6 +241,7 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
}
public void addNearby() {
knownOreLocations.addAll(droppedItemsScan(mining, world()));
BlockPos playerFeet = playerFeet();
int searchDist = 4;//why four? idk
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> locs = locs2
.stream()
.distinct()
// 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))

View File

@ -262,6 +262,11 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
});
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")) {
String name = msg.substring(6).trim();
Optional<Entity> toFollow = Optional.empty();
@ -279,7 +284,8 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
logDirect("Not found");
return true;
}
baritone.getFollowProcess().follow(toFollow.get());
Entity effectivelyFinal = toFollow.get();
baritone.getFollowProcess().follow(x -> effectivelyFinal.equals(x));
logDirect("Following " + toFollow.get());
return true;
}

View File

@ -18,10 +18,13 @@
package baritone.utils;
import baritone.Baritone;
import baritone.api.event.events.TickEvent;
import baritone.api.event.listener.AbstractGameEventListener;
import baritone.api.pathing.goals.Goal;
import baritone.api.process.IBaritoneProcess;
import baritone.api.process.PathingCommand;
import baritone.behavior.PathingBehavior;
import baritone.pathing.calc.AbstractNodeCostSearch;
import baritone.pathing.path.PathExecutor;
import net.minecraft.util.math.BlockPos;
@ -36,10 +39,20 @@ public class PathingControlManager {
private final HashSet<IBaritoneProcess> processes; // unGh
private IBaritoneProcess inControlLastTick;
private IBaritoneProcess inControlThisTick;
private PathingCommand command;
public PathingControlManager(Baritone baritone) {
this.baritone = baritone;
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) {
@ -61,38 +74,35 @@ public class PathingControlManager {
return inControlThisTick;
}
public void doTheThingWithTheStuff() {
public void preTick() {
inControlLastTick = inControlThisTick;
PathingCommand cmd = doTheStuff();
if (cmd == null) {
command = doTheStuff();
if (command == null) {
return;
}
PathingBehavior p = baritone.getPathingBehavior();
switch (cmd.commandType) {
switch (command.commandType) {
case REQUEST_PAUSE:
p.requestPause();
break;
case CANCEL_AND_SET_GOAL:
p.secretInternalSetGoal(cmd.goal);
p.secretInternalSetGoal(command.goal);
p.cancelSegmentIfSafe();
break;
case FORCE_REVALIDATE_GOAL_AND_PATH:
p.secretInternalSetGoalAndPath(cmd.goal);
if (cmd.goal == null || forceRevalidate(cmd.goal) || revalidateGoal(cmd.goal)) {
// pwnage
p.cancelSegmentIfSafe();
if (!p.isPathing() && !AbstractNodeCostSearch.getCurrentlyRunning().isPresent()) {
p.secretInternalSetGoalAndPath(command.goal);
}
break;
case REVALIDATE_GOAL_AND_PATH:
p.secretInternalSetGoalAndPath(cmd.goal);
if (Baritone.settings().cancelOnGoalInvalidation.get() && (cmd.goal == null || revalidateGoal(cmd.goal))) {
p.cancelSegmentIfSafe();
if (!p.isPathing() && !AbstractNodeCostSearch.getCurrentlyRunning().isPresent()) {
p.secretInternalSetGoalAndPath(command.goal);
}
break;
case SET_GOAL_AND_PATH:
// now this i can do
if (cmd.goal != null) {
baritone.getPathingBehavior().secretInternalSetGoalAndPath(cmd.goal);
if (command.goal != null) {
baritone.getPathingBehavior().secretInternalSetGoalAndPath(command.goal);
}
break;
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) {
PathExecutor current = baritone.getPathingBehavior().getCurrent();
if (current != null) {