Merge remote-tracking branch 'origin/master' into elytra

This commit is contained in:
Brady 2023-06-14 15:48:16 -05:00
commit 7b6f9b3eb6
No known key found for this signature in database
GPG Key ID: 73A788379A197567
47 changed files with 1278 additions and 206 deletions

View File

@ -4,14 +4,16 @@
</p>
<p align="center">
<a href="https://github.com/cabaletta/baritone/tree/master"><img src="https://img.shields.io/badge/MC-1.12.2-brightgreen.svg" alt="Minecraft"/></a>
<a href="https://github.com/cabaletta/baritone/tree/1.13.2"><img src="https://img.shields.io/badge/MC-1.13.2-yellow.svg" alt="Minecraft"/></a>
<a href="https://github.com/cabaletta/baritone/tree/1.14.4"><img src="https://img.shields.io/badge/MC-1.14.4-yellow.svg" alt="Minecraft"/></a>
<a href="https://github.com/cabaletta/baritone/tree/1.15.2"><img src="https://img.shields.io/badge/MC-1.15.2-yellow.svg" alt="Minecraft"/></a>
<a href="https://github.com/cabaletta/baritone/tree/1.16.5"><img src="https://img.shields.io/badge/MC-1.16.5-brightgreen.svg" alt="Minecraft"/></a>
<a href="https://github.com/cabaletta/baritone/tree/1.17.1"><img src="https://img.shields.io/badge/MC-1.17.1-yellow.svg" alt="Minecraft"/></a>
<a href="https://github.com/cabaletta/baritone/tree/1.18.2"><img src="https://img.shields.io/badge/MC-1.18.2-brightgreen.svg" alt="Minecraft"/></a>
<a href="https://github.com/cabaletta/baritone/tree/1.19.3"><img src="https://img.shields.io/badge/MC-1.19.3-brightgreen.svg" alt="Minecraft"/></a>
<a href="#Baritone"><img src="https://img.shields.io/badge/MC-1.12.2-brightgreen.svg" alt="Minecraft"/></a>
<a href="#Baritone"><img src="https://img.shields.io/badge/MC-1.13.2-yellow.svg" alt="Minecraft"/></a>
<a href="#Baritone"><img src="https://img.shields.io/badge/MC-1.14.4-yellow.svg" alt="Minecraft"/></a>
<a href="#Baritone"><img src="https://img.shields.io/badge/MC-1.15.2-yellow.svg" alt="Minecraft"/></a>
<a href="#Baritone"><img src="https://img.shields.io/badge/MC-1.16.5-brightgreen.svg" alt="Minecraft"/></a>
<a href="#Baritone"><img src="https://img.shields.io/badge/MC-1.17.1-yellow.svg" alt="Minecraft"/></a>
<a href="#Baritone"><img src="https://img.shields.io/badge/MC-1.18.2-brightgreen.svg" alt="Minecraft"/></a>
<a href="#Baritone"><img src="https://img.shields.io/badge/MC-1.19.2-brightgreen.svg" alt="Minecraft"/></a>
<a href="#Baritone"><img src="https://img.shields.io/badge/MC-1.19.4-brightgreen.svg" alt="Minecraft"/></a>
<a href="#Baritone"><img src="https://img.shields.io/badge/MC-1.20.1-brightgreen.svg" alt="Minecraft"/></a>
</p>
<p align="center">
@ -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)

View File

@ -729,6 +729,12 @@ public final class Settings {
*/
public final Setting<Boolean> 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<Boolean> blockFreeLook = new Setting<>(false);
/**
* Will cause some minor behavioral differences to ensure that Baritone works on anticheats.
* <p>

View File

@ -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);
}

View File

@ -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 <https://www.gnu.org/licenses/>.
*/
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<EnumFacing.Axis> {
INSTANCE;
@Override
public EnumFacing.Axis get(IDatatypeContext ctx) throws CommandException {
return EnumFacing.Axis.valueOf(ctx.getConsumer().getString().toUpperCase(Locale.US));
}
@Override
public Stream<String> 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();
}
}

View File

@ -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";

View File

@ -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(

View File

@ -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);

View File

@ -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(

View File

@ -17,6 +17,8 @@
package baritone.api.pathing.goals;
import java.util.Objects;
/**
* Invert any goal.
* <p>
@ -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());

View File

@ -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(

View File

@ -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) {

View File

@ -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(

View File

@ -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(

View File

@ -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(

View File

@ -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(

View File

@ -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<IBlockState> 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);
}
};
}
}

View File

@ -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 <https://www.gnu.org/licenses/>.
*/
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;
}
}

View File

@ -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 <https://www.gnu.org/licenses/>.
*/
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);
}
}

View File

@ -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 <https://www.gnu.org/licenses/>.
*/
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];
}
}

View File

@ -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 <https://www.gnu.org/licenses/>.
*/
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 <b><u>NOT</u></b> 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);
}
}

View File

@ -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 <https://www.gnu.org/licenses/>.
*/
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)
);
}
}
}

View File

