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 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.
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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))
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user