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 baritone.api.cache.IWorldData; 021import net.minecraft.block.BlockSlab; 022import net.minecraft.client.entity.EntityPlayerSP; 023import net.minecraft.util.math.BlockPos; 024import net.minecraft.util.math.RayTraceResult; 025import net.minecraft.util.math.Vec3d; 026import net.minecraft.world.World; 027 028import java.util.Optional; 029 030/** 031 * @author Brady 032 * @since 11/12/2018 033 */ 034public interface IPlayerContext { 035 036 EntityPlayerSP player(); 037 038 IPlayerController playerController(); 039 040 World world(); 041 042 IWorldData worldData(); 043 044 RayTraceResult objectMouseOver(); 045 046 default BetterBlockPos playerFeet() { 047 // TODO find a better way to deal with soul sand!!!!! 048 BetterBlockPos feet = new BetterBlockPos(player().posX, player().posY + 0.1251, player().posZ); 049 050 // sometimes when calling this from another thread or while world is null, it'll throw a NullPointerException 051 // that causes the game to immediately crash 052 // 053 // so of course crashing on 2b is horribly bad due to queue times and logout spot 054 // catch the NPE and ignore it if it does happen 055 // 056 // this does not impact performance at all since we're not null checking constantly 057 // if there is an exception, the only overhead is Java generating the exception object... so we can ignore it 058 try { 059 if (world().getBlockState(feet).getBlock() instanceof BlockSlab) { 060 return feet.up(); 061 } 062 } catch (NullPointerException ignored) {} 063 064 return feet; 065 } 066 067 default Vec3d playerFeetAsVec() { 068 return new Vec3d(player().posX, player().posY, player().posZ); 069 } 070 071 default Vec3d playerHead() { 072 return new Vec3d(player().posX, player().posY + player().getEyeHeight(), player().posZ); 073 } 074 075 default Rotation playerRotations() { 076 return new Rotation(player().rotationYaw, player().rotationPitch); 077 } 078 079 static double eyeHeight(boolean ifSneaking) { 080 return ifSneaking ? 1.54 : 1.62; 081 } 082 083 /** 084 * Returns the block that the crosshair is currently placed over. Updated once per tick. 085 * 086 * @return The position of the highlighted block 087 */ 088 default Optional<BlockPos> getSelectedBlock() { 089 RayTraceResult result = objectMouseOver(); 090 if (result != null && result.typeOfHit == RayTraceResult.Type.BLOCK) { 091 return Optional.of(result.getBlockPos()); 092 } 093 return Optional.empty(); 094 } 095 096 default boolean isLookingAt(BlockPos pos) { 097 return getSelectedBlock().equals(Optional.of(pos)); 098 } 099}