a much needed path executor overhaul
This commit is contained in:
parent
13cfb8e369
commit
12b64ead5c
@ -31,7 +31,7 @@ public enum EventState {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates that whatever movement the event is being
|
* Indicates that whatever movement the event is being
|
||||||
* dispatched as a result of has already occured.
|
* dispatched as a result of has already occurred.
|
||||||
*/
|
*/
|
||||||
POST
|
POST
|
||||||
}
|
}
|
||||||
|
@ -102,6 +102,7 @@ public abstract class Movement implements Helper, MovementHelper {
|
|||||||
* @return Status
|
* @return Status
|
||||||
*/
|
*/
|
||||||
public MovementStatus update() {
|
public MovementStatus update() {
|
||||||
|
player().capabilities.allowFlying = false;
|
||||||
MovementState latestState = updateState(currentState);
|
MovementState latestState = updateState(currentState);
|
||||||
if (BlockStateInterface.isLiquid(playerFeet())) {
|
if (BlockStateInterface.isLiquid(playerFeet())) {
|
||||||
latestState.setInput(Input.JUMP, true);
|
latestState.setInput(Input.JUMP, true);
|
||||||
|
@ -71,11 +71,11 @@ public interface IPath extends Helper {
|
|||||||
*/
|
*/
|
||||||
Goal getGoal();
|
Goal getGoal();
|
||||||
|
|
||||||
default Tuple<Double, BlockPos> closestPathPos(double x, double y, double z) {
|
default Tuple<Double, BlockPos> closestPathPos() {
|
||||||
double best = -1;
|
double best = -1;
|
||||||
BlockPos bestPos = null;
|
BlockPos bestPos = null;
|
||||||
for (BlockPos pos : positions()) {
|
for (BlockPos pos : positions()) {
|
||||||
double dist = Utils.distanceToCenter(pos, x, y, z);
|
double dist = Utils.playerDistanceToCenter(pos);
|
||||||
if (dist < best || best == -1) {
|
if (dist < best || best == -1) {
|
||||||
best = dist;
|
best = dist;
|
||||||
bestPos = pos;
|
bestPos = pos;
|
||||||
|
@ -26,7 +26,7 @@ import baritone.pathing.movement.movements.MovementFall;
|
|||||||
import baritone.pathing.movement.movements.MovementTraverse;
|
import baritone.pathing.movement.movements.MovementTraverse;
|
||||||
import baritone.utils.BlockStateInterface;
|
import baritone.utils.BlockStateInterface;
|
||||||
import baritone.utils.Helper;
|
import baritone.utils.Helper;
|
||||||
import net.minecraft.client.entity.EntityPlayerSP;
|
import baritone.utils.Utils;
|
||||||
import net.minecraft.init.Blocks;
|
import net.minecraft.init.Blocks;
|
||||||
import net.minecraft.util.Tuple;
|
import net.minecraft.util.Tuple;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
@ -75,18 +75,11 @@ public class PathExecutor implements Helper {
|
|||||||
if (event.getType() == TickEvent.Type.OUT) {
|
if (event.getType() == TickEvent.Type.OUT) {
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
if (pathPosition >= path.length()) {
|
if (pathPosition >= path.length() - 1) {
|
||||||
//stop bugging me, I'm done
|
return true; // stop bugging me, I'm done
|
||||||
//TODO Baritone.INSTANCE.behaviors.remove(this)
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
BlockPos whereShouldIBe = path.positions().get(pathPosition);
|
BlockPos whereShouldIBe = path.positions().get(pathPosition);
|
||||||
EntityPlayerSP thePlayer = mc.player;
|
|
||||||
BlockPos whereAmI = playerFeet();
|
BlockPos whereAmI = playerFeet();
|
||||||
if (pathPosition == path.length() - 1) {
|
|
||||||
pathPosition++;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (!whereShouldIBe.equals(whereAmI)) {
|
if (!whereShouldIBe.equals(whereAmI)) {
|
||||||
//System.out.println("Should be at " + whereShouldIBe + " actually am at " + whereAmI);
|
//System.out.println("Should be at " + whereShouldIBe + " actually am at " + whereAmI);
|
||||||
if (!Blocks.AIR.equals(BlockStateInterface.getBlock(whereAmI.down()))) {//do not skip if standing on air, because our position isn't stable to skip
|
if (!Blocks.AIR.equals(BlockStateInterface.getBlock(whereAmI.down()))) {//do not skip if standing on air, because our position isn't stable to skip
|
||||||
@ -98,7 +91,7 @@ public class PathExecutor implements Helper {
|
|||||||
for (int j = pathPosition; j <= previousPos; j++) {
|
for (int j = pathPosition; j <= previousPos; j++) {
|
||||||
path.movements().get(j).reset();
|
path.movements().get(j).reset();
|
||||||
}
|
}
|
||||||
Baritone.INSTANCE.getInputOverrideHandler().clearAllKeys();
|
clearKeys();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -109,39 +102,29 @@ public class PathExecutor implements Helper {
|
|||||||
}
|
}
|
||||||
System.out.println("Double skip sundae");
|
System.out.println("Double skip sundae");
|
||||||
pathPosition = i - 1;
|
pathPosition = i - 1;
|
||||||
Baritone.INSTANCE.getInputOverrideHandler().clearAllKeys();
|
clearKeys();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Tuple<Double, BlockPos> status = path.closestPathPos(thePlayer.posX, thePlayer.posY, thePlayer.posZ);
|
Tuple<Double, BlockPos> status = path.closestPathPos();
|
||||||
double distanceFromPath = status.getFirst();
|
if (possiblyOffPath(status, MAX_DIST_FROM_PATH)) {
|
||||||
if (distanceFromPath > MAX_DIST_FROM_PATH) {
|
|
||||||
ticksAway++;
|
ticksAway++;
|
||||||
System.out.println("FAR AWAY FROM PATH FOR " + ticksAway + " TICKS. Current distance: " + distanceFromPath + ". Threshold: " + MAX_DIST_FROM_PATH);
|
System.out.println("FAR AWAY FROM PATH FOR " + ticksAway + " TICKS. Current distance: " + status.getFirst() + ". Threshold: " + MAX_DIST_FROM_PATH);
|
||||||
if (ticksAway > MAX_TICKS_AWAY) {
|
if (ticksAway > MAX_TICKS_AWAY) {
|
||||||
logDebug("Too far away from path for too long, cancelling path");
|
logDebug("Too far away from path for too long, cancelling path");
|
||||||
System.out.println("Too many ticks");
|
cancel();
|
||||||
pathPosition = path.length() + 3;
|
|
||||||
Baritone.INSTANCE.getInputOverrideHandler().clearAllKeys();
|
|
||||||
failed = true;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ticksAway = 0;
|
ticksAway = 0;
|
||||||
}
|
}
|
||||||
if (distanceFromPath > MAX_MAX_DIST_FROM_PATH) {
|
if (possiblyOffPath(status, MAX_MAX_DIST_FROM_PATH)) { // ok, stop right away, we're way too far.
|
||||||
if (!(path.movements().get(pathPosition) instanceof MovementFall)) { // might be midair
|
|
||||||
if (pathPosition == 0 || !(path.movements().get(pathPosition - 1) instanceof MovementFall)) { // might have overshot the landing
|
|
||||||
logDebug("too far from path");
|
logDebug("too far from path");
|
||||||
pathPosition = path.length() + 3;
|
cancel();
|
||||||
Baritone.INSTANCE.getInputOverrideHandler().clearAllKeys();
|
|
||||||
failed = true;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
//this commented block is literally cursed.
|
//this commented block is literally cursed.
|
||||||
/*Out.log(actions.get(pathPosition));
|
/*Out.log(actions.get(pathPosition));
|
||||||
if (pathPosition < actions.size() - 1) {//if there are two ActionBridges in a row and they are at right angles, walk diagonally. This makes it so you walk at 45 degrees along a zigzag path instead of doing inefficient zigging and zagging
|
if (pathPosition < actions.size() - 1) {//if there are two ActionBridges in a row and they are at right angles, walk diagonally. This makes it so you walk at 45 degrees along a zigzag path instead of doing inefficient zigging and zagging
|
||||||
@ -176,7 +159,9 @@ public class PathExecutor implements Helper {
|
|||||||
}*/
|
}*/
|
||||||
long start = System.nanoTime() / 1000000L;
|
long start = System.nanoTime() / 1000000L;
|
||||||
for (int i = pathPosition - 10; i < pathPosition + 10; i++) {
|
for (int i = pathPosition - 10; i < pathPosition + 10; i++) {
|
||||||
if (i >= 0 && i < path.movements().size()) {
|
if (i < 0 || i >= path.movements().size()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
Movement m = path.movements().get(i);
|
Movement m = path.movements().get(i);
|
||||||
HashSet<BlockPos> prevBreak = new HashSet<>(m.toBreak());
|
HashSet<BlockPos> prevBreak = new HashSet<>(m.toBreak());
|
||||||
HashSet<BlockPos> prevPlace = new HashSet<>(m.toPlace());
|
HashSet<BlockPos> prevPlace = new HashSet<>(m.toPlace());
|
||||||
@ -194,7 +179,6 @@ public class PathExecutor implements Helper {
|
|||||||
recalcBP = true;
|
recalcBP = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (recalcBP) {
|
if (recalcBP) {
|
||||||
HashSet<BlockPos> newBreak = new HashSet<>();
|
HashSet<BlockPos> newBreak = new HashSet<>();
|
||||||
HashSet<BlockPos> newPlace = new HashSet<>();
|
HashSet<BlockPos> newPlace = new HashSet<>();
|
||||||
@ -221,9 +205,7 @@ public class PathExecutor implements Helper {
|
|||||||
for (int i = 1; i < Baritone.settings().costVerificationLookahead.get() && pathPosition + i < path.length() - 1; i++) {
|
for (int i = 1; i < Baritone.settings().costVerificationLookahead.get() && pathPosition + i < path.length() - 1; i++) {
|
||||||
if (path.movements().get(pathPosition + i).calculateCostWithoutCaching() >= ActionCosts.COST_INF) {
|
if (path.movements().get(pathPosition + i).calculateCostWithoutCaching() >= ActionCosts.COST_INF) {
|
||||||
logDebug("Something has changed in the world and a future movement has become impossible. Cancelling.");
|
logDebug("Something has changed in the world and a future movement has become impossible. Cancelling.");
|
||||||
pathPosition = path.length() + 3;
|
cancel();
|
||||||
failed = true;
|
|
||||||
Baritone.INSTANCE.getInputOverrideHandler().clearAllKeys();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -231,108 +213,98 @@ public class PathExecutor implements Helper {
|
|||||||
double currentCost = movement.recalculateCost();
|
double currentCost = movement.recalculateCost();
|
||||||
if (currentCost >= ActionCosts.COST_INF) {
|
if (currentCost >= ActionCosts.COST_INF) {
|
||||||
logDebug("Something has changed in the world and this movement has become impossible. Cancelling.");
|
logDebug("Something has changed in the world and this movement has become impossible. Cancelling.");
|
||||||
pathPosition = path.length() + 3;
|
cancel();
|
||||||
failed = true;
|
|
||||||
Baritone.INSTANCE.getInputOverrideHandler().clearAllKeys();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!movement.calculatedWhileLoaded() && currentCost - currentMovementInitialCostEstimate > Baritone.settings().maxCostIncrease.get()) {
|
if (!movement.calculatedWhileLoaded() && currentCost - currentMovementInitialCostEstimate > Baritone.settings().maxCostIncrease.get()) {
|
||||||
logDebug("Original cost " + currentMovementInitialCostEstimate + " current cost " + currentCost + ". Cancelling.");
|
logDebug("Original cost " + currentMovementInitialCostEstimate + " current cost " + currentCost + ". Cancelling.");
|
||||||
pathPosition = path.length() + 3;
|
cancel();
|
||||||
failed = true;
|
|
||||||
Baritone.INSTANCE.getInputOverrideHandler().clearAllKeys();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
player().capabilities.allowFlying = false;
|
|
||||||
MovementState.MovementStatus movementStatus = movement.update();
|
MovementState.MovementStatus movementStatus = movement.update();
|
||||||
if (movementStatus == UNREACHABLE || movementStatus == FAILED) {
|
if (movementStatus == UNREACHABLE || movementStatus == FAILED) {
|
||||||
logDebug("Movement returns status " + movementStatus);
|
logDebug("Movement returns status " + movementStatus);
|
||||||
pathPosition = path.length() + 3;
|
cancel();
|
||||||
failed = true;
|
|
||||||
Baritone.INSTANCE.getInputOverrideHandler().clearAllKeys();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (movementStatus == SUCCESS) {
|
if (movementStatus == SUCCESS) {
|
||||||
//System.out.println("Movement done, next path");
|
//System.out.println("Movement done, next path");
|
||||||
pathPosition++;
|
pathPosition++;
|
||||||
ticksOnCurrent = 0;
|
ticksOnCurrent = 0;
|
||||||
Baritone.INSTANCE.getInputOverrideHandler().clearAllKeys();
|
clearKeys();
|
||||||
onTick(event);
|
onTick(event);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
sprintIfRequested();
|
sprintIfRequested();
|
||||||
ticksOnCurrent++;
|
ticksOnCurrent++;
|
||||||
if (ticksOnCurrent > currentMovementInitialCostEstimate + Baritone.settings().movementTimeoutTicks.get()) {
|
if (ticksOnCurrent > currentMovementInitialCostEstimate + Baritone.settings().movementTimeoutTicks.get()) {
|
||||||
// only fail if the total time has exceeded the initial estimate
|
// only cancel if the total time has exceeded the initial estimate
|
||||||
// as you break the blocks required, the remaining cost goes down, to the point where
|
// as you break the blocks required, the remaining cost goes down, to the point where
|
||||||
// ticksOnCurrent is greater than recalculateCost + 100
|
// ticksOnCurrent is greater than recalculateCost + 100
|
||||||
// this is why we cache cost at the beginning, and don't recalculate for this comparison every tick
|
// this is why we cache cost at the beginning, and don't recalculate for this comparison every tick
|
||||||
logDebug("This movement has taken too long (" + ticksOnCurrent + " ticks, expected " + currentMovementInitialCostEstimate + "). Cancelling.");
|
logDebug("This movement has taken too long (" + ticksOnCurrent + " ticks, expected " + currentMovementInitialCostEstimate + "). Cancelling.");
|
||||||
movement.cancel();
|
cancel();
|
||||||
Baritone.INSTANCE.getInputOverrideHandler().clearAllKeys();
|
|
||||||
pathPosition = path.length() + 3;
|
|
||||||
failed = true;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false; // movement is in progress
|
return false; // movement is in progress
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean possiblyOffPath(Tuple<Double, BlockPos> status, double leniency) {
|
||||||
|
double distanceFromPath = status.getFirst();
|
||||||
|
if (distanceFromPath > leniency) {
|
||||||
|
// when we're midair in the middle of a fall, we're very far from both the beginning and the end, but we aren't actually off path
|
||||||
|
if (path.movements().get(pathPosition) instanceof MovementFall) {
|
||||||
|
BlockPos fallDest = path.positions().get(pathPosition + 1); // .get(pathPosition) is the block we fell off of
|
||||||
|
if (Utils.playerFlatDistanceToCenter(fallDest) < 0.5) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void sprintIfRequested() {
|
private void sprintIfRequested() {
|
||||||
|
|
||||||
|
// first and foremost, if allowSprint is off, or if we don't have enough hunger, don't try and sprint
|
||||||
if (!new CalculationContext().canSprint()) {
|
if (!new CalculationContext().canSprint()) {
|
||||||
player().setSprinting(false);
|
player().setSprinting(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if the movement requested sprinting, then we're done
|
||||||
if (Baritone.INSTANCE.getInputOverrideHandler().isInputForcedDown(mc.gameSettings.keyBindSprint)) {
|
if (Baritone.INSTANCE.getInputOverrideHandler().isInputForcedDown(mc.gameSettings.keyBindSprint)) {
|
||||||
if (!player().isSprinting()) {
|
if (!player().isSprinting()) {
|
||||||
player().setSprinting(true);
|
player().setSprinting(true);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Movement movement = path.movements().get(pathPosition);
|
|
||||||
if (movement instanceof MovementDescend && pathPosition < path.length() - 2) {
|
// however, descend doesn't request sprinting, beceause it doesn't know the context of what movement comes after it
|
||||||
BlockPos descendStart = movement.getSrc();
|
Movement current = path.movements().get(pathPosition);
|
||||||
BlockPos descendEnd = movement.getDest();
|
if (current instanceof MovementDescend && pathPosition < path.length() - 2) {
|
||||||
BlockPos into = descendEnd.subtract(descendStart.down()).add(descendEnd);
|
|
||||||
if (into.getY() != descendEnd.getY()) {
|
// (dest - src) + dest is offset 1 more in the same direction
|
||||||
throw new IllegalStateException(); // sanity check
|
// so it's the block we'd need to worry about running into if we decide to sprint straight through this descend
|
||||||
}
|
|
||||||
for (int i = 0; i <= 2; i++) {
|
BlockPos into = current.getDest().subtract(current.getSrc().down()).add(current.getDest());
|
||||||
if (MovementHelper.avoidWalkingInto(BlockStateInterface.getBlock(into.up(i)))) {
|
for (int y = 0; y <= 2; y++) { // we could hit any of the three blocks
|
||||||
|
if (MovementHelper.avoidWalkingInto(BlockStateInterface.getBlock(into.up(y)))) {
|
||||||
logDebug("Sprinting would be unsafe");
|
logDebug("Sprinting would be unsafe");
|
||||||
player().setSprinting(false);
|
player().setSprinting(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Movement next = path.movements().get(pathPosition + 1);
|
Movement next = path.movements().get(pathPosition + 1);
|
||||||
if (next instanceof MovementDescend) {
|
if (canSprintInto(current, next)) {
|
||||||
if (next.getDirection().equals(movement.getDirection())) {
|
if (playerFeet().equals(current.getDest())) {
|
||||||
if (playerFeet().equals(movement.getDest())) {
|
|
||||||
pathPosition++;
|
pathPosition++;
|
||||||
Baritone.INSTANCE.getInputOverrideHandler().clearAllKeys();
|
clearKeys();
|
||||||
}
|
|
||||||
if (!player().isSprinting()) {
|
|
||||||
player().setSprinting(true);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (next instanceof MovementTraverse) {
|
|
||||||
if (next.getDirection().down().equals(movement.getDirection()) && MovementHelper.canWalkOn(next.getDest().down())) {
|
|
||||||
if (playerFeet().equals(movement.getDest())) {
|
|
||||||
pathPosition++;
|
|
||||||
Baritone.INSTANCE.getInputOverrideHandler().clearAllKeys();
|
|
||||||
}
|
|
||||||
if (!player().isSprinting()) {
|
|
||||||
player().setSprinting(true);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (next instanceof MovementDiagonal && Baritone.settings().allowOvershootDiagonalDescend.get()) {
|
|
||||||
if (playerFeet().equals(movement.getDest())) {
|
|
||||||
pathPosition++;
|
|
||||||
Baritone.INSTANCE.getInputOverrideHandler().clearAllKeys();
|
|
||||||
}
|
}
|
||||||
if (!player().isSprinting()) {
|
if (!player().isSprinting()) {
|
||||||
player().setSprinting(true);
|
player().setSprinting(true);
|
||||||
@ -344,6 +316,34 @@ public class PathExecutor implements Helper {
|
|||||||
player().setSprinting(false);
|
player().setSprinting(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean canSprintInto(Movement current, Movement next) {
|
||||||
|
if (next instanceof MovementDescend) {
|
||||||
|
if (next.getDirection().equals(current.getDirection())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (next instanceof MovementTraverse) {
|
||||||
|
if (next.getDirection().down().equals(current.getDirection()) && MovementHelper.canWalkOn(next.getDest().down())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (next instanceof MovementDiagonal && Baritone.settings().allowOvershootDiagonalDescend.get()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void clearKeys() {
|
||||||
|
// i'm just sick and tired of this snippet being everywhere lol
|
||||||
|
Baritone.INSTANCE.getInputOverrideHandler().clearAllKeys();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cancel() {
|
||||||
|
clearKeys();
|
||||||
|
pathPosition = path.length() + 3;
|
||||||
|
failed = true;
|
||||||
|
}
|
||||||
|
|
||||||
public int getPosition() {
|
public int getPosition() {
|
||||||
return pathPosition;
|
return pathPosition;
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,6 @@
|
|||||||
package baritone.utils;
|
package baritone.utils;
|
||||||
|
|
||||||
import net.minecraft.client.settings.KeyBinding;
|
import net.minecraft.client.settings.KeyBinding;
|
||||||
import org.lwjgl.input.Keyboard;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -134,7 +133,7 @@ public final class InputOverrideHandler implements Helper {
|
|||||||
/**
|
/**
|
||||||
* The actual game {@link KeyBinding} being forced.
|
* The actual game {@link KeyBinding} being forced.
|
||||||
*/
|
*/
|
||||||
private KeyBinding keyBinding;
|
private final KeyBinding keyBinding;
|
||||||
|
|
||||||
Input(KeyBinding keyBinding) {
|
Input(KeyBinding keyBinding) {
|
||||||
this.keyBinding = keyBinding;
|
this.keyBinding = keyBinding;
|
||||||
|
@ -19,6 +19,7 @@ package baritone.utils;
|
|||||||
|
|
||||||
import net.minecraft.block.BlockFire;
|
import net.minecraft.block.BlockFire;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
|
import net.minecraft.client.entity.EntityPlayerSP;
|
||||||
import net.minecraft.util.math.AxisAlignedBB;
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.MathHelper;
|
import net.minecraft.util.math.MathHelper;
|
||||||
@ -112,6 +113,16 @@ public final class Utils {
|
|||||||
return Math.sqrt(xdiff * xdiff + ydiff * ydiff + zdiff * zdiff);
|
return Math.sqrt(xdiff * xdiff + ydiff * ydiff + zdiff * zdiff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static double playerDistanceToCenter(BlockPos pos) {
|
||||||
|
EntityPlayerSP player = (new Helper() {}).player();
|
||||||
|
return distanceToCenter(pos, player.posX, player.posY, player.posZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double playerFlatDistanceToCenter(BlockPos pos) {
|
||||||
|
EntityPlayerSP player = (new Helper() {}).player();
|
||||||
|
return distanceToCenter(pos, player.posX, pos.getY() + 0.5, player.posZ);
|
||||||
|
}
|
||||||
|
|
||||||
public static double degToRad(double deg) {
|
public static double degToRad(double deg) {
|
||||||
return deg * DEG_TO_RAD;
|
return deg * DEG_TO_RAD;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user