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.BetterBlockPos;
021import baritone.api.utils.SettingsUtil;
022import net.minecraft.core.BlockPos;
023import net.minecraft.core.Direction;
024
025/**
026 * Dig a tunnel in a certain direction, but if you have to deviate from the path, go back to where you started
027 */
028public class GoalStrictDirection implements Goal {
029
030    public final int x;
031    public final int y;
032    public final int z;
033    public final int dx;
034    public final int dz;
035
036    public GoalStrictDirection(BlockPos origin, Direction direction) {
037        x = origin.getX();
038        y = origin.getY();
039        z = origin.getZ();
040        dx = direction.getStepX();
041        dz = direction.getStepZ();
042        if (dx == 0 && dz == 0) {
043            throw new IllegalArgumentException(direction + "");
044        }
045    }
046
047    @Override
048    public boolean isInGoal(int x, int y, int z) {
049        return false;
050    }
051
052    @Override
053    public double heuristic(int x, int y, int z) {
054        int distanceFromStartInDesiredDirection = (x - this.x) * dx + (z - this.z) * dz;
055
056        int distanceFromStartInIncorrectDirection = Math.abs((x - this.x) * dz) + Math.abs((z - this.z) * dx);
057
058        int verticalDistanceFromStart = Math.abs(y - this.y);
059
060        // we want heuristic to decrease as desiredDirection increases
061        double heuristic = -distanceFromStartInDesiredDirection * 100;
062
063        heuristic += distanceFromStartInIncorrectDirection * 1000;
064        heuristic += verticalDistanceFromStart * 1000;
065        return heuristic;
066    }
067
068    @Override
069    public double heuristic() {
070        return Double.NEGATIVE_INFINITY;
071    }
072
073    @Override
074    public boolean equals(Object o) {
075        if (this == o) {
076            return true;
077        }
078        if (o == null || getClass() != o.getClass()) {
079            return false;
080        }
081
082        GoalStrictDirection goal = (GoalStrictDirection) o;
083        return x == goal.x
084                && y == goal.y
085                && z == goal.z
086                && dx == goal.dx
087                && dz == goal.dz;
088    }
089
090    @Override
091    public int hashCode() {
092        int hash = (int) BetterBlockPos.longHash(x, y, z);
093        hash = hash * 630627507 + dx;
094        hash = hash * -283028380 + dz;
095        return hash;
096    }
097
098    @Override
099    public String toString() {
100        return String.format(
101                "GoalStrictDirection{x=%s, y=%s, z=%s, dx=%s, dz=%s}",
102                SettingsUtil.maybeCensor(x),
103                SettingsUtil.maybeCensor(y),
104                SettingsUtil.maybeCensor(z),
105                SettingsUtil.maybeCensor(dx),
106                SettingsUtil.maybeCensor(dz)
107        );
108    }
109}