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.utils.SettingsUtil;
021import baritone.api.utils.interfaces.IGoalRenderPos;
022import net.minecraft.util.math.BlockPos;
023
024/**
025 * A specific BlockPos goal
026 *
027 * @author leijurv
028 */
029public class GoalBlock implements Goal, IGoalRenderPos {
030
031    /**
032     * The X block position of this goal
033     */
034    public final int x;
035
036    /**
037     * The Y block position of this goal
038     */
039    public final int y;
040
041    /**
042     * The Z block position of this goal
043     */
044    public final int z;
045
046    public GoalBlock(BlockPos pos) {
047        this(pos.getX(), pos.getY(), pos.getZ());
048    }
049
050    public GoalBlock(int x, int y, int z) {
051        this.x = x;
052        this.y = y;
053        this.z = z;
054    }
055
056    @Override
057    public boolean isInGoal(int x, int y, int z) {
058        return x == this.x && y == this.y && z == this.z;
059    }
060
061    @Override
062    public double heuristic(int x, int y, int z) {
063        int xDiff = x - this.x;
064        int yDiff = y - this.y;
065        int zDiff = z - this.z;
066        return calculate(xDiff, yDiff, zDiff);
067    }
068
069    @Override
070    public String toString() {
071        return String.format(
072                "GoalBlock{x=%s,y=%s,z=%s}",
073                SettingsUtil.maybeCensor(x),
074                SettingsUtil.maybeCensor(y),
075                SettingsUtil.maybeCensor(z)
076        );
077    }
078
079    /**
080     * @return The position of this goal as a {@link BlockPos}
081     */
082    @Override
083    public BlockPos getGoalPos() {
084        return new BlockPos(x, y, z);
085    }
086
087    public static double calculate(double xDiff, int yDiff, double zDiff) {
088        double heuristic = 0;
089
090        // if yDiff is 1 that means that currentY-goalY==1 which means that we're 1 block above where we should be
091        // therefore going from 0,yDiff,0 to a GoalYLevel of 0 is accurate
092        heuristic += GoalYLevel.calculate(0, yDiff);
093
094        //use the pythagorean and manhattan mixture from GoalXZ
095        heuristic += GoalXZ.calculate(xDiff, zDiff);
096        return heuristic;
097    }
098}