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

Помогите как сделать так, что бы после 5 атак по блоку он ломался

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

  1. Автор темы
    SlaveSr

    SlaveSr Участник

    Баллы:
    31
    как сделать так, что бы после 5 атак по блоку он ломался
    вот часть кода, когда ударяю 5 раз ничего не происходит, если ударяю не золотым слитком то в консоль пишет оишбку Could not pass event PlayerInteractEvent.
    код:
    Код:
        @EventHandler(priority= EventPriority.NORMAL)
        public void onAttackBlock(PlayerInteractEvent e) {
    
            Block block = e.getPlayer().getTargetBlock(null,5);
            int x = block.getX();
            int y = block.getY();
            int z = block.getZ();
            int BlockHealth = 15;
            if (e.getAction() == Action.LEFT_CLICK_BLOCK) {
                BlockHealth -= 1;
            }
            if(BlockHealth == 10) {
                block.breakNaturally(new ItemStack(Material.GOLD_INGOT));
            }
        }
     
  2. HauserGrim

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

    Баллы:
    96
    Так как эта переменная внутри метода, она каждый раз создаётся заново.
    Создай HashMap за пределами метода, храни там расположение блока и кол-во ударов.
     
  3. Автор темы
    SlaveSr

    SlaveSr Участник

    Баллы:
    31
    можешь пожалуйста написать? я не понимаю как это сделать
    код:
    Код:
     HashMap<String, Integer> map = new HashMap<String, Integer>();
    
        @EventHandler(priority= EventPriority.NORMAL)
        public void onAttackBlock(PlayerInteractEvent e) {
            map.put("BlockHealth", 15);
    
            Block block = e.getPlayer().getTargetBlock(null,5);
            int x = block.getX();
            int y = block.getY();
            int z = block.getZ();
            map.put("BlockCoordinations", block.getX(), block.getY(), block.getZ());
            if (e.getAction() == Action.LEFT_CLICK_BLOCK) {
                map.get("BlockHealth") -= 1;
            }
            if(BlockHealth == 10) {
                block.breakNaturally(new ItemStack(Material.GOLD_INGOT));
            }
        }
     
  4. Автор темы
    SlaveSr

    SlaveSr Участник

    Баллы:
    31
    Код:
        HashMap<String, Integer> map = new HashMap<String, Integer>();
    
        @EventHandler(priority= EventPriority.NORMAL)
        public void onAttackBlock(PlayerInteractEvent e) {
            map.put("BlockHealth", 15);
    
            Block block = e.getPlayer().getTargetBlock(null,5);
            int x = block.getX();
            int y = block.getY();
            int z = block.getZ();
            int BlockHealth = map.get("BlockHealth");
            if (e.getAction() == Action.LEFT_CLICK_BLOCK) {
                BlockHealth -= 1;
            }
            if(BlockHealth == 10) {
                block.breakNaturally(new ItemStack(Material.GOLD_INGOT));
            }
        }
    
    что то сделал... но я не понимаю как записать координаты блока в хешмап
     
  5. HauserGrim

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

    Баллы:
    96
    Каждый раз при вызове ивента ты туда кладёшь это. Т.е, каждый раз сбрасываешь. Нужно проверять, есть ли уже значение в мапе.

    Тебе нужно записывать в ключ что-то уникальное для блока, например его локацию.
    Иначе таким образом ты будешь считать любой блок за один.


    Ударенный блок лучше получить через event.getClickedBlock()

    Зачем тебе 15 "жизней" блока и ломать на 10?


    Давай сначала.

    Создаёшь мапу Location, Integer
    В ивенте делаешь проверку на то, что игрок левой кнопкой ударил по блоку event.getAction()
    == Action.LEFT_CLICK_BLOCK
    Теперь получаешь блок event.getClickedBlock()
    У блока получаешь локацию block.getLocation()
    Проверяешь, есть ли локация в мапе, если есть - берёшь оттуда по локации число ударов и записываешь изменённое, если нету - записываешь туда локацию и число ударов
    Проверяешь число и делаешь, что тебе нужно, при достижении нужного значения
     
  6. Level132331

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

    Баллы:
    66
    Код:
    HashMap<Location, Integer> map = new HashMap<>();
    
        @EventHandler
        public void onInteract(PlayerInteractEvent e) {
            if (e.getClickedBlock() == null) return;
            map.putIfAbsent(e.getClickedBlock().getLocation(), 0);
                if (e.getAction() == Action.LEFT_CLICK_BLOCK) {
                    if (map.containsKey(e.getClickedBlock().getLocation())) {
                        map.put(e.getClickedBlock().getLocation(), map.get(e.getClickedBlock().getLocation()) + 1);
                        if (map.get(e.getClickedBlock().getLocation()) == 10) {
                            e.getClickedBlock().setType(Material.AIR);
                            e.getClickedBlock().getWorld().dropItemNaturally(e.getClickedBlock().getLocation(), new ItemStack(Material.GOLD_INGOT));
                        }
                    }
                }
        }
    Если хочешь дропать слиток золота, то нужно использовать e.getClickedBlock().getWorld().dropItemNaturally(), потому что
    breakNaturally берет ItemStack инструмента, с помощью которого сломан этот блок.
     
    Последнее редактирование: 16 июл 2023
  7. Автор темы
    SlaveSr

    SlaveSr Участник

    Баллы:
    31
    я и хотел чтобы блок ломался определенным предметом, а золотой слиток сделал для примера, сработапт или нет
     
  8. Автор темы
    SlaveSr

    SlaveSr Участник

    Баллы:
    31
    можно ли сделать чтобы после 5 ударов по ОДНОМУ блоку ломались еще 3 блока рядом с ним?
     
  9. Автор темы
    SlaveSr

    SlaveSr Участник

    Баллы:
    31
    и чтоб эти блоки были одинакового материала
     
  10. Level132331

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

    Баллы:
    66
    Код:
    HashMap<Location, Integer> map = new HashMap<>();
    
        @EventHandler
        public void onInteract(PlayerInteractEvent e) {
            if (e.getClickedBlock() == null) return;
            Block block = e.getClickedBlock();
            if (e.getAction() == Action.LEFT_CLICK_BLOCK) {
                if (map.containsKey(block.getLocation())) {
                    map.put(block.getLocation(), map.get(block.getLocation()) + 1);
                    if (map.get(block.getLocation()) == 5) {
                        map.remove(e.getClickedBlock().getLocation());
                        Location loc1 = block.getLocation().clone().add(1, 0, 0);
                        Location loc2 = block.getLocation().clone().add(-1, 0, 0);
                        if (block.getType().equals(loc1.getBlock().getType()) && block.getType().equals(loc2.getBlock().getType())) {
                            block.setType(Material.AIR);
                            loc1.getBlock().setType(Material.AIR);
                            loc2.getBlock().setType(Material.AIR);
                            block.getWorld().dropItemNaturally(block.getLocation(), new ItemStack(Material.GOLD_INGOT));
                        }
                    }
                } else {
                    map.putIfAbsent(block.getLocation(), 0);
                }
            }
        }
    Быстро накидал, уверен что можно сделать иначе и проще. Что учитывать, что не учитывать - тут уже сам
     
    Последнее редактирование: 17 июл 2023
  11. Автор темы
    SlaveSr

    SlaveSr Участник

    Баллы:
    31
    спасибо
     

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