@ -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 <https://www.gnu.org/licenses/>.
*/
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);
}
}
}

View File

@ -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 <https://www.gnu.org/licenses/>.
*/
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;
}
}

View File

@ -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 <https://www.gnu.org/licenses/>.
*/
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;
}
}

View File

@ -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 <https://www.gnu.org/licenses/>.
*/
package baritone.api.utils;
/**
* @author Brady
*/
@FunctionalInterface
public interface BooleanBinaryOperator {
boolean applyAsBoolean(boolean a, boolean b);
}

View File

@ -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 <https://www.gnu.org/licenses/>.
*/
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);
}
}

View File

@ -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
*

View File

@ -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<Rotation> reachable(IPlayerContext ctx, BlockPos pos) {
return reachable(ctx.player(), pos, ctx.playerController().getBlockReachDistance());
return reachable(ctx, pos, false);
}
public static Optional<Rotation> 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<Rotation> reachable(EntityPlayerSP entity, BlockPos pos, double blockReachDistance) {
return reachable(entity, pos, blockReachDistance, false);
public static Optional<Rotation> reachable(IPlayerContext ctx, BlockPos pos, double blockReachDistance) {
return reachable(ctx, pos, blockReachDistance, false);
}
public static Optional<Rotation> reachable(EntityPlayerSP entity, BlockPos pos, double blockReachDistance, boolean wouldSneak) {
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer(entity);
if (baritone.getPlayerContext().isLookingAt(pos)) {
public static Optional<Rotation> 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<Rotation> possibleRotation = reachableCenter(entity, pos, blockReachDistance, wouldSneak);
Optional<Rotation> 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<Rotation> 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<Rotation> reachableCenter(IPlayerContext ctx, BlockPos pos, double blockReachDistance, boolean wouldSneak) {
return reachableOffset(ctx, pos, VecUtils.calculateBlockCenter(ctx.world(), pos), blockReachDistance, wouldSneak);
}
@Deprecated
public static Optional<Rotation> reachable(EntityPlayerSP entity, BlockPos pos, double blockReachDistance) {
return reachable(entity, pos, blockReachDistance, false);
}
@Deprecated
public static Optional<Rotation> 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<Rotation> 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<Rotation> reachableCenter(Entity entity, BlockPos pos, double blockReachDistance, boolean wouldSneak) {
return reachableOffset(entity, pos, VecUtils.calculateBlockCenter(entity.world, pos), blockReachDistance, wouldSneak);
}

View File

@ -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:
* <p>
* 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<Rotation> 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;
}
}
}
}

View File

@ -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()));

View File

@ -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);

View File

@ -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<BlockOptionalMeta> 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<ISchematic> 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] <axis> - Fills the selection with a cylinder bounded by the sides, oriented about the given axis. (default=y)",
"> sel hcylinder/hcyl [block] <axis> - The same as cylinder, but hollow.",
"> sel cleararea/ca - Basically 'set air'.",
"> sel replace/r <blocks...> <with> - Replaces blocks with another block.",
"> sel copy/cp <x> <y> <z> - 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 {

View File

@ -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;
}

View File

@ -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<Rotation> reachable = RotationUtils.reachable(ctx.player(), blockPos, ctx.playerController().getBlockReachDistance());
Optional<Rotation> reachable = RotationUtils.reachable(ctx, blockPos, ctx.playerController().getBlockReachDistance());
if (reachable.isPresent()) {
Rotation rotTowardsBlock = reachable.get();
state.setTarget(new MovementState.MovementTarget(rotTowardsBlock, true));

View File

@ -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);
}

View File

@ -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;

View File

@ -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

View File

@ -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<Rotation> rot = RotationUtils.reachable(ctx.player(), pos, ctx.playerController().getBlockReachDistance());
Optional<Rotation> 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

View File

@ -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<Rotation> rot = RotationUtils.reachableOffset(ctx.player(), pos, new Vec3d(pos.getX() + 0.5, pos.getY() + 1, pos.getZ() + 0.5), ctx.playerController().getBlockReachDistance(), false);
Optional<Rotation> 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<Rotation> rot = RotationUtils.reachableOffset(ctx.player(), pos, faceCenter, ctx.playerController().getBlockReachDistance(), false);
Optional<Rotation> 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) {

View File

@ -210,7 +210,7 @@ public final class GetToBlockProcess extends BaritoneProcessHelper implements IG
private boolean rightClick() {
for (BlockPos pos : knownLocations) {
Optional<Rotation> reachable = RotationUtils.reachable(ctx.player(), pos, ctx.playerController().getBlockReachDistance());
Optional<Rotation> reachable = RotationUtils.reachable(ctx, pos, ctx.playerController().getBlockReachDistance());
if (reachable.isPresent()) {
baritone.getLookBehavior().updateTarget(reachable.get(), true);
if (knownLocations.contains(ctx.getSelectedBlock().orElse(null))) {

View File

@ -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() {

View File

@ -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<BlockPos> 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);
}
}

View File

@ -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)));
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}
}

View File

@ -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;
}

View File

@ -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());