Получение ближайшего моба

Версия Minecraft
1.15.2
205
12
103
Привет. Появилась такая задача, нужно чтоб снаряд автоматически наводился на ближайшую энтить возле него примерно в радиусе 5-10 блоков. Проблема сейчас в том, что я не знаю как получить эту энтить. Есть у кого-то идеи или примеры реализации?


Possessed_Hatchet_%28demo%29.gif
 
Java:
world.getEntitiesWithinAABB(EntityLivingBase.class, player.getEntityBoundingBox().grow(Сколько требуется), null).stream().sorted(new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                return (int) (Math.signum(player.getDistance((Entity)o1) - player.getDistance((Entity)o2)));
            }}).findFirst().orElse(null);
Возвращает либо ближайшее энтити в AABB, либо null, если таковых нет.
 
Проведя определённые наблюдения выяснилось, что всех этих извращений можно избежать. В классе World есть метод findNearestEntityWithinAABB.
 
205
12
103
findNearestEntityWithinAABB
Сейчас посмотрю. Потому что мой костыль выглядит.. Ммм.. Опасно.


Java:
    private void findNearbyEntities() {
        AxisAlignedBB axisalignedbb = (new AxisAlignedBB(this.getPosition()))
                .grow(10)
                .expand(0.0D, (double) this.world.getHeight(), 0.0D);
        List<MobEntity> list = this.world.getEntitiesWithinAABB(MobEntity.class, axisalignedbb);
        for (MobEntity target : list) {
            double projectileX = Math.abs(this.getPosX());
            double projectileY = Math.abs(this.getPosY());
            double projectileZ = Math.abs(this.getPosZ());
            double targetX = Math.abs(target.getPosX());
            double targetY = Math.abs(target.getPosY());
            double targetZ = Math.abs(target.getPosZ());
            if (projectileX > targetX || projectileY > targetY || projectileZ > targetZ) {
                this.target = target;
                this.moveTowardsTarget();
            }
        }
    }

UPD: Не нашел. Какая версия игры?
 

Icosider

Kotliner
Администратор
3,601
99
664
Зачем ты модуль делаешь для позиции? Если у тебя моб будет на отрицательной позиции, то твоя проверка не сработает, к тому же у entity есть метод getDistance, в который можно передать таргет и следовательно упростить всё в несколько раз. А ещё у тебя не сортируется список на ближайших к игроку энтить. На счёт того метода от @Jack Raiden'a, это 1.12.2
 

Icosider

Kotliner
Администратор
3,601
99
664
Нету, даже похожего на него.

ТС, лови кусок кода из исходников 1.12.2
Java:
@Nullable
    public <T extends Entity> T findNearestEntityWithinAABB(Class <? extends T > entityType, AxisAlignedBB aabb, T closestTo)
    {
        List<T> list = this.<T>getEntitiesWithinAABB(entityType, aabb);
        T t = null;
        double d0 = Double.MAX_VALUE;

        for (int j2 = 0; j2 < list.size(); ++j2)
        {
            T t1 = list.get(j2);

            if (t1 != closestTo && EntitySelectors.NOT_SPECTATING.apply(t1))
            {
                double d1 = closestTo.getDistanceSq(t1);

                if (d1 <= d0)
                {
                    t = t1;
                    d0 = d1;
                }
            }
        }

        return t;
    }
 
205
12
103
ТС, лови кусок кода из исходников 1.12.2
Кажется, я не совсем понимаю как это правильно использовать.

Java:
    @Nullable
    public <T extends Entity> T findNearestEntityWithinAABB(Class<? extends T> entityType, AxisAlignedBB aabb, T closestTo) {
        List<T> list = this.world.<T>getEntitiesWithinAABB(entityType, aabb);
        T t = null;
        double d0 = Double.MAX_VALUE;
        for (int j2 = 0; j2 < list.size(); ++j2) {
            T t1 = list.get(j2);
            if (t1 != closestTo) {
                double d1 = closestTo.getDistanceSq(t1);
                if (d1 <= d0) {
                    t = t1;
                    d0 = d1;
                }
            }
        }
        return t;
    }

