Войти или зарегистрироваться
  • Вы находитесь в сообществе Rubukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на различные языки плагины наших коллег из других стран.

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

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));
        }
    }
 
Так как эта переменная внутри метода, она каждый раз создаётся заново.
Создай HashMap за пределами метода, храни там расположение блока и кол-во ударов.
можешь пожалуйста написать? я не понимаю как это сделать
код:
Код:
 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));
        }
    }
 
Код:
    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));
        }
    }
что то сделал... но я не понимаю как записать координаты блока в хешмап
 
Каждый раз при вызове ивента ты туда кладёшь это. Т.е, каждый раз сбрасываешь. Нужно проверять, есть ли уже значение в мапе.

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


e.getPlayer().getTargetBlock(null,5);
Ударенный блок лучше получить через event.getClickedBlock()

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


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

Создаёшь мапу Location, Integer
В ивенте делаешь проверку на то, что игрок левой кнопкой ударил по блоку event.getAction()
== Action.LEFT_CLICK_BLOCK
Теперь получаешь блок event.getClickedBlock()
У блока получаешь локацию block.getLocation()
Проверяешь, есть ли локация в мапе, если есть - берёшь оттуда по локации число ударов и записываешь изменённое, если нету - записываешь туда локацию и число ударов
Проверяешь число и делаешь, что тебе нужно, при достижении нужного значения
 
Код:
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 инструмента, с помощью которого сломан этот блок.
 
Последнее редактирование:
Код:
HashMap<Location, Integer> map = new HashMap<>();

    @EventHandler
    public void onInteract(PlayerInteractEvent e) {
        if (e.getClickedBlock() == null) return;
        map.putIfAbsent(e.getClickedBlock().getLocation(), 0);
        if (map.containsKey(e.getClickedBlock().getLocation())) {
            if (e.getAction() == Action.LEFT_CLICK_BLOCK) {
                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 инструмента, с помощью которого сломан этот блок.
я и хотел чтобы блок ломался определенным предметом, а золотой слиток сделал для примера, сработапт или нет
 
Код:
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 инструмента, с помощью которого сломан этот блок.
можно ли сделать чтобы после 5 ударов по ОДНОМУ блоку ломались еще 3 блока рядом с ним?
 
Код:
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);
            }
        }
    }

Быстро накидал, уверен что можно сделать иначе и проще. Что учитывать, что не учитывать - тут уже сам
 
Последнее редактирование:
Код:
HashMap<Location, Integer> map = new HashMap<>();

    @EventHandler
    public void onInteract(PlayerInteractEvent e) {
        if (e.getClickedBlock() == null) return;
        Block block = e.getClickedBlock();
        map.putIfAbsent(block.getLocation(), 0);
            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));
                        }
                    }
                }
            }
    }

Быстро накидал, уверен что можно сделать иначе и проще. Что учитывать, что не учитывать - тут уже сам
спасибо
 

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

Назад
Верх