Shared damage

Discussion in 'Plugin Development' started by FactBoy, Jul 2, 2020.

  1. Offline

    FactBoy

    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.
     
    Last edited: Jul 2, 2020
  2. Offline

    bowlerguy66

    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);
                }
            }
    
     
  3. Offline

    KarimAKL

    @FactBoy Just to add onto what @bowlerguy66 said, you can use "Math.max(0, p.getHealth() - event.getDamage())" instead of an if statement.
     
    bowlerguy66 likes this.
  4. Offline

    DutchJellyV2

    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.
     
    Strahan likes this.

Share This Page