Compare commits

...

36 Commits

Author SHA1 Message Date
Leijurv
0db18a7caf v0.0.8 2018-10-11 11:48:07 -07:00
Leijurv
a1c0f4dbb4 keep baritone provider properly 2018-10-11 11:10:59 -07:00
Brady
db7d3184c9 fINAL 2018-10-11 12:34:40 -05:00
Brady
7dfe6ac3ca Add EntityPlayerSP field to relevant events 2018-10-11 12:32:42 -05:00
Leijurv
8fd921c60e disable cancelOnGoalInvalidation 2018-10-10 21:28:55 -07:00
Leijurv
fec29d03fd automatically break block while suffocating, fixes #33 2018-10-10 21:25:21 -07:00
Leijurv
9bd205f190 center pillar regardless of timing 2018-10-10 21:07:59 -07:00
Leijurv
089037663e tweak backtrack cost favoring coefficient 2018-10-10 21:06:31 -07:00
leijurv
8c0bc3e2ef splice tighter, fixes #44 2018-10-10 20:49:25 -07:00
leijurv
db21045cfb renderPathIgnoreDepth 2018-10-10 20:40:15 -07:00
Leijurv
fbf0f2271c revamp pathStart, fixes #209 2018-10-10 17:05:51 -07:00
Leijurv
7e78ed2139 rework minebehavior threading model, fixes #217 2018-10-10 16:40:33 -07:00
Leijurv
5676acbba6 add off hand, fixes #206 2018-10-10 16:29:48 -07:00
Leijurv
43b155d7b8 better check than air 2018-10-10 16:27:48 -07:00
Brady
93158226b6 The sources jar should use SRG names not MCP 2018-10-10 14:10:02 -05:00
Leijurv
d3bf4ef198 renderSelectionBoxesIgnoreDepth 2018-10-09 19:34:53 -07:00
Leijurv
fc9d13a03c there was literally no reason to have it like that 2018-10-09 17:36:35 -07:00
Leijurv
22d2036657 splice better, fixes #215 2018-10-09 16:40:04 -07:00
Leijurv
9e15960581 fix pause stuttering, fixes #216 2018-10-09 16:13:46 -07:00
leijurv
738ce25ff0 tighten fall column 2018-10-09 11:15:42 -07:00
Brady
5da9347e2c Merge pull request #214 from cabaletta/path-api
Pathing API
2018-10-09 00:14:25 -05:00
Brady
771e892b31 Get Cutoff implementation out of API we DON'T need you 2018-10-09 00:10:50 -05:00
Leijurv
9df5f942de add shebang 2018-10-08 22:01:57 -07:00
Brady
0fb5f3233f MovementStatus javadocs 2018-10-08 23:52:36 -05:00
Leijurv
f17ce87e45 publicize 2018-10-08 21:51:19 -07:00
Leijurv
a497a944a6 bottom of the class 2018-10-08 21:49:36 -07:00
Brady
2e69bbe371 Minimal CutoffResult Javadocs 2018-10-08 23:34:12 -05:00
Brady
875f01c358 More comprehensive IPath javadocs 2018-10-08 23:29:16 -05:00
Brady
6a4a8ab2d9 I'm an IDIOT 2018-10-08 21:09:54 -05:00
Brady
8278576227 Rename getCurrentPathSearch to getPathFinder 2018-10-08 21:02:55 -05:00
Brady
7d0aa4d7a5 Add override annotation to getPath in PathExecutor 2018-10-08 20:39:33 -05:00
Brady
2b4512ee3f Move to API 2018-10-08 20:37:52 -05:00
Brady
e23a9c976a Bad code 2018-10-08 20:01:44 -05:00
Brady
1449edb8af Didn't need to do that 2018-10-08 19:59:25 -05:00
Brady
d177db5a35 IMovement
Hey would you look at that
2018-10-08 19:57:22 -05:00
Brady
1245e222a7 Begin path api prep 2018-10-08 19:23:43 -05:00
50 changed files with 771 additions and 291 deletions

View File

