下面列出了net.minecraft.util.shape.VoxelShape#net.minecraft.util.math.Box 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
public void onEnable()
{
EVENTS.add(UpdateListener.class, this);
EVENTS.add(CameraTransformViewBobbingListener.class, this);
EVENTS.add(RenderListener.class, this);
itemBox = GL11.glGenLists(1);
GL11.glNewList(itemBox, GL11.GL_COMPILE);
GL11.glEnable(GL11.GL_BLEND);
GL11.glDisable(GL11.GL_TEXTURE_2D);
GL11.glDisable(GL11.GL_DEPTH_TEST);
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glColor4f(1, 1, 0, 0.5F);
RenderUtils.drawOutlinedBox(new Box(-0.5, 0, -0.5, 0.5, 1, 0.5));
GL11.glEndList();
}
private void updateCyanList()
{
GL11.glNewList(displayLists[0], GL11.GL_COMPILE);
GL11.glPushMatrix();
GL11.glTranslated(start.getX(), start.getY(), start.getZ());
GL11.glTranslated(0.5, 0.5, 0.5);
GL11.glColor4f(0, 1, 1, 0.5F);
GL11.glBegin(GL11.GL_LINES);
RenderUtils.drawNode(new Box(-0.25, -0.25, -0.25, 0.25, 0.25, 0.25));
GL11.glEnd();
RenderUtils.drawArrow(Vec3d.of(direction.getVector()).multiply(0.25),
Vec3d.of(direction.getVector()).multiply(Math.max(0.5, length)));
GL11.glPopMatrix();
GL11.glEndList();
}
public boolean isOverLiquid()
{
boolean foundLiquid = false;
boolean foundSolid = false;
// check collision boxes below player
ArrayList<Box> blockCollisions = MC.world
.getBlockCollisions(MC.player,
MC.player.getBoundingBox().offset(0, -0.5, 0))
.map(VoxelShape::getBoundingBox)
.collect(Collectors.toCollection(() -> new ArrayList<>()));
for(Box bb : blockCollisions)
{
BlockPos pos = new BlockPos(bb.getCenter());
Material material = BlockUtils.getState(pos).getMaterial();
if(material == Material.WATER || material == Material.LAVA)
foundLiquid = true;
else if(material != Material.AIR)
foundSolid = true;
}
return foundLiquid && !foundSolid;
}
private ArrayList<Box> calculateMinecartBoxes(float partialTicks)
{
ArrayList<Box> minecartBoxes = new ArrayList<>(minecarts.size());
minecarts.forEach(e -> {
double offsetX = -(e.getX() - e.lastRenderX)
+ (e.getX() - e.lastRenderX) * partialTicks;
double offsetY = -(e.getY() - e.lastRenderY)
+ (e.getY() - e.lastRenderY) * partialTicks;
double offsetZ = -(e.getZ() - e.lastRenderZ)
+ (e.getZ() - e.lastRenderZ) * partialTicks;
minecartBoxes
.add(e.getBoundingBox().offset(offsetX, offsetY, offsetZ));
});
return minecartBoxes;
}
@Override
public void onUpdate()
{
if(!MC.player.isOnGround() || MC.options.keyJump.isPressed())
return;
if(MC.player.isSneaking() || MC.options.keySneak.isPressed())
return;
Box box = MC.player.getBoundingBox();
Box adjustedBox = box.offset(0, -0.5, 0).expand(-0.001, 0, -0.001);
Stream<VoxelShape> blockCollisions =
MC.world.getBlockCollisions(MC.player, adjustedBox);
if(blockCollisions.findAny().isPresent())
return;
MC.player.jump();
}
public static void drawFilledBox(Box box, float r, float g, float b, float a) {
gl11Setup();
Vec3d ren = renderPos();
/* Fill */
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBufferBuilder();
buffer.begin(5, VertexFormats.POSITION_COLOR);
WorldRenderer.buildBox(buffer,
box.minX - ren.x, box.minY - ren.y, box.minZ - ren.z,
box.maxX - ren.x, box.maxY - ren.y, box.maxZ - ren.z, r, g, b, a/2f);
tessellator.draw();
/* Outline */
WorldRenderer.drawBoxOutline(new Box(
box.minX - ren.x, box.minY - ren.y, box.minZ - ren.z,
box.maxX - ren.x, box.maxY - ren.y, box.maxZ - ren.z), r, g, b, a);
gl11Cleanup();
}
@Override
public void onEntityCollision(BlockState blockState, World world, BlockPos pos, Entity entity) {
super.onEntityCollision(blockState, world, pos, entity);
if(entity instanceof ItemEntity) {
List<ItemEntity> entities = world.getEntities(ItemEntity.class, new Box(pos), e -> true);
BasicInventory inventory = new BasicInventory(entities.size());
entities.forEach(itemEntity -> { //required for multi-input recipes
ItemStack stack = itemEntity.getStack();
inventory.add(stack);
});
Optional<FluidRecipe> match = world.getRecipeManager()
.getFirstMatch(recipeType, inventory, world);
if (match.isPresent()) {
spawnCraftingResult(world, pos, match.get().craft(inventory));
for (Ingredient ingredient : match.get().getIngredients()) {
for (ItemEntity testEntity : entities) {
if (ingredient.test(testEntity.getStack())) {
testEntity.getStack().decrement(1);
break;
}
}
}
}
}
}
@Override
public void onUpdate()
{
ClientPlayerEntity player = MC.player;
Vec3d v = player.getVelocity();
if(player.isOnGround() || player.isTouchingWater() || player.isInLava()
|| player.isClimbing() || v.y >= 0)
return;
if(minHeight.getValue() > 0)
{
Box box = player.getBoundingBox();
box = box.union(box.offset(0, -minHeight.getValue(), 0));
if(!MC.world.doesNotCollide(box))
return;
BlockPos min =
new BlockPos(new Vec3d(box.minX, box.minY, box.minZ));
BlockPos max =
new BlockPos(new Vec3d(box.maxX, box.maxY, box.maxZ));
Stream<BlockPos> stream = StreamSupport
.stream(BlockUtils.getAllInBox(min, max).spliterator(), true);
// manual collision check, since liquids don't have bounding boxes
if(stream.map(BlockUtils::getState).map(BlockState::getMaterial)
.anyMatch(Material::isLiquid))
return;
}
player.setVelocity(v.x, Math.max(v.y, -fallSpeed.getValue()), v.z);
player.flyingSpeed *= moveSpeed.getValueF();
}
@Override
public void onEnable()
{
EVENTS.add(UpdateListener.class, this);
EVENTS.add(PacketOutputListener.class, this);
EVENTS.add(IsPlayerInWaterListener.class, this);
EVENTS.add(PlayerMoveListener.class, this);
EVENTS.add(CameraTransformViewBobbingListener.class, this);
EVENTS.add(IsNormalCubeListener.class, this);
EVENTS.add(SetOpaqueCubeListener.class, this);
EVENTS.add(RenderListener.class, this);
fakePlayer = new FakePlayerEntity();
GameOptions gs = MC.options;
KeyBinding[] bindings = {gs.keyForward, gs.keyBack, gs.keyLeft,
gs.keyRight, gs.keyJump, gs.keySneak};
for(KeyBinding binding : bindings)
binding.setPressed(((IKeyBinding)binding).isActallyPressed());
playerBox = GL11.glGenLists(1);
GL11.glNewList(playerBox, GL11.GL_COMPILE);
Box bb = new Box(-0.5, 0, -0.5, 0.5, 1, 0.5);
RenderUtils.drawOutlinedBox(bb);
GL11.glEndList();
}
@Override
public void onEnable()
{
EVENTS.add(UpdateListener.class, this);
EVENTS.add(CameraTransformViewBobbingListener.class, this);
EVENTS.add(RenderListener.class, this);
playerBox = GL11.glGenLists(1);
GL11.glNewList(playerBox, GL11.GL_COMPILE);
Box bb = new Box(-0.5, 0, -0.5, 0.5, 1, 0.5);
RenderUtils.drawOutlinedBox(bb);
GL11.glEndList();
}
@Override
public void onEnable()
{
EVENTS.add(UpdateListener.class, this);
EVENTS.add(CameraTransformViewBobbingListener.class, this);
EVENTS.add(RenderListener.class, this);
mobBox = GL11.glGenLists(1);
GL11.glNewList(mobBox, GL11.GL_COMPILE);
Box bb = new Box(-0.5, 0, -0.5, 0.5, 1, 0.5);
RenderUtils.drawOutlinedBox(bb);
GL11.glEndList();
}
private void setupDisplayLists()
{
Box box = new Box(BlockPos.ORIGIN);
greenBox = GL11.glGenLists(1);
GL11.glNewList(greenBox, GL11.GL_COMPILE);
GL11.glColor4f(0, 1, 0, 0.25F);
RenderUtils.drawSolidBox(box);
GL11.glColor4f(0, 1, 0, 0.5F);
RenderUtils.drawOutlinedBox(box);
GL11.glEndList();
orangeBox = GL11.glGenLists(1);
GL11.glNewList(orangeBox, GL11.GL_COMPILE);
GL11.glColor4f(1, 0.5F, 0, 0.25F);
RenderUtils.drawSolidBox(box);
GL11.glColor4f(1, 0.5F, 0, 0.5F);
RenderUtils.drawOutlinedBox(box);
GL11.glEndList();
cyanBox = GL11.glGenLists(1);
GL11.glNewList(cyanBox, GL11.GL_COMPILE);
GL11.glColor4f(0, 1, 1, 0.25F);
RenderUtils.drawSolidBox(box);
GL11.glColor4f(0, 1, 1, 0.5F);
RenderUtils.drawOutlinedBox(box);
GL11.glEndList();
purpleBox = GL11.glGenLists(1);
GL11.glNewList(purpleBox, GL11.GL_COMPILE);
GL11.glColor4f(1, 0, 1, 0.25F);
RenderUtils.drawSolidBox(box);
GL11.glColor4f(1, 0, 1, 0.5F);
RenderUtils.drawOutlinedBox(box);
GL11.glEndList();
normalChests = GL11.glGenLists(1);
}
private Box getBoxFromChest(ChestBlockEntity chestBE)
{
BlockState state = chestBE.getCachedState();
if(!state.contains(ChestBlock.CHEST_TYPE))
return null;
ChestType chestType = state.get(ChestBlock.CHEST_TYPE);
// ignore other block in double chest
if(chestType == ChestType.LEFT)
return null;
BlockPos pos = chestBE.getPos();
if(!BlockUtils.canBeClicked(pos))
return null;
Box box = BlockUtils.getBoundingBox(pos);
// larger box for double chest
if(chestType != ChestType.SINGLE)
{
BlockPos pos2 = pos.offset(ChestBlock.getFacing(state));
if(BlockUtils.canBeClicked(pos2))
{
Box box2 = BlockUtils.getBoundingBox(pos2);
box = box.union(box2);
}
}
return box;
}
private void renderBoxes(ArrayList<Box> boxes, int displayList)
{
for(Box box : boxes)
{
GL11.glPushMatrix();
GL11.glTranslated(box.minX, box.minY, box.minZ);
GL11.glScaled(box.maxX - box.minX, box.maxY - box.minY,
box.maxZ - box.minZ);
GL11.glCallList(displayList);
GL11.glPopMatrix();
}
}
private void renderLines(Vec3d start, ArrayList<Box> boxes)
{
for(Box box : boxes)
{
Vec3d end = box.getCenter();
GL11.glVertex3d(start.x, start.y, start.z);
GL11.glVertex3d(end.x, end.y, end.z);
}
}
private boolean faceEntityClient(LivingEntity entity)
{
// get position & rotation
Vec3d eyesPos = RotationUtils.getEyesPos();
Vec3d lookVec = RotationUtils.getServerLookVec();
// try to face center of boundingBox
Box bb = entity.getBoundingBox();
if(faceVectorClient(bb.getCenter()))
return true;
// if not facing center, check if facing anything in boundingBox
return bb.rayTrace(eyesPos,
eyesPos.add(lookVec.multiply(range.getValue()))) != null;
}
@Override
protected ItemStack dispenseSilently(BlockPointer source, ItemStack stack)
{
if (!CarpetExtraSettings.dispensersFillMinecarts)
{
return defaultBehaviour(source, stack);
}
else
{
BlockPos pos = source.getBlockPos().offset((Direction) source.getBlockState().get(DispenserBlock.FACING));
List<MinecartEntity> list = source.getWorld().<MinecartEntity>getEntities(MinecartEntity.class, new Box(pos), null);
if (list.isEmpty())
{
return defaultBehaviour(source, stack);
}
else
{
MinecartEntity minecart = list.get(0);
minecart.remove();
AbstractMinecartEntity minecartEntity = AbstractMinecartEntity.create(minecart.world, minecart.getX(), minecart.getY(), minecart.getZ(), this.minecartType);
minecartEntity.setVelocity(minecart.getVelocity());
minecartEntity.pitch = minecart.pitch;
minecartEntity.yaw = minecart.yaw;
minecart.world.spawnEntity(minecartEntity);
stack.decrement(1);
return stack;
}
}
}
@Override
protected ItemStack dispenseSilently(BlockPointer source, ItemStack stack) {
BlockPos pos = source.getBlockPos().offset((Direction) source.getBlockState().get(DispenserBlock.FACING));
List<AnimalEntity> list = source.getWorld().getEntities(AnimalEntity.class, new Box(pos),null);
boolean failure = false;
for(AnimalEntity mob : list) {
if(!mob.isBreedingItem(stack)) continue;
if(mob.getBreedingAge() != 0 || mob.isInLove()) {
failure = true;
continue;
}
stack.decrement(1);
mob.lovePlayer(null);
return stack;
}
if(failure) return stack;
// fix here for now - if problem shows up next time, will need to fix it one level above.
if(
CarpetExtraSettings.dispenserPlacesBlocks &&
stack.getItem() instanceof BlockItem &&
PlaceBlockDispenserBehavior.canPlace(((BlockItem) stack.getItem()).getBlock())
)
{
return PlaceBlockDispenserBehavior.getInstance().dispenseSilently(source, stack);
}
else
{
return super.dispenseSilently(source, stack);
}
}
@Inject(
method = "toTag",
at = @At(value = "INVOKE", shift = At.Shift.BEFORE, ordinal = 0,
target = "Lnet/minecraft/nbt/CompoundTag;put(Ljava/lang/String;Lnet/minecraft/nbt/Tag;)Lnet/minecraft/nbt/Tag;")
)
private void onToTag(CompoundTag compoundTag_1, CallbackInfoReturnable<CompoundTag> cir)
{
if (CarpetExtraSettings.reloadSuffocationFix)
{
Box box = this.getBoundingBox();
compoundTag_1.put("CM_Box", this.toListTag(box.x1, box.y1, box.z1, box.x2, box.y2, box.z2));
}
}
@Inject(
method = "fromTag",
at = @At(value = "INVOKE", shift = At.Shift.AFTER,
target = "Lnet/minecraft/entity/Entity;readCustomDataFromTag(Lnet/minecraft/nbt/CompoundTag;)V")
)
private void onFromTag(CompoundTag compoundTag_1, CallbackInfo ci)
{
if (this.shouldSetPositionOnLoad())
{
this.refreshPosition();
}
if (CarpetExtraSettings.reloadSuffocationFix && compoundTag_1.contains("CM_Box", 9))
{
ListTag box_tag = compoundTag_1.getList("CM_Box", 6);
Box box = new Box(box_tag.getDouble(0), box_tag.getDouble(1),
box_tag.getDouble(2), box_tag.getDouble(3),
box_tag.getDouble(4), box_tag.getDouble(5));
double deltaX = ((box.x1 + box.x2) / 2.0D) - this.x;
double deltaY = box.y1 - this.y;
double deltaZ = ((box.z1 + box.z2) / 2.0D) - this.z;
// Credits: MrGrim (MUP) -> Sanity check.
// If the position and BoundingBox center point are > 0.1 blocks apart then do not restore the BoundingBox. In vanilla
// this should never happen, but mods might not be aware that the BoundingBox is stored and that the entity
// position will be reset to it.
if (((deltaX * deltaX) + (deltaY * deltaY) + (deltaZ * deltaZ)) < 0.01D)
{
this.setBoundingBox(box);
}
}
}
@Inject(
method = "dispenseSilently(Lnet/minecraft/util/math/BlockPointer;Lnet/minecraft/item/ItemStack;)Lnet/minecraft/item/ItemStack;",
at = @At("HEAD"), cancellable = true
)
private void milkCow(BlockPointer pointer, ItemStack stack, CallbackInfoReturnable<ItemStack> cir)
{
if (!CarpetExtraSettings.dispensersMilkCows)
return;
World world = pointer.getWorld();
if (!world.isClient)
{
BlockPos pos = pointer.getBlockPos().offset(pointer.getBlockState().get(DispenserBlock.FACING));
List<CowEntity> cows = world.getEntities(CowEntity.class, new Box(pos), e -> e.isAlive() && !e.isBaby());
if (!cows.isEmpty())
{
stack.decrement(1);
if (stack.isEmpty())
{
cir.setReturnValue(new ItemStack(Items.MILK_BUCKET));
}
else
{
if (((DispenserBlockEntity)pointer.getBlockEntity()).addToFirstFreeSlot(new ItemStack(Items.MILK_BUCKET)) < 0)
{
this.dispense(pointer, new ItemStack(Items.MILK_BUCKET));
}
cir.setReturnValue(stack);
}
}
}
}
public static boolean doesBoxTouchBlock(Box box, Block block) {
for (int x = (int) Math.floor(box.minX); x < Math.ceil(box.maxX); x++) {
for (int y = (int) Math.floor(box.minY); y < Math.ceil(box.maxY); y++) {
for (int z = (int) Math.floor(box.minZ); z < Math.ceil(box.maxZ); z++) {
if (MinecraftClient.getInstance().world.getBlockState(new BlockPos(x, y, z)).getBlock() == block) {
return true;
}
}
}
}
return false;
}
public static boolean isBoxEmpty(Box box) {
for (int x = (int) Math.floor(box.minX); x < Math.ceil(box.maxX); x++) {
for (int y = (int) Math.floor(box.minY); y < Math.ceil(box.maxY); y++) {
for (int z = (int) Math.floor(box.minZ); z < Math.ceil(box.maxZ); z++) {
if (!NONSOLID_BLOCKS.contains(MinecraftClient.getInstance().world.getBlockState(new BlockPos(x, y, z)).getBlock())) {
return false;
}
}
}
}
return true;
}
public static boolean doesBoxTouchBlock(Box box, Block block) {
for (int x = (int) Math.floor(box.minX); x < Math.ceil(box.maxX); x++) {
for (int y = (int) Math.floor(box.minY); y < Math.ceil(box.maxY); y++) {
for (int z = (int) Math.floor(box.minZ); z < Math.ceil(box.maxZ); z++) {
if (MinecraftClient.getInstance().world.getBlockState(new BlockPos(x, y, z)).getBlock() == block) {
return true;
}
}
}
}
return false;
}
public static boolean isBoxEmpty(Box box) {
for (int x = (int) Math.floor(box.minX); x < Math.ceil(box.maxX); x++) {
for (int y = (int) Math.floor(box.minY); y < Math.ceil(box.maxY); y++) {
for (int z = (int) Math.floor(box.minZ); z < Math.ceil(box.maxZ); z++) {
if (!NONSOLID_BLOCKS.contains(MinecraftClient.getInstance().world.getBlockState(new BlockPos(x, y, z)).getBlock())) {
return false;
}
}
}
}
return true;
}
public static void drawFilledBox(Box box, float r, float g, float b, float a) {
gl11Setup();
// Fill
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer();
buffer.begin(5, VertexFormats.POSITION_COLOR);
WorldRenderer.drawBox(buffer,
box.minX, box.minY, box.minZ,
box.maxX, box.maxY, box.maxZ, r, g, b, a/2f);
tessellator.draw();
// Outline
buffer.begin(3, VertexFormats.POSITION_COLOR);
buffer.vertex(box.minX, box.minY, box.minZ).color(r, b, b, a/2f).next();
buffer.vertex(box.minX, box.minY, box.maxZ).color(r, b, b, a/2f).next();
buffer.vertex(box.maxX, box.minY, box.maxZ).color(r, b, b, a/2f).next();
buffer.vertex(box.maxX, box.minY, box.minZ).color(r, b, b, a/2f).next();
buffer.vertex(box.minX, box.minY, box.minZ).color(r, b, b, a/2f).next();
buffer.vertex(box.minX, box.maxY, box.minZ).color(r, b, b, a/2f).next();
buffer.vertex(box.maxX, box.maxY, box.minZ).color(r, b, b, a/2f).next();
buffer.vertex(box.maxX, box.maxY, box.maxZ).color(r, b, b, a/2f).next();
buffer.vertex(box.minX, box.maxY, box.maxZ).color(r, b, b, a/2f).next();
buffer.vertex(box.minX, box.maxY, box.minZ).color(r, b, b, a/2f).next();
buffer.vertex(box.minX, box.minY, box.maxZ).color(r, b, b, 0f).next();
buffer.vertex(box.minX, box.maxY, box.maxZ).color(r, b, b, a/2f).next();
buffer.vertex(box.maxX, box.minY, box.maxZ).color(r, b, b, 0f).next();
buffer.vertex(box.maxX, box.maxY, box.maxZ).color(r, b, b, a/2f).next();
buffer.vertex(box.maxX, box.minY, box.minZ).color(r, b, b, 0f).next();
buffer.vertex(box.maxX, box.maxY, box.minZ).color(r, b, b, a/2f).next();
tessellator.draw();
gl11Cleanup();
}
public static boolean doesBoxTouchBlock(Box box, Block block) {
for (int x = (int) Math.floor(box.x1); x < Math.ceil(box.x2); x++) {
for (int y = (int) Math.floor(box.y1); y < Math.ceil(box.y2); y++) {
for (int z = (int) Math.floor(box.z1); z < Math.ceil(box.z2); z++) {
if (MinecraftClient.getInstance().world.getBlockState(new BlockPos(x, y, z)).getBlock() == block) {
return true;
}
}
}
}
return false;
}
public static boolean isBoxEmpty(Box box) {
for (int x = (int) Math.floor(box.x1); x < Math.ceil(box.x2); x++) {
for (int y = (int) Math.floor(box.y1); y < Math.ceil(box.y2); y++) {
for (int z = (int) Math.floor(box.z1); z < Math.ceil(box.z2); z++) {
if (!NONSOLID_BLOCKS.contains(MinecraftClient.getInstance().world.getBlockState(new BlockPos(x, y, z)).getBlock())) {
return false;
}
}
}
}
return true;
}
public static void drawFilledBox(Box box, float r, float g, float b, float a) {
gl11Setup();
// Fill
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer();
buffer.begin(5, VertexFormats.POSITION_COLOR);
WorldRenderer.drawBox(buffer,
box.x1, box.y1, box.z1,
box.x2, box.y2, box.z2, r, g, b, a/2f);
tessellator.draw();
// Outline
buffer.begin(3, VertexFormats.POSITION_COLOR);
buffer.vertex(box.x1, box.y1, box.z1).color(r, b, b, a/2f).next();
buffer.vertex(box.x1, box.y1, box.z2).color(r, b, b, a/2f).next();
buffer.vertex(box.x2, box.y1, box.z2).color(r, b, b, a/2f).next();
buffer.vertex(box.x2, box.y1, box.z1).color(r, b, b, a/2f).next();
buffer.vertex(box.x1, box.y1, box.z1).color(r, b, b, a/2f).next();
buffer.vertex(box.x1, box.y2, box.z1).color(r, b, b, a/2f).next();
buffer.vertex(box.x2, box.y2, box.z1).color(r, b, b, a/2f).next();
buffer.vertex(box.x2, box.y2, box.z2).color(r, b, b, a/2f).next();
buffer.vertex(box.x1, box.y2, box.z2).color(r, b, b, a/2f).next();
buffer.vertex(box.x1, box.y2, box.z1).color(r, b, b, a/2f).next();
buffer.vertex(box.x1, box.y1, box.z2).color(r, b, b, 0f).next();
buffer.vertex(box.x1, box.y2, box.z2).color(r, b, b, a/2f).next();
buffer.vertex(box.x2, box.y1, box.z2).color(r, b, b, 0f).next();
buffer.vertex(box.x2, box.y2, box.z2).color(r, b, b, a/2f).next();
buffer.vertex(box.x2, box.y1, box.z1).color(r, b, b, 0f).next();
buffer.vertex(box.x2, box.y2, box.z1).color(r, b, b, a/2f).next();
tessellator.draw();
gl11Cleanup();
}
public static EntityHitResult rayTraceEntities(Entity source, float partialTicks, double reach, double maxSqDist)
{
Vec3d pos = source.getCameraPosVec(partialTicks);
Vec3d reachVec = source.getRotationVec(partialTicks).multiply(reach);
Box box = source.getBoundingBox().stretch(reachVec).expand(1);
return rayTraceEntities(source, pos, pos.add(reachVec), box, e -> !e.isSpectator() && e.collides(), maxSqDist);
}