Playerdamageevent AND entitydamagebyentity event

Discussion in 'Plugin Development' started by Bienyyy, Jun 22, 2016.

Thread Status:
Not open for further replies.
  1. Offline

    Bienyyy

    Is it possible to use the both of them in one single plugin? The exact question probably is: is it possible to make use of the entitydamagebyentityevent and does the playerdamageevent still get passed after the entitydamagebyentityevent is not cancelled if i use event priority high on the first one?
     
  2. Offline

    timtower Administrator Administrator Moderator

    @Bienyyy Yes, you can use them in the same plugin, you can even make a plugin with every single event out there if you want.
    Not sure in what order they are called though.
     
  3. Offline

    Bienyyy

    okay... cause it seemed not to work for me. in the entitydamageevent i checked if the player was hit by another player with a gold sword and if thats the case i cancelled the event. For me this didnt trigger at all. everything in the playerdamageevent continued to work though. anyways, thanks for the answer :)
     
  4. Offline

    timtower Administrator Administrator Moderator

    @Bienyyy Could you post your full code then?
     
  5. Offline

    Bienyyy

    there you go
    Code:
    @EventHandler(priority = EventPriority.HIGH)
        public void onDuel(EntityDamageByEntityEvent event){
            if(event.getEntity() instanceof Player && event.getDamager() instanceof Player){
                Player player = (Player) event.getEntity();
                Player p2 = (Player) event.getDamager();
                if(p2.getItemInHand().getType().equals(Material.GOLD_SWORD)){
                    if(duel.get(player).equals(p2)){
                        startD(p2, player, false);
                        duel.remove(player);
                        event.setCancelled(true);
                    }
                    else{
                        duel.put(p2, player);
                        event.setCancelled(true);
                    }
                }
            }
        }
    this shouldnt do anything at all if p2s held item is not a gold sword or am i totally wrong somewhere?
    also i am assuming if this gets triggered, the playerdmgevent shouldnt be passed at all
     
  6. Offline

    WolfMage1

    Guessing entity damage event would be called first then player,

    Just seems the logical way for it to happen for me.

    I'm really curious to find out though.
     
  7. Offline

    Lordloss

    Looks fine for me, did you try debugging to see where it gets stuck?
     
  8. Offline

    Bienyyy

    Yeah, i used the broadcastmessage command in the second line. So the event doesnt even get passed. Every other event still works tho
     
  9. Offline

    WolfMage1

    Events only dont pass if they're not registered :p,
     
  10. Offline

    Bienyyy

    As i said. The other events get passed. I registered the events. But thanks for the reply:)
     
  11. Offline

    Zombie_Striker

    @Bienyyy
    Use == when comparing enums. Use .equals when comparing objects.

    Also, the player could also be holding nothing, so the item in their hand would be null. This means this line can throw an NPE. Make sure the item is not null before getting the type.

    Are you getting any errors? Are you sure the "startD" and "duel" methods go through?
     
    bwfcwalshy likes this.
  12. Offline

    Bienyyy

    Duel is just a hashmap consisting of two players. Yes i am absolutely sure startD works, as i also use it to start a duel for the queue.
     
  13. Offline

    SP3NC3RXD

    I never actually thought about this. I'm curious to find out too!
     
  14. Offline

    Lordloss

    Try to store the playernames or UUID in the hashmap and not the player objects. And make a debug message after every if
     
  15. Offline

    Bienyyy

    Thats not the problem. I already put a debug message right at the start od the event and it does not get passed at all. Ive been also using playerdata for a queue and it works smooth as butter. I guess ill just put everything in the playerdamageevent and check for if the last damage source equals an online player who holds a gold sword. Still thank you all
     
  16. Offline

    WolfMage1

    While both are still technically correct as .equals (i believe) just refers to ==, == is null safe so it is better to use for enums.

    However,

    The fact that == never throws NPE in my mind is a disadvantage of ==. There should hardly ever be a need for enum types to be null, since any extra state that you may want to express via null can just be added to the enum as an additional instance. If it is unexpectedly null, I'd rather have a NPE than == silently evaluating to false
     
    Last edited: Jun 24, 2016
  17. Offline

    I Al Istannen

    @WolfMage1
    Yes, .equals in its implementation in the Object class, just uses "==". Yes, it is null safe, not like equals.

    Personally, I would still use "==" with enums. It also adds compiler time type compatibility (so Color.BLACK == Paint.BLACK wouldn't compile, the equals code would and return false. May be handy sometimes)

    Equals only throws a NPE if the object you call it on is null. So ChatColor.RED.equals(null) will return false, just like ==. Only throws a NPE if you use null.equals(ChatColor.RED). This is documented in the Object#equals(Object) javadoc:

    I think it is personal preference. I prefer the possibly swallowed NPE, which oftentimes isn't thrown, if you compare expected vs. given.
    I find it more readable, so FOO.equals(BAR) is harder to read than FOO == BAR. Might be me though.
    I also like the compile time type evaluation, as you may Import the wrong thing and equals doesn't complain.
    And I don't really think null safety is bad there.

    Won't force you to anything, just explain another point of view.
     
  18. Offline

    Bienyyy

    so yeah, i played around a bit and failed horribly. as i have no way to test it now because everybody i could play minecraft with is not around im just asking you if what i did is at least possible:
    Code:
    if(event instanceof EntityDamageByEntityEvent){
                            EntityDamageByEntityEvent evt = (EntityDamageByEntityEvent) event;
                            if(evt.getDamager() instanceof Player){
                                winner = (Player) evt.getDamager();
                                if(winner.getItemInHand().getType() == Material.GOLD_SWORD){
                                    if(duel.get(loser.getDisplayName()).equals(winner.getDisplayName())){
                                        if(winner.equals(queue) || loser.equals(queue)){
                                            queue = null;
                                        }
                                        if(winner.equals(queueR) || loser.equals(queueR)){
                                            queueR = null;
                                        }
                                        winner.playSound(winner.getLocation(), Sound.ORB_PICKUP, 1, 1);
                                        startCombat(winner, loser, false);
                                        duel.remove(loser.getName());
                                        winner.sendMessage(S + ChatColor.GRAY + " You accepted " + loser.getName() + "'s challenge!");
                                        loser.sendMessage(S + ChatColor.GRAY + " " + winner.getDisplayName() + " accepted your challenge!");
                                    }
                                    else{
                                        duel.put(winner.getDisplayName(), loser.getDisplayName());
                                        winner.playSound(winner.getLocation(), Sound.ORB_PICKUP, 1, 1);
                                        winner.sendMessage(S + ChatColor.GRAY + " You challenged " + loser.getDisplayName() + " to a duel!");
                                        loser.sendMessage(S + ChatColor.GRAY + " " + winner.getDisplayName() + " challenged you to a duel!");
                                    }
                                }
                            }
                        }
    i have no idea if checking if the event is an entitydamagebyentityevent will work at all but it seems if it does its the most reliable method to get the last player that hit you.
    that whole code is part of an if else structure in my entitydamageevent.
    yes i am absolutely certain that everything around this (that could affect it) works for sure. if you want the whole event i can post it but its honestly a ~90 lines long code and also a mess.
     
  19. Offline

    I Al Istannen

    @Bienyyy
    Don't know if suggesting this is allowed (as offline mode is not supported, but this in no way encourages offline mode and there shouldn't be any consequences on anything he wants to try by putting the server in it), but a testing server in offline mode should help with the player amount problem.

    @Mods: Is this allowed? I will report this post, so that you can remove it if not. I just thought it would be one of the best solutions to his problem and doesn't seem to contradict the rules clearly (Offline mode is often the result of piracy so we choose not to support it on these forums. It is not and no problems should arise of it. And it is a test server.).
     
    Last edited: Jun 24, 2016
  20. Offline

    Zombie_Striker

    @I Al Istannen
    For testing, it is fine. It's only questionable if a server is in offline mode when there is no other reason (besides for piracy) for it to be.
     
    I Al Istannen likes this.
  21. Offline

    Bienyyy

    Does that still give the server the player uuids? If not its not gonna work my plugin relys heavily on those. Id still like to know if its even technically possible for an entitydamageevent to be an instance of entitydamagebyentity event. Thanks for the suggestions tho
     
  22. Offline

    I Al Istannen

    @Bienyyy
    The server gives a (random?) UUID to the player.

    Code:
    @EventHandler
    public void onHit(EntityDamageEvent e) {
        System.out.println(e.getClass());
    }
    Output when hitting a creeper:
    So, yes it can be an entityDamageByEntityEvent
     
  23. Offline

    Bienyyy

    Thank you! That makes things much easier:)
     
  24. Offline

    Bienyyy

    So yeah, i did this on 2 occasions. on one of them it worked perfectly fine, on the other one however - meaning the code i added in this thread before it says it could not pass the entitydamagebyentity event even though i use it the same way i do in the working statement.

    any idea why it refuses to do what it should do?
    Code:
    if(!combat.contains(loser)){
                        if(event instanceof EntityDamageByEntityEvent){
                            EntityDamageByEntityEvent evt = (EntityDamageByEntityEvent) event;
                            if(evt.getDamager() instanceof Player){
                                winner = (Player) evt.getDamager();
                                if(winner.getItemInHand().getType() == Material.GOLD_SWORD){
                                    if(duel.get(loser.getDisplayName()).equals(winner.getDisplayName())){
                                        if(winner.equals(queue) || loser.equals(queue)){
                                            queue = null;
                                        }
                                        if(winner.equals(queueR) || loser.equals(queueR)){
                                            queueR = null;
                                        }
                                        winner.playSound(winner.getLocation(), Sound.ORB_PICKUP, 1, 1);
                                        startCombat(winner, loser, false);
                                        duel.remove(loser.getName());
                                        winner.sendMessage(S + ChatColor.GRAY + " You accepted " + loser.getName() + "'s challenge!");
                                        loser.sendMessage(S + ChatColor.GRAY + " " + winner.getDisplayName() + " accepted your challenge!");
                                    }
                                    else{
                                        duel.put(winner.getDisplayName(), loser.getDisplayName());
                                        winner.playSound(winner.getLocation(), Sound.ORB_PICKUP, 1, 1);
                                        winner.sendMessage(S + ChatColor.GRAY + " You challenged " + loser.getDisplayName() + " to a duel!");
                                        loser.sendMessage(S + ChatColor.GRAY + " " + winner.getDisplayName() + " challenged you to a duel!");
                                    }
                                }
                            }
                        }
                        //every kind of damage besides lavadamage gets cancelled WORKING
                        if (event.getCause() != DamageCause.LAVA){
                            event.setCancelled(true);
                        }
                    }
    i first check if the entity is a player and assign it to the variable loser.
    then (thats where this code here starts) it checks if the hit player is in combat (an array of players).
    if not and if the event is an entitydamagebyentity event we get the damager assigned to the winner value.
    if said player is holding a gold sword one of these two options should apply but it just wont get to this point. Also the hit player gets damaged even tho the event always gets cancelled if its not lava damage besides this very specific situation. I am really getting pretty frustrated with this as i dont see why its so hard for me.

    EDIT: also i put server output lines in there and it seems to work well until the thing IN the goldsword-if statement. so it gets that the player who hit the other player is holding a gold sword but for whatever reason gets an error after that.
    duel is just a Hashmap<String,String> where for every player the last players name he hit is stored.

    EDIT #2 so... the server says theres a nullpointerexception in line:
    if(duel.get(loser.getDisplayName()).equals(winner.getDisplayName())){...
    i dont get how thats possible as i clearly initialize duel, i use winner for the operations before and loser is just the " (Player) event.getEntity();" thing you normally do. how is it even possible for this to lead to a nullpointerexception?
     
    Last edited: Jun 26, 2016
  25. Offline

    I Al Istannen

    @Bienyyy
    What exactly is the error? Could you post the stacktrace?

    I could imagine a Null Pointer Exception (NPE) if the player has nothing in his hand.
     
  26. Offline

    Bienyyy

    thanks for your help, i finally got that shit figured out and feel stupid as hell xD
    so yeah i wrote
    duel.get(player.getDisplayName).equals(blabla) which is fine IF player.getDisplayName is a key in said hashmap. thats what threw the exception. I changed it to compare winners name with losers duel entry and it finally works :)
     
    I Al Istannen likes this.
Thread Status:
Not open for further replies.

Share This Page