@@ -20,7 +20,7 @@ import java.util.jar.JarOutputStream
*/
group 'baritone'
version '0.0.7'
version '0.0.8'
buildscript {
repositories {
@@ -61,7 +61,9 @@ minecraft {
mappings = 'snapshot_20180731'
tweakClass = 'baritone.launch.BaritoneTweaker'
runDir = 'run'
makeObfSourceJar = false
// The sources jar should use SRG names not MCP to ensure compatibility with all mappings
makeObfSourceJar = true
}
repositories {

View File

@@ -1,3 +1,4 @@
#!/bin/sh
set -e # this makes the whole script fail immediately if any one of these commands fails
./gradlew build
export VERSION=$(cat build.gradle | grep "version '" | cut -d "'" -f 2-2)
@@ -9,7 +10,7 @@ echo "-injars 'baritone-$VERSION.jar'" >> api.pro # insert current version
cat ../../scripts/proguard.pro | grep -v "this is the rt jar" | grep -v "\-injars" >> api.pro # remove default rt jar and injar lines
echo "-libraryjars '$(java -verbose 2>/dev/null | sed -ne '1 s/\[Opened \(.*\)\]/\1/p')'" >> api.pro # insert correct rt.jar location
tail api.pro # debug, print out what the previous two commands generated
cat api.pro | grep -v "\-keep class baritone.api" > standalone.pro # standalone doesn't keep baritone api
cat api.pro | grep -v "this is the keep api" > standalone.pro # standalone doesn't keep baritone api
#instead of downloading these jars from my dropbox in a zip, just assume gradle's already got them for us
mkdir -p tempLibraries

View File

@@ -1,4 +1,4 @@
-injars baritone-0.0.7.jar
-injars baritone-0.0.8.jar
-outjars Obfuscated
@@ -16,8 +16,9 @@
-flattenpackagehierarchy
-repackageclasses 'baritone'
-keep class baritone.api.** { *; }
-keep class baritone.api.** { *; } # this is the keep api
-keep class baritone.BaritoneProvider
-keep class baritone.api.IBaritoneProvider
# setting names are reflected from field names, so keep field names
-keepclassmembers class baritone.api.Settings {

View File

@@ -156,7 +156,7 @@ public class Settings {
*
* @see <a href="https://github.com/cabaletta/baritone/issues/18">Issue #18</a>
*/
public Setting<Double> backtrackCostFavoringCoefficient = new Setting<>(0.1);
public Setting<Double> backtrackCostFavoringCoefficient = new Setting<>(0.5);
/**
* Don't repropagate cost improvements below 0.01 ticks. They're all just floating point inaccuracies,
@@ -307,6 +307,16 @@ public class Settings {
*/
public Setting<Boolean> renderGoalIgnoreDepth = new Setting<>(false);
/**
* Ignore depth when rendering the selection boxes (to break, to place, to walk into)
*/
public Setting<Boolean> renderSelectionBoxesIgnoreDepth = new Setting<>(false);
/**
* Ignore depth when rendering the path
*/
public Setting<Boolean> renderPathIgnoreDepth = new Setting<>(false);
/**
* Line width of the path when rendered, in pixels
*/
@@ -379,7 +389,7 @@ public class Settings {
* <p>
* Also on cosmic prisons this should be set to true since you don't actually mine the ore it just gets replaced with stone.
*/
public Setting<Boolean> cancelOnGoalInvalidation = new Setting<>(true);
public Setting<Boolean> cancelOnGoalInvalidation = new Setting<>(false);
/**
* The "axis" command (aka GoalAxis) will go to a axis, or diagonal axis, at this Y level.
@@ -531,7 +541,7 @@ public class Settings {
// here be dragons
{
Settings() {
Field[] temp = getClass().getFields();
HashMap<String, Setting<?>> tmpByName = new HashMap<>();
List<Setting<?>> tmpAll = new ArrayList<>();
@@ -566,6 +576,4 @@ public class Settings {
}
return result;
}
Settings() { }
}

View File

@@ -17,7 +17,10 @@
package baritone.api.behavior;
import baritone.api.pathing.calc.IPathFinder;
import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.calc.IPath;
import baritone.api.pathing.path.IPathExecutor;
import java.util.Optional;
@@ -65,4 +68,30 @@ public interface IPathingBehavior extends IBehavior {
* Cancels the pathing behavior or the current path calculation.
*/
void cancel();
/**
* Returns the current path, from the current path executor, if there is one.
*
* @return The current path
*/
default Optional<IPath> getPath() {
return Optional.ofNullable(getCurrent()).map(IPathExecutor::getPath);
}
/**
* @return The current path finder being executed
*/
Optional<IPathFinder> getPathFinder();
/**
* @return The current path executor
*/
IPathExecutor getCurrent();
/**
* Returns the next path executor, created when planning ahead.
*
* @return The next path executor
*/
IPathExecutor getNext();
}

View File

@@ -20,6 +20,8 @@ package baritone.api.event.events;
import net.minecraft.util.math.BlockPos;
/**
* Called when the local player interacts with a block, can be either {@link Type#BREAK} or {@link Type#USE}.
*
* @author Brady
* @since 8/22/2018
*/

View File

@@ -17,20 +17,22 @@
package baritone.api.event.events;
import baritone.api.event.events.type.Cancellable;
import baritone.api.event.events.type.ManagedPlayerEvent;
import net.minecraft.client.entity.EntityPlayerSP;
/**
* @author Brady
* @since 8/1/2018 6:39 PM
*/
public final class ChatEvent extends Cancellable {
public final class ChatEvent extends ManagedPlayerEvent.Cancellable {
/**
* The message being sent
*/
private final String message;
public ChatEvent(String message) {
public ChatEvent(EntityPlayerSP player, String message) {
super(player);
this.message = message;
}

View File

@@ -18,6 +18,7 @@
package baritone.api.event.events;
import baritone.api.event.events.type.EventState;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.Packet;
/**
@@ -26,15 +27,22 @@ import net.minecraft.network.Packet;
*/
public final class PacketEvent {
private final NetworkManager networkManager;
private final EventState state;
private final Packet<?> packet;
public PacketEvent(EventState state, Packet<?> packet) {
public PacketEvent(NetworkManager networkManager, EventState state, Packet<?> packet) {
this.networkManager = networkManager;
this.state = state;
this.packet = packet;
}
public final NetworkManager getNetworkManager() {
return this.networkManager;
}
public final EventState getState() {
return this.state;
}

View File

@@ -18,19 +18,22 @@
package baritone.api.event.events;
import baritone.api.event.events.type.EventState;
import baritone.api.event.events.type.ManagedPlayerEvent;
import net.minecraft.client.entity.EntityPlayerSP;
/**
* @author Brady
* @since 8/21/2018
*/
public final class PlayerUpdateEvent {
public final class PlayerUpdateEvent extends ManagedPlayerEvent {
/**
* The state of the event
*/
private final EventState state;
public PlayerUpdateEvent(EventState state) {
public PlayerUpdateEvent(EntityPlayerSP player, EventState state) {
super(player);
this.state = state;
}

View File

@@ -18,6 +18,8 @@
package baritone.api.event.events;
import baritone.api.event.events.type.EventState;
import baritone.api.event.events.type.ManagedPlayerEvent;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
@@ -25,7 +27,7 @@ import net.minecraft.entity.EntityLivingBase;
* @author Brady
* @since 8/21/2018
*/
public final class RotationMoveEvent {
public final class RotationMoveEvent extends ManagedPlayerEvent {
/**
* The type of event
@@ -37,7 +39,8 @@ public final class RotationMoveEvent {
*/
private final EventState state;
public RotationMoveEvent(EventState state, Type type) {
public RotationMoveEvent(EntityPlayerSP player, EventState state, Type type) {
super(player);
this.state = state;
this.type = type;
}

View File

@@ -21,23 +21,19 @@ package baritone.api.event.events.type;
* @author Brady
* @since 8/1/2018 6:41 PM
*/
public class Cancellable {
public class Cancellable implements ICancellable {
/**
* Whether or not this event has been cancelled
*/
private boolean cancelled;
/**
* Cancels this event
*/
@Override
public final void cancel() {
this.cancelled = true;
}
/**
* @return Whether or not this event has been cancelled
*/
@Override
public final boolean isCancelled() {
return this.cancelled;
}

View File

@@ -0,0 +1,35 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.event.events.type;
/**
* @author Brady
* @since 10/11/2018
*/
public interface ICancellable {
/**
* Cancels this event
*/
void cancel();
/**
* @return Whether or not this event has been cancelled
*/
boolean isCancelled();
}

View File

@@ -0,0 +1,61 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.event.events.type;
import net.minecraft.client.entity.EntityPlayerSP;
/**
* An event that has a reference to a locally managed player.
*
* @author Brady
* @since 10/11/2018
*/
public class ManagedPlayerEvent {
protected final EntityPlayerSP player;
public ManagedPlayerEvent(EntityPlayerSP player) {
this.player = player;
}
public final EntityPlayerSP getPlayer() {
return this.player;
}
public static class Cancellable extends ManagedPlayerEvent implements ICancellable {
/**
* Whether or not this event has been cancelled
*/
private boolean cancelled;
public Cancellable(EntityPlayerSP player) {
super(player);
}
@Override
public final void cancel() {
this.cancelled = true;
}
@Override
public final boolean isCancelled() {
return this.cancelled;
}
}
}

View File

@@ -15,37 +15,35 @@
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.pathing.path;
package baritone.api.pathing.calc;
import baritone.Baritone;
import baritone.api.Settings;
import baritone.api.pathing.goals.Goal;
import baritone.pathing.movement.Movement;
import baritone.utils.Helper;
import baritone.utils.Utils;
import baritone.utils.pathing.BetterBlockPos;
import net.minecraft.client.Minecraft;
import net.minecraft.util.Tuple;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.chunk.EmptyChunk;
import baritone.api.pathing.movement.IMovement;
import baritone.api.utils.BetterBlockPos;
import java.util.List;
/**
* @author leijurv
* @author leijurv, Brady
*/
public interface IPath extends Helper {
public interface IPath {
/**
* Ordered list of movements to carry out.
* movements.get(i).getSrc() should equal positions.get(i)
* movements.get(i).getDest() should equal positions.get(i+1)
* movements.size() should equal positions.size()-1
*
* @return All of the movements to carry out
*/
List<Movement> movements();
List<IMovement> movements();
/**
* All positions along the way.
* Should begin with the same as getSrc and end with the same as getDest
*
* @return All of the positions along this path
*/
List<BetterBlockPos> positions();
@@ -53,10 +51,10 @@ public interface IPath extends Helper {
* This path is actually going to be executed in the world. Do whatever additional processing is required.
* (as opposed to Path objects that are just constructed every frame for rendering)
*/
default void postprocess() {}
default void postProcess() {}
/**
* Number of positions in this path
* Returns the number of positions in this path. Equivalent to {@code positions().size()}.
*
* @return Number of positions in this path
*/
@@ -65,74 +63,74 @@ public interface IPath extends Helper {
}
/**
* What goal was this path calculated towards?
*
* @return
* @return The goal that this path was calculated towards
*/
Goal getGoal();
default Tuple<Double, BlockPos> closestPathPos() {
double best = -1;
BlockPos bestPos = null;
for (BlockPos pos : positions()) {
double dist = Utils.playerDistanceToCenter(pos);
if (dist < best || best == -1) {
best = dist;
bestPos = pos;
}
}
return new Tuple<>(best, bestPos);
}
/**
* Returns the number of nodes that were considered during calculation before
* this path was found.
*
* @return The number of nodes that were considered before finding this path
*/
int getNumNodesConsidered();
/**
* Where does this path start
* Returns the start position of this path. This is the first element in the
* {@link List} that is returned by {@link IPath#positions()}.
*
* @return The start position of this path
*/
default BetterBlockPos getSrc() {
return positions().get(0);
}
/**
* Where does this path end
* Returns the end position of this path. This is the last element in the
* {@link List} that is returned by {@link IPath#positions()}.
*
* @return The end position of this path.
*/
default BetterBlockPos getDest() {
List<BetterBlockPos> pos = positions();
return pos.get(pos.size() - 1);
}
/**
* Returns the estimated number of ticks to complete the path from the given node index.
*
* @param pathPosition The index of the node we're calculating from
* @return The estimated number of ticks remaining frm the given position
*/
default double ticksRemainingFrom(int pathPosition) {
double sum = 0;
//this is fast because we aren't requesting recalculation, it's just cached
for (int i = pathPosition; i < movements().size(); i++) {
sum += movements().get(i).getCost(null);
sum += movements().get(i).getCost();
}
return sum;
}
int getNumNodesConsidered();
/**
* Cuts off this path at the loaded chunk border, and returns the resulting path. Default
* implementation just returns this path, without the intended functionality.
*
* @return The result of this cut-off operation
*/
default IPath cutoffAtLoadedChunks() {
for (int i = 0; i < positions().size(); i++) {
BlockPos pos = positions().get(i);
if (Minecraft.getMinecraft().world.getChunk(pos) instanceof EmptyChunk) {
logDebug("Cutting off path at edge of loaded chunks");
logDebug("Length decreased by " + (positions().size() - i - 1));
return new CutoffPath(this, i);
}
}
logDebug("Path ends within loaded chunks");
return this;
}
/**
* Cuts off this path using the min length and cutoff factor settings, and returns the resulting path.
* Default implementation just returns this path, without the intended functionality.
*
* @see Settings#pathCutoffMinimumLength
* @see Settings#pathCutoffFactor
*
* @return The result of this cut-off operation
*/
default IPath staticCutoff(Goal destination) {
if (length() < Baritone.settings().pathCutoffMinimumLength.get()) {
return this;
}
if (destination == null || destination.isInGoal(getDest())) {
return this;
}
double factor = Baritone.settings().pathCutoffFactor.get();
int newLength = (int) (length() * factor);
logDebug("Static cutoff " + length() + " to " + newLength);
return new CutoffPath(this, newLength);
return this;
}
}

View File

@@ -15,10 +15,9 @@
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.pathing.calc;
package baritone.api.pathing.calc;
import baritone.api.pathing.goals.Goal;
import baritone.pathing.path.IPath;
import java.util.Optional;

View File

@@ -0,0 +1,67 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.pathing.movement;
import baritone.api.utils.BetterBlockPos;
import net.minecraft.util.math.BlockPos;
import java.util.List;
/**
* @author Brady
* @since 10/8/2018
*/
public interface IMovement {
double getCost();
MovementStatus update();
/**
* Resets the current state status to {@link MovementStatus#PREPPING}
*/
void reset();
/**
* Resets the cache for special break, place, and walk into blocks
*/
void resetBlockCache();
/**
* @return Whether or not it is safe to cancel the current movement state
*/
boolean safeToCancel();
double recalculateCost();
double calculateCostWithoutCaching();
boolean calculatedWhileLoaded();
BetterBlockPos getSrc();
BetterBlockPos getDest();
BlockPos getDirection();
List<BlockPos> toBreak();
List<BlockPos> toPlace();
List<BlockPos> toWalkInto();
}

View File

@@ -0,0 +1,74 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.pathing.movement;
/**
* @author Brady
* @since 10/8/2018
*/
public enum MovementStatus {
/**
* We are preparing the movement to be executed. This is when any blocks obstructing the destination are broken.
*/
PREPPING(false),
/**
* We are waiting for the movement to begin, after {@link MovementStatus#PREPPING}.
*/
WAITING(false),
/**
* The movement is currently in progress, after {@link MovementStatus#WAITING}
*/
RUNNING(false),
/**
* The movement has been completed and we are at our destination
*/
SUCCESS(true),
/**
* There was a change in state between calculation and actual
* movement execution, and the movement has now become impossible.
*/
UNREACHABLE(true),
/**
* Unused
*/
FAILED(true),
/**
* "Unused"
*/
CANCELED(true);
/**
* Whether or not this status indicates a complete movement.
*/
private final boolean complete;
MovementStatus(boolean complete) {
this.complete = complete;
}
public final boolean isComplete() {
return this.complete;
}
}

View File

@@ -0,0 +1,29 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.pathing.path;
import baritone.api.pathing.calc.IPath;
/**
* @author Brady
* @since 10/8/2018
*/
public interface IPathExecutor {
IPath getPath();
}

View File

@@ -15,9 +15,8 @@
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.utils.pathing;
package baritone.api.utils;
import baritone.pathing.calc.AbstractNodeCostSearch;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
@@ -54,11 +53,30 @@ public final class BetterBlockPos extends BlockPos {
@Override
public int hashCode() {
return (int) AbstractNodeCostSearch.posHash(x, y, z);
return (int) longHash(x, y, z);
}
public static long longHash(BetterBlockPos pos) {
return AbstractNodeCostSearch.posHash(pos.x, pos.y, pos.z);
return longHash(pos.x, pos.y, pos.z);
}
public static long longHash(int x, int y, int z) {
/*
* This is the hashcode implementation of Vec3i (the superclass of the class which I shall not name)
*
* public int hashCode() {
* return (this.getY() + this.getZ() * 31) * 31 + this.getX();
* }
*
* That is terrible and has tons of collisions and makes the HashMap terribly inefficient.
*
* That's why we grab out the X, Y, Z and calculate our own hashcode
*/
long hash = 3241;
hash = 3457689L * hash + x;
hash = 8734625L * hash + y;
hash = 2873465L * hash + z;
return hash;
}
@Override

View File

@@ -20,7 +20,7 @@ package baritone.launch.mixins;
import baritone.Baritone;
import baritone.api.event.events.RotationMoveEvent;
import baritone.api.event.events.type.EventState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.entity.Entity;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
@@ -40,8 +40,8 @@ public class MixinEntity {
)
private void preMoveRelative(float strafe, float up, float forward, float friction, CallbackInfo ci) {
Entity _this = (Entity) (Object) this;
if (_this == Minecraft.getMinecraft().player)
Baritone.INSTANCE.getGameEventHandler().onPlayerRotationMove(new RotationMoveEvent(EventState.PRE, RotationMoveEvent.Type.MOTION_UPDATE));
if (EntityPlayerSP.class.isInstance(_this))
Baritone.INSTANCE.getGameEventHandler().onPlayerRotationMove(new RotationMoveEvent((EntityPlayerSP) _this, EventState.PRE, RotationMoveEvent.Type.MOTION_UPDATE));
}
@Inject(
@@ -50,7 +50,7 @@ public class MixinEntity {
)
private void postMoveRelative(float strafe, float up, float forward, float friction, CallbackInfo ci) {
Entity _this = (Entity) (Object) this;
if (_this == Minecraft.getMinecraft().player)
Baritone.INSTANCE.getGameEventHandler().onPlayerRotationMove(new RotationMoveEvent(EventState.POST, RotationMoveEvent.Type.MOTION_UPDATE));
if (EntityPlayerSP.class.isInstance(_this))
Baritone.INSTANCE.getGameEventHandler().onPlayerRotationMove(new RotationMoveEvent((EntityPlayerSP) _this, EventState.POST, RotationMoveEvent.Type.MOTION_UPDATE));
}
}

View File

@@ -20,8 +20,7 @@ package baritone.launch.mixins;
import baritone.Baritone;
import baritone.api.event.events.RotationMoveEvent;
import baritone.api.event.events.type.EventState;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.Entity;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.entity.EntityLivingBase;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
@@ -40,9 +39,9 @@ public class MixinEntityLivingBase {
at = @At("HEAD")
)
private void preJump(CallbackInfo ci) {
Entity _this = (Entity) (Object) this;
if (_this == Minecraft.getMinecraft().player)
Baritone.INSTANCE.getGameEventHandler().onPlayerRotationMove(new RotationMoveEvent(EventState.PRE, RotationMoveEvent.Type.JUMP));
EntityLivingBase _this = (EntityLivingBase) (Object) this;
if (EntityPlayerSP.class.isInstance(_this))
Baritone.INSTANCE.getGameEventHandler().onPlayerRotationMove(new RotationMoveEvent((EntityPlayerSP) _this, EventState.PRE, RotationMoveEvent.Type.JUMP));
}
@Inject(
@@ -50,8 +49,8 @@ public class MixinEntityLivingBase {
at = @At("RETURN")
)
private void postJump(CallbackInfo ci) {
Entity _this = (Entity) (Object) this;
if (_this == Minecraft.getMinecraft().player)
Baritone.INSTANCE.getGameEventHandler().onPlayerRotationMove(new RotationMoveEvent(EventState.POST, RotationMoveEvent.Type.JUMP));
EntityLivingBase _this = (EntityLivingBase) (Object) this;
if (EntityPlayerSP.class.isInstance(_this))
Baritone.INSTANCE.getGameEventHandler().onPlayerRotationMove(new RotationMoveEvent((EntityPlayerSP) _this, EventState.POST, RotationMoveEvent.Type.JUMP));
}
}

View File

@@ -40,7 +40,7 @@ public class MixinEntityPlayerSP {
cancellable = true
)
private void sendChatMessage(String msg, CallbackInfo ci) {
ChatEvent event = new ChatEvent(msg);
ChatEvent event = new ChatEvent((EntityPlayerSP) (Object) this, msg);
Baritone.INSTANCE.getGameEventHandler().onSendChatMessage(event);
if (event.isCancelled()) {
ci.cancel();
@@ -57,7 +57,7 @@ public class MixinEntityPlayerSP {
)
)
private void onPreUpdate(CallbackInfo ci) {
Baritone.INSTANCE.getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent(EventState.PRE));
Baritone.INSTANCE.getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent((EntityPlayerSP) (Object) this, EventState.PRE));
}
@Inject(
@@ -70,6 +70,6 @@ public class MixinEntityPlayerSP {
)
)
private void onPostUpdate(CallbackInfo ci) {
Baritone.INSTANCE.getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent(EventState.POST));
Baritone.INSTANCE.getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent((EntityPlayerSP) (Object) this, EventState.POST));
}
}

View File

@@ -40,7 +40,6 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
/**

View File

@@ -54,7 +54,7 @@ public class MixinNetworkManager {
)
private void preDispatchPacket(Packet<?> inPacket, final GenericFutureListener<? extends Future<? super Void>>[] futureListeners, CallbackInfo ci) {
if (this.direction == EnumPacketDirection.CLIENTBOUND) {
Baritone.INSTANCE.getGameEventHandler().onSendPacket(new PacketEvent(EventState.PRE, inPacket));
Baritone.INSTANCE.getGameEventHandler().onSendPacket(new PacketEvent((NetworkManager) (Object) this, EventState.PRE, inPacket));
}
}
@@ -64,7 +64,7 @@ public class MixinNetworkManager {
)
private void postDispatchPacket(Packet<?> inPacket, final GenericFutureListener<? extends Future<? super Void>>[] futureListeners, CallbackInfo ci) {
if (this.direction == EnumPacketDirection.CLIENTBOUND) {
Baritone.INSTANCE.getGameEventHandler().onSendPacket(new PacketEvent(EventState.POST, inPacket));
Baritone.INSTANCE.getGameEventHandler().onSendPacket(new PacketEvent((NetworkManager) (Object) this, EventState.POST, inPacket));
}
}
@@ -77,7 +77,7 @@ public class MixinNetworkManager {
)
private void preProcessPacket(ChannelHandlerContext context, Packet<?> packet, CallbackInfo ci) {
if (this.direction == EnumPacketDirection.CLIENTBOUND) {
Baritone.INSTANCE.getGameEventHandler().onReceivePacket(new PacketEvent(EventState.PRE, packet));}
Baritone.INSTANCE.getGameEventHandler().onReceivePacket(new PacketEvent((NetworkManager) (Object) this, EventState.PRE, packet));}
}
@Inject(
@@ -86,7 +86,7 @@ public class MixinNetworkManager {
)
private void postProcessPacket(ChannelHandlerContext context, Packet<?> packet, CallbackInfo ci) {
if (this.channel.isOpen() && this.direction == EnumPacketDirection.CLIENTBOUND) {
Baritone.INSTANCE.getGameEventHandler().onReceivePacket(new PacketEvent(EventState.POST, packet));
Baritone.INSTANCE.getGameEventHandler().onReceivePacket(new PacketEvent((NetworkManager) (Object) this, EventState.POST, packet));
}
}
}

View File

@@ -19,16 +19,15 @@ package baritone.behavior;
import baritone.Baritone;
import baritone.api.behavior.IMineBehavior;
import baritone.api.event.events.PathEvent;
import baritone.api.event.events.TickEvent;
import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.goals.GoalBlock;
import baritone.api.pathing.goals.GoalComposite;
import baritone.api.pathing.goals.GoalTwoBlocks;
import baritone.cache.CachedChunk;
import baritone.cache.ChunkPacker;
import baritone.cache.WorldProvider;
import baritone.cache.WorldScanner;
import baritone.api.pathing.goals.GoalBlock;
import baritone.api.pathing.goals.GoalComposite;
import baritone.api.pathing.goals.GoalTwoBlocks;
import baritone.utils.BlockStateInterface;
import baritone.utils.Helper;
import net.minecraft.block.Block;
@@ -78,35 +77,37 @@ public final class MineBehavior extends Behavior implements IMineBehavior, Helpe
int mineGoalUpdateInterval = Baritone.settings().mineGoalUpdateInterval.get();
if (mineGoalUpdateInterval != 0) {
if (event.getCount() % mineGoalUpdateInterval == 0) {
Baritone.INSTANCE.getExecutor().execute(this::updateGoal);
Baritone.INSTANCE.getExecutor().execute(this::rescan);
}
}
PathingBehavior.INSTANCE.revalidateGoal();
}
@Override
public void onPathEvent(PathEvent event) {
updateGoal();
PathingBehavior.INSTANCE.revalidateGoal();
}
private void updateGoal() {
if (mining == null) {
return;
}
if (!locationsCache.isEmpty()) {
locationsCache = prune(new ArrayList<>(locationsCache), mining, 64);
PathingBehavior.INSTANCE.setGoal(coalesce(locationsCache));
List<BlockPos> locs = locationsCache;
if (!locs.isEmpty()) {
locs = prune(new ArrayList<>(locs), mining, 64);
PathingBehavior.INSTANCE.setGoal(coalesce(locs));
PathingBehavior.INSTANCE.path();
locationsCache = locs;
}
}
private void rescan() {
if (mining == null) {
return;
}
List<BlockPos> locs = scanFor(mining, 64);
if (locs.isEmpty()) {
logDebug("No locations for " + mining + " known, cancelling");
cancel();
mine(0, (String[]) null);
return;
}
locationsCache = locs;
PathingBehavior.INSTANCE.setGoal(coalesce(locs));
PathingBehavior.INSTANCE.path();
}
public GoalComposite coalesce(List<BlockPos> locs) {
@@ -176,6 +177,7 @@ public final class MineBehavior extends Behavior implements IMineBehavior, Helpe
this.mining = blocks == null || blocks.length == 0 ? null : Arrays.stream(blocks).map(ChunkPacker::stringToBlock).collect(Collectors.toList());
this.quantity = quantity;
this.locationsCache = new ArrayList<>();
rescan();
updateGoal();
}
@@ -184,6 +186,7 @@ public final class MineBehavior extends Behavior implements IMineBehavior, Helpe
this.mining = blocks == null || blocks.length == 0 ? null : Arrays.asList(blocks);
this.quantity = quantity;
this.locationsCache = new ArrayList<>();
rescan();
updateGoal();
}

View File

@@ -23,27 +23,24 @@ import baritone.api.event.events.PathEvent;
import baritone.api.event.events.PlayerUpdateEvent;
import baritone.api.event.events.RenderEvent;
import baritone.api.event.events.TickEvent;
import baritone.api.pathing.calc.IPath;
import baritone.api.pathing.calc.IPathFinder;
import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.goals.GoalXZ;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.interfaces.IGoalRenderPos;
import baritone.pathing.calc.AStarPathFinder;
import baritone.pathing.calc.AbstractNodeCostSearch;
import baritone.pathing.calc.IPathFinder;
import baritone.pathing.calc.CutoffPath;
import baritone.pathing.movement.MovementHelper;
import baritone.pathing.path.IPath;
import baritone.pathing.path.PathExecutor;
import baritone.utils.BlockBreakHelper;
import baritone.utils.BlockStateInterface;
import baritone.utils.Helper;
import baritone.utils.PathRenderer;
import baritone.utils.pathing.BetterBlockPos;
import net.minecraft.init.Blocks;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.chunk.EmptyChunk;
import java.util.Collection;
import java.util.HashSet;
import java.util.Optional;
import java.util.*;
import java.util.stream.Collectors;
public final class PathingBehavior extends Behavior implements IPathingBehavior, Helper {
@@ -104,6 +101,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
dispatchPathEvent(PathEvent.CONTINUING_ONTO_PLANNED_NEXT);
current = next;
next = null;
current.onTick(event);
return;
}
// at this point, current just ended, but we aren't in the goal and have no plan for the future
@@ -122,12 +120,13 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
if (safe) {
// a movement just ended
if (next != null) {
if (next.getPath().positions().contains(playerFeet())) {
if (next.snipsnapifpossible()) {
// jump directly onto the next path
logDebug("Splicing into planned next path early...");
dispatchPathEvent(PathEvent.SPLICING_ONTO_NEXT_EARLY);
current = next;
next = null;
current.onTick(event);
return;
}
}
@@ -190,19 +189,19 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
return goal;
}
@Override
public PathExecutor getCurrent() {
return current;
}
@Override
public PathExecutor getNext() {
return next;
}
// TODO: Expose this method in the API?
// In order to do so, we'd need to move over IPath which has a whole lot of references to other
// things that may not need to be exposed necessarily, so we'll need to figure that out.
public Optional<IPath> getPath() {
return Optional.ofNullable(current).map(PathExecutor::getPath);
@Override
public Optional<IPathFinder> getPathFinder() {
return Optional.ofNullable(AbstractNodeCostSearch.currentlyRunning());
}
@Override
@@ -253,12 +252,46 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
}
/**
* See issue #209
*
* @return The starting {@link BlockPos} for a new path
*/
private BlockPos pathStart() {
public BlockPos pathStart() {
BetterBlockPos feet = playerFeet();
if (BlockStateInterface.get(feet.down()).getBlock().equals(Blocks.AIR) && MovementHelper.canWalkOn(feet.down().down())) {
return feet.down();
if (!MovementHelper.canWalkOn(feet.down())) {
if (player().onGround) {
double playerX = player().posX;
double playerZ = player().posZ;
ArrayList<BetterBlockPos> closest = new ArrayList<>();
for (int dx = -1; dx <= 1; dx++) {
for (int dz = -1; dz <= 1; dz++) {
closest.add(new BetterBlockPos(feet.x + dx, feet.y, feet.z + dz));
}
}
closest.sort(Comparator.comparingDouble(pos -> ((pos.x + 0.5D) - playerX) * ((pos.x + 0.5D) - playerX) + ((pos.z + 0.5D) - playerZ) * ((pos.z + 0.5D) - playerZ)));
for (int i = 0; i < 4; i++) {
BetterBlockPos possibleSupport = closest.get(i);
double xDist = Math.abs((possibleSupport.x + 0.5D) - playerX);
double zDist = Math.abs((possibleSupport.z + 0.5D) - playerZ);
if (xDist > 0.8 && zDist > 0.8) {
// can't possibly be sneaking off of this one, we're too far away
continue;
}
if (MovementHelper.canWalkOn(possibleSupport.down()) && MovementHelper.canWalkThrough(possibleSupport) && MovementHelper.canWalkThrough(possibleSupport.up())) {
// this is plausible
logDebug("Faking path start assuming player is standing off the edge of a block");
return possibleSupport;
}
}
} else {
// !onGround
// we're in the middle of a jump
if (MovementHelper.canWalkOn(feet.down().down())) {
logDebug("Faking path start assuming player is midair and falling");
return feet.down();
}
}
}
return feet;
}
@@ -283,9 +316,30 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
Optional<IPath> path = findPath(start, previous);
if (Baritone.settings().cutoffAtLoadBoundary.get()) {
path = path.map(IPath::cutoffAtLoadedChunks);
path = path.map(p -> {
IPath result = p.cutoffAtLoadedChunks();
if (result instanceof CutoffPath) {
logDebug("Cutting off path at edge of loaded chunks");
logDebug("Length decreased by " + (p.length() - result.length()));
} else {
logDebug("Path ends within loaded chunks");
}
return result;
});
}
Optional<PathExecutor> executor = path.map(p -> p.staticCutoff(goal)).map(PathExecutor::new);
Optional<PathExecutor> executor = path.map(p -> {
IPath result = p.staticCutoff(goal);
if (result instanceof CutoffPath) {
logDebug("Static cutoff " + p.length() + " to " + result.length());
}
return result;
}).map(PathExecutor::new);
synchronized (pathPlanLock) {
if (current == null) {
if (executor.isPresent()) {

View File

@@ -42,7 +42,7 @@ public class WorldData implements IWorldData {
this.waypoints = new Waypoints(directory.resolve("waypoints"));
}
void onClose() {
public void onClose() {
Baritone.INSTANCE.getExecutor().execute(() -> {
System.out.println("Started saving the world in a new thread");
cache.save();

View File

@@ -20,10 +20,11 @@ package baritone.pathing.calc;
import baritone.Baritone;
import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.movement.ActionCosts;
import baritone.api.pathing.calc.IPath;
import baritone.api.utils.BetterBlockPos;
import baritone.pathing.calc.openset.BinaryHeapOpenSet;
import baritone.pathing.movement.CalculationContext;
import baritone.pathing.movement.Moves;
import baritone.pathing.path.IPath;
import baritone.utils.BlockStateInterface;
import baritone.utils.Helper;
import baritone.utils.pathing.MutableMoveResult;
@@ -47,7 +48,7 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
@Override
protected Optional<IPath> calculate0(long timeout) {
startNode = getNodeAtPosition(startX, startY, startZ, posHash(startX, startY, startZ));
startNode = getNodeAtPosition(startX, startY, startZ, BetterBlockPos.longHash(startX, startY, startZ));
startNode.cost = 0;
startNode.combinedCost = startNode.estimatedCostToGoal;
BinaryHeapOpenSet openSet = new BinaryHeapOpenSet();
@@ -122,7 +123,7 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
if (actionCost <= 0) {
throw new IllegalStateException(moves + " calculated implausible cost " + actionCost);
}
long hashCode = posHash(res.x, res.y, res.z);
long hashCode = BetterBlockPos.longHash(res.x, res.y, res.z);
if (favoring && favored.contains(hashCode)) {
// see issue #18
actionCost *= favorCoeff;

View File

@@ -18,8 +18,9 @@
package baritone.pathing.calc;
import baritone.Baritone;
import baritone.api.pathing.calc.IPathFinder;
import baritone.api.pathing.goals.Goal;
import baritone.pathing.path.IPath;
import baritone.api.pathing.calc.IPath;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import java.util.Optional;
@@ -88,7 +89,7 @@ public abstract class AbstractNodeCostSearch implements IPathFinder {
this.cancelRequested = false;
try {
Optional<IPath> path = calculate0(timeout);
path.ifPresent(IPath::postprocess);
path.ifPresent(IPath::postProcess);
isFinished = true;
return path;
} finally {
@@ -140,25 +141,6 @@ public abstract class AbstractNodeCostSearch implements IPathFinder {
return node;
}
public static long posHash(int x, int y, int z) {
/*
* This is the hashcode implementation of Vec3i (the superclass of the class which I shall not name)
*
* public int hashCode() {
* return (this.getY() + this.getZ() * 31) * 31 + this.getX();
* }
*
* That is terrible and has tons of collisions and makes the HashMap terribly inefficient.
*
* That's why we grab out the X, Y, Z and calculate our own hashcode
*/
long hash = 3241;
hash = 3457689L * hash + x;
hash = 8734625L * hash + y;
hash = 2873465L * hash + z;
return hash;
}
public static void forceCancel() {
currentlyRunning = null;
}
@@ -225,4 +207,8 @@ public abstract class AbstractNodeCostSearch implements IPathFinder {
public static Optional<AbstractNodeCostSearch> getCurrentlyRunning() {
return Optional.ofNullable(currentlyRunning);
}
public static AbstractNodeCostSearch currentlyRunning() {
return currentlyRunning;
}
}

View File

@@ -15,11 +15,12 @@
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.pathing.path;
package baritone.pathing.calc;
import baritone.api.pathing.goals.Goal;
import baritone.pathing.movement.Movement;
import baritone.utils.pathing.BetterBlockPos;
import baritone.api.pathing.movement.IMovement;
import baritone.api.pathing.calc.IPath;
import baritone.api.utils.BetterBlockPos;
import java.util.Collections;
import java.util.List;
@@ -28,13 +29,13 @@ public class CutoffPath implements IPath {
private final List<BetterBlockPos> path;
private final List<Movement> movements;
private final List<IMovement> movements;
private final int numNodes;
private final Goal goal;
public CutoffPath(IPath prev, int lastPositionToInclude) {
CutoffPath(IPath prev, int lastPositionToInclude) {
path = prev.positions().subList(0, lastPositionToInclude + 1);
movements = prev.movements().subList(0, lastPositionToInclude + 1);
numNodes = prev.getNumNodesConsidered();
@@ -47,7 +48,7 @@ public class CutoffPath implements IPath {
}
@Override
public List<Movement> movements() {
public List<IMovement> movements() {
return Collections.unmodifiableList(movements);
}

View File

@@ -17,12 +17,16 @@
package baritone.pathing.calc;
import baritone.api.BaritoneAPI;
import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.movement.IMovement;
import baritone.api.pathing.calc.IPath;
import baritone.api.utils.BetterBlockPos;
import baritone.pathing.movement.Movement;
import baritone.pathing.movement.Moves;
import baritone.pathing.path.IPath;
import baritone.utils.pathing.BetterBlockPos;
import net.minecraft.client.Minecraft;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.chunk.EmptyChunk;
import java.util.ArrayList;
import java.util.Collections;
@@ -149,7 +153,7 @@ class Path implements IPath {
}
@Override
public void postprocess() {
public void postProcess() {
if (verified) {
throw new IllegalStateException();
}
@@ -161,7 +165,7 @@ class Path implements IPath {
}
@Override
public List<Movement> movements() {
public List<IMovement> movements() {
if (!verified) {
throw new IllegalStateException();
}
@@ -187,4 +191,28 @@ class Path implements IPath {
public BetterBlockPos getDest() {
return end;
}
@Override
public IPath cutoffAtLoadedChunks() {
for (int i = 0; i < positions().size(); i++) {
BlockPos pos = positions().get(i);
if (Minecraft.getMinecraft().world.getChunk(pos) instanceof EmptyChunk) {
return new CutoffPath(this, i);
}
}
return this;
}
@Override
public IPath staticCutoff(Goal destination) {
if (length() < BaritoneAPI.getSettings().pathCutoffMinimumLength.get()) {
return this;
}
if (destination == null || destination.isInGoal(getDest())) {
return this;
}
double factor = BaritoneAPI.getSettings().pathCutoffFactor.get();
int newLength = (int) (length() * factor);
return new CutoffPath(this, newLength);
}
}

View File

@@ -19,6 +19,7 @@ package baritone.pathing.calc;
import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.movement.ActionCosts;
import baritone.api.utils.BetterBlockPos;
/**
* A node in the path, containing the cost and steps to get to it.
@@ -30,20 +31,20 @@ public final class PathNode {
/**
* The position of this node
*/
final int x;
final int y;
final int z;
public final int x;
public final int y;
public final int z;
/**
* Cached, should always be equal to goal.heuristic(pos)
*/
final double estimatedCostToGoal;
public final double estimatedCostToGoal;
/**
* Total cost of getting from start to here
* Mutable and changed by PathFinder
*/
double cost;
public double cost;
/**
* Should always be equal to estimatedCosttoGoal + cost
@@ -55,13 +56,13 @@ public final class PathNode {
* In the graph search, what previous node contributed to the cost
* Mutable and changed by PathFinder
*/
PathNode previous;
public PathNode previous;
/**
* Is this a member of the open set in A*? (only used during pathfinding)
* Instead of doing a costly member check in the open set, cache membership in each node individually too.
*/
boolean isOpen;
public boolean isOpen;
/**
* Where is this node in the array flattenization of the binary heap? Needed for decrease-key operations.
@@ -85,7 +86,7 @@ public final class PathNode {
*/
@Override
public int hashCode() {
return (int) AbstractNodeCostSearch.posHash(x, y, z);
return (int) BetterBlockPos.longHash(x, y, z);
}
@Override

View File

@@ -18,12 +18,13 @@
package baritone.pathing.movement;
import baritone.Baritone;
import baritone.api.pathing.movement.IMovement;
import baritone.api.pathing.movement.MovementStatus;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.Rotation;
import baritone.behavior.LookBehavior;
import baritone.behavior.LookBehaviorUtils;
import baritone.pathing.movement.MovementState.MovementStatus;
import baritone.utils.*;
import baritone.utils.pathing.BetterBlockPos;
import net.minecraft.block.BlockLiquid;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
@@ -36,7 +37,7 @@ import java.util.Optional;
import static baritone.utils.InputOverrideHandler.Input;
public abstract class Movement implements Helper, MovementHelper {
public abstract class Movement implements IMovement, Helper, MovementHelper {
protected static final EnumFacing[] HORIZONTALS = {EnumFacing.NORTH, EnumFacing.SOUTH, EnumFacing.EAST, EnumFacing.WEST};
@@ -77,24 +78,27 @@ public abstract class Movement implements Helper, MovementHelper {
this(src, dest, toBreak, null);
}
public double getCost(CalculationContext context) {
@Override
public double getCost() {
if (cost == null) {
cost = calculateCost(context != null ? context : new CalculationContext());
cost = calculateCost(new CalculationContext());
}
return cost;
}
protected abstract double calculateCost(CalculationContext context);
@Override
public double recalculateCost() {
cost = null;
return getCost(null);
return getCost();
}
protected void override(double cost) {
this.cost = cost;
}
@Override
public double calculateCostWithoutCaching() {
return calculateCost(new CalculationContext());
}
@@ -105,12 +109,16 @@ public abstract class Movement implements Helper, MovementHelper {
*
* @return Status
*/
@Override
public MovementStatus update() {
player().capabilities.allowFlying = false;
MovementState latestState = updateState(currentState);
if (BlockStateInterface.isLiquid(playerFeet())) {
latestState.setInput(Input.JUMP, true);
}
if (player().isEntityInsideOpaqueBlock()) {
latestState.setInput(Input.CLICK_LEFT, true);
}
// If the movement target has to force the new rotations, or we aren't using silent move, then force the rotations
latestState.getTarget().getRotation().ifPresent(rotation ->
@@ -147,7 +155,8 @@ public abstract class Movement implements Helper, MovementHelper {
currentState = latestState;
if (isFinished()) {
// If the current status indicates a completed movement
if (currentState.getStatus().isComplete()) {
onFinish(latestState);
}
@@ -187,6 +196,7 @@ public abstract class Movement implements Helper, MovementHelper {
return true;
}
@Override
public boolean safeToCancel() {
return safeToCancel(currentState);
}
@@ -195,16 +205,12 @@ public abstract class Movement implements Helper, MovementHelper {
return true;
}
public boolean isFinished() {
return (currentState.getStatus() != MovementStatus.RUNNING
&& currentState.getStatus() != MovementStatus.PREPPING
&& currentState.getStatus() != MovementStatus.WAITING);
}
@Override
public BetterBlockPos getSrc() {
return src;
}
@Override
public BetterBlockPos getDest() {
return dest;
}
@@ -223,6 +229,7 @@ public abstract class Movement implements Helper, MovementHelper {
currentState.setStatus(MovementStatus.CANCELED);
}
@Override
public void reset() {
currentState = new MovementState().setStatus(MovementStatus.PREPPING);
}
@@ -247,6 +254,7 @@ public abstract class Movement implements Helper, MovementHelper {
return state;
}
@Override
public BlockPos getDirection() {
return getDest().subtract(getSrc());
}
@@ -255,10 +263,19 @@ public abstract class Movement implements Helper, MovementHelper {
calculatedWhileLoaded = !(world().getChunk(getDest()) instanceof EmptyChunk);
}
@Override
public boolean calculatedWhileLoaded() {
return calculatedWhileLoaded;
}
@Override
public void resetBlockCache() {
toBreakCached = null;
toPlaceCached = null;
toWalkIntoCached = null;
}
@Override
public List<BlockPos> toBreak() {
if (toBreakCached != null) {
return toBreakCached;
@@ -273,6 +290,7 @@ public abstract class Movement implements Helper, MovementHelper {
return result;
}
@Override
public List<BlockPos> toPlace() {
if (toPlaceCached != null) {
return toPlaceCached;
@@ -285,6 +303,7 @@ public abstract class Movement implements Helper, MovementHelper {
return result;
}
@Override
public List<BlockPos> toWalkInto() { // overridden by movementdiagonal
if (toWalkIntoCached == null) {
toWalkIntoCached = new ArrayList<>();

View File

@@ -19,11 +19,11 @@ package baritone.pathing.movement;
import baritone.Baritone;
import baritone.api.pathing.movement.ActionCosts;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.Rotation;
import baritone.behavior.LookBehaviorUtils;
import baritone.pathing.movement.MovementState.MovementTarget;
import baritone.utils.*;
import baritone.utils.pathing.BetterBlockPos;
import net.minecraft.block.*;
import net.minecraft.block.properties.PropertyBool;
import net.minecraft.block.state.IBlockState;
@@ -31,6 +31,7 @@ import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.entity.Entity;
import net.minecraft.init.Blocks;
import net.minecraft.item.ItemPickaxe;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.NonNullList;
@@ -457,6 +458,22 @@ public interface MovementHelper extends ActionCosts, Helper {
return true;
}
}
if (Baritone.settings().acceptableThrowawayItems.get().contains(p.inventory.offHandInventory.get(0).getItem())) {
// main hand takes precedence over off hand
// that means that if we have block A selected in main hand and block B in off hand, right clicking places block B
// we've already checked above ^ and the main hand can't possible have an acceptablethrowawayitem
// so we need to select in the main hand something that doesn't right click
// so not a shovel, not a hoe, not a block, etc
for (byte i = 0; i < 9; i++) {
ItemStack item = inv.get(i);
if (item.isEmpty() || item.getItem() instanceof ItemPickaxe) {
if (select) {
p.inventory.currentItem = i;
}
return true;
}
}
}
return false;
}

View File

@@ -17,6 +17,7 @@
package baritone.pathing.movement;
import baritone.api.pathing.movement.MovementStatus;
import baritone.api.utils.Rotation;
import baritone.utils.InputOverrideHandler.Input;
import net.minecraft.util.math.Vec3d;
@@ -72,10 +73,6 @@ public class MovementState {
return this.inputState;
}
public enum MovementStatus {
PREPPING, WAITING, RUNNING, SUCCESS, UNREACHABLE, FAILED, CANCELED
}
public static class MovementTarget {
/**

View File

@@ -17,8 +17,8 @@
package baritone.pathing.movement;
import baritone.api.utils.BetterBlockPos;
import baritone.pathing.movement.movements.*;
import baritone.utils.pathing.BetterBlockPos;
import baritone.utils.pathing.MutableMoveResult;
import net.minecraft.util.EnumFacing;

View File

@@ -18,16 +18,16 @@
package baritone.pathing.movement.movements;
import baritone.Baritone;
import baritone.api.pathing.movement.MovementStatus;
import baritone.api.utils.BetterBlockPos;
import baritone.behavior.LookBehaviorUtils;
import baritone.pathing.movement.CalculationContext;
import baritone.pathing.movement.Movement;
import baritone.pathing.movement.MovementHelper;
import baritone.pathing.movement.MovementState;
import baritone.pathing.movement.MovementState.MovementStatus;
import baritone.utils.BlockStateInterface;
import baritone.utils.InputOverrideHandler;
import baritone.utils.Utils;
import baritone.utils.pathing.BetterBlockPos;
import net.minecraft.block.BlockFalling;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;

View File

@@ -18,14 +18,14 @@
package baritone.pathing.movement.movements;
import baritone.Baritone;
import baritone.api.pathing.movement.MovementStatus;
import baritone.api.utils.BetterBlockPos;
import baritone.pathing.movement.CalculationContext;
import baritone.pathing.movement.Movement;
import baritone.pathing.movement.MovementHelper;
import baritone.pathing.movement.MovementState;
import baritone.pathing.movement.MovementState.MovementStatus;
import baritone.utils.BlockStateInterface;
import baritone.utils.InputOverrideHandler;
import baritone.utils.pathing.BetterBlockPos;
import baritone.utils.pathing.MutableMoveResult;
import net.minecraft.block.Block;
import net.minecraft.block.BlockFalling;

View File

@@ -17,13 +17,14 @@
package baritone.pathing.movement.movements;
import baritone.api.pathing.movement.MovementStatus;
import baritone.api.utils.BetterBlockPos;
import baritone.pathing.movement.CalculationContext;
import baritone.pathing.movement.Movement;
import baritone.pathing.movement.MovementHelper;
import baritone.pathing.movement.MovementState;
import baritone.utils.BlockStateInterface;
import baritone.utils.InputOverrideHandler;
import baritone.utils.pathing.BetterBlockPos;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
@@ -140,12 +141,12 @@ public class MovementDiagonal extends Movement {
@Override
public MovementState updateState(MovementState state) {
super.updateState(state);
if (state.getStatus() != MovementState.MovementStatus.RUNNING) {
if (state.getStatus() != MovementStatus.RUNNING) {
return state;
}
if (playerFeet().equals(dest)) {
state.setStatus(MovementState.MovementStatus.SUCCESS);
state.setStatus(MovementStatus.SUCCESS);
return state;
}
if (!BlockStateInterface.isLiquid(playerFeet())) {

View File

@@ -17,12 +17,13 @@
package baritone.pathing.movement.movements;
import baritone.api.pathing.movement.MovementStatus;
import baritone.api.utils.BetterBlockPos;
import baritone.pathing.movement.CalculationContext;
import baritone.pathing.movement.Movement;
import baritone.pathing.movement.MovementHelper;
import baritone.pathing.movement.MovementState;
import baritone.utils.BlockStateInterface;
import baritone.utils.pathing.BetterBlockPos;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
@@ -64,12 +65,12 @@ public class MovementDownward extends Movement {
@Override
public MovementState updateState(MovementState state) {
super.updateState(state);
if (state.getStatus() != MovementState.MovementStatus.RUNNING) {
if (state.getStatus() != MovementStatus.RUNNING) {
return state;
}
if (playerFeet().equals(dest)) {
return state.setStatus(MovementState.MovementStatus.SUCCESS);
return state.setStatus(MovementStatus.SUCCESS);
}
double diffX = player().posX - (dest.getX() + 0.5);
double diffZ = player().posZ - (dest.getZ() + 0.5);

View File

@@ -18,18 +18,18 @@
package baritone.pathing.movement.movements;
import baritone.Baritone;
import baritone.api.pathing.movement.MovementStatus;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.Rotation;
import baritone.pathing.movement.CalculationContext;
import baritone.pathing.movement.Movement;
import baritone.pathing.movement.MovementHelper;
import baritone.pathing.movement.MovementState;
import baritone.pathing.movement.MovementState.MovementStatus;
import baritone.pathing.movement.MovementState.MovementTarget;
import baritone.utils.BlockStateInterface;
import baritone.utils.InputOverrideHandler;
import baritone.utils.RayTraceUtils;
import baritone.utils.Utils;
import baritone.utils.pathing.BetterBlockPos;
import baritone.utils.pathing.MutableMoveResult;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.init.Items;
@@ -106,7 +106,7 @@ public class MovementFall extends Movement {
}
}
Vec3d destCenter = Utils.getBlockPosCenter(dest); // we are moving to the 0.5 center not the edge (like if we were falling on a ladder)
if (Math.abs(player().posX - destCenter.x) > 0.2 || Math.abs(player().posZ - destCenter.z) > 0.2) {
if (Math.abs(player().posX - destCenter.x) > 0.15 || Math.abs(player().posZ - destCenter.z) > 0.15) {
state.setInput(InputOverrideHandler.Input.MOVE_FORWARD, true);
}
return state;

View File

@@ -18,6 +18,8 @@
package baritone.pathing.movement.movements;
import baritone.Baritone;
import baritone.api.pathing.movement.MovementStatus;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.Rotation;
import baritone.behavior.LookBehaviorUtils;
import baritone.pathing.movement.CalculationContext;
@@ -25,7 +27,6 @@ import baritone.pathing.movement.Movement;
import baritone.pathing.movement.MovementHelper;
import baritone.pathing.movement.MovementState;
import baritone.utils.*;
import baritone.utils.pathing.BetterBlockPos;
import baritone.utils.pathing.MutableMoveResult;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
@@ -168,13 +169,13 @@ public class MovementParkour extends Movement {
// once this movement is instantiated, the state is default to PREPPING
// but once it's ticked for the first time it changes to RUNNING
// since we don't really know anything about momentum, it suffices to say Parkour can only be canceled on the 0th tick
return state.getStatus() != MovementState.MovementStatus.RUNNING;
return state.getStatus() != MovementStatus.RUNNING;
}
@Override
public MovementState updateState(MovementState state) {
super.updateState(state);
if (state.getStatus() != MovementState.MovementStatus.RUNNING) {
if (state.getStatus() != MovementStatus.RUNNING) {
return state;
}
if (dist >= 4) {
@@ -186,10 +187,10 @@ public class MovementParkour extends Movement {
if (d == Blocks.VINE || d == Blocks.LADDER) {
// it physically hurt me to add support for parkour jumping onto a vine
// but i did it anyway
return state.setStatus(MovementState.MovementStatus.SUCCESS);
return state.setStatus(MovementStatus.SUCCESS);
}
if (player().posY - playerFeet().getY() < 0.094) { // lilypads
state.setStatus(MovementState.MovementStatus.SUCCESS);
state.setStatus(MovementStatus.SUCCESS);
}
} else if (!playerFeet().equals(src)) {
if (playerFeet().equals(src.offset(direction)) || player().posY - playerFeet().getY() > 0.0001) {
@@ -203,7 +204,7 @@ public class MovementParkour extends Movement {
}
if (MovementHelper.canPlaceAgainst(against1)) {
if (!MovementHelper.throwaway(true)) {//get ready to place a throwaway block
return state.setStatus(MovementState.MovementStatus.UNREACHABLE);
return state.setStatus(MovementStatus.UNREACHABLE);
}
double faceX = (dest.getX() + against1.getX() + 1.0D) * 0.5D;
double faceY = (dest.getY() + against1.getY()) * 0.5D;

View File

@@ -17,6 +17,8 @@
package baritone.pathing.movement.movements;
import baritone.api.pathing.movement.MovementStatus;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.Rotation;
import baritone.pathing.movement.CalculationContext;
import baritone.pathing.movement.Movement;
@@ -25,7 +27,6 @@ import baritone.pathing.movement.MovementState;
import baritone.utils.BlockStateInterface;
import baritone.utils.InputOverrideHandler;
import baritone.utils.Utils;
import baritone.utils.pathing.BetterBlockPos;
import net.minecraft.block.*;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
@@ -34,18 +35,11 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
public class MovementPillar extends Movement {
private int numTicks = 0;
public MovementPillar(BetterBlockPos start, BetterBlockPos end) {
super(start, end, new BetterBlockPos[]{start.up(2)}, start);
}
@Override
public void reset() {
super.reset();
numTicks = 0;
}
@Override
protected double calculateCost(CalculationContext context) {
return cost(context, src.x, src.y, src.z);
@@ -148,7 +142,7 @@ public class MovementPillar extends Movement {
@Override
public MovementState updateState(MovementState state) {
super.updateState(state);
if (state.getStatus() != MovementState.MovementStatus.RUNNING) {
if (state.getStatus() != MovementStatus.RUNNING) {
return state;
}
@@ -161,7 +155,7 @@ public class MovementPillar extends Movement {
state.setInput(InputOverrideHandler.Input.MOVE_FORWARD, true);
}
if (playerFeet().equals(dest)) {
return state.setStatus(MovementState.MovementStatus.SUCCESS);
return state.setStatus(MovementStatus.SUCCESS);
}
return state;
}
@@ -178,11 +172,11 @@ public class MovementPillar extends Movement {
BlockPos against = vine ? getAgainst(src) : src.offset(fromDown.getValue(BlockLadder.FACING).getOpposite());
if (against == null) {
logDebug("Unable to climb vines");
return state.setStatus(MovementState.MovementStatus.UNREACHABLE);
return state.setStatus(MovementStatus.UNREACHABLE);
}
if (playerFeet().equals(against.up()) || playerFeet().equals(dest)) {
return state.setStatus(MovementState.MovementStatus.SUCCESS);
return state.setStatus(MovementStatus.SUCCESS);
}
if (MovementHelper.isBottomSlab(src.down())) {
state.setInput(InputOverrideHandler.Input.JUMP, true);
@@ -198,28 +192,25 @@ public class MovementPillar extends Movement {
} else {
// Get ready to place a throwaway block
if (!MovementHelper.throwaway(true)) {
return state.setStatus(MovementState.MovementStatus.UNREACHABLE);
return state.setStatus(MovementStatus.UNREACHABLE);
}
numTicks++;
// If our Y coordinate is above our goal, stop jumping
state.setInput(InputOverrideHandler.Input.JUMP, player().posY < dest.getY());
state.setInput(InputOverrideHandler.Input.SNEAK, true);
// Otherwise jump
if (numTicks > 20) {
double diffX = player().posX - (dest.getX() + 0.5);
double diffZ = player().posZ - (dest.getZ() + 0.5);
double dist = Math.sqrt(diffX * diffX + diffZ * diffZ);
if (dist > 0.17) {//why 0.17? because it seemed like a good number, that's why
//[explanation added after baritone port lol] also because it needs to be less than 0.2 because of the 0.3 sneak limit
//and 0.17 is reasonably less than 0.2
double diffX = player().posX - (dest.getX() + 0.5);
double diffZ = player().posZ - (dest.getZ() + 0.5);
double dist = Math.sqrt(diffX * diffX + diffZ * diffZ);
if (dist > 0.17) {//why 0.17? because it seemed like a good number, that's why
//[explanation added after baritone port lol] also because it needs to be less than 0.2 because of the 0.3 sneak limit
//and 0.17 is reasonably less than 0.2
// If it's been more than forty ticks of trying to jump and we aren't done yet, go forward, maybe we are stuck
state.setInput(InputOverrideHandler.Input.MOVE_FORWARD, true);
}
// If it's been more than forty ticks of trying to jump and we aren't done yet, go forward, maybe we are stuck
state.setInput(InputOverrideHandler.Input.MOVE_FORWARD, true);
}
if (!blockIsThere) {
Block fr = BlockStateInterface.get(src).getBlock();
if (!(fr instanceof BlockAir || fr.isReplaceable(Minecraft.getMinecraft().world, src))) {
@@ -233,7 +224,7 @@ public class MovementPillar extends Movement {
// If we are at our goal and the block below us is placed
if (playerFeet().equals(dest) && blockIsThere) {
return state.setStatus(MovementState.MovementStatus.SUCCESS);
return state.setStatus(MovementStatus.SUCCESS);
}
return state;

View File

@@ -18,6 +18,8 @@
package baritone.pathing.movement.movements;
import baritone.Baritone;
import baritone.api.pathing.movement.MovementStatus;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.Rotation;
import baritone.behavior.LookBehaviorUtils;
import baritone.pathing.movement.CalculationContext;
@@ -27,7 +29,6 @@ import baritone.pathing.movement.MovementState;
import baritone.utils.BlockStateInterface;
import baritone.utils.InputOverrideHandler;
import baritone.utils.Utils;
import baritone.utils.pathing.BetterBlockPos;
import net.minecraft.block.*;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
@@ -144,13 +145,13 @@ public class MovementTraverse extends Movement {
@Override
public MovementState updateState(MovementState state) {
super.updateState(state);
if (state.getStatus() != MovementState.MovementStatus.RUNNING) {
if (state.getStatus() != MovementStatus.RUNNING) {
// if the setting is enabled
if (!Baritone.settings().walkWhileBreaking.get()) {
return state;
}
// and if we're prepping (aka mining the block in front)
if (state.getStatus() != MovementState.MovementStatus.PREPPING) {
if (state.getStatus() != MovementStatus.PREPPING) {
return state;
}
// and if it's fine to walk into the blocks in front
@@ -225,7 +226,7 @@ public class MovementTraverse extends Movement {
if (isTheBridgeBlockThere) {
if (playerFeet().equals(dest)) {
return state.setStatus(MovementState.MovementStatus.SUCCESS);
return state.setStatus(MovementStatus.SUCCESS);
}
if (wasTheBridgeBlockAlwaysThere && !BlockStateInterface.isLiquid(playerFeet())) {
state.setInput(InputOverrideHandler.Input.SPRINT, true);
@@ -248,7 +249,7 @@ public class MovementTraverse extends Movement {
if (MovementHelper.canPlaceAgainst(against1)) {
if (!MovementHelper.throwaway(true)) { // get ready to place a throwaway block
logDebug("bb pls get me some blocks. dirt or cobble");
return state.setStatus(MovementState.MovementStatus.UNREACHABLE);
return state.setStatus(MovementStatus.UNREACHABLE);
}
if (!Baritone.settings().assumeSafeWalk.get()) {
state.setInput(InputOverrideHandler.Input.SNEAK, true);
@@ -287,7 +288,7 @@ public class MovementTraverse extends Movement {
// Out.log(from + " " + to + " " + faceX + "," + faceY + "," + faceZ + " " + whereAmI);
if (!MovementHelper.throwaway(true)) {// get ready to place a throwaway block
logDebug("bb pls get me some blocks. dirt or cobble");
return state.setStatus(MovementState.MovementStatus.UNREACHABLE);
return state.setStatus(MovementStatus.UNREACHABLE);
}
double faceX = (dest.getX() + src.getX() + 1.0D) * 0.5D;
double faceY = (dest.getY() + src.getY() - 1.0D) * 0.5D;
@@ -324,7 +325,7 @@ public class MovementTraverse extends Movement {
// if we're in the process of breaking blocks before walking forwards
// or if this isn't a sneak place (the block is already there)
// then it's safe to cancel this
return state.getStatus() != MovementState.MovementStatus.RUNNING || MovementHelper.canWalkOn(dest.down());
return state.getStatus() != MovementStatus.RUNNING || MovementHelper.canWalkOn(dest.down());
}
@Override

View File

@@ -19,22 +19,24 @@ package baritone.pathing.path;
import baritone.Baritone;
import baritone.api.event.events.TickEvent;
import baritone.api.pathing.calc.IPath;
import baritone.api.pathing.movement.ActionCosts;
import baritone.api.pathing.movement.IMovement;
import baritone.api.pathing.movement.MovementStatus;
import baritone.api.pathing.path.IPathExecutor;
import baritone.api.utils.BetterBlockPos;
import baritone.pathing.calc.AbstractNodeCostSearch;
import baritone.pathing.movement.CalculationContext;
import baritone.pathing.movement.Movement;
import baritone.pathing.movement.MovementHelper;
import baritone.pathing.movement.MovementState;
import baritone.pathing.movement.movements.*;
import baritone.utils.*;
import baritone.utils.pathing.BetterBlockPos;
import net.minecraft.init.Blocks;
import net.minecraft.util.Tuple;
import net.minecraft.util.math.BlockPos;
import java.util.*;
import static baritone.pathing.movement.MovementState.MovementStatus.*;
import static baritone.api.pathing.movement.MovementStatus.*;
/**
* Behavior to execute a precomputed path. Does not (yet) deal with path segmentation or stitching
@@ -42,7 +44,7 @@ import static baritone.pathing.movement.MovementState.MovementStatus.*;
*
* @author leijurv
*/
public class PathExecutor implements Helper {
public class PathExecutor implements IPathExecutor, Helper {
private static final double MAX_MAX_DIST_FROM_PATH = 3;
private static final double MAX_DIST_FROM_PATH = 2;
@@ -128,7 +130,7 @@ public class PathExecutor implements Helper {
}
}
}
Tuple<Double, BlockPos> status = path.closestPathPos();
Tuple<Double, BlockPos> status = closestPathPos(path);
if (possiblyOffPath(status, MAX_DIST_FROM_PATH)) {
ticksAway++;
System.out.println("FAR AWAY FROM PATH FOR " + ticksAway + " TICKS. Current distance: " + status.getFirst() + ". Threshold: " + MAX_DIST_FROM_PATH);
@@ -182,13 +184,11 @@ public class PathExecutor implements Helper {
if (i < 0 || i >= path.movements().size()) {
continue;
}
Movement m = path.movements().get(i);
IMovement m = path.movements().get(i);
HashSet<BlockPos> prevBreak = new HashSet<>(m.toBreak());
HashSet<BlockPos> prevPlace = new HashSet<>(m.toPlace());
HashSet<BlockPos> prevWalkInto = new HashSet<>(m.toWalkInto());
m.toBreakCached = null;
m.toPlaceCached = null;
m.toWalkIntoCached = null;
m.resetBlockCache();
if (!prevBreak.equals(new HashSet<>(m.toBreak()))) {
recalcBP = true;
}
@@ -217,12 +217,12 @@ public class PathExecutor implements Helper {
if (end - start > 0) {
System.out.println("Recalculating break and place took " + (end - start) + "ms");
}*/
Movement movement = path.movements().get(pathPosition);
IMovement movement = path.movements().get(pathPosition);
boolean canCancel = movement.safeToCancel();
if (costEstimateIndex == null || costEstimateIndex != pathPosition) {
costEstimateIndex = pathPosition;
// do this only once, when the movement starts, and deliberately get the cost as cached when this path was calculated, not the cost as it is right now
currentMovementOriginalCostEstimate = movement.getCost(null);
currentMovementOriginalCostEstimate = movement.getCost();
for (int i = 1; i < Baritone.settings().costVerificationLookahead.get() && pathPosition + i < path.length() - 1; i++) {
if (path.movements().get(pathPosition + i).calculateCostWithoutCaching() >= ActionCosts.COST_INF && canCancel) {
logDebug("Something has changed in the world and a future movement has become impossible. Cancelling.");
@@ -244,9 +244,10 @@ public class PathExecutor implements Helper {
}
if (shouldPause()) {
logDebug("Pausing since current best path is a backtrack");
clearKeys();
return true;
}
MovementState.MovementStatus movementStatus = movement.update();
MovementStatus movementStatus = movement.update();
if (movementStatus == UNREACHABLE || movementStatus == FAILED) {
logDebug("Movement returns status " + movementStatus);
cancel();
@@ -274,6 +275,19 @@ public class PathExecutor implements Helper {
return false; // movement is in progress
}
private Tuple<Double, BlockPos> closestPathPos(IPath path) {
double best = -1;
BlockPos bestPos = null;
for (BlockPos pos : path.positions()) {
double dist = Utils.playerDistanceToCenter(pos);
if (dist < best || best == -1) {
best = dist;
bestPos = pos;
}
}
return new Tuple<>(best, bestPos);
}
private boolean shouldPause() {
Optional<AbstractNodeCostSearch> current = AbstractNodeCostSearch.getCurrentlyRunning();
if (!current.isPresent()) {
@@ -325,11 +339,24 @@ public class PathExecutor implements Helper {
}
}
/**
* Regardless of current path position, snap to the current player feet if possible
*/
public boolean snipsnapifpossible() {
int index = path.positions().indexOf(playerFeet());
if (index == -1) {
return false;
}
pathPosition = index;
clearKeys();
return true;
}
private void sprintIfRequested() {
// first and foremost, if allowSprint is off, or if we don't have enough hunger, don't try and sprint
if (!new CalculationContext().canSprint()) {
Baritone.INSTANCE.getInputOverrideHandler().setInputForceState(InputOverrideHandler.Input.SPRINT,false);
Baritone.INSTANCE.getInputOverrideHandler().setInputForceState(InputOverrideHandler.Input.SPRINT, false);
player().setSprinting(false);
return;
}
@@ -343,10 +370,10 @@ public class PathExecutor implements Helper {
}
// we'll take it from here, no need for minecraft to see we're holding down control and sprint for us
Baritone.INSTANCE.getInputOverrideHandler().setInputForceState(InputOverrideHandler.Input.SPRINT,false);
Baritone.INSTANCE.getInputOverrideHandler().setInputForceState(InputOverrideHandler.Input.SPRINT, false);
// however, descend doesn't request sprinting, beceause it doesn't know the context of what movement comes after it
Movement current = path.movements().get(pathPosition);
IMovement current = path.movements().get(pathPosition);
if (current instanceof MovementDescend && pathPosition < path.length() - 2) {
// (dest - src) + dest is offset 1 more in the same direction
@@ -361,7 +388,7 @@ public class PathExecutor implements Helper {
}
}
Movement next = path.movements().get(pathPosition + 1);
IMovement next = path.movements().get(pathPosition + 1);
if (next instanceof MovementAscend && current.getDirection().up().equals(next.getDirection().down())) {
// a descend then an ascend in the same direction
if (!player().isSprinting()) {
@@ -385,7 +412,7 @@ public class PathExecutor implements Helper {
//logDebug("Turning off sprinting " + movement + " " + next + " " + movement.getDirection() + " " + next.getDirection().down() + " " + next.getDirection().down().equals(movement.getDirection()));
}
if (current instanceof MovementAscend && pathPosition != 0) {
Movement prev = path.movements().get(pathPosition - 1);
IMovement prev = path.movements().get(pathPosition - 1);
if (prev instanceof MovementDescend && prev.getDirection().up().equals(current.getDirection().down())) {
BlockPos center = current.getSrc().up();
if (player().posY >= center.getY()) { // playerFeet adds 0.1251 to account for soul sand
@@ -400,7 +427,7 @@ public class PathExecutor implements Helper {
player().setSprinting(false);
}
private static boolean canSprintInto(Movement current, Movement next) {
private static boolean canSprintInto(IMovement current, IMovement next) {
if (next instanceof MovementDescend) {
if (next.getDirection().equals(current.getDirection())) {
return true;
@@ -438,6 +465,7 @@ public class PathExecutor implements Helper {
return pathPosition;
}
@Override
public IPath getPath() {
return path;
}

View File

@@ -35,8 +35,6 @@ public class BaritoneAutoTest implements AbstractGameEventListener, Helper {
public static final BaritoneAutoTest INSTANCE = new BaritoneAutoTest();
private BaritoneAutoTest() {}
public static final boolean ENABLE_AUTO_TEST = "true".equals(System.getenv("BARITONE_AUTO_TEST"));
private static final long TEST_SEED = -928872506371745L;
private static final BlockPos STARTING_POSITION = new BlockPos(0, 65, 0);
@@ -123,4 +121,6 @@ public class BaritoneAutoTest implements AbstractGameEventListener, Helper {
}
}
}
private BaritoneAutoTest() {}
}

View File

@@ -32,7 +32,6 @@ import baritone.cache.ChunkPacker;
import baritone.cache.Waypoint;
import baritone.cache.WorldProvider;
import baritone.pathing.calc.AbstractNodeCostSearch;
import baritone.pathing.movement.CalculationContext;
import baritone.pathing.movement.Movement;
import baritone.pathing.movement.MovementHelper;
import baritone.pathing.movement.Moves;
@@ -470,10 +469,10 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
while (moves.contains(null)) {
moves.remove(null);
}
moves.sort(Comparator.comparingDouble(movement -> movement.getCost(new CalculationContext())));
moves.sort(Comparator.comparingDouble(Movement::getCost));
for (Movement move : moves) {
String[] parts = move.getClass().toString().split("\\.");
double cost = move.getCost(new CalculationContext());
double cost = move.getCost();
String strCost = cost + "";
if (cost >= ActionCosts.COST_INF) {
strCost = "IMPOSSIBLE";

View File

@@ -18,8 +18,8 @@
package baritone.utils;
import baritone.Baritone;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.Rotation;
import baritone.utils.pathing.BetterBlockPos;
import net.minecraft.block.BlockSlab;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityPlayerSP;

View File

@@ -19,16 +19,16 @@ package baritone.utils;
import baritone.Baritone;
import baritone.api.event.events.RenderEvent;
import baritone.api.pathing.calc.IPath;
import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.goals.GoalComposite;
import baritone.api.pathing.goals.GoalTwoBlocks;
import baritone.api.pathing.goals.GoalXZ;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.interfaces.IGoalRenderPos;
import baritone.behavior.PathingBehavior;
import baritone.pathing.calc.AbstractNodeCostSearch;
import baritone.pathing.path.IPath;
import baritone.pathing.path.PathExecutor;
import baritone.utils.pathing.BetterBlockPos;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityPlayerSP;
@@ -67,12 +67,13 @@ public final class PathRenderer implements Helper {
Goal goal = behavior.getGoal();
EntityPlayerSP player = mc.player;
if (goal != null && Baritone.settings().renderGoal.value) {
PathRenderer.drawLitDankGoalBox(player, goal, partialTicks, Baritone.settings().colorGoalBox.get());
drawLitDankGoalBox(player, goal, partialTicks, Baritone.settings().colorGoalBox.get());
}
if (!Baritone.settings().renderPath.get()) {
return;
}
//drawManySelectionBoxes(player, Collections.singletonList(behavior.pathStart()), partialTicks, Color.WHITE);
//long start = System.nanoTime();
@@ -84,28 +85,28 @@ public final class PathRenderer implements Helper {
// Render the current path, if there is one
if (current != null && current.getPath() != null) {
int renderBegin = Math.max(current.getPosition() - 3, 0);
PathRenderer.drawPath(current.getPath(), renderBegin, player, partialTicks, Baritone.settings().colorCurrentPath.get(), Baritone.settings().fadePath.get(), 10, 20);
drawPath(current.getPath(), renderBegin, player, partialTicks, Baritone.settings().colorCurrentPath.get(), Baritone.settings().fadePath.get(), 10, 20);
}
if (next != null && next.getPath() != null) {
PathRenderer.drawPath(next.getPath(), 0, player, partialTicks, Baritone.settings().colorNextPath.get(), Baritone.settings().fadePath.get(), 10, 20);
drawPath(next.getPath(), 0, player, partialTicks, Baritone.settings().colorNextPath.get(), Baritone.settings().fadePath.get(), 10, 20);
}
//long split = System.nanoTime();
if (current != null) {
PathRenderer.drawManySelectionBoxes(player, current.toBreak(), partialTicks, Baritone.settings().colorBlocksToBreak.get());
PathRenderer.drawManySelectionBoxes(player, current.toPlace(), partialTicks, Baritone.settings().colorBlocksToPlace.get());
PathRenderer.drawManySelectionBoxes(player, current.toWalkInto(), partialTicks, Baritone.settings().colorBlocksToWalkInto.get());
drawManySelectionBoxes(player, current.toBreak(), partialTicks, Baritone.settings().colorBlocksToBreak.get());
drawManySelectionBoxes(player, current.toPlace(), partialTicks, Baritone.settings().colorBlocksToPlace.get());
drawManySelectionBoxes(player, current.toWalkInto(), partialTicks, Baritone.settings().colorBlocksToWalkInto.get());
}
// If there is a path calculation currently running, render the path calculation process
AbstractNodeCostSearch.getCurrentlyRunning().ifPresent(currentlyRunning -> {
currentlyRunning.bestPathSoFar().ifPresent(p -> {
PathRenderer.drawPath(p, 0, player, partialTicks, Baritone.settings().colorBestPathSoFar.get(), Baritone.settings().fadePath.get(), 10, 20);
drawPath(p, 0, player, partialTicks, Baritone.settings().colorBestPathSoFar.get(), Baritone.settings().fadePath.get(), 10, 20);
});
currentlyRunning.pathToMostRecentNodeConsidered().ifPresent(mr -> {
PathRenderer.drawPath(mr, 0, player, partialTicks, Baritone.settings().colorMostRecentConsidered.get(), Baritone.settings().fadePath.get(), 10, 20);
PathRenderer.drawManySelectionBoxes(player, Collections.singletonList(mr.getDest()), partialTicks, Baritone.settings().colorMostRecentConsidered.get());
drawPath(mr, 0, player, partialTicks, Baritone.settings().colorMostRecentConsidered.get(), Baritone.settings().fadePath.get(), 10, 20);
drawManySelectionBoxes(player, Collections.singletonList(mr.getDest()), partialTicks, Baritone.settings().colorMostRecentConsidered.get());
});
});
//long end = System.nanoTime();
@@ -122,6 +123,9 @@ public final class PathRenderer implements Helper {
GlStateManager.glLineWidth(Baritone.settings().pathRenderLineWidthPixels.get());
GlStateManager.disableTexture2D();
GlStateManager.depthMask(false);
if (Baritone.settings().renderPathIgnoreDepth.get()) {
GlStateManager.disableDepth();
}
List<BetterBlockPos> positions = path.positions();
int next;
Tessellator tessellator = Tessellator.getInstance();
@@ -162,6 +166,9 @@ public final class PathRenderer implements Helper {
drawLine(player, x1, y1, z1, x2, y2, z2, partialTicks);
tessellator.draw();
}
if (Baritone.settings().renderPathIgnoreDepth.get()) {
GlStateManager.enableDepth();
}
//GlStateManager.color(0.0f, 0.0f, 0.0f, 0.4f);
GlStateManager.depthMask(true);
GlStateManager.enableTexture2D();
@@ -187,6 +194,11 @@ public final class PathRenderer implements Helper {
GlStateManager.glLineWidth(Baritone.settings().pathRenderLineWidthPixels.get());
GlStateManager.disableTexture2D();
GlStateManager.depthMask(false);
if (Baritone.settings().renderSelectionBoxesIgnoreDepth.get()) {
GlStateManager.disableDepth();
}
float expand = 0.002F;
//BlockPos blockpos = movingObjectPositionIn.getBlockPos();
@@ -228,6 +240,10 @@ public final class PathRenderer implements Helper {
TESSELLATOR.draw();
});
if (Baritone.settings().renderSelectionBoxesIgnoreDepth.get()) {
GlStateManager.enableDepth();
}
GlStateManager.depthMask(true);
GlStateManager.enableTexture2D();
GlStateManager.disableBlend();

View File

@@ -17,6 +17,7 @@
package baritone.utils.pathing;
import baritone.api.utils.BetterBlockPos;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import org.junit.Test;