Solved Get The Last Damager on PlayerDeathEvent

Discussion in 'Plugin Development' started by jonacroco, Nov 30, 2015.

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

    jonacroco

    Hey !
    I'm just trying to solve my problem with PlayerDeathEvent.. I want to get the last entity who damaged the player before he dies and if this entity was a player, broadcast something. But i don't know how to do this because when a player damage an other one and push it into the void, the last damage was the void..
    How to do this please ?
    Thanks !
    Jonacroco

    (I'm french, sorry for my bad english.. ^^)
     
  2. Offline

    mcdorli

    PlayerDeathEvent#getEntity().getKiller()
     
  3. Offline

    jonacroco

    Thanks for your anwser but when i get the killer, if the player dies in the void, this not returns to the killer but to nothing..
     
  4. Offline

    Zombie_Striker

    @jonacroco
    Save the last player that damaged another player in a Hashmap (Google how to create hashmaps if you do knot now how to). If the player died, and that player was in the hashmap, remove the player from hashmap and send the message.
     
  5. Offline

    Scimiguy

    Dont save the player, save the uuid of the player
     
  6. Offline

    jonacroco

    Ok thanks ! I will try with the HashMap :3
     
  7. Offline

    Scimiguy

    If it solves your problem, dont forget to come back and edit the title of this thread to mark it as solved
     
  8. Offline

    jonacroco

    It doesn't fix the problem...
    I have this Event :

    Code:
    private static HashMap<Player, String> lastdamager = new HashMap<Player, String>();
    
       @EventHandler
       public void onPlayerDeath(PlayerDeathEvent e) {
    
         e.setDeathMessage("");
         Player player = (Player) e.getEntity();
         Player damager = (Player) player.getLastDamageCause().getEntity();
       
         if(player.getLastDamageCause().getEntity().equals(damager)) {
           lastdamager.put(damager, damager.getName());
           if(player.isDead()) {
             lastdamager.remove(damager, damager.getName());
             if(BumbRush.RedTeam.contains(damager)) {
               int i = 0;
               ScoreBoardLobby.redkills.add(i++);
               Bukkit.broadcastMessage("2");
             }
             if(BumbRush.BlueTeam.contains(damager)) {
               int i = 0;
               ScoreBoardLobby.bluekills.add(i++);
               Bukkit.broadcastMessage("3");
             }
           
           }
         }
    I don't know how i can save the PlayerUUID int the HashMap because it's written with letters and number, so is it and integer, a double ? :/
    Help pls :/
     
    Last edited: Nov 30, 2015
  9. Offline

    Zombie_Striker

    You are still using the Player. Replace Player with the player's name or (preferably) the UUID of the player.
    This looks like a possible abuse of static.
    So if the last cause of damage is the last cause of damage?This should always be true.

    Instead of putting the player in the hashmap once he's actually dead, put him in the hashmap when a player damages the player by using EntityDamageEntityEvent.
     
  10. Offline

    jonacroco

    Thanks !
    Is this looks like that ?
    Code:
    if(player.getLastDamageCause() instanceof EntityDamageByEntityEvent) {
     
  11. Offline

    Zombie_Striker

    @jonacroco
    *facedesk*

    Please do rubber duck debugging (Talk out what that line is doing.) What does each thing return?
     
  12. Offline

    jonacroco

    I have this :
    Code:
        HashMap<Player, String> lastdamager = new HashMap<Player, String>();
    
        @EventHandler
        public void onPlayerDeath(PlayerDeathEvent e) {
    
            e.setDeathMessage("");
            Player player = (Player) e.getEntity();
            Player damaged = (Player) player.getLastDamageCause().getEntity();
    
            if(player.getLastDamageCause() instanceof EntityDamageByEntityEvent) {
                //that line check if the damageCause is Entity Damage By an other one
                lastdamager.put(damaged, damaged.getUniqueId().toString());
                if(player.isDead()) {
                    lastdamager.remove(damaged, damaged.getUniqueId().toString());
                    if(BumbRush.RedTeam.contains(damaged)) {
                        int i = 0;
                        ScoreBoardLobby.redkills.add(i++);
                    }
                    if(BumbRush.BlueTeam.contains(damaged)) {
                        int i = 0;
                        ScoreBoardLobby.bluekills.add(i++);
                    }
                   
                }
            }
    like that ?
    sorry i don't understand every things you say..
     
  13. Offline

    Zombie_Striker

    @jonacroco
    You are testing if the LastDamageCause (which returns an entitiy) is an instance of EntityDamgedByEntityEvent (An Event)

    So you're saying "Is an Entity the same as an Event?"

    What I meant was the same way you have PlayerDeathEvent, make a new Event for EntityDamagedByEntityEvent. Once you created that event, that's when you add the player to the Hashmap.
     
  14. Offline

    jonacroco

    Thanks ^^'
    So now i have an EntityDamagedByEntity with that code:
    Code:
          
     
    HashMap<Player, String> lastdamager = new HashMap<Player, String>();
       
       @EventHandler
       public void onEntityDamageByEntity(EntityDamageByEntityEvent e) {
         
         Player player = (Player) e.getEntity();
         Player damager = (Player) e.getDamager();
         
         lastdamager.put(damager, damager.getUniqueId().toString());
    
    Is it correct ?
    In the PlayerDeathEvent Event i have this :
    Code:
        @EventHandler
        public void onPlayerDeath(PlayerDeathEvent e) {
    
            e.setDeathMessage("");
            Player player = (Player) e.getEntity();
            Player damaged = (Player) player.getLastDamageCause().getEntity();
    
            if(lastdamager.contains(damaged)) {
                if(player.isDead()) {
                    lastdamager.remove(damaged, damaged.getUniqueId().toString());
                
                    if(BumbRush.RedTeam.contains(damaged)) {
                        int i = 0;
                        ScoreBoardLobby.redkills.add(i++);
                    }
                    if(BumbRush.BlueTeam.contains(damaged)) {
                        int i = 0;
                        ScoreBoardLobby.bluekills.add(i++);
                    }
                
                }
               }
    Is it already correct ?
    thanks
     
  15. Offline

    Zombie_Striker

    @jonacroco
    You shouldn't blind cast. You should check if the entities are players first.

    Okay, so you are now storing who killed tje player last, now its time to get the damager
    Remove this line, and after you know that the lastdamager contains the killed player, and before you remove the player, Add this
    Code:
    Player killer = Bukkit.getServer().getPlayer(lastDamager.get(damaged));
     
  16. Offline

    jonacroco

    Ok so now if i have all understanded i have that :

    Code:
    public static HashMap<Player, String> lastdamager = new HashMap<Player, String>();
    
    @EventHandler
        public void onEntityDamageByEntity(EntityDamageByEntityEvent e) {
         
            Player damager = (Player) e.getDamager();
         
            lastdamager.put(damager, damager.getUniqueId().toString());
        }
    
    @EventHandler
        public void onPlayerDeath(PlayerDeathEvent e) {
            e.setDeathMessage("");
            Player player = (Player) e.getEntity();
            Player damaged = (Player) player.getLastDamageCause().getEntity();
    
            if(damaged instanceof Player) {
                if(lastdamager.containsKey(damaged.getUniqueId().toString())) {
                    if(player.isDead()) {
                        Player killer = Bukkit.getServer().getPlayer(lastdamager.get(damaged));
                        lastdamager.remove(damaged, damaged.getUniqueId().toString());
                        if(BumbRush.RedTeam.contains(killer)) {
                            int i = 0;
                            ScoreBoardLobby.redkills.add(i++);
                        }
                        if(BumbRush.BlueTeam.contains(killer)) {
                            int i = 0;
                            ScoreBoardLobby.bluekills.add(i++);
                        }
                    }
    
                }
            }
    }
    
    all right or i missed something ? :/
     
  17. Offline

    Scimiguy

    Why dont you actually try running it and see what comes back
     
  18. Offline

    jonacroco

    I have tried running it but nothing appened :/
     
  19. Offline

    Zombie_Striker

    @Scimiguy Although he should do this, its better he posted 5 min ago than 5 minutes from now.
    This won't work because you checking if the key is a UUID
    And you are putting in the Player instance as the key.

    Either put in the UUID, and check if the hashmap contains a UUID
    OR
    Put in a Player and check if the hashmap contains the Player.
     
  20. Offline

    teej107

    Bro! Do you even JavaDoc? http://jd.bukkit.org/org/bukkit/entity/Entity.html#getLastDamageCause()

    This code seemed better off than your last. There are still a few mistakes though. getLastDamageCause() could return null and you are also blindly casting. I would also recommend Rubber Duck debugging.
     
    Zombie_Striker likes this.
  21. Offline

    jonacroco

    Lol ^^
    This method should work in fact xD
    But if i put the damager and the damager.getUniqueId().toString in the Hashmap lastdamager, when i check if the damager is in, i have to do
    Code:
    if(lastdamager.containsKey(damager)) { 
    ? or
    Code:
    if(lastdamager.containsKey(damager.getUniqueID().toString)) {
    ?
    Thanks !
     
  22. Offline

    Zombie_Striker

    teej107 likes this.
  23. Offline

    jonacroco

    I have gaps with hashMaps, i don't understand their logic :/
     
  24. Offline

    Scimiguy

    A hashmap is just a collection where one thing refers to another thing.

    So if your references (keys) are uuids, youd store a uuid and a value with it.
    That way you can get the value you stored simply by giving it your key, which in this case would be a uuid
     
  25. Offline

    RoboticPlayer

    First, get rid of the static modifier on your HashMap. Secondly, store the player's UUID, not the player object (HashMap<UUID, String>). Third, put
    Player damaged = (Player) player.getLastDamageCause().getEntity();
    After you check if it is a player. Even though you are still checking (which is good), check BEFORE you cast.
     
  26. Offline

    teej107

  27. Offline

    jonacroco

    Thanks all for your answers !

    @teej107
    Okok, so i try to understand now ^^
    So i have a HashMap named lastdamager with Player as key and player UUID as value :
    Code:
        public HashMap<Player, String> lastdamager = new HashMap<Player, String>();
    Firstly, in the EntityDamagedByEntityEvent :
    Code:
        @EventHandler
        public void onEntityDamageByEntity(EntityDamageByEntityEvent e) {
    
            Player damager = (Player) e.getDamager();
            lastdamager.put(damager, damager.getUniqueId().toString());
        }
    
    Secondly, in the PlayerDeathEvent i do this :
    Code:
        @EventHandler
        public void onPlayerDeath(PlayerDeathEvent e) {
    
            e.setDeathMessage("");
            Player player = (Player) e.getEntity();
            Player damager = (Player) player.getLastDamageCause().getEntity();
    
            if(damager instanceof Player) {
                if(lastdamager.containsKey(damager) && !damager.equals(null)) {
                    if(player.isDead()) {
                        Player killer = Bukkit.getServer().getPlayer(lastdamager.get(damager));
                        lastdamager.remove(damager, damager.getName());
    
                        if(BumbRush.RedTeam.contains(killer)) {
                            int i = 0;
                            ScoreBoardLobby.redkills.add(i++);
                        }
    
                        if(BumbRush.BlueTeam.contains(killer)) {
                            int i = 0;
                            ScoreBoardLobby.bluekills.add(i++);
                        }
               
                    }
                }
    
            }
    All right ?
    I check the 'damager' Key is in my lastdamager HashMap ^^

    I have runned this code :
    Code:
    public HashMap<Player, String> lastdamager = new HashMap<Player, String>();
    
        @EventHandler
        public void onEntityDamageByEntity(EntityDamageByEntityEvent e) {
    
            Player damager = (Player) e.getDamager();
            lastdamager.put(damager, damager.getUniqueId().toString());
            Bukkit.broadcastMessage("" + lastdamager.toString());
        }
    
        @EventHandler
        public void onPlayerDeath(PlayerDeathEvent e) {
    
            e.setDeathMessage("");
            Player damaged = (Player) e.getEntity().getLastDamageCause().getEntity();
    
            if(damaged instanceof Player) {
                Bukkit.broadcastMessage("" + lastdamager.toString());
                Bukkit.broadcastMessage("1");
                if(!lastdamager.isEmpty()) {
                    if(damaged.isDead()) {
                        Bukkit.broadcastMessage("2");
                        Player killer = Bukkit.getServer().getPlayer(lastdamager.get(damaged));
                        lastdamager.remove(damaged.getKiller(), damaged.getUniqueId().toString());
                        Bukkit.broadcastMessage("" + lastdamager.toString());
                     
                        if(BumbRush.RedTeam.contains(killer)) {
                            Bukkit.broadcastMessage("4");
                            int i = 0;
                            ScoreBoardLobby.redkills.add(i++);
                            damaged.sendMessage("§aVous §6avec été tué par §c" + killer.getName());
                            killer.sendMessage("§aVous §6avez tué §c" + damaged.getName());
                        }
    
                        if(BumbRush.BlueTeam.contains(killer)) {
                            Bukkit.broadcastMessage("5");
                            int i = 0;
                            ScoreBoardLobby.bluekills.add(i++);
                            damaged.sendMessage("§aVous §6avec été tué par §c" + killer.getName());
                            killer.sendMessage("§aVous §6avez tué §c" + damaged.getName());
                        }
                     
                    }
                }
    
            }
    
    But the line
    Code:
                        Player killer = Bukkit.getServer().getPlayer(lastdamager.get(damaged));
    returns me a console error like this :
    Code:
    [19:17:27 ERROR]: Could not pass event PlayerDeathEvent to BRplugin v1.0
    org.bukkit.event.EventException
            at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.ja
    va:303) ~[Craftbukkit_1.8.jar:git-Spigot-"4133000"]
            at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.jav
    a:62) ~[Craftbukkit_1.8.jar:git-Spigot-"4133000"]
            at org.bukkit.plugin.SimplePluginManager.fireEvent(SimplePluginManager.j
    ava:509) [Craftbukkit_1.8.jar:git-Spigot-"4133000"]
            at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.j
    ava:494) [Craftbukkit_1.8.jar:git-Spigot-"4133000"]
            at org.bukkit.craftbukkit.v1_8_R1.event.CraftEventFactory.callPlayerDeat
    hEvent(CraftEventFactory.java:381) [Craftbukkit_1.8.jar:git-Spigot-"4133000"]
            at net.minecraft.server.v1_8_R1.EntityPlayer.die(EntityPlayer.java:407)
    [Craftbukkit_1.8.jar:git-Spigot-"4133000"]
            at net.minecraft.server.v1_8_R1.EntityLiving.damageEntity(EntityLiving.j
    ava:765) [Craftbukkit_1.8.jar:git-Spigot-"4133000"]
            at net.minecraft.server.v1_8_R1.EntityHuman.damageEntity(EntityHuman.jav
    a:799) [Craftbukkit_1.8.jar:git-Spigot-"4133000"]
            at net.minecraft.server.v1_8_R1.EntityPlayer.damageEntity(EntityPlayer.j
    ava:486) [Craftbukkit_1.8.jar:git-Spigot-"4133000"]
            at net.minecraft.server.v1_8_R1.EntityHuman.attack(EntityHuman.java:1000
    ) [Craftbukkit_1.8.jar:git-Spigot-"4133000"]
            at net.minecraft.server.v1_8_R1.EntityPlayer.attack(EntityPlayer.java:10
    43) [Craftbukkit_1.8.jar:git-Spigot-"4133000"]
            at net.minecraft.server.v1_8_R1.PlayerConnection.a(PlayerConnection.java
    :1280) [Craftbukkit_1.8.jar:git-Spigot-"4133000"]
            at net.minecraft.server.v1_8_R1.PacketPlayInUseEntity.a(SourceFile:52) [
    Craftbukkit_1.8.jar:git-Spigot-"4133000"]
            at net.minecraft.server.v1_8_R1.PacketPlayInUseEntity.a(SourceFile:11) [
    Craftbukkit_1.8.jar:git-Spigot-"4133000"]
            at net.minecraft.server.v1_8_R1.PacketHandleTask.run(SourceFile:13) [Cra
    ftbukkit_1.8.jar:git-Spigot-"4133000"]
            at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) [
    ?:1.8.0_51]
            at java.util.concurrent.FutureTask.run(Unknown Source) [?:1.8.0_51]
            at net.minecraft.server.v1_8_R1.MinecraftServer.z(MinecraftServer.java:6
    86) [Craftbukkit_1.8.jar:git-Spigot-"4133000"]
            at net.minecraft.server.v1_8_R1.DedicatedServer.z(DedicatedServer.java:3
    16) [Craftbukkit_1.8.jar:git-Spigot-"4133000"]
            at net.minecraft.server.v1_8_R1.MinecraftServer.y(MinecraftServer.java:6
    27) [Craftbukkit_1.8.jar:git-Spigot-"4133000"]
            at net.minecraft.server.v1_8_R1.MinecraftServer.run(MinecraftServer.java
    :530) [Craftbukkit_1.8.jar:git-Spigot-"4133000"]
            at java.lang.Thread.run(Unknown Source) [?:1.8.0_51]
    Caused by: java.lang.IllegalArgumentException: Name cannot be null
            at org.apache.commons.lang.Validate.notNull(Validate.java:192) ~[Craftbu
    kkit_1.8.jar:git-Spigot-"4133000"]
            at org.bukkit.craftbukkit.v1_8_R1.CraftServer.getPlayer(CraftServer.java
    :398) ~[Craftbukkit_1.8.jar:git-Spigot-"4133000"]
            at fr.jonacroco.src.listeners.player.PlayerDeath.onPlayerDeath(PlayerDea
    th.java:40) ~[?:?]
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0
    _51]
            at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0
    _51]
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1
    .8.0_51]
            at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_51]
            at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.ja
    va:299) ~[Craftbukkit_1.8.jar:git-Spigot-"4133000"]
            ... 21 more
    So the error is line 40 in the code which correpond to this line :
    Code:
      Player killer = Bukkit.getServer().getPlayer(lastdamager.get(damaged));
    Help please.. :'(

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
    EDIT: sorry
     
    Last edited: Dec 1, 2015
  28. Offline

    Zombie_Striker

    That's your problem. The string provided is null.
     
  29. Offline

    Scimiguy

    Don't store players.
     
  30. Offline

    jonacroco

    That's so hard...
    Also any idea to get the last damageR of a player because
    Code:
     e.getEntity.getLastDamageCause.getEntity()
    returns to the player wich was damaged (in PlayerDeathEvent) ?
    Thanks
     
Thread Status:
Not open for further replies.

Share This Page