Solved EntityDamageEvent firing twice

Discussion in 'Spigot Plugin Development' started by AwesomestGamer, Mar 27, 2020.

Thread Status:
Not open for further replies.
  1. The following code is having onEntityDamageEvent fire twice when the player is damaged by void. I'm not sure how to fix it; can someone explain? And before anyone suggests, I don't want to use NMS/Reflection for this system because of how annoying it is. I'm only doing things that are impossible without protocol/packets with NMS/Reflection.
    Code (Java):
    package to.us.blockverse.CrystalCapture;

    import java.util.HashMap;
    import java.util.Map;

    import org.bukkit.ChatColor;
    import org.bukkit.Location;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.entity.EntityDamageByEntityEvent;
    import org.bukkit.event.entity.EntityDamageEvent;
    import org.bukkit.event.entity.EntityDamageEvent.DamageCause;

    import static org.bukkit.Bukkit.*;

    public class Death implements Listener {
        static CrystalCapture plugin = CrystalCapture.getPlugin(CrystalCapture.class);

        static Map<Player, Player> victimToAssailant = new HashMap<>();
        @EventHandler
        public void onEntityDamageEvent(EntityDamageEvent event) {
            getLogger().info("EntityDamageEvent occurred!");
            if(!(event.getEntity() instanceof Player)) return;
            if((event.getCause() == DamageCause.ENTITY_ATTACK)) return;
            Player victim = (Player) event.getEntity();
            Player assailant = victimToAssailant.get(victim);

            if(event.getFinalDamage() >= victim.getHealth()) {
                event.setCancelled(true);
                triggerDeath(victim);
                if (assailant != null) {
                    triggerDeath(victim);
                    getServer().broadcastMessage(ChatColor.RED + victim.getDisplayName() + ChatColor.GRAY + "(1) was deleted by " + assailant.getDisplayName());
                    assailant.sendMessage(ChatColor.GREEN + "(1) You killed " + victim.getDisplayName());
                }
                else {
                    getServer().broadcastMessage(ChatColor.RED + victim.getDisplayName() + ChatColor.GRAY + "(1) died");
                }
            }
        }

        @EventHandler
        public void onEntityDamageByEntityEvent(EntityDamageByEntityEvent event) {
            Player victim = (Player) event.getEntity();
            if(!(event.getDamager() instanceof Player)) return;
            victimToAssailant.remove(victim);
            Player assailant = (Player) event.getDamager();
            victimToAssailant.put(victim, assailant);

            if(event.getFinalDamage() >= victim.getHealth()) {
                event.setCancelled(true);
                triggerDeath(victim);
                assailant.sendMessage(ChatColor.GREEN + "(2) You killed " + victim.getDisplayName());
                getServer().broadcastMessage(ChatColor.RED + victim.getDisplayName() + ChatColor.GRAY + "(2) was deleted by " +  assailant.getDisplayName());
            }
        }

        private void triggerDeath(Player victim) {
            victimToAssailant.remove(victim);
            victim.setHealth(20);
            victim.getInventory().clear();
            MinigameController.getInstance().spawnPlayer(victim);
        }
    }
     
  2. Is there more than one instance of your Plugin?
    Have you registered the Listener twice?
    Have you verified that nothing else is triggering another EntityDamageEvent (another Plugin)?
    Have you debugged the values of the event and verified that it is indeed the same event (void damage) twice?

    Asides from that, you are heavily abusing static inside your code.
     
    • Agree Agree x 1
  3. Nope. Frankly, I don't think abusing static matters here since it works, and I'll be the only one to ever maintain this codebase. Much of this code will be rewritten anyways. Here's an entire test plugin, if you have the time to look through it. It has everything needed to reproduce the error.
     

    Attached Files:

  4. Remember that it is on 1.8.8.
     
  5. And yes, I do try all of the beginner things. I'm not an idiot, and as of right now I believe that it is a bug and I need a workaround.
     
  6. This.
    This.
    This.

    You managed to say so many very famous phrases in just one post :)

    Regarding your problem, maybe this little clip I've recorded explains it by itself:
     
  7. Yes, I am trying to convert to singleton format. As you can see, in my original code (not the test plugin I sent), the class MinigameController is a singleton (because it was written recently). I learn as I code, and I guess I'll have to learn the hard way because ironically learning through catastrophes teaches me the best. Unless not using static here would solve the issue, then I'll stick with it until I clean up the entire codebase.
    And a question about that—I'm not teleporting the player so high up that they could be getting fall damage. Does minecraft store the fall distance from falling into the void?
     
  8. Yes. You will need:
    Code (Java):
    player.setFallDistance(0.0f);
     
  9. Thank you. Marked as solved and thread locked. Note: If you are someone in the future looking at this, just DM me.
     
Thread Status:
Not open for further replies.