Hi, it's my first time posting a question in this platform. So, quite recently I have been studying coding plugins and I stumbled upon this problem. Inside the for loop I aimed to damage other players that was not damaged. So, I made a new event that has a cause which is suicide so that when it damages the player this method will not be called all over again eventually killing the player. I did my research and found out about calling a new entity damage event to damage the player but it does not seem to work. I need an alternative way to damage my player but not calling this event over and over. Code: p.Damage(event.getDamage()); the code above loops the event Code: @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); } } } } The commented code works but when it reaches negative numbers it does not kill the player it only set the players health to a negative number.
You have to explicitly kill the player yourself when you're setting damage. Test if the cHealth <= 0 and then kill the player. Also, it's better practice to minimize the amount of times you nest your if statements. Instead of this: Code: 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); } } } do this: Code: if (!(event.getEntity() instanceof Player)) return; if (event.getCause() == DamageCause.SUICIDE) return; 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); } }
@FactBoy Just to add onto what @bowlerguy66 said, you can use "Math.max(0, p.getHealth() - event.getDamage())" instead of an if statement.
To offer another suggestion: You can also use Java's stream to do something for all players that don't have a certain name! Also, I would recommend you to try to get a player ID to compare because these are constant. Anyways, here's the stream adaptation in case you're interested in how they work, I also use ID's here instead: Code: Bukkit.getOnlinePlayers().stream().filter(p -> !p.getUniqueId().equals(damagedId)).forEach(p -> { //code for other players that are not damaged }); Personally I really like Java streams because they can help reduce nesting and prevent simple errors in your manually coded loops: nobody's perfect, and the Java stream library pretty much is.