[ServerSide] На кого смотрит игрок?

Версия Minecraft
1.7.10
API
Forge
236
4
22
Всем привет. Да, знаю, похожая тема была, но про блок, на который смотрит игрок. Мне же нужно точно тоже самое на серверсайде, но искать нужно и ентити и блок. Вот кусок кода, который я нашёл где-то на этом форуме:

Блок, на который смотрит игрок:
public static MovingObjectPosition getTarget(EntityPlayer player) {
    int distance = 5;
    Vec3 vec3 = Vec3.createVectorHelper(player.posX, player.posY + player.getEyeHeight(), player.posZ);
    Vec3 vec31 = player.getLook(1F);
    Vec3 vec32 = vec3.addVector(vec31.xCoord * distance, vec31.yCoord * distance, vec31.zCoord * distance);
    return player.worldObj.rayTraceBlocks(vec3, vec32);
}
Но, как я уже сказал, мне ещё нужно находить ентити. Есть ли пример реализации кода? Я предполагаю, нужно создать AABB с радиусом во все стороны в 5 блоков от игрока и отобрать из этой зоны ентити, которые попадают под взгляд игрока. Но как это правильно сделать? А главный вопрос - есть ли уже готовое / более оптимальное решение по получению блока и ентити по взгляду игрока?
 
1,038
57
229
Каждый entity может проверить видит ли он другого. Видит ли игрок entity? (это код из Эндермена, он же начинает нападать на игрока если чо)
Ну и мир не без добрых людей, тут было про AOE (по площади). Дошли руки до дженериков
Вообще где то был доступ ко всем Entity и можно тупо в цикле проверить попадает ли Entity в эти границы (ну или по радиусу проверить).
 
236
4
22
Каждый entity может проверить видит ли он другого. Видит ли игрок entity? (это код из Эндермена, он же начинает нападать на игрока если чо)
Ну и мир не без добрых людей, тут было про AOE (по площади). Дошли руки до дженериков
Вообще где то был доступ ко всем Entity и можно тупо в цикле проверить попадает ли Entity в эти границы (ну или по радиусу проверить).
Ну примерно я понял. Я просто не дружу с векторами, так что... Плоховато дело. Надеюсь что-нибудь всё же скостыляю.
 
1,038
57
229
236
4
22
world.getEntitiesWithinAABBExcludingEntity - можешь задать радиус и т.д через тот же AABB
Нужно найти самого ближайшего ентити к игроку и чтоб игрок его видел (меж ними не было блоков и расстояние не более 5)
 
236
4
22
не проблема, обращайся
Короче попытался что-то сделать на примерах что ты кинул. По идеи правильно (и то не уверен) но мне нужно на каждую итерацию цикла while сдвигать AABB на 1 блок по взгляду игрока (то есть прибавлять x, y или z на 1 или -1). Как мне узнать какую переменную надо менять и как именно (инкремент или декремент)

