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.utils;
019
020import net.minecraft.block.BlockFire;
021import net.minecraft.block.state.IBlockState;
022import net.minecraft.entity.Entity;
023import net.minecraft.util.math.AxisAlignedBB;
024import net.minecraft.util.math.BlockPos;
025import net.minecraft.util.math.Vec3d;
026import net.minecraft.world.World;
027
028/**
029 * @author Brady
030 * @since 10/13/2018
031 */
032public final class VecUtils {
033
034    private VecUtils() {}
035
036    /**
037     * Calculates the center of the block at the specified position's bounding box
038     *
039     * @param world The world that the block is in, used to provide the bounding box
040     * @param pos   The block position
041     * @return The center of the block's bounding box
042     * @see #getBlockPosCenter(BlockPos)
043     */
044    public static Vec3d calculateBlockCenter(World world, BlockPos pos) {
045        IBlockState b = world.getBlockState(pos);
046        AxisAlignedBB bbox = b.getBoundingBox(world, pos);
047        double xDiff = (bbox.minX + bbox.maxX) / 2;
048        double yDiff = (bbox.minY + bbox.maxY) / 2;
049        double zDiff = (bbox.minZ + bbox.maxZ) / 2;
050        if (b.getBlock() instanceof BlockFire) {//look at bottom of fire when putting it out
051            yDiff = 0;
052        }
053        return new Vec3d(
054                pos.getX() + xDiff,
055                pos.getY() + yDiff,
056                pos.getZ() + zDiff
057        );
058    }
059
060    /**
061     * Gets the assumed center position of the given block position.
062     * This is done by adding 0.5 to the X, Y, and Z axes.
063     * <p>
064     * TODO: We may want to consider replacing many usages of this method with #calculateBlockCenter(BlockPos)
065     *
066     * @param pos The block position
067     * @return The assumed center of the position
068     * @see #calculateBlockCenter(World, BlockPos)
069     */
070    public static Vec3d getBlockPosCenter(BlockPos pos) {
071        return new Vec3d(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5);
072    }
073
074    /**
075     * Gets the distance from the specified position to the assumed center of the specified block position.
076     *
077     * @param pos The block position
078     * @param x   The x pos
079     * @param y   The y pos
080     * @param z   The z pos
081     * @return The distance from the assumed block center to the position
082     * @see #getBlockPosCenter(BlockPos)
083     */
084    public static double distanceToCenter(BlockPos pos, double x, double y, double z) {
085        double xdiff = pos.getX() + 0.5 - x;
086        double ydiff = pos.getY() + 0.5 - y;
087        double zdiff = pos.getZ() + 0.5 - z;
088        return Math.sqrt(xdiff * xdiff + ydiff * ydiff + zdiff * zdiff);
089    }
090
091    /**
092     * Gets the distance from the specified entity's position to the assumed
093     * center of the specified block position.
094     *
095     * @param entity The entity
096     * @param pos    The block position
097     * @return The distance from the entity to the block's assumed center
098     * @see #getBlockPosCenter(BlockPos)
099     */
100    public static double entityDistanceToCenter(Entity entity, BlockPos pos) {
101        return distanceToCenter(pos, entity.posX, entity.posY, entity.posZ);
102    }
103
104    /**
105     * Gets the distance from the specified entity's position to the assumed
106     * center of the specified block position, ignoring the Y axis.
107     *
108     * @param entity The entity
109     * @param pos    The block position
110     * @return The horizontal distance from the entity to the block's assumed center
111     * @see #getBlockPosCenter(BlockPos)
112     */
113    public static double entityFlatDistanceToCenter(Entity entity, BlockPos pos) {
114        return distanceToCenter(pos, entity.posX, pos.getY() + 0.5, entity.posZ);
115    }
116}