Блоки исцеления / урона выводятся дважды? - PullRequest
1 голос
/ 01 апреля 2020
 @EventHandler
    public void playerInteraction(PlayerInteractEvent event)
    {
        Action action = event.getAction();
        Player player = event.getPlayer();
        Block block = event.getClickedBlock();

        if (action.equals(Action.RIGHT_CLICK_BLOCK))
        {
            if (block.getType().equals(Material.NETHER_WART_BLOCK))
            {
                player.setHealth(player.getHealth() -1);
                player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_HURT, 10, 1);
            }
            else if (block.getType().equals(Material.DIAMOND_BLOCK))
            {
                player.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 1000, 2));
                player.playSound(player.getLocation(), Sound.ENTITY_SPLASH_POTION_BREAK, 10, 1);
            }
            else if(block.getType().equals(Material.EMERALD_BLOCK))
            {
                if (player.getHealth() != 20)
                {
                    player.setHealth(player.getHealth() + 1);
                    player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 10, 1);;
                }
                if (player.getHealth() == 20)
                {
                    player.sendMessage(ChatColor.DARK_RED + "You are already at full health!");
                }
            }
        }
    }

По какой-то причине все эти вещи происходят дважды, когда я щелкаю правой кнопкой мыши по обозначенным блокам. Кто-нибудь знает почему? Я опубликовал весь метод, это событие взаимодействия с игроком.

Спасибо:)

1 Ответ

0 голосов
/ 06 апреля 2020

Прежде всего, убедитесь, что вы дважды не зарегистрировали класс Listener, содержащий обработчик событий.

Если это не так, согласно этой теме на форумах spigot, так как Mojang добавил левый слот в Minecraft, некоторые события, такие как PlayerInteractEvent или InventoryClickEvent, будут вызваны дважды (по одному для каждой руки).

Одним из возможных исправлений является «отключение» левой руки на обработчике событий:

@EventHandler
public void onPlayerInteraction(PlayerInteractEvent event) {
    if(event.getAction() == Action.RIGHT_CLICK_BLOCK && event.getHand() == EquipmentSlot.HAND) {
        //Do something once
    }
} 

Если вам требуется, чтобы обе руки использовались для запуска события, вы можете сделать следующее:

  1. При первом запуске кода вы добавляете игрока в список.
  2. Перед выполнением кода вы проверяете, есть ли игрок в списке. Если он находится в списке, это означает, что код был выполнен один раз, так что вы можете его пропустить.
  3. Запланируйте задачу по удалению игрока из списка через несколько тиков.

Код может быть следующим:

public class Foo implements Listener {

    //An instance of the main plugin class
    private MainClass plugin;

    private List<UUID> playerBlacklist = new ArrayList<>();

    @EventHandler
    public void onPlayerInteractEvent(PlayerInteractEvent event) {
        if(playerBlacklist.contains(event.getPlayer().getUniqueId)) {
            return;
        } else {
            blacklistPlayer(event.getPlayer());
        }
        //Do something
    }

    private void blacklistPlayer(UUID uuid) {
        playerBlacklist.add(uuid);
        BukkitRunnable runnable = new BukkitRunnable(){
            @Override
            public void run() {
                playerBlacklist.remove(uuid);
            }
        }
        runnable.runTaskLaterAsynchronously(plugin, 5L);
    }
}

Дайте мне знать, если это решило вашу проблему.

...