[Solved] Death Location

Discussion in 'Plugin Development' started by AndrewM16921, Oct 31, 2011.

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

    AndrewM16921

    Trying to get the Location when a player dies.

    I've tried this:
    Code:
    public void onPlayerRespawn(PlayerRespawnEvent event)
    {
    	back.put(event.getPlayer().getName(), event.getPlayer().getLocation());
    }
    Code:
    public void onPlayerDeath(PlayerDeathEvent event)
    {
    	back.put(((Player)event.getEntity()).getName(), event.getEntity().getLocation());
    }
    Code:
    public void onEntityDeath(EntityDeathEvent event)
    {
    	if(event.getEntity() instanceof Player)
    	{
    		pl.setBack( ((Player)event.getEntity()), event.getEntity().getLocation() );
    	}
    }
    but the location seems to be where they respawned to. How do I get the location they died at?

    Only other thing I can think of, is player damage event and if health == 0 ... then use that location?

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 20, 2016
  2. Offline

    Daniel Heppner

    Isn't there an event for player death? Then just store the location in a hashmap somewhere.
     
  3. Offline

    AndrewM16921

    I did that, but the getLocation() is the location where the player respawns at :/ at least it was when i tested it...
     
  4. Offline

    Daniel Heppner

    That's strange. Check how another plugin does it like CommandBook or something.
     
  5. Offline

    AndrewM16921

    This is the best thing I found (in essentials)
    Code:
    @Override
    public void onEntityDeath(final EntityDeathEvent event)
    {
    	if (event instanceof PlayerDeathEvent)
    	{
    		final PlayerDeathEvent pdevent = (PlayerDeathEvent)event;
    		final User user = ess.getUser(pdevent.getEntity());
    		if (user.isAuthorized("essentials.back.ondeath") && !ess.getSettings().isCommandDisabled("back"))
    		{
    			user.setLastLocation();
    			user.sendMessage(Util.i18n("backAfterDeath"));
    		}
    		if (!ess.getSettings().areDeathMessagesEnabled())
    		{
    			pdevent.setDeathMessage("");
    		}
    	}
    }
    Seems they handle it with a whole bunch of their own stuff x.x any suggestions for me? Something preferably somewhat simplistic...
     
  6. Offline

    Daniel Heppner

    Essentials is crap. >_<
     
  7. Offline

    Jogy34

    1.Essentials is that bad.
    2.You could probably do something like this (based off of the essentials code given)
    Code:
    @Override public void onEntityDeath(final EntityDeathEvent event) { 	if (event instanceof PlayerDeathEvent) 	{
                    Player player = event.getPlayer();
                    Location loc = player.getLocation();
                    //save location
            }
    }
    
     
  8. Offline

    AndrewM16921

    Thanks, but if you read my initial post, that's precisely what I tried to do.The problem is, when I do that the getLocation() method doesn't seem to return where the player died at, but rather where it is after it died (i.e. respawn location). I'll take a closer look at CommandBook... maybe it will shed some further clues on this.


    EDIT:

    Seems what sk89q does in commnadbook is creates a UserSession when a player logs in and tracks the locations of the player... therefore having several previous locations. Hmph. I really think the death event SHOULD have a getDeathLocation() method. Sadface.

    Gonna try listening for damage, and if it's a player and health == 0 ... then set location. Maybe that will work.
     
  9. Offline

    Father Of Time

    Just an idea, but have you though of using the OnEntityDamage event? that event stores the damaged entity, and the amount damaged. What you could do is OnDamage if ( Health - Damage ) < 0 then you know the player is going to die as a result of the damage, so use that location before the death event is triggered.

    Code:
        public void onEntityDamage(EntityDamageEvent event)
        {
            if( event instanceof EntityDamageByEntityEvent )
            {
                EntityDamageByEntityEvent nEvent = (EntityDamageByEntityEvent)event;
            }
       }
                
    Just an idea as a work around, hope this helps!

    Edit: Oh crap, I just saw the last sentence of your edit :p
     
  10. Offline

    nisovin

    EntityDeathEvent should work. I just tested it and it worked for me.
     
  11. Offline

    AndrewM16921

    Weird... I've tried it several times. Hmm. I shall try it again, though. I have a feeling it's not going to work... both essentials and commandbook seem to track the players' previous movement elsewhere, not using either of those events. I shall try again, though.

    Still doesn't work for me. I wonder, could it have something to do with the fact that I respawn in a bed?

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 20, 2016
  12. Offline

    Father Of Time

    Seeing as it's working for one user and not another it leads me to believe it's a bukkit version issue. What version of bukkit are you using? I have no idea but it might be bugged...
     
  13. Offline

    nisovin

    If that's true, it's a change from how it used to work. I'll test it later.
     
  14. Offline

    AndrewM16921

  15. Offline

    Don Redhorse

    hmm I'm using:

    Code:
    Block signBlock = player.getWorld().getBlockAt(player.getLocation().getBlockX(),
                                    player.getLocation().getBlockY(),
                                    player.getLocation().getBlockZ());
    and it is in an EntityListener onEntityDeath

    and yeah the signBlock is the block where the sign will be after the player died.
     
  16. Offline

    AndrewM16921

    Maybe it's a problem with my logic somewhere else in my code... I'll post the relevant snippets I guess.
    Basically trying to implement the common "/back" command. It works pretty well with other teleports (though I just found out sometimes it has a problem with normal teleports too, which is why I now think the problem is somewhere else). Problem I was having was on death. Maybe I missed something stupid, idk.

    Code:java
    1. if(cmd.getName().equalsIgnoreCase("back"))
    2. {
    3. if(sender.hasPermission(BACK) || sender.isOp() || sender.hasPermission(WILDCARD))
    4. {
    5. Location to = playerListener.getBack(player);
    6. if(to != null)
    7. {
    8. player.teleport(to);
    9. }
    10. else
    11. {
    12. sender.sendMessage(ChatColor.RED + "[NC]"+ChatColor.YELLOW+": You must have previously teleported or died in order to use this command.");
    13. }
    14. }
    15. else
    16. {
    17. noPermission(sender);
    18. }
    19. }


    Code:java
    1. public class NCPlayerListener extends PlayerListener
    2. {
    3. private HashMap<String, Location> back;
    4. public NCPlayerListener()
    5. {
    6. back = new HashMap<String, Location>();
    7. }
    8. public void onPlayerTeleport(PlayerTeleportEvent event)
    9. {
    10. back.put(event.getPlayer().getName(), event.getFrom());
    11. }
    12.  
    13. //I have tried the same thing for EntityDeathEvent in an EntityListener
    14. public void onPlayerDeath(PlayerDeathEvent event)
    15. {
    16. back.put(((Player)event.getEntity()).getName(), event.getEntity().getLocation());
    17. }
    18. public void onPlayerKick(PlayerKickEvent event)
    19. {
    20. playerLeave(event.getPlayer());
    21. }
    22. public void onPlayerQuit(PlayerQuitEvent event)
    23. {
    24. playerLeave(event.getPlayer());
    25. }
    26. public void playerLeave(Player player)
    27. {
    28. if(back.containsKey(player.getName()))
    29. back.remove(player.getName());
    30. }
    31. public Location getBack(Player player)
    32. {
    33. if(back.containsKey(player.getName()))
    34. return back.get(player.getName());
    35. return null;
    36. }
    37. public void setBack(Player player, Location loc)
    38. {
    39. back.put(player.getName(), loc);
    40. }
    41. }
     
  17. Offline

    nisovin

    Try printing the player's location to console in the event listener. If it prints correctly, it means you have a problem somewhere else.

    Edit: It's possible a teleport event is fired when the player respawns. You might want to look into that, because it could be screwing your back location up.
     
  18. Offline

    AndrewM16921

    Yeah, I actually printing the from and to locations and was just about to post that. Turns out when you die you get teleported slightly, not sure if it's because of the bed or if it's always on respawn, going to try it now. I'll have to figure out how to fix this.

    I think if you're stuck inside a wall very slightly you get teleported to a safe location very near by... is there a way to check if this is the cause of the teleport?

    only thing i can think of is if the distance between them is greater than some small amount

    This worked for me:
    Code:
    public void onPlayerTeleport(PlayerTeleportEvent event)
    	{
    		if(event.getFrom().distanceSquared(event.getTo()) > 1)
    			back.put(event.getPlayer().getName(), event.getFrom());
    	}
    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 20, 2016
  19. Offline

    whatapigdoes

    Code:
        public Location getDeathLoc(EntityDamageEvent event){
            if (event.getEntity() instanceof Player){
                if (event.getEntity().isDead()){
                    Location deathloc = event.getEntity().getLocation();
                    return deathloc;
                }
            }else{
                return;
            }
        }
     
  20. Offline

    Jogy34

    this is... an almost two year old thread.
     
Thread Status:
Not open for further replies.

Share This Page