Entity Death

Discussion in 'Plugin Development' started by kangkyuchang, Jan 13, 2020.

  1. Offline

    kangkyuchang

    I wanna give items when Entity died. Currently, I use the EntityDeathEvent. But It's not what I want.
    in detailed, I wanna give all the players that died Entity. However, If the last attacking player kills an Entity, the item is only give to that player. I want to give an item to every player who attacked when the Entity dies.
     
  2. Online

    timtower Moderator Moderator

  3. Offline

    kangkyuchang

    @timtower How do I give an item only when an Entity died? EntityDeathEvent ? Right?
     
  4. Online

    timtower Moderator Moderator

  5. Offline

    kangkyuchang

    @timtower How do I run EntityDamageByEntityEvent and EntityDeathEvent at the same time ?
     
  6. Online

    timtower Moderator Moderator

  7. Offline

    kangkyuchang

    @timtower Sorry, I do this for the first time. So I don't know well.
    Code:
    public void Test(EntityDamageByEntityEvent e, EntityDeathEvent event)
        {
            if(e.getEntity() == null) return;
           
            if(e.getEntityType() == EntityType.SKELETON_HORSE)
            {
                if(event.getEntityType() == EntityType.SKELETON_HORSE) {
                    e.getDamager().sendMessage("TEST");
                }
            }
        }
    Right?
     
  8. Online

    timtower Moderator Moderator

    @kangkyuchang 2 methods, you have 2 parameters now, that won't work.
     
  9. Offline

    kangkyuchang

    @timtower what are 2 methods? I don't understand. I would appreciate it if you explain in detail.
     
  10. Online

    timtower Moderator Moderator

  11. Offline

    kangkyuchang

    @timtower I do it. But what I really wanted to ask is this next way. Thank you for helping me every time and sorry to bother you.
    Code:
    public void Damage(EntityDamageByEntityEvent e)
        {
            if(e.getEntity() == null) return;
           
            if(e.getEntityType() == EntityType.SKELETON_HORSE)
            {
                e.getDamager().sendMessage("TEST");
            }
        }
        public void Death(EntityDeathEvent e)
        {
            if(e.getEntityType() == EntityType.SKELETON_HORSE)
            {
            }
        }
     
  12. Online

    timtower Moderator Moderator

  13. Offline

    kangkyuchang

    @timtower I got it. I'll solve it by myself. Thank you.
     
    timtower likes this.
  14. Offline

    kangkyuchang

    @timtower I tried it. But 2 Event run separately.
     
  15. Offline

    Strahan

    Yes, they are separate events triggered by two different things. If you are attacking an entity, each time you hit it
    EntityDamageByEntityEvent will fire then when it dies, EntityDeathEvent fires. That's the way it is supposed to work.
     
  16. Offline

    kangkyuchang

    @Strahan Then, How do I give an item to everyone who hits the Entity when it dies?
     
  17. Online

    timtower Moderator Moderator

    @kangkyuchang You make a Map<UUID, List<UUID>>
    First UUID is the one that gets hit.
    Second list are the players that hit the entity.
    On death you give everything in the list an item.
     
  18. Offline

    kangkyuchang

    @timtower
    Code:
    public static Map<UUID,List<UUID>> damageplayer = new HashMap<UUID,List<UUID>>();
       @EventHandler
        public void Damage(EntityDamageByEntityEvent e) {
            damageplayer.put(e.getEntityType().equals(EntityType.SKELETON_HORSE), e.getDamager().getUniqueId())
        }
    I'm not sure if I use it this way,,,
     
  19. Offline

    KarimAKL

    @kangkyuchang Make all your checks before you add it to the list.
    Do note that you need to add the entity's UUID object to the list, not the entity object itself.
    Also, the map doesn't need to be static.
     
  20. Offline

    Strahan

    Remember, your Map is UUID key, List of UUID value. In your event, you aren't referencing a List at all. Are you intending this functionality only for skeleton horses? If so, the first thing you should do is check if the damaged entity is not a skeleton horse and return. That will filter so it only applies to that mob. Then make a List<UUID>, setting it from the Map if the key exists or a fresh if not. Add the player's UUID if it doesn't exist in the list then set it to the map and voila.

    That said, this won't achieve your desired functionality of "If the last attacking player kills an Entity, the item is only give to that player. I want to give an item to every player who attacked when the Entity dies". This will cover giving an item to everyone who contributed, but not the last attacker.

    Though I think rewarding last attacker is flawed; someone could spend 10 minutes wearing the ender dragon from full health down to 1 HP left then a new player comes in and hits it with an arrow and BAM, they get the big prize. I would, instead, track damage contribution and give the big prize to the player with the highest damage dealt.
     
  21. Offline

    kangkyuchang

    Code:
    public static Map<UUID,List<UUID>> damageplayer = new HashMap<UUID,List<UUID>>();
        @EventHandler
        public void Damage(EntityDamageByEntityEvent e) {
            if(e.getEntity() == null) return;
            if(e.getEntityType() == EntityType.SKELETON_HORSE)
            {
                damageplayer.keySet().add(e.getEntity().getUniqueId());
                List<UUID> List = new ArrayList<UUID>();
                if (damageplayer.containsKey(e.getEntity().getUniqueId())) {
                    List.add(e.getDamager().getUniqueId());
                    damageplayer.put(e.getEntity().getUniqueId(), List);
                }
            }
        }
    I don't know if it's correct because I learned java Map and never used it. Please point out if it's wrong.
     
  22. Offline

    KarimAKL

    Use damagerplayer.put(UUID, List<UUID>);
     
  23. Offline

    Strahan

    Yea, that's still not quite right. You shouldn't add as you did, do it as Karim suggested. Trying to add a key the way you are w/o verifying that first it doesn't exist in the collection will make it unhappy. Doing it with put avoids that as it will overwrite if it exists.

    Also remember you need to get the List from the Map if the entity is in the map, otherwise you're just pushing an empty list in. Also do not name a variable with a class name (List). You do not need to check if getEntity() is null by the way, it cannot be. The logic would be something like:
    Code:
    event {
      If the entity is not a skeleton horse, return
    
      Make a new List with the player's UUID in it
      Does the map contain a key for this entity?  {
        Set the list you made to the list from the map
        If the player isn't in the list, add them
      }
      Put the list back to the map
    }
     
    Pr0totype2 likes this.
  24. Offline

    kangkyuchang

    Code:
    public void Damage(EntityDamageByEntityEvent e) {
            if(!e.getEntityType().equals(EntityType.SKELETON_HORSE)) return;
            List<UUID> List = new ArrayList<UUID>();
            List.set(0, e.getDamager().getUniqueId());
            if (damageplayer.containsKey(e.getEntity().getUniqueId())) {
                damageplayer.put(e.getEntity().getUniqueId(), List);
                List.add(e.getDamager().getUniqueId());
            }
            damageplayer.put(e.getEntity().getUniqueId(), List);
        }
    I don't know phrase that "Make a new List with the player's UUID in it"
     
  25. Offline

    KarimAKL

    Follow the Java naming conventions.

    Use List#add(UUID) instead of List#set(0, UUID)

    You've almost got it here, you just need to get the list from the map.

    I'd set the part above to something like this:
    Code:Java
    1. Create a set that points to null
    2. if (the map has a key equal to e.getEntity().getUniqueId()) {
    3. Set the above set to Map#get(e.getEntity().getUniqueId())
    4. } else Set the above list to a new HashSet
    5. Add e.getDamager().getUniqueId() to the above set, with the Set#add method
    6. Put the set into the map with the key e.getEntity().getUniqueId()

    EDIT: Changed from ArrayList to HashSet.
     
    Last edited: Jan 16, 2020
    Strahan likes this.
  26. Offline

    Strahan

    What he said, though I'd offer some slight tweak to that:
    Code:Java
    1. Create a new List as an empty ArrayList<UUID>
    2. if (the map has a key equal to e.getEntity().getUniqueId()) {
    3. Set the above list to Map#get(e.getEntity().getUniqueId())
    4. }
    5. if (the List does not contain the damager UUID) {
    6. Add e.getDamager().getUniqueId() to the above list, with the List#add method
    7. }
    8. Put the list into the map with the key e.getEntity().getUniqueId()
     
  27. Offline

    KarimAKL

    @Strahan Now that i think about it, it'd probably be better to use a HashSet instead of an ArrayList.
    That way it doesn't get any duplicate values (so you won't have to check), and i've read that it's faster as well.
     
  28. Offline

    kangkyuchang

    Code:
    public static Map<UUID,HashSet<UUID>> damageplayer = new HashMap<UUID,HashSet<UUID>>();
        HashSet<UUID> PU = new HashSet<UUID>();
           
        @EventHandler
        public void Damage(EntityDamageByEntityEvent e) {
            if(e.getEntity() == null) return;
            if(!e.getEntityType().equals(EntityType.SKELETON_HORSE)) return;
            PU.add(e.getEntity().getUniqueId());
            if (damageplayer.containsKey(e.getEntity().getUniqueId())) {
                damageplayer.get(e.getEntity().getUniqueId());
            }
            if(PU.contains(e.getDamager().getUniqueId()))
            {
                PU.add(e.getDamager().getUniqueId());
            }
            damageplayer.put(e.getEntity().getUniqueId(), PU);
        }
    Thank you for helping someone like me. But I'm not sure exactly what I did.
     
  29. Offline

    KarimAKL

    1. The map doesn't need to be static.

    2. You don't need this Set, the Sets you want are the values inside the map.

    3. You don't need to null check the entity as it cannot be null.
    4. It's recommended to compare enums with == instead of .equals(), but in this case it's just better practice.

    5. Just getting the Set isn't enough, you need to set the current Set to that value, which is why you need a Set inside the method scope.

    6. You're using a Set now, not a List, so this check isn't needed. (Sets cannot have duplicate values)

    Try adjusting your code with this information in mind, then let us know how it goes.
     
  30. Offline

    kangkyuchang

    Code:
    public Map<UUID,List<UUID>> damageplayer = new HashMap<UUID,List<UUID>>();
        List<UUID> PU = new ArrayList<UUID>();
           
        @EventHandler
        public void Damage(EntityDamageByEntityEvent e) {
            if(!e.getEntityType().equals(EntityType.SKELETON_HORSE)) return;
            PU.add(e.getEntity().getUniqueId());
            if (damageplayer.containsKey(e.getEntity().getUniqueId())) {
                damageplayer.keySet().add(e.getEntity().getUniqueId());
                damageplayer.get(e.getEntity().getUniqueId());
            }
            List<UUID> set = damageplayer.get(e.getEntity().getUniqueId());
            if(PU.contains(e.getDamager().getUniqueId()))
            {
                PU.add(e.getDamager().getUniqueId());
                set.add(e.getDamager().getUniqueId());
            }
            damageplayer.put(e.getEntity().getUniqueId(), PU);
        }
    What is the set?
     

Share This Page