1. Вы находитесь в сообществе Rubukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на различные языки плагины наших коллег из других стран.
    Скрыть объявление
Скрыть объявление
В преддверии глобального обновления, мы проводим исследования, которые помогут нам сделать опыт пользования форумом ещё удобнее. Помогите нам, примите участие!

Помогите Проверять, есть ли в радиусе похожий блок

Тема в разделе "Разработка плагинов для новичков", создана пользователем nt34t34, 20 янв 2023.

Статус темы:
Закрыта.
  1. Автор темы
    nt34t34

    nt34t34 Участник Пользователь

    Баллы:
    31
    Имя в Minecraft:
    Wap
    Я пытаюсь сделать плагин, чтоб нельзя была ставить Ендер сундук, если в радиусе есть другой Ендер сундук. Пока дела идут плохи. Даже близко рабочего кода нет.
     
  2. Dymeth

    Dymeth Активный участник Пользователь

    Баллы:
    98
    Имя в Minecraft:
    Dymeth
    Определяешь границы кубоида с заданным радиусом вокруг блока.
    Перебираешь все блоки в кубоиде и проверяешь тип каждого блока. Как только найдешь нужный - прерываешь все три цикла и выполняешь необходимые действия.
    Если кубоид большой, то необходимо перенести перебор в асинхрон с чанк снапшотом или перебирать в синхроне, но разбить задачу на разные тики
     
  3. Автор темы
    nt34t34

    nt34t34 Участник Пользователь

    Баллы:
    31
    Имя в Minecraft:
    Wap
    А можно кодом пожалуйста? И примерно описанное делать пытался, но цикл выполняется несколько раз и радиус не определяется т.е. работает на любом расстоянии от блока
     
    Последнее редактирование: 20 янв 2023
  4. Dymeth

    Dymeth Активный участник Пользователь

    Баллы:
    98
    Имя в Minecraft:
    Dymeth
    Показывай код.

    Что значит радиус не определяется? Ты самостоятельно его задаёшь константой
     
  5. Автор темы
    nt34t34

    nt34t34 Участник Пользователь

    Баллы:
    31
    Имя в Minecraft:
    Wap
    Код:
        @EventHandler
        public boolean Block(BlockPlaceEvent e) {
            int radius = 1;
            Player p = e.getPlayer();
            Block middle = e.getBlockPlaced();
            for (int x = -(radius); x <= radius; x++) {
                for (int y = -(radius); y <= radius; y++) {
                    for (int z = -(radius); z <= radius; z++) {
                        if (middle.getRelative(x, y, z).getType() == Material.ENDER_CHEST) {
                            p.sendMessage("Yes");
                        }
                    }
                }
            }
            return false;
        }
     
  6. Dymeth

    Dymeth Активный участник Пользователь

    Баллы:
    98
    Имя в Minecraft:
    Dymeth
    Почему у тебя обработчик имеет тип boolean? Все слушатели void должны быть.

    В остальном у меня твой код работает.

    Если у тебя всё ещё не выполняется - возможно установку отменяют другие плагины. В этом случае поменяй приоритет события:
    @EventHandler(priority = EventPriority.LOWEST)

    P.S. Возможно, есть смысл прерывать все циклы после обнаружения эндер-сундука, но тут уже тебе виднее
     
  7. Автор темы
    nt34t34

    nt34t34 Участник Пользователь

    Баллы:
    31
    Имя в Minecraft:
    Wap
    Он работает, но криво. Например: когда я ставлю ендер сундук в радиусе, мне пишет "Yes" 3 раза, а когда вне радиуса, то 1 раз. Если я добавлю e.setCancelled(true), то что в радиусе, что вне радиуса эвент будет отменяться и блок не поставится
     
  8. Dymeth

    Dymeth Активный участник Пользователь

    Баллы:
    98
    Имя в Minecraft:
    Dymeth
    При установке эндер-сундука тебе пишет Yes всегда, потому что устанавливаемый блок тоже учитывается при переборе блоков. Чтобы этого избежать - игнорируй центральный блок при переборе (со смещением 0;0;0)
     
  9. Автор темы
    nt34t34

    nt34t34 Участник Пользователь

    Баллы:
    31
    Имя в Minecraft:
    Wap
    Привет, у меня что-то получилось, вкратце, оно теперь работает не от поставленного блока(middle), а от игрока и вот я не знаю как это исправить, возможно знаю, но пока не понимаю. Технически код работает полностью как мне нужно, но от игрока, а не от блока :((((
    Код:
        public static List<Block> getNearbyBlocks(Location location, int radius) {
            List<Block> blocks = new ArrayList<Block>();
            for(int x = location.getBlockX() - radius; x <= location.getBlockX() + radius; x++) {
                for(int y = location.getBlockY() - radius; y <= location.getBlockY() + radius; y++) {
                    for(int z = location.getBlockZ() - radius; z <= location.getBlockZ() + radius; z++) {
                        blocks.add(Objects.requireNonNull(location.getWorld()).getBlockAt(x, y, z));
                    }
                }
            }
            return blocks;
        }
    
        @EventHandler
        public static void onSetBlock(BlockPlaceEvent e) {
            Player p = e.getPlayer();
            Block block = e.getBlockPlaced();
            for(Block b : getNearbyBlocks(p.getLocation(), 1)) {
                if (b.getType() == Material.ENDER_CHEST) {
                    p.sendMessage("Yes");
                    e.setCancelled(true); break;
                }
            }
        }
     
  10. OJIEKCAHDP

    OJIEKCAHDP Активный участник Пользователь

    Баллы:
    76
    Имя в Minecraft:
    OJIEKCAHDP
    Так ты в цикле берёшь локацию игрока, а не блока -_-
     
Статус темы:
Закрыта.

Поделиться этой страницей