Java:
    @Override
    public void tick() {
        super.tick();

        if (dataManager.get(IS_RETURNING) == 0) {
            this.target = (MobEntity) findNearestEntityWithinAABB(MobEntity.class, new AxisAlignedBB(this.getPosition()), this);
            this.moveTowardsTarget();
        }
    }
Java:
    private void moveTowardsTarget() {
        rotationYaw = (float) Math.toRadians(yawDegreesBetweenPoints(getPosX(), getPosY(), getPosZ(), target.getPosX(), target.getPosY(), target.getPosZ()));
        rotationPitch = (float) Math.toRadians(pitchDegreesBetweenPoints(getPosX(), getPosY(), getPosZ(), target.getPosX(), target.getPosY(), target.getPosZ()));
        Vec3d moveVec = lookVector(this.rotationYaw, this.rotationPitch).scale(SPEED);

        this.setMotion(
                0.5f * this.getMotion().getX() + 0.5f * moveVec.x,
                0.5f * this.getMotion().getY() + 0.5f * moveVec.y,
                0.5f * this.getMotion().getZ() + 0.5f * moveVec.z);
    }
 
Последнее редактирование:

Icosider

Kotliner
Администратор
3,601
99
664
Зачем тебе глобальная переменная? Ты можешь сразу передать в свой метод moveTowardsTarget цель. Крч, смотри интерфейс IEntityReader(его реализовывает класс World, так что можешь получить через него), там есть нужны тебе методы для поиска ближайших сущностей(аналогично коду выше, который я скинул). На счёт движения к сущности/точке, напиши своё AI для сущности и используй в нём PathNavigator. В пример смотри: FollowOwnerGoal и FollowParentGoal
 
205
12
103
Уф, как все сложно-то. Посмотрел этот метод в интерфейсе, в нем довольно много всего требуется для использования, особенно меня волнует EntityPredicate. Посмотрю уже в более светлое время суток, а то вырубает и соображалка не работает.

На всякий случай выложу сюда этот метод:

Java:
   @Nullable
   default <T extends LivingEntity> T getClosestEntityWithinAABB(Class<? extends T> entityClazz, EntityPredicate p_217360_2_, @Nullable LivingEntity target, double x, double y, double z, AxisAlignedBB boundingBox) {
      return this.getClosestEntity(this.getEntitiesWithinAABB(entityClazz, boundingBox, (Predicate<T>)null), p_217360_2_, target, x, y, z);
   }

И то, как я себе представляю его в (почти) заполненном виде:
Java:
MobEntity target = world.getClosestEntityWithinAABB(MobEntity.class, predicate_shit, this, this.getPosX(), this.getPosY(), this.getPosZ(), this.getBoundingBox().grow(10.0D));

Опять же, я уже совершенно не понимаю что происходит и гляну уже с утра.
 
7,099
324
1,510
Снаряды шалкера автонаводятся, можно посмотреть, как они сделаны
1586562974812.png
 

tox1cozZ

aka Agravaine
8,455
598
2,892
На счёт движения к сущности/точке, напиши своё AI для сущности и используй в нём PathNavigator. В пример смотри: FollowOwnerGoal и FollowParentGoal
Класс, аи у проджектайла 👍👍👍
 
205
12
103
Снаряды шалкера автонаводятся, можно посмотреть, как они сделаны
Емнип, там таргет сразу известен, и проджектайл просто летит к цели, изменяя траекторию по заданному алгоритму, но точно я уже не помню.

На всякий случай выложу сюда этот метод

Попробовал подтянуться к нему, всё обрывается на не совсем понятном мне использовании поля target:
Java:
MobEntity target = this.world.getClosestEntityWithinAABB(MobEntity.class, (new EntityPredicate().setDistance(6.0D)), this/[I]неизвестно что должно быть тут[/I]/, this.getPosX(), this.getPosY(), this.getPosZ(), this.getBoundingBox().grow(10.0D));
 
Сверху