在for循环中,我旨在破坏未损坏的其他玩家。因此,我做了一个新事件,其原因是自杀,因此当它损坏玩家时,不会再次调用此方法,最终会杀死玩家。我进行了研究,发现了有关调用新的实体损坏事件EntityDamageEvent e = new EntityDamageEvent(p, DamageCause.SUICIDE,(int)event.getDamage()); Bukkit.getServer().getPluginManager().callEvent(e);损坏播放器的操作,但似乎不起作用。我需要一种替代方法来破坏我的玩家,但又不要一遍又一遍地调用此事件。p.Damage(event.getDamage());当放置在内部时,事件循环。

@EventHandler
    public void onPlayerDamage(EntityDamageEvent event) {
        if(event.getEntity() instanceof Player && event.getCause() != DamageCause.SUICIDE ) {
            Player damaged =  (Player) event.getEntity();
            for(Player p :Bukkit.getOnlinePlayers()) {
                if(!p.getName().equalsIgnoreCase(damaged.getName())) {
                    EntityDamageEvent e = new EntityDamageEvent(p, DamageCause.SUICIDE,(int)event.getDamage());
                    Bukkit.getServer().getPluginManager().callEvent(e);

                    //double cHealth =p.getHealth()-event.getDamage();
                    //p.setHealth(cHealth);
                }
            }


        }
注释的代码有效,但是当达到负数时,它不会杀死播放器,而只会将播放器的运行状况设置为负数。

最佳答案

调用伤害事件不会伤害玩家。事件用于在事件发生时通知插件,事件本身不会使任何事情发生。
Damageable#setHealth方法不会调用Damage事件,因此您可以在不重复调用该事件的情况下使用它。如javadocs所述,如果运行状况小于0,则该方法将抛出IllegalArgumentException,因此只需对其进行检查。

double cHealth = p.getHealth() - event.getDamage();
p.setHealth(cHealth < 0 ? 0 : cHealth);
但是,我不建议使用setHealth方法,因为它不会考虑装甲。要使用Damageable#damage方法而不会重复调用Damage事件,可以将播放器添加到集合中,并检查播放器是否在该集合中。
private Set<Player> playerSet = new HashSet<>();

@EventHandler
public void onPlayerDamage(EntityDamageEvent event) {
    if (event.getEntity() instanceof Player) {
        Player damaged = (Player) event.getEntity();
        if (!playerSet.contains(damaged)) {
            for (Player p : Bukkit.getOnlinePlayers()) {
                if (!damaged.equals(p)) {
                    playerSet.add(p);
                    p.damage(event.getDamage());
                }
            }
        } else {
            playerSet.remove(damaged);
        }
    }
}

08-17 02:07