diff --git a/README.md b/README.md index 8ae8090d7..c6a90ff93 100644 --- a/README.md +++ b/README.md @@ -4,14 +4,16 @@

- Minecraft - Minecraft - Minecraft - Minecraft - Minecraft - Minecraft - Minecraft - Minecraft + Minecraft + Minecraft + Minecraft + Minecraft + Minecraft + Minecraft + Minecraft + Minecraft + Minecraft + Minecraft

@@ -64,6 +66,7 @@ Baritone is the pathfinding system used in [Impact](https://impactclient.net/) s | [1.19.2 Forge](https://github.com/cabaletta/baritone/releases/download/v1.9.4/baritone-api-forge-1.9.4.jar) | [1.19.2 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.9.4/baritone-api-fabric-1.9.4.jar) | | [1.19.3 Forge](https://github.com/cabaletta/baritone/releases/download/v1.9.1/baritone-api-forge-1.9.1.jar) | [1.19.3 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.9.1/baritone-api-fabric-1.9.1.jar) | | [1.19.4 Forge](https://github.com/cabaletta/baritone/releases/download/v1.9.3/baritone-api-forge-1.9.3.jar) | [1.19.4 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.9.3/baritone-api-fabric-1.9.3.jar) | +| [1.20.1 Forge](https://github.com/cabaletta/baritone/releases/download/v1.10.1/baritone-api-forge-1.10.1.jar) | [1.20.1 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.10.1/baritone-api-fabric-1.10.1.jar) | **How to immediately get started:** Type `#goto 1000 500` in chat to go to x=1000 z=500. Type `#mine diamond_ore` to mine diamond ore. Type `#stop` to stop. For more, read [the usage page](USAGE.md) and/or watch this [tutorial playlist](https://www.youtube.com/playlist?list=PLnwnJ1qsS7CoQl9Si-RTluuzCo_4Oulpa) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 343fe823a..30506fd08 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -729,6 +729,12 @@ public final class Settings { */ public final Setting freeLook = new Setting<>(true); + /** + * Break and place blocks without having to force the client-sided rotations. Having this setting enabled implies + * {@link #freeLook}. + */ + public final Setting blockFreeLook = new Setting<>(false); + /** * Will cause some minor behavioral differences to ensure that Baritone works on anticheats. *

diff --git a/src/api/java/baritone/api/behavior/ILookBehavior.java b/src/api/java/baritone/api/behavior/ILookBehavior.java index 058a5dd88..218e8b59a 100644 --- a/src/api/java/baritone/api/behavior/ILookBehavior.java +++ b/src/api/java/baritone/api/behavior/ILookBehavior.java @@ -26,14 +26,11 @@ import baritone.api.utils.Rotation; public interface ILookBehavior extends IBehavior { /** - * Updates the current {@link ILookBehavior} target to target - * the specified rotations on the next tick. If force is {@code true}, - * then freeLook will be overriden and angles will be set regardless. - * If any sort of block interaction is required, force should be {@code true}, - * otherwise, it should be {@code false}; + * Updates the current {@link ILookBehavior} target to target the specified rotations on the next tick. If any sort + * of block interaction is required, {@code blockInteract} should be {@code true}. * - * @param rotation The target rotations - * @param force Whether or not to "force" the rotations + * @param rotation The target rotations + * @param blockInteract Whether the target rotations are needed for a block interaction */ - void updateTarget(Rotation rotation, boolean force); + void updateTarget(Rotation rotation, boolean blockInteract); } diff --git a/src/api/java/baritone/api/command/datatypes/ForAxis.java b/src/api/java/baritone/api/command/datatypes/ForAxis.java new file mode 100644 index 000000000..48efb39b7 --- /dev/null +++ b/src/api/java/baritone/api/command/datatypes/ForAxis.java @@ -0,0 +1,43 @@ +/* + * 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 . + */ + +package baritone.api.command.datatypes; + +import baritone.api.command.exception.CommandException; +import baritone.api.command.helpers.TabCompleteHelper; +import net.minecraft.util.EnumFacing; + +import java.util.Locale; +import java.util.stream.Stream; + +public enum ForAxis implements IDatatypeFor { + INSTANCE; + + @Override + public EnumFacing.Axis get(IDatatypeContext ctx) throws CommandException { + return EnumFacing.Axis.valueOf(ctx.getConsumer().getString().toUpperCase(Locale.US)); + } + + @Override + public Stream tabComplete(IDatatypeContext ctx) throws CommandException { + return new TabCompleteHelper() + .append(Stream.of(EnumFacing.Axis.values()) + .map(EnumFacing.Axis::getName).map(String::toLowerCase)) + .filterPrefix(ctx.getConsumer().getString()) + .stream(); + } +} diff --git a/src/api/java/baritone/api/pathing/goals/GoalAxis.java b/src/api/java/baritone/api/pathing/goals/GoalAxis.java index 7c9b26705..ad8fb892e 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalAxis.java +++ b/src/api/java/baritone/api/pathing/goals/GoalAxis.java @@ -42,6 +42,11 @@ public class GoalAxis implements Goal { return flatAxisDistance * BaritoneAPI.getSettings().costHeuristic.value + GoalYLevel.calculate(BaritoneAPI.getSettings().axisHeight.value, y); } + @Override + public boolean equals(Object o) { + return o.getClass() == GoalAxis.class; + } + @Override public String toString() { return "GoalAxis"; diff --git a/src/api/java/baritone/api/pathing/goals/GoalBlock.java b/src/api/java/baritone/api/pathing/goals/GoalBlock.java index bd339549b..d76fdc7af 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalBlock.java +++ b/src/api/java/baritone/api/pathing/goals/GoalBlock.java @@ -66,6 +66,21 @@ public class GoalBlock implements Goal, IGoalRenderPos { return calculate(xDiff, yDiff, zDiff); } + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + GoalBlock goal = (GoalBlock) o; + return x == goal.x + && y == goal.y + && z == goal.z; + } + @Override public String toString() { return String.format( diff --git a/src/api/java/baritone/api/pathing/goals/GoalComposite.java b/src/api/java/baritone/api/pathing/goals/GoalComposite.java index 47522492b..d64f8e33e 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalComposite.java +++ b/src/api/java/baritone/api/pathing/goals/GoalComposite.java @@ -67,6 +67,19 @@ public class GoalComposite implements Goal { return min; } + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + GoalComposite goal = (GoalComposite) o; + return Arrays.equals(goals, goal.goals); + } + @Override public String toString() { return "GoalComposite" + Arrays.toString(goals); diff --git a/src/api/java/baritone/api/pathing/goals/GoalGetToBlock.java b/src/api/java/baritone/api/pathing/goals/GoalGetToBlock.java index 8d6fdcb30..b5caafa48 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalGetToBlock.java +++ b/src/api/java/baritone/api/pathing/goals/GoalGetToBlock.java @@ -60,6 +60,21 @@ public class GoalGetToBlock implements Goal, IGoalRenderPos { return GoalBlock.calculate(xDiff, yDiff < 0 ? yDiff + 1 : yDiff, zDiff); } + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + GoalGetToBlock goal = (GoalGetToBlock) o; + return x == goal.x + && y == goal.y + && z == goal.z; + } + @Override public String toString() { return String.format( diff --git a/src/api/java/baritone/api/pathing/goals/GoalInverted.java b/src/api/java/baritone/api/pathing/goals/GoalInverted.java index 354e2ce39..e559088ef 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalInverted.java +++ b/src/api/java/baritone/api/pathing/goals/GoalInverted.java @@ -17,6 +17,8 @@ package baritone.api.pathing.goals; +import java.util.Objects; + /** * Invert any goal. *

@@ -50,6 +52,19 @@ public class GoalInverted implements Goal { return Double.NEGATIVE_INFINITY; } + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + GoalInverted goal = (GoalInverted) o; + return Objects.equals(origin, goal.origin); + } + @Override public String toString() { return String.format("GoalInverted{%s}", origin.toString()); diff --git a/src/api/java/baritone/api/pathing/goals/GoalNear.java b/src/api/java/baritone/api/pathing/goals/GoalNear.java index 2252446cd..166138ff4 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalNear.java +++ b/src/api/java/baritone/api/pathing/goals/GoalNear.java @@ -86,6 +86,22 @@ public class GoalNear implements Goal, IGoalRenderPos { return new BlockPos(x, y, z); } + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + GoalNear goal = (GoalNear) o; + return x == goal.x + && y == goal.y + && z == goal.z + && rangeSq == goal.rangeSq; + } + @Override public String toString() { return String.format( diff --git a/src/api/java/baritone/api/pathing/goals/GoalRunAway.java b/src/api/java/baritone/api/pathing/goals/GoalRunAway.java index b704ae4a6..166ad5a98 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalRunAway.java +++ b/src/api/java/baritone/api/pathing/goals/GoalRunAway.java @@ -23,6 +23,7 @@ import it.unimi.dsi.fastutil.doubles.DoubleOpenHashSet; import net.minecraft.util.math.BlockPos; import java.util.Arrays; +import java.util.Objects; /** * Useful for automated combat (retreating specifically) @@ -124,6 +125,21 @@ public class GoalRunAway implements Goal { return maxInside; } + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + GoalRunAway goal = (GoalRunAway) o; + return distanceSq == goal.distanceSq + && Arrays.equals(from, goal.from) + && Objects.equals(maintainY, goal.maintainY); + } + @Override public String toString() { if (maintainY != null) { diff --git a/src/api/java/baritone/api/pathing/goals/GoalStrictDirection.java b/src/api/java/baritone/api/pathing/goals/GoalStrictDirection.java index e93f47ac0..b8e4b43b2 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalStrictDirection.java +++ b/src/api/java/baritone/api/pathing/goals/GoalStrictDirection.java @@ -69,6 +69,23 @@ public class GoalStrictDirection implements Goal { return Double.NEGATIVE_INFINITY; } + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + GoalStrictDirection goal = (GoalStrictDirection) o; + return x == goal.x + && y == goal.y + && z == goal.z + && dx == goal.dx + && dz == goal.dz; + } + @Override public String toString() { return String.format( diff --git a/src/api/java/baritone/api/pathing/goals/GoalTwoBlocks.java b/src/api/java/baritone/api/pathing/goals/GoalTwoBlocks.java index 27be981e4..d6fff33a2 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalTwoBlocks.java +++ b/src/api/java/baritone/api/pathing/goals/GoalTwoBlocks.java @@ -72,6 +72,21 @@ public class GoalTwoBlocks implements Goal, IGoalRenderPos { return new BlockPos(x, y, z); } + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + GoalTwoBlocks goal = (GoalTwoBlocks) o; + return x == goal.x + && y == goal.y + && z == goal.z; + } + @Override public String toString() { return String.format( diff --git a/src/api/java/baritone/api/pathing/goals/GoalXZ.java b/src/api/java/baritone/api/pathing/goals/GoalXZ.java index 63d39cd78..2c551d395 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalXZ.java +++ b/src/api/java/baritone/api/pathing/goals/GoalXZ.java @@ -64,6 +64,19 @@ public class GoalXZ implements Goal { return calculate(xDiff, zDiff); } + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + GoalXZ goal = (GoalXZ) o; + return x == goal.x && z == goal.z; + } + @Override public String toString() { return String.format( diff --git a/src/api/java/baritone/api/pathing/goals/GoalYLevel.java b/src/api/java/baritone/api/pathing/goals/GoalYLevel.java index 603ef9bd1..37745e8de 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalYLevel.java +++ b/src/api/java/baritone/api/pathing/goals/GoalYLevel.java @@ -58,6 +58,19 @@ public class GoalYLevel implements Goal, ActionCosts { return 0; } + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + GoalYLevel goal = (GoalYLevel) o; + return level == goal.level; + } + @Override public String toString() { return String.format( diff --git a/src/api/java/baritone/api/schematic/MaskSchematic.java b/src/api/java/baritone/api/schematic/MaskSchematic.java index 229f58d5b..2853c6e58 100644 --- a/src/api/java/baritone/api/schematic/MaskSchematic.java +++ b/src/api/java/baritone/api/schematic/MaskSchematic.java @@ -17,6 +17,7 @@ package baritone.api.schematic; +import baritone.api.schematic.mask.Mask; import net.minecraft.block.state.IBlockState; import java.util.List; @@ -41,4 +42,14 @@ public abstract class MaskSchematic extends AbstractSchematic { public IBlockState desiredState(int x, int y, int z, IBlockState current, List approxPlaceable) { return schematic.desiredState(x, y, z, current, approxPlaceable); } + + public static MaskSchematic create(ISchematic schematic, Mask function) { + return new MaskSchematic(schematic) { + + @Override + protected boolean partOfMask(int x, int y, int z, IBlockState currentState) { + return function.partOfMask(x, y, z, currentState); + } + }; + } } diff --git a/src/api/java/baritone/api/schematic/mask/AbstractMask.java b/src/api/java/baritone/api/schematic/mask/AbstractMask.java new file mode 100644 index 000000000..ce92af0ec --- /dev/null +++ b/src/api/java/baritone/api/schematic/mask/AbstractMask.java @@ -0,0 +1,49 @@ +/* + * 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 . + */ + +package baritone.api.schematic.mask; + +/** + * @author Brady + */ +public abstract class AbstractMask implements Mask { + + private final int widthX; + private final int heightY; + private final int lengthZ; + + public AbstractMask(int widthX, int heightY, int lengthZ) { + this.widthX = widthX; + this.heightY = heightY; + this.lengthZ = lengthZ; + } + + @Override + public int widthX() { + return this.widthX; + } + + @Override + public int heightY() { + return this.heightY; + } + + @Override + public int lengthZ() { + return this.lengthZ; + } +} diff --git a/src/api/java/baritone/api/schematic/mask/Mask.java b/src/api/java/baritone/api/schematic/mask/Mask.java new file mode 100644 index 000000000..7df6f8f04 --- /dev/null +++ b/src/api/java/baritone/api/schematic/mask/Mask.java @@ -0,0 +1,60 @@ +/* + * 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 . + */ + +package baritone.api.schematic.mask; + +import baritone.api.schematic.mask.operator.BinaryOperatorMask; +import baritone.api.schematic.mask.operator.NotMask; +import baritone.api.utils.BooleanBinaryOperators; +import net.minecraft.block.state.IBlockState; + +/** + * @author Brady + */ +public interface Mask { + + /** + * @param x The relative x position of the block + * @param y The relative y position of the block + * @param z The relative z position of the block + * @param currentState The current state of that block in the world, may be {@code null} + * @return Whether the given position is included in this mask + */ + boolean partOfMask(int x, int y, int z, IBlockState currentState); + + int widthX(); + + int heightY(); + + int lengthZ(); + + default Mask not() { + return new NotMask(this); + } + + default Mask union(Mask other) { + return new BinaryOperatorMask(this, other, BooleanBinaryOperators.OR); + } + + default Mask intersection(Mask other) { + return new BinaryOperatorMask(this, other, BooleanBinaryOperators.AND); + } + + default Mask xor(Mask other) { + return new BinaryOperatorMask(this, other, BooleanBinaryOperators.XOR); + } +} diff --git a/src/api/java/baritone/api/schematic/mask/PreComputedMask.java b/src/api/java/baritone/api/schematic/mask/PreComputedMask.java new file mode 100644 index 000000000..aed26cc94 --- /dev/null +++ b/src/api/java/baritone/api/schematic/mask/PreComputedMask.java @@ -0,0 +1,44 @@ +/* + * 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 . + */ + +package baritone.api.schematic.mask; + +/** + * @author Brady + */ +final class PreComputedMask extends AbstractMask implements StaticMask { + + private final boolean[][][] mask; + + public PreComputedMask(StaticMask mask) { + super(mask.widthX(), mask.heightY(), mask.lengthZ()); + + this.mask = new boolean[this.heightY()][this.lengthZ()][this.widthX()]; + for (int y = 0; y < this.heightY(); y++) { + for (int z = 0; z < this.lengthZ(); z++) { + for (int x = 0; x < this.widthX(); x++) { + this.mask[y][z][x] = mask.partOfMask(x, y, z); + } + } + } + } + + @Override + public boolean partOfMask(int x, int y, int z) { + return this.mask[y][z][x]; + } +} diff --git a/src/api/java/baritone/api/schematic/mask/StaticMask.java b/src/api/java/baritone/api/schematic/mask/StaticMask.java new file mode 100644 index 000000000..220a94828 --- /dev/null +++ b/src/api/java/baritone/api/schematic/mask/StaticMask.java @@ -0,0 +1,82 @@ +/* + * 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 . + */ + +package baritone.api.schematic.mask; + +import baritone.api.schematic.mask.operator.BinaryOperatorMask; +import baritone.api.schematic.mask.operator.NotMask; +import baritone.api.utils.BooleanBinaryOperators; +import net.minecraft.block.state.IBlockState; + +/** + * A mask that is context-free. In other words, it doesn't require the current block state to determine if a relative + * position is a part of the mask. + * + * @author Brady + */ +public interface StaticMask extends Mask { + + /** + * Determines if a given relative coordinate is included in this mask, without the need for the current block state. + * + * @param x The relative x position of the block + * @param y The relative y position of the block + * @param z The relative z position of the block + * @return Whether the given position is included in this mask + */ + boolean partOfMask(int x, int y, int z); + + /** + * Implements the parent {@link Mask#partOfMask partOfMask function} by calling the static function + * provided in this functional interface without needing the {@link IBlockState} argument. This {@code default} + * implementation should NOT be overriden. + * + * @param x The relative x position of the block + * @param y The relative y position of the block + * @param z The relative z position of the block + * @param currentState The current state of that block in the world, may be {@code null} + * @return Whether the given position is included in this mask + */ + @Override + default boolean partOfMask(int x, int y, int z, IBlockState currentState) { + return this.partOfMask(x, y, z); + } + + @Override + default StaticMask not() { + return new NotMask.Static(this); + } + + default StaticMask union(StaticMask other) { + return new BinaryOperatorMask.Static(this, other, BooleanBinaryOperators.OR); + } + + default StaticMask intersection(StaticMask other) { + return new BinaryOperatorMask.Static(this, other, BooleanBinaryOperators.AND); + } + + default StaticMask xor(StaticMask other) { + return new BinaryOperatorMask.Static(this, other, BooleanBinaryOperators.XOR); + } + + /** + * Returns a pre-computed mask using {@code this} function, with the specified size parameters. + */ + default StaticMask compute() { + return new PreComputedMask(this); + } +} diff --git a/src/api/java/baritone/api/schematic/mask/operator/BinaryOperatorMask.java b/src/api/java/baritone/api/schematic/mask/operator/BinaryOperatorMask.java new file mode 100644 index 000000000..e591c7873 --- /dev/null +++ b/src/api/java/baritone/api/schematic/mask/operator/BinaryOperatorMask.java @@ -0,0 +1,71 @@ +/* + * 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 . + */ + +package baritone.api.schematic.mask.operator; + +import baritone.api.schematic.mask.AbstractMask; +import baritone.api.schematic.mask.Mask; +import baritone.api.schematic.mask.StaticMask; +import baritone.api.utils.BooleanBinaryOperator; +import net.minecraft.block.state.IBlockState; + +/** + * @author Brady + */ +public final class BinaryOperatorMask extends AbstractMask { + + private final Mask a; + private final Mask b; + private final BooleanBinaryOperator operator; + + public BinaryOperatorMask(Mask a, Mask b, BooleanBinaryOperator operator) { + super(a.widthX(), a.heightY(), a.lengthZ()); + this.a = a; + this.b = b; + this.operator = operator; + } + + @Override + public boolean partOfMask(int x, int y, int z, IBlockState currentState) { + return this.operator.applyAsBoolean( + this.a.partOfMask(x, y, z, currentState), + this.b.partOfMask(x, y, z, currentState) + ); + } + + public static final class Static extends AbstractMask implements StaticMask { + + private final StaticMask a; + private final StaticMask b; + private final BooleanBinaryOperator operator; + + public Static(StaticMask a, StaticMask b, BooleanBinaryOperator operator) { + super(a.widthX(), a.heightY(), a.lengthZ()); + this.a = a; + this.b = b; + this.operator = operator; + } + + @Override + public boolean partOfMask(int x, int y, int z) { + return this.operator.applyAsBoolean( + this.a.partOfMask(x, y, z), + this.b.partOfMask(x, y, z) + ); + } + } +} diff --git a/src/api/java/baritone/api/schematic/mask/operator/NotMask.java b/src/api/java/baritone/api/schematic/mask/operator/NotMask.java new file mode 100644 index 000000000..f9f770b82 --- /dev/null +++ b/src/api/java/baritone/api/schematic/mask/operator/NotMask.java @@ -0,0 +1,56 @@ +/* + * 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 . + */ + +package baritone.api.schematic.mask.operator; + +import baritone.api.schematic.mask.AbstractMask; +import baritone.api.schematic.mask.Mask; +import baritone.api.schematic.mask.StaticMask; +import net.minecraft.block.state.IBlockState; + +/** + * @author Brady + */ +public final class NotMask extends AbstractMask { + + private final Mask source; + + public NotMask(Mask source) { + super(source.widthX(), source.heightY(), source.lengthZ()); + this.source = source; + } + + @Override + public boolean partOfMask(int x, int y, int z, IBlockState currentState) { + return !this.source.partOfMask(x, y, z, currentState); + } + + public static final class Static extends AbstractMask implements StaticMask { + + private final StaticMask source; + + public Static(StaticMask source) { + super(source.widthX(), source.heightY(), source.lengthZ()); + this.source = source; + } + + @Override + public boolean partOfMask(int x, int y, int z) { + return !this.source.partOfMask(x, y, z); + } + } +} diff --git a/src/api/java/baritone/api/schematic/mask/shape/CylinderMask.java b/src/api/java/baritone/api/schematic/mask/shape/CylinderMask.java new file mode 100644 index 000000000..71b0d43c9 --- /dev/null +++ b/src/api/java/baritone/api/schematic/mask/shape/CylinderMask.java @@ -0,0 +1,69 @@ +/* + * 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 . + */ + +package baritone.api.schematic.mask.shape; + +import baritone.api.schematic.mask.AbstractMask; +import baritone.api.schematic.mask.StaticMask; +import net.minecraft.util.EnumFacing; + +/** + * @author Brady + */ +public final class CylinderMask extends AbstractMask implements StaticMask { + + private final double centerA; + private final double centerB; + private final double radiusSqA; + private final double radiusSqB; + private final boolean filled; + private final EnumFacing.Axis alignment; + + public CylinderMask(int widthX, int heightY, int lengthZ, boolean filled, EnumFacing.Axis alignment) { + super(widthX, heightY, lengthZ); + this.centerA = this.getA(widthX, heightY) / 2.0; + this.centerB = this.getB(heightY, lengthZ) / 2.0; + this.radiusSqA = (this.centerA - 1) * (this.centerA - 1); + this.radiusSqB = (this.centerB - 1) * (this.centerB - 1); + this.filled = filled; + this.alignment = alignment; + } + + @Override + public boolean partOfMask(int x, int y, int z) { + double da = Math.abs((this.getA(x, y) + 0.5) - this.centerA); + double db = Math.abs((this.getB(y, z) + 0.5) - this.centerB); + if (this.outside(da, db)) { + return false; + } + return this.filled + || this.outside(da + 1, db) + || this.outside(da, db + 1); + } + + private boolean outside(double da, double db) { + return da * da / this.radiusSqA + db * db / this.radiusSqB > 1; + } + + private int getA(int x, int y) { + return this.alignment == EnumFacing.Axis.X ? y : x; + } + + private int getB(int y, int z) { + return this.alignment == EnumFacing.Axis.Z ? y : z; + } +} diff --git a/src/api/java/baritone/api/schematic/mask/shape/SphereMask.java b/src/api/java/baritone/api/schematic/mask/shape/SphereMask.java new file mode 100644 index 000000000..d805c98a8 --- /dev/null +++ b/src/api/java/baritone/api/schematic/mask/shape/SphereMask.java @@ -0,0 +1,64 @@ +/* + * 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 . + */ + +package baritone.api.schematic.mask.shape; + +import baritone.api.schematic.mask.AbstractMask; +import baritone.api.schematic.mask.StaticMask; + +/** + * @author Brady + */ +public final class SphereMask extends AbstractMask implements StaticMask { + + private final double centerX; + private final double centerY; + private final double centerZ; + private final double radiusSqX; + private final double radiusSqY; + private final double radiusSqZ; + private final boolean filled; + + public SphereMask(int widthX, int heightY, int lengthZ, boolean filled) { + super(widthX, heightY, lengthZ); + this.centerX = widthX / 2.0; + this.centerY = heightY / 2.0; + this.centerZ = lengthZ / 2.0; + this.radiusSqX = this.centerX * this.centerX; + this.radiusSqY = this.centerY * this.centerY; + this.radiusSqZ = this.centerZ * this.centerZ; + this.filled = filled; + } + + @Override + public boolean partOfMask(int x, int y, int z) { + double dx = Math.abs((x + 0.5) - this.centerX); + double dy = Math.abs((y + 0.5) - this.centerY); + double dz = Math.abs((z + 0.5) - this.centerZ); + if (this.outside(dx, dy, dz)) { + return false; + } + return this.filled + || this.outside(dx + 1, dy, dz) + || this.outside(dx, dy + 1, dz) + || this.outside(dx, dy, dz + 1); + } + + private boolean outside(double dx, double dy, double dz) { + return dx * dx / this.radiusSqX + dy * dy / this.radiusSqY + dz * dz / this.radiusSqZ > 1; + } +} diff --git a/src/api/java/baritone/api/utils/BooleanBinaryOperator.java b/src/api/java/baritone/api/utils/BooleanBinaryOperator.java new file mode 100644 index 000000000..cfb85e644 --- /dev/null +++ b/src/api/java/baritone/api/utils/BooleanBinaryOperator.java @@ -0,0 +1,27 @@ +/* + * 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 . + */ + +package baritone.api.utils; + +/** + * @author Brady + */ +@FunctionalInterface +public interface BooleanBinaryOperator { + + boolean applyAsBoolean(boolean a, boolean b); +} diff --git a/src/api/java/baritone/api/utils/BooleanBinaryOperators.java b/src/api/java/baritone/api/utils/BooleanBinaryOperators.java new file mode 100644 index 000000000..11605c965 --- /dev/null +++ b/src/api/java/baritone/api/utils/BooleanBinaryOperators.java @@ -0,0 +1,38 @@ +/* + * 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 . + */ + +package baritone.api.utils; + +/** + * @author Brady + */ +public enum BooleanBinaryOperators implements BooleanBinaryOperator { + OR((a, b) -> a || b), + AND((a, b) -> a && b), + XOR((a, b) -> a ^ b); + + private final BooleanBinaryOperator op; + + BooleanBinaryOperators(BooleanBinaryOperator op) { + this.op = op; + } + + @Override + public boolean applyAsBoolean(boolean a, boolean b) { + return this.op.applyAsBoolean(a, b); + } +} diff --git a/src/api/java/baritone/api/utils/Rotation.java b/src/api/java/baritone/api/utils/Rotation.java index 54f63ebfa..8dab287de 100644 --- a/src/api/java/baritone/api/utils/Rotation.java +++ b/src/api/java/baritone/api/utils/Rotation.java @@ -26,12 +26,12 @@ public class Rotation { /** * The yaw angle of this Rotation */ - private float yaw; + private final float yaw; /** * The pitch angle of this Rotation */ - private float pitch; + private final float pitch; public Rotation(float yaw, float pitch) { this.yaw = yaw; @@ -110,6 +110,10 @@ public class Rotation { ); } + public Rotation withPitch(float pitch) { + return new Rotation(this.yaw, pitch); + } + /** * Is really close to * diff --git a/src/api/java/baritone/api/utils/RotationUtils.java b/src/api/java/baritone/api/utils/RotationUtils.java index 39e68fd4f..1991ab878 100644 --- a/src/api/java/baritone/api/utils/RotationUtils.java +++ b/src/api/java/baritone/api/utils/RotationUtils.java @@ -134,14 +134,14 @@ public final class RotationUtils { * @param ctx Context for the viewing entity * @param pos The target block position * @return The optional rotation - * @see #reachable(EntityPlayerSP, BlockPos, double) + * @see #reachable(IPlayerContext, BlockPos, double) */ public static Optional reachable(IPlayerContext ctx, BlockPos pos) { - return reachable(ctx.player(), pos, ctx.playerController().getBlockReachDistance()); + return reachable(ctx, pos, false); } public static Optional reachable(IPlayerContext ctx, BlockPos pos, boolean wouldSneak) { - return reachable(ctx.player(), pos, ctx.playerController().getBlockReachDistance(), wouldSneak); + return reachable(ctx, pos, ctx.playerController().getBlockReachDistance(), wouldSneak); } /** @@ -151,18 +151,17 @@ public final class RotationUtils { * side that is reachable. The return type will be {@link Optional#empty()} if the entity is * unable to reach any of the sides of the block. * - * @param entity The viewing entity + * @param ctx Context for the viewing entity * @param pos The target block position * @param blockReachDistance The block reach distance of the entity * @return The optional rotation */ - public static Optional reachable(EntityPlayerSP entity, BlockPos pos, double blockReachDistance) { - return reachable(entity, pos, blockReachDistance, false); + public static Optional reachable(IPlayerContext ctx, BlockPos pos, double blockReachDistance) { + return reachable(ctx, pos, blockReachDistance, false); } - public static Optional reachable(EntityPlayerSP entity, BlockPos pos, double blockReachDistance, boolean wouldSneak) { - IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer(entity); - if (baritone.getPlayerContext().isLookingAt(pos)) { + public static Optional reachable(IPlayerContext ctx, BlockPos pos, double blockReachDistance, boolean wouldSneak) { + if (ctx.isLookingAt(pos)) { /* * why add 0.0001? * to indicate that we actually have a desired pitch @@ -173,10 +172,10 @@ public final class RotationUtils { * * or if you're a normal person literally all this does it ensure that we don't nudge the pitch to a normal level */ - Rotation hypothetical = new Rotation(entity.rotationYaw, entity.rotationPitch + 0.0001F); + Rotation hypothetical = ctx.playerRotations().add(new Rotation(0, 0.0001F)); if (wouldSneak) { // the concern here is: what if we're looking at it now, but as soon as we start sneaking we no longer are - RayTraceResult result = RayTraceUtils.rayTraceTowards(entity, hypothetical, blockReachDistance, true); + RayTraceResult result = RayTraceUtils.rayTraceTowards(ctx.player(), hypothetical, blockReachDistance, true); if (result != null && result.typeOfHit == RayTraceResult.Type.BLOCK && result.getBlockPos().equals(pos)) { return Optional.of(hypothetical); // yes, if we sneaked we would still be looking at the block } @@ -184,19 +183,19 @@ public final class RotationUtils { return Optional.of(hypothetical); } } - Optional possibleRotation = reachableCenter(entity, pos, blockReachDistance, wouldSneak); + Optional possibleRotation = reachableCenter(ctx, pos, blockReachDistance, wouldSneak); //System.out.println("center: " + possibleRotation); if (possibleRotation.isPresent()) { return possibleRotation; } - IBlockState state = entity.world.getBlockState(pos); - AxisAlignedBB aabb = state.getBoundingBox(entity.world, pos); + IBlockState state = ctx.world().getBlockState(pos); + AxisAlignedBB aabb = state.getBoundingBox(ctx.world(), pos); for (Vec3d sideOffset : BLOCK_SIDE_MULTIPLIERS) { double xDiff = aabb.minX * sideOffset.x + aabb.maxX * (1 - sideOffset.x); double yDiff = aabb.minY * sideOffset.y + aabb.maxY * (1 - sideOffset.y); double zDiff = aabb.minZ * sideOffset.z + aabb.maxZ * (1 - sideOffset.z); - possibleRotation = reachableOffset(entity, pos, new Vec3d(pos).add(xDiff, yDiff, zDiff), blockReachDistance, wouldSneak); + possibleRotation = reachableOffset(ctx, pos, new Vec3d(pos).add(xDiff, yDiff, zDiff), blockReachDistance, wouldSneak); if (possibleRotation.isPresent()) { return possibleRotation; } @@ -209,12 +208,54 @@ public final class RotationUtils { * the given offsetted position. The return type will be {@link Optional#empty()} if * the entity is unable to reach the block with the offset applied. * - * @param entity The viewing entity + * @param ctx Context for the viewing entity * @param pos The target block position * @param offsetPos The position of the block with the offset applied. * @param blockReachDistance The block reach distance of the entity * @return The optional rotation */ + public static Optional reachableOffset(IPlayerContext ctx, BlockPos pos, Vec3d offsetPos, double blockReachDistance, boolean wouldSneak) { + Vec3d eyes = wouldSneak ? RayTraceUtils.inferSneakingEyePosition(ctx.player()) : ctx.player().getPositionEyes(1.0F); + Rotation rotation = calcRotationFromVec3d(eyes, offsetPos, ctx.playerRotations()); + RayTraceResult result = RayTraceUtils.rayTraceTowards(ctx.player(), rotation, blockReachDistance, wouldSneak); + //System.out.println(result); + if (result != null && result.typeOfHit == RayTraceResult.Type.BLOCK) { + if (result.getBlockPos().equals(pos)) { + return Optional.of(rotation); + } + if (ctx.world().getBlockState(pos).getBlock() instanceof BlockFire && result.getBlockPos().equals(pos.down())) { + return Optional.of(rotation); + } + } + return Optional.empty(); + } + + /** + * Determines if the specified entity is able to reach the specified block where it is + * looking at the direct center of it's hitbox. + * + * @param ctx Context for the viewing entity + * @param pos The target block position + * @param blockReachDistance The block reach distance of the entity + * @return The optional rotation + */ + public static Optional reachableCenter(IPlayerContext ctx, BlockPos pos, double blockReachDistance, boolean wouldSneak) { + return reachableOffset(ctx, pos, VecUtils.calculateBlockCenter(ctx.world(), pos), blockReachDistance, wouldSneak); + } + + @Deprecated + public static Optional reachable(EntityPlayerSP entity, BlockPos pos, double blockReachDistance) { + return reachable(entity, pos, blockReachDistance, false); + } + + @Deprecated + public static Optional reachable(EntityPlayerSP entity, BlockPos pos, double blockReachDistance, boolean wouldSneak) { + IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer(entity); + IPlayerContext ctx = baritone.getPlayerContext(); + return reachable(ctx, pos, blockReachDistance, wouldSneak); + } + + @Deprecated public static Optional reachableOffset(Entity entity, BlockPos pos, Vec3d offsetPos, double blockReachDistance, boolean wouldSneak) { Vec3d eyes = wouldSneak ? RayTraceUtils.inferSneakingEyePosition(entity) : entity.getPositionEyes(1.0F); Rotation rotation = calcRotationFromVec3d(eyes, offsetPos, new Rotation(entity.rotationYaw, entity.rotationPitch)); @@ -231,15 +272,7 @@ public final class RotationUtils { return Optional.empty(); } - /** - * Determines if the specified entity is able to reach the specified block where it is - * looking at the direct center of it's hitbox. - * - * @param entity The viewing entity - * @param pos The target block position - * @param blockReachDistance The block reach distance of the entity - * @return The optional rotation - */ + @Deprecated public static Optional reachableCenter(Entity entity, BlockPos pos, double blockReachDistance, boolean wouldSneak) { return reachableOffset(entity, pos, VecUtils.calculateBlockCenter(entity.world, pos), blockReachDistance, wouldSneak); } diff --git a/src/main/java/baritone/behavior/LookBehavior.java b/src/main/java/baritone/behavior/LookBehavior.java index 32e5c22f5..99e496e6f 100644 --- a/src/main/java/baritone/behavior/LookBehavior.java +++ b/src/main/java/baritone/behavior/LookBehavior.java @@ -20,40 +20,43 @@ package baritone.behavior; import baritone.Baritone; import baritone.api.Settings; import baritone.api.behavior.ILookBehavior; +import baritone.api.event.events.PacketEvent; import baritone.api.event.events.PlayerUpdateEvent; import baritone.api.event.events.RotationMoveEvent; +import baritone.api.event.events.WorldEvent; +import baritone.api.utils.Helper; +import baritone.api.utils.IPlayerContext; import baritone.api.utils.Rotation; +import net.minecraft.network.play.client.CPacketPlayer; + +import java.util.Optional; public final class LookBehavior extends Behavior implements ILookBehavior { /** - * Target's values are as follows: - *

- * getFirst() -> yaw - * getSecond() -> pitch + * The current look target, may be {@code null}. */ - private Rotation target; + private Target target; /** - * Whether or not rotations are currently being forced + * The rotation known to the server. Returned by {@link #getEffectiveRotation()} for use in {@link IPlayerContext}. */ - private boolean force; + private Rotation serverRotation; /** - * The last player yaw angle. Used when free looking + * The last player rotation. Used when free looking * * @see Settings#freeLook */ - private float lastYaw; + private Rotation prevRotation; public LookBehavior(Baritone baritone) { super(baritone); } @Override - public void updateTarget(Rotation target, boolean force) { - this.target = target; - this.force = force || !Baritone.settings().freeLook.value; + public void updateTarget(Rotation rotation, boolean blockInteract) { + this.target = new Target(rotation, blockInteract); } @Override @@ -61,35 +64,48 @@ public final class LookBehavior extends Behavior implements ILookBehavior { if (this.target == null) { return; } - - // Whether or not we're going to silently set our angles - boolean silent = Baritone.settings().antiCheatCompatibility.value && !this.force; - switch (event.getState()) { case PRE: { - if (this.force) { - ctx.player().rotationYaw = this.target.getYaw(); - float oldPitch = ctx.player().rotationPitch; - float desiredPitch = this.target.getPitch(); - ctx.player().rotationPitch = desiredPitch; - ctx.player().rotationYaw += (Math.random() - 0.5) * Baritone.settings().randomLooking.value; - ctx.player().rotationPitch += (Math.random() - 0.5) * Baritone.settings().randomLooking.value; - if (desiredPitch == oldPitch && !Baritone.settings().freeLook.value) { - nudgeToLevel(); - } - this.target = null; + if (this.target.mode == Target.Mode.NONE) { + return; } - if (silent) { - this.lastYaw = ctx.player().rotationYaw; - ctx.player().rotationYaw = this.target.getYaw(); + if (this.target.mode == Target.Mode.SERVER) { + this.prevRotation = new Rotation(ctx.player().rotationYaw, ctx.player().rotationPitch); + } + + final float oldYaw = ctx.playerRotations().getYaw(); + final float oldPitch = ctx.playerRotations().getPitch(); + + float desiredYaw = this.target.rotation.getYaw(); + float desiredPitch = this.target.rotation.getPitch(); + + // In other words, the target doesn't care about the pitch, so it used playerRotations().getPitch() + // and it's safe to adjust it to a normal level + if (desiredPitch == oldPitch) { + desiredPitch = nudgeToLevel(desiredPitch); + } + + desiredYaw += (Math.random() - 0.5) * Baritone.settings().randomLooking.value; + desiredPitch += (Math.random() - 0.5) * Baritone.settings().randomLooking.value; + + ctx.player().rotationYaw = calculateMouseMove(oldYaw, desiredYaw); + ctx.player().rotationPitch = calculateMouseMove(oldPitch, desiredPitch); + + if (this.target.mode == Target.Mode.CLIENT) { + // The target can be invalidated now since it won't be needed for RotationMoveEvent + this.target = null; } break; } case POST: { - if (silent) { - ctx.player().rotationYaw = this.lastYaw; - this.target = null; + // Reset the player's rotations back to their original values + if (this.prevRotation != null) { + ctx.player().rotationYaw = this.prevRotation.getYaw(); + ctx.player().rotationPitch = this.prevRotation.getPitch(); + this.prevRotation = null; } + // The target is done being used for this game tick, so it can be invalidated + this.target = null; break; } default: @@ -97,34 +113,116 @@ public final class LookBehavior extends Behavior implements ILookBehavior { } } + @Override + public void onSendPacket(PacketEvent event) { + if (!(event.getPacket() instanceof CPacketPlayer)) { + return; + } + + final CPacketPlayer packet = (CPacketPlayer) event.getPacket(); + if (packet instanceof CPacketPlayer.Rotation || packet instanceof CPacketPlayer.PositionRotation) { + this.serverRotation = new Rotation(packet.getYaw(0.0f), packet.getPitch(0.0f)); + } + } + + @Override + public void onWorldEvent(WorldEvent event) { + this.serverRotation = null; + this.target = null; + } + public void pig() { if (this.target != null) { - ctx.player().rotationYaw = this.target.getYaw(); + ctx.player().rotationYaw = this.target.rotation.getYaw(); } } + public Optional getEffectiveRotation() { + if (Baritone.settings().freeLook.value || Baritone.settings().blockFreeLook.value) { + return Optional.ofNullable(this.serverRotation); + } + // If neither of the freeLook settings are on, just defer to the player's actual rotations + return Optional.empty(); + } + @Override public void onPlayerRotationMove(RotationMoveEvent event) { if (this.target != null) { - - event.setYaw(this.target.getYaw()); - - // If we have antiCheatCompatibility on, we're going to use the target value later in onPlayerUpdate() - // Also the type has to be MOTION_UPDATE because that is called after JUMP - if (!Baritone.settings().antiCheatCompatibility.value && event.getType() == RotationMoveEvent.Type.MOTION_UPDATE && !this.force) { - this.target = null; - } + event.setYaw(this.target.rotation.getYaw()); } } /** * Nudges the player's pitch to a regular level. (Between {@code -20} and {@code 10}, increments are by {@code 1}) */ - private void nudgeToLevel() { - if (ctx.player().rotationPitch < -20) { - ctx.player().rotationPitch++; - } else if (ctx.player().rotationPitch > 10) { - ctx.player().rotationPitch--; + private static float nudgeToLevel(float pitch) { + if (pitch < -20) { + return pitch + 1; + } else if (pitch > 10) { + return pitch - 1; + } + return pitch; + } + + private static float calculateMouseMove(float current, float target) { + final float delta = target - current; + final int deltaPx = angleToMouse(delta); + return current + mouseToAngle(deltaPx); + } + + private static int angleToMouse(float angleDelta) { + final float minAngleChange = mouseToAngle(1); + return Math.round(angleDelta / minAngleChange); + } + + private static float mouseToAngle(int mouseDelta) { + final float f = Helper.mc.gameSettings.mouseSensitivity * 0.6f + 0.2f; + return mouseDelta * f * f * f * 8.0f * 0.15f; + } + + private static class Target { + + public final Rotation rotation; + public final Mode mode; + + public Target(Rotation rotation, boolean blockInteract) { + this.rotation = rotation; + this.mode = Mode.resolve(blockInteract); + } + + enum Mode { + /** + * Rotation will be set client-side and is visual to the player + */ + CLIENT, + + /** + * Rotation will be set server-side and is silent to the player + */ + SERVER, + + /** + * Rotation will remain unaffected on both the client and server + */ + NONE; + + static Mode resolve(boolean blockInteract) { + final Settings settings = Baritone.settings(); + final boolean antiCheat = settings.antiCheatCompatibility.value; + final boolean blockFreeLook = settings.blockFreeLook.value; + final boolean freeLook = settings.freeLook.value; + + if (!freeLook && !blockFreeLook) return CLIENT; + if (!blockFreeLook && blockInteract) return CLIENT; + + // Regardless of if antiCheatCompatibility is enabled, if a blockInteract is requested then the player + // rotation needs to be set somehow, otherwise Baritone will halt since objectMouseOver() will just be + // whatever the player is mousing over visually. Let's just settle for setting it silently. + if (antiCheat || blockInteract) return SERVER; + + // Pathing regularly without antiCheatCompatibility, don't set the player rotation + return NONE; + } } } } diff --git a/src/main/java/baritone/command/defaults/GoalCommand.java b/src/main/java/baritone/command/defaults/GoalCommand.java index 40822e057..a174ecad9 100644 --- a/src/main/java/baritone/command/defaults/GoalCommand.java +++ b/src/main/java/baritone/command/defaults/GoalCommand.java @@ -51,7 +51,7 @@ public class GoalCommand extends Command { } } else { args.requireMax(3); - BetterBlockPos origin = baritone.getPlayerContext().playerFeet(); + BetterBlockPos origin = ctx.playerFeet(); Goal goal = args.getDatatypePost(RelativeGoal.INSTANCE, origin); goalProcess.setGoal(goal); logDirect(String.format("Goal: %s", goal.toString())); diff --git a/src/main/java/baritone/command/defaults/GotoCommand.java b/src/main/java/baritone/command/defaults/GotoCommand.java index 896e3f5f8..333d7fa57 100644 --- a/src/main/java/baritone/command/defaults/GotoCommand.java +++ b/src/main/java/baritone/command/defaults/GotoCommand.java @@ -46,7 +46,7 @@ public class GotoCommand extends Command { // is no need to handle the case of empty arguments. if (args.peekDatatypeOrNull(RelativeCoordinate.INSTANCE) != null) { args.requireMax(3); - BetterBlockPos origin = baritone.getPlayerContext().playerFeet(); + BetterBlockPos origin = ctx.playerFeet(); Goal goal = args.getDatatypePost(RelativeGoal.INSTANCE, origin); logDirect(String.format("Going to: %s", goal.toString())); baritone.getCustomGoalProcess().setGoalAndPath(goal); diff --git a/src/main/java/baritone/command/defaults/SelCommand.java b/src/main/java/baritone/command/defaults/SelCommand.java index 5677eec3c..9abe417ac 100644 --- a/src/main/java/baritone/command/defaults/SelCommand.java +++ b/src/main/java/baritone/command/defaults/SelCommand.java @@ -21,6 +21,7 @@ import baritone.Baritone; import baritone.api.IBaritone; import baritone.api.command.Command; import baritone.api.command.argument.IArgConsumer; +import baritone.api.command.datatypes.ForAxis; import baritone.api.command.datatypes.ForBlockOptionalMeta; import baritone.api.command.datatypes.ForEnumFacing; import baritone.api.command.datatypes.RelativeBlockPos; @@ -31,6 +32,8 @@ import baritone.api.command.helpers.TabCompleteHelper; import baritone.api.event.events.RenderEvent; import baritone.api.event.listener.AbstractGameEventListener; import baritone.api.schematic.*; +import baritone.api.schematic.mask.shape.CylinderMask; +import baritone.api.schematic.mask.shape.SphereMask; import baritone.api.selection.ISelection; import baritone.api.selection.ISelectionManager; import baritone.api.utils.BetterBlockPos; @@ -50,6 +53,7 @@ import java.awt.*; import java.util.List; import java.util.*; import java.util.function.Function; +import java.util.function.UnaryOperator; import java.util.stream.Stream; public class SelCommand extends Command { @@ -72,7 +76,7 @@ public class SelCommand extends Command { float lineWidth = Baritone.settings().selectionLineWidth.value; boolean ignoreDepth = Baritone.settings().renderSelectionIgnoreDepth.value; IRenderer.startLines(color, opacity, lineWidth, ignoreDepth); - IRenderer.drawAABB(new AxisAlignedBB(pos1, pos1.add(1, 1, 1))); + IRenderer.emitAABB(new AxisAlignedBB(pos1, pos1.add(1, 1, 1))); IRenderer.endLines(ignoreDepth); } }); @@ -117,11 +121,13 @@ public class SelCommand extends Command { logDirect("Undid pos2"); } } - } else if (action == Action.SET || action == Action.WALLS || action == Action.SHELL || action == Action.CLEARAREA || action == Action.REPLACE) { + } else if (action.isFillAction()) { BlockOptionalMeta type = action == Action.CLEARAREA ? new BlockOptionalMeta(Blocks.AIR) : args.getDatatypeFor(ForBlockOptionalMeta.INSTANCE); - BlockOptionalMetaLookup replaces = null; + + final BlockOptionalMetaLookup replaces; // Action.REPLACE + final EnumFacing.Axis alignment; // Action.(H)CYLINDER if (action == Action.REPLACE) { args.requireMin(1); List replacesList = new ArrayList<>(); @@ -131,8 +137,15 @@ public class SelCommand extends Command { } type = args.getDatatypeFor(ForBlockOptionalMeta.INSTANCE); replaces = new BlockOptionalMetaLookup(replacesList.toArray(new BlockOptionalMeta[0])); + alignment = null; + } else if (action == Action.CYLINDER || action == Action.HCYLINDER) { + args.requireMax(1); + alignment = args.hasAny() ? args.getDatatypeFor(ForAxis.INSTANCE) : EnumFacing.Axis.Y; + replaces = null; } else { args.requireMax(0); + replaces = null; + alignment = null; } ISelection[] selections = manager.getSelections(); if (selections.length == 0) { @@ -151,14 +164,35 @@ public class SelCommand extends Command { for (ISelection selection : selections) { Vec3i size = selection.size(); BetterBlockPos min = selection.min(); - ISchematic schematic = new FillSchematic(size.getX(), size.getY(), size.getZ(), type); - if (action == Action.WALLS) { - schematic = new WallsSchematic(schematic); - } else if (action == Action.SHELL) { - schematic = new ShellSchematic(schematic); - } else if (action == Action.REPLACE) { - schematic = new ReplaceSchematic(schematic, replaces); - } + + // Java 8 so no switch expressions 😿 + UnaryOperator create = fill -> { + final int w = fill.widthX(); + final int h = fill.heightY(); + final int l = fill.lengthZ(); + + switch (action) { + case WALLS: + return new WallsSchematic(fill); + case SHELL: + return new ShellSchematic(fill); + case REPLACE: + return new ReplaceSchematic(fill, replaces); + case SPHERE: + return MaskSchematic.create(fill, new SphereMask(w, h, l, true).compute()); + case HSPHERE: + return MaskSchematic.create(fill, new SphereMask(w, h, l, false).compute()); + case CYLINDER: + return MaskSchematic.create(fill, new CylinderMask(w, h, l, true, alignment).compute()); + case HCYLINDER: + return MaskSchematic.create(fill, new CylinderMask(w, h, l, false, alignment).compute()); + default: + // Silent fail + return fill; + } + }; + + ISchematic schematic = create.apply(new FillSchematic(size.getX(), size.getY(), size.getZ(), type)); composite.put(schematic, min.x - origin.x, min.y - origin.y, min.z - origin.z); } baritone.getBuilderProcess().build("Fill", composite, origin); @@ -254,12 +288,15 @@ public class SelCommand extends Command { if (args.hasAtMost(3)) { return args.tabCompleteDatatype(RelativeBlockPos.INSTANCE); } - } else if (action == Action.SET || action == Action.WALLS || action == Action.CLEARAREA || action == Action.REPLACE) { + } else if (action.isFillAction()) { if (args.hasExactlyOne() || action == Action.REPLACE) { while (args.has(2)) { args.get(); } return args.tabCompleteDatatype(ForBlockOptionalMeta.INSTANCE); + } else if (args.hasExactly(2) && (action == Action.CYLINDER || action == Action.HCYLINDER)) { + args.get(); + return args.tabCompleteDatatype(ForAxis.INSTANCE); } } else if (action == Action.EXPAND || action == Action.CONTRACT || action == Action.SHIFT) { if (args.hasExactlyOne()) { @@ -305,6 +342,10 @@ public class SelCommand extends Command { "> sel set/fill/s/f [block] - Completely fill all selections with a block.", "> sel walls/w [block] - Fill in the walls of the selection with a specified block.", "> sel shell/shl [block] - The same as walls, but fills in a ceiling and floor too.", + "> sel sphere/sph [block] - Fills the selection with a sphere bounded by the sides.", + "> sel hsphere/hsph [block] - The same as sphere, but hollow.", + "> sel cylinder/cyl [block] - Fills the selection with a cylinder bounded by the sides, oriented about the given axis. (default=y)", + "> sel hcylinder/hcyl [block] - The same as cylinder, but hollow.", "> sel cleararea/ca - Basically 'set air'.", "> sel replace/r - Replaces blocks with another block.", "> sel copy/cp - Copy the selected area relative to the specified or your position.", @@ -324,6 +365,10 @@ public class SelCommand extends Command { SET("set", "fill", "s", "f"), WALLS("walls", "w"), SHELL("shell", "shl"), + SPHERE("sphere", "sph"), + HSPHERE("hsphere", "hsph"), + CYLINDER("cylinder", "cyl"), + HCYLINDER("hcylinder", "hcyl"), CLEARAREA("cleararea", "ca"), REPLACE("replace", "r"), EXPAND("expand", "ex"), @@ -355,6 +400,18 @@ public class SelCommand extends Command { } return names.toArray(new String[0]); } + + public final boolean isFillAction() { + return this == SET + || this == WALLS + || this == SHELL + || this == SPHERE + || this == HSPHERE + || this == CYLINDER + || this == HCYLINDER + || this == CLEARAREA + || this == REPLACE; + } } enum TransformTarget { diff --git a/src/main/java/baritone/command/defaults/SurfaceCommand.java b/src/main/java/baritone/command/defaults/SurfaceCommand.java index 842b8050c..5d914aded 100644 --- a/src/main/java/baritone/command/defaults/SurfaceCommand.java +++ b/src/main/java/baritone/command/defaults/SurfaceCommand.java @@ -38,13 +38,13 @@ public class SurfaceCommand extends Command { @Override public void execute(String label, IArgConsumer args) throws CommandException { - final BetterBlockPos playerPos = baritone.getPlayerContext().playerFeet(); - final int surfaceLevel = baritone.getPlayerContext().world().getSeaLevel(); - final int worldHeight = baritone.getPlayerContext().world().getActualHeight(); + final BetterBlockPos playerPos = ctx.playerFeet(); + final int surfaceLevel = ctx.world().getSeaLevel(); + final int worldHeight = ctx.world().getActualHeight(); // Ensure this command will not run if you are above the surface level and the block above you is air // As this would imply that your are already on the open surface - if (playerPos.getY() > surfaceLevel && mc.world.getBlockState(playerPos.up()).getBlock() instanceof BlockAir) { + if (playerPos.getY() > surfaceLevel && ctx.world().getBlockState(playerPos.up()).getBlock() instanceof BlockAir) { logDirect("Already at surface"); return; } diff --git a/src/main/java/baritone/pathing/movement/Movement.java b/src/main/java/baritone/pathing/movement/Movement.java index c46b24dea..5a17d26c5 100644 --- a/src/main/java/baritone/pathing/movement/Movement.java +++ b/src/main/java/baritone/pathing/movement/Movement.java @@ -164,7 +164,7 @@ public abstract class Movement implements IMovement, MovementHelper { if (!MovementHelper.canWalkThrough(ctx, blockPos) && !(BlockStateInterface.getBlock(ctx, blockPos) instanceof BlockLiquid)) { // can't break liquid, so don't try somethingInTheWay = true; MovementHelper.switchToBestToolFor(ctx, BlockStateInterface.get(ctx, blockPos)); - Optional reachable = RotationUtils.reachable(ctx.player(), blockPos, ctx.playerController().getBlockReachDistance()); + Optional reachable = RotationUtils.reachable(ctx, blockPos, ctx.playerController().getBlockReachDistance()); if (reachable.isPresent()) { Rotation rotTowardsBlock = reachable.get(); state.setTarget(new MovementState.MovementTarget(rotTowardsBlock, true)); diff --git a/src/main/java/baritone/pathing/movement/MovementHelper.java b/src/main/java/baritone/pathing/movement/MovementHelper.java index 575815ea2..b14b2d69c 100644 --- a/src/main/java/baritone/pathing/movement/MovementHelper.java +++ b/src/main/java/baritone/pathing/movement/MovementHelper.java @@ -599,9 +599,9 @@ public interface MovementHelper extends ActionCosts, Helper { static void moveTowards(IPlayerContext ctx, MovementState state, BlockPos pos) { state.setTarget(new MovementTarget( - new Rotation(RotationUtils.calcRotationFromVec3d(ctx.playerHead(), + RotationUtils.calcRotationFromVec3d(ctx.playerHead(), VecUtils.getBlockPosCenter(pos), - ctx.playerRotations()).getYaw(), ctx.player().rotationPitch), + ctx.playerRotations()).withPitch(ctx.playerRotations().getPitch()), false )).setInput(Input.MOVE_FORWARD, true); } diff --git a/src/main/java/baritone/pathing/movement/movements/MovementDescend.java b/src/main/java/baritone/pathing/movement/movements/MovementDescend.java index d36843cdd..2d8180356 100644 --- a/src/main/java/baritone/pathing/movement/movements/MovementDescend.java +++ b/src/main/java/baritone/pathing/movement/movements/MovementDescend.java @@ -234,11 +234,10 @@ public class MovementDescend extends Movement { if (safeMode()) { double destX = (src.getX() + 0.5) * 0.17 + (dest.getX() + 0.5) * 0.83; double destZ = (src.getZ() + 0.5) * 0.17 + (dest.getZ() + 0.5) * 0.83; - EntityPlayerSP player = ctx.player(); state.setTarget(new MovementState.MovementTarget( - new Rotation(RotationUtils.calcRotationFromVec3d(ctx.playerHead(), + RotationUtils.calcRotationFromVec3d(ctx.playerHead(), new Vec3d(destX, dest.getY(), destZ), - new Rotation(player.rotationYaw, player.rotationPitch)).getYaw(), player.rotationPitch), + ctx.playerRotations()).withPitch(ctx.playerRotations().getPitch()), false )).setInput(Input.MOVE_FORWARD, true); return state; diff --git a/src/main/java/baritone/pathing/movement/movements/MovementPillar.java b/src/main/java/baritone/pathing/movement/movements/MovementPillar.java index cfa9d9260..0198b28fe 100644 --- a/src/main/java/baritone/pathing/movement/movements/MovementPillar.java +++ b/src/main/java/baritone/pathing/movement/movements/MovementPillar.java @@ -190,9 +190,9 @@ public class MovementPillar extends Movement { boolean vine = fromDown.getBlock() == Blocks.VINE; Rotation rotation = RotationUtils.calcRotationFromVec3d(ctx.playerHead(), VecUtils.getBlockPosCenter(positionToPlace), - new Rotation(ctx.player().rotationYaw, ctx.player().rotationPitch)); + ctx.playerRotations()); if (!ladder) { - state.setTarget(new MovementState.MovementTarget(new Rotation(ctx.player().rotationYaw, rotation.getPitch()), true)); + state.setTarget(new MovementState.MovementTarget(ctx.playerRotations().withPitch(rotation.getPitch()), true)); } boolean blockIsThere = MovementHelper.canWalkOn(ctx, src) || ladder; @@ -251,7 +251,7 @@ public class MovementPillar extends Movement { Block fr = frState.getBlock(); // TODO: Evaluate usage of getMaterial().isReplaceable() if (!(fr instanceof BlockAir || frState.getMaterial().isReplaceable())) { - RotationUtils.reachable(ctx.player(), src, ctx.playerController().getBlockReachDistance()) + RotationUtils.reachable(ctx, src, ctx.playerController().getBlockReachDistance()) .map(rot -> new MovementState.MovementTarget(rot, true)) .ifPresent(state::setTarget); state.setInput(Input.JUMP, false); // breaking is like 5x slower when you're jumping diff --git a/src/main/java/baritone/process/BuilderProcess.java b/src/main/java/baritone/process/BuilderProcess.java index c7868a4a0..2d10bcd55 100644 --- a/src/main/java/baritone/process/BuilderProcess.java +++ b/src/main/java/baritone/process/BuilderProcess.java @@ -30,10 +30,7 @@ import baritone.api.schematic.ISchematic; import baritone.api.schematic.IStaticSchematic; import baritone.api.schematic.SubstituteSchematic; import baritone.api.schematic.format.ISchematicFormat; -import baritone.api.utils.BetterBlockPos; -import baritone.api.utils.RayTraceUtils; -import baritone.api.utils.Rotation; -import baritone.api.utils.RotationUtils; +import baritone.api.utils.*; import baritone.api.utils.input.Input; import baritone.pathing.movement.CalculationContext; import baritone.pathing.movement.Movement; @@ -283,7 +280,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil IBlockState curr = bcc.bsi.get0(x, y, z); if (curr.getBlock() != Blocks.AIR && !(curr.getBlock() instanceof BlockLiquid) && !valid(curr, desired, false)) { BetterBlockPos pos = new BetterBlockPos(x, y, z); - Optional rot = RotationUtils.reachable(ctx.player(), pos, ctx.playerController().getBlockReachDistance()); + Optional rot = RotationUtils.reachable(ctx, pos, ctx.playerController().getBlockReachDistance()); if (rot.isPresent()) { return Optional.of(new Tuple<>(pos, rot.get())); } @@ -764,6 +761,20 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil return primary.heuristic(x, y, z); } + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + JankyGoalComposite goal = (JankyGoalComposite) o; + return Objects.equals(primary, goal.primary) + && Objects.equals(fallback, goal.fallback); + } + @Override public String toString() { return "JankyComposite Primary: " + primary + " Fallback: " + fallback; @@ -785,6 +796,16 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil // but any other adjacent works for breaking, including inside or below return super.isInGoal(x, y, z); } + + @Override + public String toString() { + return String.format( + "GoalBreak{x=%s,y=%s,z=%s}", + SettingsUtil.maybeCensor(x), + SettingsUtil.maybeCensor(y), + SettingsUtil.maybeCensor(z) + ); + } } private Goal placementGoal(BlockPos pos, BuilderCalculationContext bcc) { @@ -828,6 +849,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil this.allowSameLevel = allowSameLevel; } + @Override public boolean isInGoal(int x, int y, int z) { if (x == this.x && y == this.y && z == this.z) { return false; @@ -844,10 +866,32 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil return super.isInGoal(x, y, z); } + @Override public double heuristic(int x, int y, int z) { // prioritize lower y coordinates return this.y * 100 + super.heuristic(x, y, z); } + + @Override + public boolean equals(Object o) { + if (!super.equals(o)) { + return false; + } + + GoalAdjacent goal = (GoalAdjacent) o; + return allowSameLevel == goal.allowSameLevel + && Objects.equals(no, goal.no); + } + + @Override + public String toString() { + return String.format( + "GoalAdjacent{x=%s,y=%s,z=%s}", + SettingsUtil.maybeCensor(x), + SettingsUtil.maybeCensor(y), + SettingsUtil.maybeCensor(z) + ); + } } public static class GoalPlace extends GoalBlock { @@ -856,10 +900,21 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil super(placeAt.up()); } + @Override public double heuristic(int x, int y, int z) { // prioritize lower y coordinates return this.y * 100 + super.heuristic(x, y, z); } + + @Override + public String toString() { + return String.format( + "GoalPlace{x=%s,y=%s,z=%s}", + SettingsUtil.maybeCensor(x), + SettingsUtil.maybeCensor(y), + SettingsUtil.maybeCensor(z) + ); + } } @Override diff --git a/src/main/java/baritone/process/FarmProcess.java b/src/main/java/baritone/process/FarmProcess.java index a9188299c..1536bdb61 100644 --- a/src/main/java/baritone/process/FarmProcess.java +++ b/src/main/java/baritone/process/FarmProcess.java @@ -268,7 +268,7 @@ public final class FarmProcess extends BaritoneProcessHelper implements IFarmPro both.addAll(openSoulsand); for (BlockPos pos : both) { boolean soulsand = openSoulsand.contains(pos); - Optional rot = RotationUtils.reachableOffset(ctx.player(), pos, new Vec3d(pos.getX() + 0.5, pos.getY() + 1, pos.getZ() + 0.5), ctx.playerController().getBlockReachDistance(), false); + Optional rot = RotationUtils.reachableOffset(ctx, pos, new Vec3d(pos.getX() + 0.5, pos.getY() + 1, pos.getZ() + 0.5), ctx.playerController().getBlockReachDistance(), false); if (rot.isPresent() && isSafeToCancel && baritone.getInventoryBehavior().throwaway(true, soulsand ? this::isNetherWart : this::isPlantable)) { RayTraceResult result = RayTraceUtils.rayTraceTowards(ctx.player(), rot.get(), ctx.playerController().getBlockReachDistance()); if (result.typeOfHit == RayTraceResult.Type.BLOCK && result.sideHit == EnumFacing.UP) { @@ -286,7 +286,7 @@ public final class FarmProcess extends BaritoneProcessHelper implements IFarmPro continue; } Vec3d faceCenter = new Vec3d(pos).add(0.5, 0.5, 0.5).add(new Vec3d(dir.getDirectionVec()).scale(0.5)); - Optional rot = RotationUtils.reachableOffset(ctx.player(), pos, faceCenter, ctx.playerController().getBlockReachDistance(), false); + Optional rot = RotationUtils.reachableOffset(ctx, pos, faceCenter, ctx.playerController().getBlockReachDistance(), false); if (rot.isPresent() && isSafeToCancel && baritone.getInventoryBehavior().throwaway(true, this::isCocoa)) { RayTraceResult result = RayTraceUtils.rayTraceTowards(ctx.player(), rot.get(), ctx.playerController().getBlockReachDistance()); if (result.typeOfHit == RayTraceResult.Type.BLOCK && result.sideHit == dir) { diff --git a/src/main/java/baritone/process/GetToBlockProcess.java b/src/main/java/baritone/process/GetToBlockProcess.java index 16fc3dda5..7f8376b84 100644 --- a/src/main/java/baritone/process/GetToBlockProcess.java +++ b/src/main/java/baritone/process/GetToBlockProcess.java @@ -210,7 +210,7 @@ public final class GetToBlockProcess extends BaritoneProcessHelper implements IG private boolean rightClick() { for (BlockPos pos : knownLocations) { - Optional reachable = RotationUtils.reachable(ctx.player(), pos, ctx.playerController().getBlockReachDistance()); + Optional reachable = RotationUtils.reachable(ctx, pos, ctx.playerController().getBlockReachDistance()); if (reachable.isPresent()) { baritone.getLookBehavior().updateTarget(reachable.get(), true); if (knownLocations.contains(ctx.getSelectedBlock().orElse(null))) { diff --git a/src/main/java/baritone/process/InventoryPauserProcess.java b/src/main/java/baritone/process/InventoryPauserProcess.java index ab210532b..9752912b9 100644 --- a/src/main/java/baritone/process/InventoryPauserProcess.java +++ b/src/main/java/baritone/process/InventoryPauserProcess.java @@ -34,14 +34,14 @@ public class InventoryPauserProcess extends BaritoneProcessHelper { @Override public boolean isActive() { - if (mc.player == null || mc.world == null) { + if (ctx.player() == null || ctx.world() == null) { return false; } return true; } private double motion() { - return Math.sqrt(mc.player.motionX * mc.player.motionX + mc.player.motionZ * mc.player.motionZ); + return Math.sqrt(ctx.player().motionX * ctx.player().motionX + ctx.player().motionZ * ctx.player().motionZ); } private boolean stationaryNow() { diff --git a/src/main/java/baritone/process/MineProcess.java b/src/main/java/baritone/process/MineProcess.java index 6880dd86c..777b48197 100644 --- a/src/main/java/baritone/process/MineProcess.java +++ b/src/main/java/baritone/process/MineProcess.java @@ -319,6 +319,21 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro int zDiff = z - this.z; return GoalBlock.calculate(xDiff, yDiff < -1 ? yDiff + 2 : yDiff == -1 ? 0 : yDiff, zDiff); } + + @Override + public boolean equals(Object o) { + return super.equals(o); + } + + @Override + public String toString() { + return String.format( + "GoalThreeBlocks{x=%s,y=%s,z=%s}", + SettingsUtil.maybeCensor(x), + SettingsUtil.maybeCensor(y), + SettingsUtil.maybeCensor(z) + ); + } } public List droppedItemsScan() { @@ -397,7 +412,7 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro // is an x-ray and it'll get caught if (filter.has(bsi.get0(x, y, z))) { BlockPos pos = new BlockPos(x, y, z); - if ((Baritone.settings().legitMineIncludeDiagonals.value && knownOreLocations.stream().anyMatch(ore -> ore.distanceSq(pos) <= 2 /* sq means this is pytha dist <= sqrt(2) */)) || RotationUtils.reachable(ctx.player(), pos, fakedBlockReachDistance).isPresent()) { + if ((Baritone.settings().legitMineIncludeDiagonals.value && knownOreLocations.stream().anyMatch(ore -> ore.distanceSq(pos) <= 2 /* sq means this is pytha dist <= sqrt(2) */)) || RotationUtils.reachable(ctx, pos, fakedBlockReachDistance).isPresent()) { knownOreLocations.add(pos); } } diff --git a/src/main/java/baritone/selection/SelectionRenderer.java b/src/main/java/baritone/selection/SelectionRenderer.java index 89104d030..b688e9670 100644 --- a/src/main/java/baritone/selection/SelectionRenderer.java +++ b/src/main/java/baritone/selection/SelectionRenderer.java @@ -23,27 +23,27 @@ public class SelectionRenderer implements IRenderer, AbstractGameEventListener { boolean ignoreDepth = settings.renderSelectionIgnoreDepth.value; float lineWidth = settings.selectionLineWidth.value; - if (!settings.renderSelection.value) { + if (!settings.renderSelection.value || selections.length == 0) { return; } IRenderer.startLines(settings.colorSelection.value, opacity, lineWidth, ignoreDepth); for (ISelection selection : selections) { - IRenderer.drawAABB(selection.aabb(), SELECTION_BOX_EXPANSION); + IRenderer.emitAABB(selection.aabb(), SELECTION_BOX_EXPANSION); } if (settings.renderSelectionCorners.value) { IRenderer.glColor(settings.colorSelectionPos1.value, opacity); for (ISelection selection : selections) { - IRenderer.drawAABB(new AxisAlignedBB(selection.pos1(), selection.pos1().add(1, 1, 1))); + IRenderer.emitAABB(new AxisAlignedBB(selection.pos1(), selection.pos1().add(1, 1, 1))); } IRenderer.glColor(settings.colorSelectionPos2.value, opacity); for (ISelection selection : selections) { - IRenderer.drawAABB(new AxisAlignedBB(selection.pos2(), selection.pos2().add(1, 1, 1))); + IRenderer.emitAABB(new AxisAlignedBB(selection.pos2(), selection.pos2().add(1, 1, 1))); } } diff --git a/src/main/java/baritone/utils/IRenderer.java b/src/main/java/baritone/utils/IRenderer.java index e5a5ee907..26a7cf1ad 100644 --- a/src/main/java/baritone/utils/IRenderer.java +++ b/src/main/java/baritone/utils/IRenderer.java @@ -38,9 +38,14 @@ public interface IRenderer { RenderManager renderManager = Helper.mc.getRenderManager(); Settings settings = BaritoneAPI.getSettings(); + float[] color = new float[] {1.0F, 1.0F, 1.0F, 255.0F}; + static void glColor(Color color, float alpha) { float[] colorComponents = color.getColorComponents(null); - GlStateManager.color(colorComponents[0], colorComponents[1], colorComponents[2], alpha); + IRenderer.color[0] = colorComponents[0]; + IRenderer.color[1] = colorComponents[1]; + IRenderer.color[2] = colorComponents[2]; + IRenderer.color[3] = alpha; } static void startLines(Color color, float alpha, float lineWidth, boolean ignoreDepth) { @@ -54,6 +59,7 @@ public interface IRenderer { if (ignoreDepth) { GlStateManager.disableDepth(); } + buffer.begin(GL_LINES, DefaultVertexFormats.POSITION_COLOR); } static void startLines(Color color, float lineWidth, boolean ignoreDepth) { @@ -61,6 +67,7 @@ public interface IRenderer { } static void endLines(boolean ignoredDepth) { + tessellator.draw(); if (ignoredDepth) { GlStateManager.enableDepth(); } @@ -70,41 +77,45 @@ public interface IRenderer { GlStateManager.disableBlend(); } - static void drawAABB(AxisAlignedBB aabb) { + static void emitAABB(AxisAlignedBB aabb) { AxisAlignedBB toDraw = aabb.offset(-renderManager.viewerPosX, -renderManager.viewerPosY, -renderManager.viewerPosZ); - buffer.begin(GL_LINES, DefaultVertexFormats.POSITION); // bottom - buffer.pos(toDraw.minX, toDraw.minY, toDraw.minZ).endVertex(); - buffer.pos(toDraw.maxX, toDraw.minY, toDraw.minZ).endVertex(); - buffer.pos(toDraw.maxX, toDraw.minY, toDraw.minZ).endVertex(); - buffer.pos(toDraw.maxX, toDraw.minY, toDraw.maxZ).endVertex(); - buffer.pos(toDraw.maxX, toDraw.minY, toDraw.maxZ).endVertex(); - buffer.pos(toDraw.minX, toDraw.minY, toDraw.maxZ).endVertex(); - buffer.pos(toDraw.minX, toDraw.minY, toDraw.maxZ).endVertex(); - buffer.pos(toDraw.minX, toDraw.minY, toDraw.minZ).endVertex(); + buffer.pos(toDraw.minX, toDraw.minY, toDraw.minZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(toDraw.maxX, toDraw.minY, toDraw.minZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(toDraw.maxX, toDraw.minY, toDraw.minZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(toDraw.maxX, toDraw.minY, toDraw.maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(toDraw.maxX, toDraw.minY, toDraw.maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(toDraw.minX, toDraw.minY, toDraw.maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(toDraw.minX, toDraw.minY, toDraw.maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(toDraw.minX, toDraw.minY, toDraw.minZ).color(color[0], color[1], color[2], color[3]).endVertex(); // top - buffer.pos(toDraw.minX, toDraw.maxY, toDraw.minZ).endVertex(); - buffer.pos(toDraw.maxX, toDraw.maxY, toDraw.minZ).endVertex(); - buffer.pos(toDraw.maxX, toDraw.maxY, toDraw.minZ).endVertex(); - buffer.pos(toDraw.maxX, toDraw.maxY, toDraw.maxZ).endVertex(); - buffer.pos(toDraw.maxX, toDraw.maxY, toDraw.maxZ).endVertex(); - buffer.pos(toDraw.minX, toDraw.maxY, toDraw.maxZ).endVertex(); - buffer.pos(toDraw.minX, toDraw.maxY, toDraw.maxZ).endVertex(); - buffer.pos(toDraw.minX, toDraw.maxY, toDraw.minZ).endVertex(); + buffer.pos(toDraw.minX, toDraw.maxY, toDraw.minZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(toDraw.maxX, toDraw.maxY, toDraw.minZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(toDraw.maxX, toDraw.maxY, toDraw.minZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(toDraw.maxX, toDraw.maxY, toDraw.maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(toDraw.maxX, toDraw.maxY, toDraw.maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(toDraw.minX, toDraw.maxY, toDraw.maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(toDraw.minX, toDraw.maxY, toDraw.maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(toDraw.minX, toDraw.maxY, toDraw.minZ).color(color[0], color[1], color[2], color[3]).endVertex(); // corners - buffer.pos(toDraw.minX, toDraw.minY, toDraw.minZ).endVertex(); - buffer.pos(toDraw.minX, toDraw.maxY, toDraw.minZ).endVertex(); - buffer.pos(toDraw.maxX, toDraw.minY, toDraw.minZ).endVertex(); - buffer.pos(toDraw.maxX, toDraw.maxY, toDraw.minZ).endVertex(); - buffer.pos(toDraw.maxX, toDraw.minY, toDraw.maxZ).endVertex(); - buffer.pos(toDraw.maxX, toDraw.maxY, toDraw.maxZ).endVertex(); - buffer.pos(toDraw.minX, toDraw.minY, toDraw.maxZ).endVertex(); - buffer.pos(toDraw.minX, toDraw.maxY, toDraw.maxZ).endVertex(); - tessellator.draw(); + buffer.pos(toDraw.minX, toDraw.minY, toDraw.minZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(toDraw.minX, toDraw.maxY, toDraw.minZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(toDraw.maxX, toDraw.minY, toDraw.minZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(toDraw.maxX, toDraw.maxY, toDraw.minZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(toDraw.maxX, toDraw.minY, toDraw.maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(toDraw.maxX, toDraw.maxY, toDraw.maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(toDraw.minX, toDraw.minY, toDraw.maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(toDraw.minX, toDraw.maxY, toDraw.maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); } - static void drawAABB(AxisAlignedBB aabb, double expand) { - drawAABB(aabb.grow(expand, expand, expand)); + static void emitAABB(AxisAlignedBB aabb, double expand) { + emitAABB(aabb.grow(expand, expand, expand)); + } + + static void drawAABB(AxisAlignedBB aabb) { + buffer.begin(GL_LINES, DefaultVertexFormats.POSITION); + emitAABB(aabb); + tessellator.draw(); } } diff --git a/src/main/java/baritone/utils/PathRenderer.java b/src/main/java/baritone/utils/PathRenderer.java index f4e9317b3..13a14f6dc 100644 --- a/src/main/java/baritone/utils/PathRenderer.java +++ b/src/main/java/baritone/utils/PathRenderer.java @@ -31,7 +31,6 @@ import com.mojang.realmsclient.util.Pair; import net.minecraft.block.state.IBlockState; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.tileentity.TileEntityBeaconRenderer; -import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.entity.Entity; import net.minecraft.init.Blocks; import net.minecraft.util.math.AxisAlignedBB; @@ -40,6 +39,7 @@ import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; import java.awt.*; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; @@ -79,7 +79,7 @@ public final class PathRenderer implements IRenderer { } if (goal != null && settings.renderGoal.value) { - drawDankLitGoalBox(renderView, goal, partialTicks, settings.colorGoalBox.value); + drawGoal(renderView, goal, partialTicks, settings.colorGoalBox.value); } if (!settings.renderPath.value) { @@ -172,28 +172,30 @@ public final class PathRenderer implements IRenderer { IRenderer.glColor(color, alpha); } - drawLine(start.x, start.y, start.z, end.x, end.y, end.z); - - tessellator.draw(); + emitLine(start.x, start.y, start.z, end.x, end.y, end.z); } IRenderer.endLines(settings.renderPathIgnoreDepth.value); } - public static void drawLine(double x1, double y1, double z1, double x2, double y2, double z2) { + public static void emitLine(double x1, double y1, double z1, double x2, double y2, double z2) { double vpX = renderManager.viewerPosX; double vpY = renderManager.viewerPosY; double vpZ = renderManager.viewerPosZ; boolean renderPathAsFrickinThingy = !settings.renderPathAsLine.value; - buffer.begin(renderPathAsFrickinThingy ? GL_LINE_STRIP : GL_LINES, DefaultVertexFormats.POSITION); - buffer.pos(x1 + 0.5D - vpX, y1 + 0.5D - vpY, z1 + 0.5D - vpZ).endVertex(); - buffer.pos(x2 + 0.5D - vpX, y2 + 0.5D - vpY, z2 + 0.5D - vpZ).endVertex(); + buffer.pos(x1 + 0.5D - vpX, y1 + 0.5D - vpY, z1 + 0.5D - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(x2 + 0.5D - vpX, y2 + 0.5D - vpY, z2 + 0.5D - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); if (renderPathAsFrickinThingy) { - buffer.pos(x2 + 0.5D - vpX, y2 + 0.53D - vpY, z2 + 0.5D - vpZ).endVertex(); - buffer.pos(x1 + 0.5D - vpX, y1 + 0.53D - vpY, z1 + 0.5D - vpZ).endVertex(); - buffer.pos(x1 + 0.5D - vpX, y1 + 0.5D - vpY, z1 + 0.5D - vpZ).endVertex(); + buffer.pos(x2 + 0.5D - vpX, y2 + 0.5D - vpY, z2 + 0.5D - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(x2 + 0.5D - vpX, y2 + 0.53D - vpY, z2 + 0.5D - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); + + buffer.pos(x2 + 0.5D - vpX, y2 + 0.53D - vpY, z2 + 0.5D - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(x1 + 0.5D - vpX, y1 + 0.53D - vpY, z1 + 0.5D - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); + + buffer.pos(x1 + 0.5D - vpX, y1 + 0.53D - vpY, z1 + 0.5D - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(x1 + 0.5D - vpX, y1 + 0.5D - vpY, z1 + 0.5D - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); } } @@ -213,13 +215,17 @@ public final class PathRenderer implements IRenderer { toDraw = state.getSelectedBoundingBox(player.world, pos); } - IRenderer.drawAABB(toDraw, .002D); + IRenderer.emitAABB(toDraw, .002D); }); IRenderer.endLines(settings.renderSelectionBoxesIgnoreDepth.value); } - public static void drawDankLitGoalBox(Entity player, Goal goal, float partialTicks, Color color) { + public static void drawGoal(Entity player, Goal goal, float partialTicks, Color color) { + drawGoal(player, goal, partialTicks, color, true); + } + + public static void drawGoal(Entity player, Goal goal, float partialTicks, Color color, boolean setupRender) { double renderPosX = renderManager.viewerPosX; double renderPosY = renderManager.viewerPosY; double renderPosZ = renderManager.viewerPosZ; @@ -251,6 +257,7 @@ public final class PathRenderer implements IRenderer { y2 -= 0.5; maxY--; } + drawDankLitGoalBox(color, minX, maxX, minZ, maxZ, minY, maxY, y1, y2, setupRender); } else if (goal instanceof GoalXZ) { GoalXZ goalPos = (GoalXZ) goal; @@ -292,14 +299,22 @@ public final class PathRenderer implements IRenderer { y2 = 0; minY = 0 - renderPosY; maxY = 256 - renderPosY; + drawDankLitGoalBox(color, minX, maxX, minZ, maxZ, minY, maxY, y1, y2, setupRender); } else if (goal instanceof GoalComposite) { - for (Goal g : ((GoalComposite) goal).goals()) { - drawDankLitGoalBox(player, g, partialTicks, color); + // Simple way to determine if goals can be batched, without having some sort of GoalRenderer + boolean batch = Arrays.stream(((GoalComposite) goal).goals()).allMatch(IGoalRenderPos.class::isInstance); + + if (batch) { + IRenderer.startLines(color, settings.goalRenderLineWidthPixels.value, settings.renderGoalIgnoreDepth.value); + } + for (Goal g : ((GoalComposite) goal).goals()) { + drawGoal(player, g, partialTicks, color, !batch); + } + if (batch) { + IRenderer.endLines(settings.renderGoalIgnoreDepth.value); } - return; } else if (goal instanceof GoalInverted) { - drawDankLitGoalBox(player, ((GoalInverted) goal).origin, partialTicks, settings.colorInvertedGoalBox.value); - return; + drawGoal(player, ((GoalInverted) goal).origin, partialTicks, settings.colorInvertedGoalBox.value); } else if (goal instanceof GoalYLevel) { GoalYLevel goalpos = (GoalYLevel) goal; minX = player.posX - settings.yLevelBoxSize.value - renderPosX; @@ -310,37 +325,45 @@ public final class PathRenderer implements IRenderer { maxY = minY + 2; y1 = 1 + y + goalpos.level - renderPosY; y2 = 1 - y + goalpos.level - renderPosY; - } else { - return; + drawDankLitGoalBox(color, minX, maxX, minZ, maxZ, minY, maxY, y1, y2, setupRender); } + } - IRenderer.startLines(color, settings.goalRenderLineWidthPixels.value, settings.renderGoalIgnoreDepth.value); + private static void drawDankLitGoalBox(Color colorIn, double minX, double maxX, double minZ, double maxZ, double minY, double maxY, double y1, double y2, boolean setupRender) { + if (setupRender) { + IRenderer.startLines(colorIn, settings.goalRenderLineWidthPixels.value, settings.renderGoalIgnoreDepth.value); + } renderHorizontalQuad(minX, maxX, minZ, maxZ, y1); renderHorizontalQuad(minX, maxX, minZ, maxZ, y2); - buffer.begin(GL_LINES, DefaultVertexFormats.POSITION); - buffer.pos(minX, minY, minZ).endVertex(); - buffer.pos(minX, maxY, minZ).endVertex(); - buffer.pos(maxX, minY, minZ).endVertex(); - buffer.pos(maxX, maxY, minZ).endVertex(); - buffer.pos(maxX, minY, maxZ).endVertex(); - buffer.pos(maxX, maxY, maxZ).endVertex(); - buffer.pos(minX, minY, maxZ).endVertex(); - buffer.pos(minX, maxY, maxZ).endVertex(); - tessellator.draw(); + buffer.pos(minX, minY, minZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(minX, maxY, minZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(maxX, minY, minZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(maxX, maxY, minZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(maxX, minY, maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(maxX, maxY, maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(minX, minY, maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(minX, maxY, maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); - IRenderer.endLines(settings.renderGoalIgnoreDepth.value); + if (setupRender) { + IRenderer.endLines(settings.renderGoalIgnoreDepth.value); + } } private static void renderHorizontalQuad(double minX, double maxX, double minZ, double maxZ, double y) { if (y != 0) { - buffer.begin(GL_LINE_LOOP, DefaultVertexFormats.POSITION); - buffer.pos(minX, y, minZ).endVertex(); - buffer.pos(maxX, y, minZ).endVertex(); - buffer.pos(maxX, y, maxZ).endVertex(); - buffer.pos(minX, y, maxZ).endVertex(); - tessellator.draw(); + buffer.pos(minX, y, minZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(maxX, y, minZ).color(color[0], color[1], color[2], color[3]).endVertex(); + + buffer.pos(maxX, y, minZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(maxX, y, maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); + + buffer.pos(maxX, y, maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(minX, y, maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); + + buffer.pos(minX, y, maxZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(minX, y, minZ).color(color[0], color[1], color[2], color[3]).endVertex(); } } } diff --git a/src/main/java/baritone/utils/PathingControlManager.java b/src/main/java/baritone/utils/PathingControlManager.java index a83e53a1e..236e41cc6 100644 --- a/src/main/java/baritone/utils/PathingControlManager.java +++ b/src/main/java/baritone/utils/PathingControlManager.java @@ -160,7 +160,7 @@ public class PathingControlManager implements IPathingControlManager { if (newGoal.isInGoal(current.getPath().getDest())) { return false; } - return !newGoal.toString().equals(current.getPath().getGoal().toString()); + return !newGoal.equals(current.getPath().getGoal()); } return false; } diff --git a/src/main/java/baritone/utils/player/PrimaryPlayerContext.java b/src/main/java/baritone/utils/player/PrimaryPlayerContext.java index 3cb498acd..02db73a5c 100644 --- a/src/main/java/baritone/utils/player/PrimaryPlayerContext.java +++ b/src/main/java/baritone/utils/player/PrimaryPlayerContext.java @@ -19,10 +19,8 @@ package baritone.utils.player; import baritone.api.BaritoneAPI; import baritone.api.cache.IWorldData; -import baritone.api.utils.Helper; -import baritone.api.utils.IPlayerContext; -import baritone.api.utils.IPlayerController; -import baritone.api.utils.RayTraceUtils; +import baritone.api.utils.*; +import baritone.behavior.LookBehavior; import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.util.math.RayTraceResult; import net.minecraft.world.World; @@ -57,6 +55,12 @@ public enum PrimaryPlayerContext implements IPlayerContext, Helper { return BaritoneAPI.getProvider().getPrimaryBaritone().getWorldProvider().getCurrentWorld(); } + @Override + public Rotation playerRotations() { + return ((LookBehavior) BaritoneAPI.getProvider().getPrimaryBaritone().getLookBehavior()).getEffectiveRotation() + .orElseGet(IPlayerContext.super::playerRotations); + } + @Override public RayTraceResult objectMouseOver() { return RayTraceUtils.rayTraceTowards(player(), playerRotations(), playerController().getBlockReachDistance());