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