Получить все блоки, которые пересекает мой вектор

Версия Minecraft
1.7.10
1,193
31
182
Есть вектор, с длиной 100 блоков. При создании он пересекает ряд блоков. Как гетнуть все эти блоки? Энтити которых пересечет мой вектор можно взять так
List list = this.mc.theWorld.getEntitiesWithinAABBExcludingEntity(this.mc.renderViewEntity, this.mc.renderViewEntity.boundingBox.addCoord(vec31.xCoord * d0, vec31.yCoord * d0, vec31.zCoord * d0).expand((double)f1, (double)f1, (double)f1));
Есть что то для блоков?
 
Решение
а как ты блоки оранжевым подсветил?
Эвентом RenderWorldLastEvent рендерил кубы.
Вот именно это и нужно.
Тебе методы: rayTrace, getPosition и func_147447_a.
Java:
public class EventsForge {

    ArrayList<MovingObjectPosition> list = null;

    @SubscribeEvent
    public void clientTick(TickEvent.ClientTickEvent event) {
        if (mc.theWorld == null) return;
        list = rayTrace(mc.thePlayer, 100D, 1F);
    }

    @SubscribeEvent
    public void renderTick(RenderWorldLastEvent event) {
        if (list != null && !list.isEmpty()) {
            double x_fix = -(mc.thePlayer.lastTickPosX + (mc.thePlayer.posX - mc.thePlayer.lastTickPosX) * event.partialTicks);
            double y_fix =...

timaxa007

Модератор
5,831
409
672
package net.minecraft.client.renderer;
class EntityRenderer
Метод getMouseOver(float);
Java:
this.mc.objectMouseOver = this.mc.renderViewEntity.rayTrace(d0, p_78473_1_);
Если есть на пересечении блоки:
Java:
                if (this.mc.objectMouseOver != null)
                {
                    d1 = this.mc.objectMouseOver.hitVec.distanceTo(vec3);
                }
Ну или как-то так.
Переделывай под серверную сторону, так как некоторые методы и переменные в getMouseOver являются клиентскими.
 

timaxa007

Модератор
5,831
409
672
Типа переделать rayTrace и не останавливаться на первом, а продолжать. Каждый блок, который он пересечёт, добавить в список или типа того. Я так думаю.
 

timaxa007

Модератор
5,831
409
672
Может кто знает ответ на мой вопрос?
Либо я тебя не понял, либо ты меня не понял.
То как я тебя понял, тебе типа надо этого rayTrace'а:
Оранжевым отмечается Блоки которые на пересечении моего вектора, учитывая что от первого лица не все блоки видны, то я сделал через предмет для их разрушения, чтобы увидеть как это типа со стороны выглядит.
 
1,193
31
182
Вот именно это и нужно. Только мне надо брать не на векторе взгляда, а на измененном векторе взгляда с другими координатами.
Заранее скажу что я копался в ванильке, видимо плохо, но ничего не нашел.. Поэтому обращаюсь сюда. Как гетнуть столько блоков?
 

Icosider

Kotliner
Администратор
3,601
99
664
Либо я тебя не понял, либо ты меня не понял.
То как я тебя понял, тебе типа надо этого rayTrace'а:
Оранжевым отмечается Блоки которые на пересечении моего вектора, учитывая что от первого лица не все блоки видны, то я сделал через предмет для их разрушения, чтобы увидеть как это типа со стороны выглядит.
Ну спасибо Тимаха, я теперь хочу такую же аву в майн сделать, как у тебя на видео -.-
 

timaxa007

Модератор
5,831
409
672
а как ты блоки оранжевым подсветил?
Эвентом RenderWorldLastEvent рендерил кубы.
Вот именно это и нужно.
Тебе методы: rayTrace, getPosition и func_147447_a.
Java:
public class EventsForge {

    ArrayList<MovingObjectPosition> list = null;

    @SubscribeEvent
    public void clientTick(TickEvent.ClientTickEvent event) {
        if (mc.theWorld == null) return;
        list = rayTrace(mc.thePlayer, 100D, 1F);
    }

    @SubscribeEvent
    public void renderTick(RenderWorldLastEvent event) {
        if (list != null && !list.isEmpty()) {
            double x_fix = -(mc.thePlayer.lastTickPosX + (mc.thePlayer.posX - mc.thePlayer.lastTickPosX) * event.partialTicks);
            double y_fix = -(mc.thePlayer.lastTickPosY + (mc.thePlayer.posY - mc.thePlayer.lastTickPosY) * event.partialTicks);
            double z_fix = -(mc.thePlayer.lastTickPosZ + (mc.thePlayer.posZ - mc.thePlayer.lastTickPosZ) * event.partialTicks);
            GL11.glPushMatrix();
            GL11.glTranslated(x_fix, y_fix, z_fix);
            GL11.glDisable(GL11.GL_DEPTH_TEST);
            GL11.glDisable(GL11.GL_TEXTURE_2D);
            GL11.glEnable(GL11.GL_BLEND);
            GL11.glColor4f(1F, 0.5F, 0.25F, 0.35F);

            Tessellator tessellator = Tessellator.instance;

            for (MovingObjectPosition mop : list) {
                if (mop != null) {
                    switch(mop.typeOfHit) {
                    case BLOCK:
                        GL11.glPushMatrix();
                        GL11.glTranslated(mop.blockX, mop.blockY, mop.blockZ);
                        UtilModel.box(tessellator, 0, 0, 0, 1, 1, 1);
                        GL11.glPopMatrix();
                        break;
                    default:break;
                    }
                }
            }
            GL11.glDisable(GL11.GL_BLEND);
            GL11.glEnable(GL11.GL_DEPTH_TEST);
            GL11.glEnable(GL11.GL_TEXTURE_2D);
            GL11.glPopMatrix();
        }
    }

    public static ArrayList<MovingObjectPosition> rayTrace(EntityLivingBase entity, double distance, float partialTickTime) {
        Vec3 vec3 = getPosition(entity, partialTickTime);
        Vec3 vec31 = entity.getLook(partialTickTime);
        Vec3 vec32 = vec3.addVector(vec31.xCoord * distance, vec31.yCoord * distance, vec31.zCoord * distance);
        return func_147447_a(entity.worldObj, vec3, vec32, false, false, true);
    }

    private static Vec3 getPosition(EntityLivingBase entity, float partialTickTime) {
        if (partialTickTime == 1.0F) {
            return Vec3.createVectorHelper(entity.posX, entity.posY + (entity instanceof EntityPlayerMP ? entity.getEyeHeight() : 0), entity.posZ);
        } else {
            double d0 = entity.prevPosX + (entity.posX - entity.prevPosX) * (double)partialTickTime;
            double d1 = entity.prevPosY + (entity.posY - entity.prevPosY) * (double)partialTickTime;
            double d2 = entity.prevPosZ + (entity.posZ - entity.prevPosZ) * (double)partialTickTime;
            return Vec3.createVectorHelper(d0, d1 + (entity instanceof EntityPlayerMP ? entity.getEyeHeight() : 0), d2);
        }
    }

    private static ArrayList<MovingObjectPosition> func_147447_a(World world, Vec3 vec1, Vec3 vec2, boolean p_147447_3_, boolean p_147447_4_, boolean p_147447_5_) {
        if (Double.isNaN(vec1.xCoord) && Double.isNaN(vec1.yCoord) && Double.isNaN(vec1.zCoord)) return null;
        if (Double.isNaN(vec2.xCoord) && Double.isNaN(vec2.yCoord) && Double.isNaN(vec2.zCoord)) return null;
        ArrayList<MovingObjectPosition> list = new ArrayList<MovingObjectPosition>();
        int i = MathHelper.floor_double(vec2.xCoord);
        int j = MathHelper.floor_double(vec2.yCoord);
        int k = MathHelper.floor_double(vec2.zCoord);
        int l = MathHelper.floor_double(vec1.xCoord);
        int i1 = MathHelper.floor_double(vec1.yCoord);
        int j1 = MathHelper.floor_double(vec1.zCoord);
        Block block = world.getBlock(l, i1, j1);
        int k1 = world.getBlockMetadata(l, i1, j1);

        if ((!p_147447_4_ || block.getCollisionBoundingBoxFromPool(world, l, i1, j1) != null) && block.canCollideCheck(k1, p_147447_3_)) {
            MovingObjectPosition movingobjectposition = block.collisionRayTrace(world, l, i1, j1, vec1, vec2);

            if (movingobjectposition != null)
                list.add(movingobjectposition);

        }

        MovingObjectPosition movingobjectposition2 = null;
        k1 = 200;

        while (k1-- >= 0) {
            if (Double.isNaN(vec1.xCoord) || Double.isNaN(vec1.yCoord) || Double.isNaN(vec1.zCoord))
                return null;

            if (l == i && i1 == j && j1 == k) {
                if (p_147447_5_) list.add(movingobjectposition2);
                //else return null;
            }

            boolean flag6 = true;
            boolean flag3 = true;
            boolean flag4 = true;
            double d0 = 999.0D;
            double d1 = 999.0D;
            double d2 = 999.0D;

            if (i > l) {
                d0 = (double)l + 1.0D;
            }
            else if (i < l) {
                d0 = (double)l + 0.0D;
            }
            else {
                flag6 = false;
            }

            if (j > i1) {
                d1 = (double)i1 + 1.0D;
            }
            else if (j < i1) {
                d1 = (double)i1 + 0.0D;
            }
            else {
                flag3 = false;
            }

            if (k > j1) {
                d2 = (double)j1 + 1.0D;
            }
            else if (k < j1) {
                d2 = (double)j1 + 0.0D;
            }
            else {
                flag4 = false;
            }

            double d3 = 999.0D;
            double d4 = 999.0D;
            double d5 = 999.0D;
            double d6 = vec2.xCoord - vec1.xCoord;
            double d7 = vec2.yCoord - vec1.yCoord;
            double d8 = vec2.zCoord - vec1.zCoord;

            if (flag6) {
                d3 = (d0 - vec1.xCoord) / d6;
            }

            if (flag3) {
                d4 = (d1 - vec1.yCoord) / d7;
            }

            if (flag4) {
                d5 = (d2 - vec1.zCoord) / d8;
            }

            boolean flag5 = false;
            byte b0;

            if (d3 < d4 && d3 < d5) {
                if (i > l) {
                    b0 = 4;
                }
                else {
                    b0 = 5;
                }

                vec1.xCoord = d0;
                vec1.yCoord += d7 * d3;
                vec1.zCoord += d8 * d3;
            }
            else if (d4 < d5) {
                if (j > i1) {
                    b0 = 0;
                }
                else {
                    b0 = 1;
                }

                vec1.xCoord += d6 * d4;
                vec1.yCoord = d1;
                vec1.zCoord += d8 * d4;
            }
            else {
                if (k > j1) {
                    b0 = 2;
                }
                else {
                    b0 = 3;
                }

                vec1.xCoord += d6 * d5;
                vec1.yCoord += d7 * d5;
                vec1.zCoord = d2;
            }

            Vec3 vec32 = Vec3.createVectorHelper(vec1.xCoord, vec1.yCoord, vec1.zCoord);
            l = (int)(vec32.xCoord = (double)MathHelper.floor_double(vec1.xCoord));

            if (b0 == 5) {
                --l;
                ++vec32.xCoord;
            }

            i1 = (int)(vec32.yCoord = (double)MathHelper.floor_double(vec1.yCoord));

            if (b0 == 1) {
                --i1;
                ++vec32.yCoord;
            }

            j1 = (int)(vec32.zCoord = (double)MathHelper.floor_double(vec1.zCoord));

            if (b0 == 3) {
                --j1;
                ++vec32.zCoord;
            }

            Block block1 = world.getBlock(l, i1, j1);
            int l1 = world.getBlockMetadata(l, i1, j1);

            if (!p_147447_4_ || block1.getCollisionBoundingBoxFromPool(world, l, i1, j1) != null) {
                if (block1.canCollideCheck(l1, p_147447_3_)) {
                    MovingObjectPosition movingobjectposition1 = block1.collisionRayTrace(world, l, i1, j1, vec1, vec2);

                    if (movingobjectposition1 != null)
                        list.add(movingobjectposition1);

                }
                else {
                    movingobjectposition2 = new MovingObjectPosition(l, i1, j1, b0, vec1, false);
                }
            }
        }
        if (p_147447_5_)
            list.add(movingobjectposition2);
        //else return null;

        return list;
    }

}
Java:
public class ItemExp extends Item {

    @Override
    public ItemStack onItemRightClick(ItemStack itemStack, World worlld, EntityPlayer player) {
        if (!worlld.isRemote) {
            ArrayList<MovingObjectPosition> list = timaxa007.hud.client.EventsForge.rayTrace(player, 100D, 1F);

            for (MovingObjectPosition mop : list) {
                if (mop != null) {
                    switch(mop.typeOfHit) {
                    case BLOCK:
                        worlld.setBlockToAir(mop.blockX, mop.blockY, mop.blockZ);
                        break;
                    default:break;
                    }
                }
            }
        }
        return super.onItemRightClick(itemStack, worlld, player);
    }

}
 
1,193
31
182
Господи, куча ноунейм булев переменных в аргументе func, куча магических значений...
Как я понял с помощью этого метода private static ArrayList<MovingObjectPosition> func_147447_a()
Можно занести в лист список блоков, через который вектор идет?
 

timaxa007

Модератор
5,831
409
672
Т.е. да если дистанция значительно большая, то это число и по больше сделать.
Я-же скопиПастил и типа изменил return'ы (которые не null) на list.add(...).
Так-что и ошибок (типа повторяющиеся блоки, т.е. уже есть в list) не мало может быть, самому писать времени нет.
 
1,193
31
182
Нет, это мне кажется не то. Можешь подсказать, как создать список из всех блоков?
Тут кое что мне подсказывает на это:

Java:
ArrayList<MovingObjectPosition> list = new ArrayList<MovingObjectPosition>(); //создаем лист
MovingObjectPosition movingobjectposition = block.collisionRayTrace(world, l, i1, j1, vec1, vec2);
//что это? что делают в последних двух аргументах 2 вектора?
if (movingobjectposition != null)
                    list.add(movingobjectposition); //добавляем лист что то... блок? или все блоки, которых касается вектор?
Попрошу ответить на вопросы в комментах
 

timaxa007

Модератор
5,831
409
672
как создать список из всех блоков?
Правильно, это создан объект типа листа, но он пустой по мере высчитывания добавляем в этот лист наш блок.
//что это? что делают в последних двух аргументах 2 вектора?
Типа относительно их высчитывают hit'ы для блока, т.е. точка вектора относительно стенок коллизии блока.
добавляем лист что то... блок? или все блоки
Блок.
блок? или все блоки, которых касается вектор?
Блоки, типа с помощью цикла.
 
1,193
31
182
Тимаха спасаешь дико)
Допер как сделать, совместил тимахину систему и мою, получил то что хотел)
Нагло скопипастив все три метода у тимахи, получил такое:

Java:
 ArrayList<MovingObjectPosition> blocklist = rayTrace(mc.thePlayer, d0, 1F); //здесь создаем лист со всеми хитами блоков

for(int p = 0; p < blocklist.size(); p++){
                            MovingObjectPosition mop = blocklist.get(p);
                            if(mop.typeOfHit.BLOCK != null){
                            Block block = mc.theWorld.getBlock(mop.blockX, mop.blockY, mop.blockZ);
                            if(block.getMaterial() == Material.glass || block.getMaterial() == Material.air || block.getMaterial() == Material.leaves || block.getMaterial() == Material.web){
                                
                                System.out.println(block);
                            }
                            else{
                                
                                d0 = mop.hitVec.distanceTo(vec3);
                                if(block.getMaterial() != Material.air)
                                System.out.println(block);
                                break;
                            }
                            }
                        }
//здесь я перебираю циклом все блоки, которые пересечены моим вектором/векторами, и если на его пути встретился блок твердый, то вектор останавливается у его хитбокса
//если же моему вектору ничего не мешает, он спокойно "долетает" 128 блоков, ибо d0 это 128 блоков, моя дистанция поражения
Java:
 
Сверху