Java:
    public static Entity getTargetEntity(EntityPlayer player) {
        Vec3 seeVec = player.getLookVec();
        int limit = 0;
        while (limit++ <= 5) {
            for(Entity entity : (Iterable<? extends Entity>) player.worldObj.getEntitiesWithinAABBExcludingEntity(player, AxisAlignedBB.getBoundingBox(seeVec.xCoord - 0.5, seeVec.yCoord - 0.5, seeVec.zCoord - 0.5, seeVec.xCoord + 0.5, seeVec.yCoord + 0.5, seeVec.zCoord + 0.5))) {
                Vec3 visionVec = seeVec.normalize();
                Vec3 targetVec = Vec3.createVectorHelper(entity.posX - player.posX, entity.posY - (player.posY + (double) player.getEyeHeight()), entity.posZ - player.posZ).normalize();
                if(visionVec.dotProduct(targetVec) > 0.1 && player.canEntityBeSeen(entity))
                    return entity;
            }
        }
     return null;
 
236
4
22
UPD: Вообщем остановился пока на вот таком коде, костылил сам, уверен что код плохой, но +- рабочий. Единственно вопрос, что делать с размерами моба? Не все же мобы в 2 блока размером, есть значительно выше (а иногда и толще) ентити. Как их "уловить"? Если говорить о ваниле - то возмём к примеру гаста / гиганта (да, его в игре не встретить, можно командой вызвать, но дела нет) - они больше чем обычные ентити - взгляд на них не попадает.
Вот сам код, на текущий момент:

Геттер ентити, на которого смотрит игрок:
    public static Optional<Entity> getTargetEntity(EntityPlayer player) {
        Vec3 seeVec = player.getLookVec();
        Vec3 visionVec = seeVec.normalize();
        int limit = 0;
        while (limit <= 5) {
            Vec3 seeVecModified = Vec3.createVectorHelper(seeVec.xCoord * limit, seeVec.yCoord * limit, seeVec.zCoord * limit);
            AxisAlignedBB box = AxisAlignedBB.getBoundingBox(player.posX + seeVecModified.xCoord - 0.5, player.posY + seeVecModified.yCoord - 0.5, player.posZ + seeVecModified.zCoord - 0.5, player.posX + seeVecModified.xCoord + 0.5, player.posY + seeVecModified.yCoord + 0.5, player.posZ + seeVecModified.zCoord + 0.5);
            for(Entity entity : (Iterable<? extends Entity>) player.worldObj.getEntitiesWithinAABBExcludingEntity(player, box)) {
                if(!entity.isEntityAlive()) continue;
                Vec3 targetVec = Vec3.createVectorHelper(entity.posX - player.posX, entity.posY - (player.posY + (double) player.getEyeHeight()), entity.posZ - player.posZ).normalize();
                if(visionVec.dotProduct(targetVec) > 0.1 && player.canEntityBeSeen(entity))
                    return Optional.of(entity);
            }
            limit++;
        }
        return Optional.empty();
    }
,
 
236
4
22
Ну в принципе "добился" своей цели - получать таргет зрения игрока. Но работает очень даже криво, особенно с обнаружением блоков (не верные координаты блока смотрит скорее всего, видимо нужно как-то по другому округлять дабл координаты в int`овские при поиске блока)

Java:
    public static MovingObjectPosition getTarget(EntityPlayer player) {
        Vec3 seeVec = player.getLookVec();
        Vec3 visionVec = seeVec.normalize();
        int limit = 0;
        while (limit <= 5) {
            Vec3 seeVecModified = Vec3.createVectorHelper(seeVec.xCoord * limit, seeVec.yCoord * limit, seeVec.zCoord * limit);
            if(player.worldObj.isAirBlock(MathHelper.floor_double(player.posX + seeVecModified.xCoord), MathHelper.floor_double(player.posY + seeVecModified.yCoord), MathHelper.floor_double(player.posZ + seeVecModified.zCoord))) {
                AxisAlignedBB box = AxisAlignedBB.getBoundingBox(player.posX + seeVecModified.xCoord - 0.5, player.posY + seeVecModified.yCoord - 0.5, player.posZ + seeVecModified.zCoord - 0.5, player.posX + seeVecModified.xCoord + 0.5, player.posY + seeVecModified.yCoord + 0.5, player.posZ + seeVecModified.zCoord + 0.5);
                List<? extends Entity> list = ((List<? extends Entity>) player.worldObj.getEntitiesWithinAABBExcludingEntity(player, box)).stream().filter(Entity::isEntityAlive).filter(entity -> visionVec.dotProduct(Vec3.createVectorHelper(entity.posX - player.posX, entity.posY - (player.posY + (double) player.getEyeHeight()), entity.posZ - player.posZ).normalize()) > 0.1 /*&& player.canEntityBeSeen(entity)*/).collect(Collectors.toList());
                if (!list.isEmpty()) {
                    list.sort((entity1, entity2) -> (int) ((entity1.getDistanceSqToEntity(player) - entity2.getDistanceSqToEntity(player)) * 100));
                    return new MovingObjectPosition(list.get(0));
                }
            } else return new MovingObjectPosition(MathHelper.floor_double(player.posX + seeVecModified.xCoord), MathHelper.floor_double(player.posY + seeVecModified.yCoord), MathHelper.floor_double(player.posZ + seeVecModified.zCoord), 0, seeVecModified);
            limit++;
        }
        MovingObjectPosition result = new MovingObjectPosition(player);
        result.typeOfHit = MovingObjectPosition.MovingObjectType.MISS;
        return result;
    }
Жду теперь от здешних обитателей форума и профи по моддингу в майне советов, как улучшить логику этой заразы, чтобы работало более точно. Заранее спасибо вам!!!
 
1,173
28
168
Код:
                        pointedEntity = null;
                        double d0 = weaponNBT.getFloat("distance");
                        if (d0 > 190) {
                            d0 = 190;
                        }

                        double d1 = d0;

                        Vec3 vec3 = Vec3.createVectorHelper(shooter.posX, shooter.posY, shooter.posZ);
                        Vec3 vec31 = shooter.getLook(1);

                        if (shooter.isSneaking()) {
                            shooter.height = 1.56F;
                        } else {
                            shooter.height = 1.8F;
                        }

                        if (playerBase.moving.isSmall) {
                            shooter.height = 0.8F;

                        }

                        vec3.yCoord += shooter.height;

                        vec31.xCoord += w.rand.nextGaussian() * (double) (w.rand.nextBoolean() ? -1 : 1)
                                * 0.007499999832361937D * (double) weaponNBT.getFloat("spread") / 1.2F;
                        vec31.yCoord += w.rand.nextGaussian() * (double) (w.rand.nextBoolean() ? -1 : 1)
                                * 0.007499999832361937D * (double) weaponNBT.getFloat("spread") / 1.2F;
                        vec31.zCoord += w.rand.nextGaussian() * (double) (w.rand.nextBoolean() ? -1 : 1)
                                * 0.007499999832361937D * (double) weaponNBT.getFloat("spread") / 1.2F;

                        double xCord = vec31.xCoord;
                        double yCord = vec31.yCoord;// - 0.12F / d1;
                        double zCord = vec31.zCoord;
                        
                        ArrayList<MovingObjectPosition> blocklist = rayTrace(shooter, d0, 1F, xCord, yCord, zCord);
                      
                        for (int p = 0; p < blocklist.size(); p++) {
                            MovingObjectPosition mop = blocklist.get(p);
                            if (mop != null) {
                                if (mop.typeOfHit.BLOCK != null) {
                                    Block block = w.getBlock(mop.blockX, mop.blockY, mop.blockZ);
                                    if (block == Blocks.iron_bars || block.getMaterial() == Material.glass
                                            || block.getMaterial() == Material.vine
                                            || block.getMaterial() == Material.plants
                                            || block.getMaterial() == Material.air
                                            || block.getMaterial() == Material.leaves
                                            || block.getMaterial() == Material.web) {

                                    } else {
                                        vec3 = Vec3.createVectorHelper(shooter.posX, shooter.posY, shooter.posZ);
                                        vec3.yCoord += shooter.height;
                                        d0 = mop.hitVec.distanceTo(vec3);
                                        if (d0 > weaponNBT.getFloat("distance")) {
                                            d0 = weaponNBT.getFloat("distance");
                                            if (d0 > 190) {
                                                d0 = 190;
                                            }
                                        }
                                        if (!(block instanceof InvizibleBlock) && !(block instanceof BlockCollider)
                                                && !(block instanceof BlockCollider3D)) {
                                            BatthertPacketHandler.INSTANCE.sendToAll(new PacketBulletHole(
                                                    (float) mop.hitVec.xCoord, (float) mop.hitVec.yCoord,
                                                    (float) mop.hitVec.zCoord, mop.sideHit));

                                            if (k <= 1)
                                                BatthertPacketHandler.INSTANCE.sendToAll(new PacketSoundHit(
                                                        (float) mop.hitVec.xCoord, (float) mop.hitVec.yCoord,
                                                        (float) mop.hitVec.zCoord, mop.sideHit));
                                        }

                                        break;
                                    }
                                }
                            }
                        }

                        Vec3 vec32 = vec3.addVector(vec31.xCoord * d0, vec31.yCoord * d0, vec31.zCoord * d0);

                        this.pointedEntity = null;
                        Vec3 vec33 = null;
                        float f1 = 4F;
                        double d4 = d0;

                        
       

                        List list = w.getEntitiesWithinAABBExcludingEntity(shooter,
                                shooter.boundingBox.addCoord(vec31.xCoord * d0, vec31.yCoord * d0, vec31.zCoord * d0)
                                        .expand((double) f1, (double) f1, (double) f1));

в конце лист энтити, через которых проходит удлиненный вектор взгляда игрока
я это написал когда возникла необходимость перенести клиентский хитскан на сервер, код взят с майновского 1710 getMouseOver вроде, тоже клиентский
при переносе пару багов возникло, я их пофиксил, сча работает без нареканий
работаешь собсна с list
 
236
4
22
Поищи на форуме, я кидал GloomyBulletTracer вроде. Кароче там отлично все работает.
Пока что изобрёл свой велосипед на эту тему. Вроде робит. Как найду время - посмотрю твой и заменю своё.
 
Сверху