001/* 002 * This file is part of Baritone. 003 * 004 * Baritone is free software: you can redistribute it and/or modify 005 * it under the terms of the GNU Lesser General Public License as published by 006 * the Free Software Foundation, either version 3 of the License, or 007 * (at your option) any later version. 008 * 009 * Baritone is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 012 * GNU Lesser General Public License for more details. 013 * 014 * You should have received a copy of the GNU Lesser General Public License 015 * along with Baritone. If not, see <https://www.gnu.org/licenses/>. 016 */ 017 018package baritone.api.pathing.goals; 019 020import baritone.api.BaritoneAPI; 021import baritone.api.utils.BetterBlockPos; 022import baritone.api.utils.SettingsUtil; 023import net.minecraft.util.math.MathHelper; 024import net.minecraft.util.math.Vec3d; 025 026/** 027 * Useful for long-range goals that don't have a specific Y level. 028 * 029 * @author leijurv 030 */ 031public class GoalXZ implements Goal { 032 033 private static final double SQRT_2 = Math.sqrt(2); 034 035 /** 036 * The X block position of this goal 037 */ 038 private final int x; 039 040 /** 041 * The Z block position of this goal 042 */ 043 private final int z; 044 045 public GoalXZ(int x, int z) { 046 this.x = x; 047 this.z = z; 048 } 049 050 public GoalXZ(BetterBlockPos pos) { 051 this.x = pos.x; 052 this.z = pos.z; 053 } 054 055 @Override 056 public boolean isInGoal(int x, int y, int z) { 057 return x == this.x && z == this.z; 058 } 059 060 @Override 061 public double heuristic(int x, int y, int z) {//mostly copied from GoalBlock 062 int xDiff = x - this.x; 063 int zDiff = z - this.z; 064 return calculate(xDiff, zDiff); 065 } 066 067 @Override 068 public String toString() { 069 return String.format( 070 "GoalXZ{x=%s,z=%s}", 071 SettingsUtil.maybeCensor(x), 072 SettingsUtil.maybeCensor(z) 073 ); 074 } 075 076 public static double calculate(double xDiff, double zDiff) { 077 //This is a combination of pythagorean and manhattan distance 078 //It takes into account the fact that pathing can either walk diagonally or forwards 079 080 //It's not possible to walk forward 1 and right 2 in sqrt(5) time 081 //It's really 1+sqrt(2) because it'll walk forward 1 then diagonally 1 082 double x = Math.abs(xDiff); 083 double z = Math.abs(zDiff); 084 double straight; 085 double diagonal; 086 if (x < z) { 087 straight = z - x; 088 diagonal = x; 089 } else { 090 straight = x - z; 091 diagonal = z; 092 } 093 diagonal *= SQRT_2; 094 return (diagonal + straight) * BaritoneAPI.getSettings().costHeuristic.value; // big TODO tune 095 } 096 097 public static GoalXZ fromDirection(Vec3d origin, float yaw, double distance) { 098 float theta = (float) Math.toRadians(yaw); 099 double x = origin.x - MathHelper.sin(theta) * distance; 100 double z = origin.z + MathHelper.cos(theta) * distance; 101 return new GoalXZ(MathHelper.floor(x), MathHelper.floor(z)); 102 } 103 104 public int getX() { 105 return x; 106 } 107 108 public int getZ() { 109 return z; 110 } 111}