Is there a generic Health-Changed event?

Discussion in 'Plugin Development' started by Bobby_Bonsai, Mar 1, 2011.

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

    Bobby_Bonsai

    Background-story is my HealthyNames plugin, which changes the chat-name-color according to the health of a player.

    I've found the obvious EntityListener.onEntityCombust() and EntityListener.onEntityDamage() events, but I can't find events f.e. if food is used. My workaround would have been to use the PlayerListener.onPlayerItem event, but that event fires too early, before the health of the player has changed (so does the PlayerListener.onPlayerRespawn by the way).

    Is there something like a generic health-changed-event, did I miss a Listener or am I out of luck?

    I've been working with Build 439.
     
  2. Offline

    retsrif

    I need that too, though I can't find it. You should listen to whatever is the closest you can get and adjust your method to wait a specific time.
     
  3. Offline

    Nohup

    Okay, the best I could come up with is to create an asynchronous thread during the onPlayerItem that would start off sleeping and then would update your text. So something like:


    Code:
        public class UpdateHealth implements Runnable
        {
            private final Player _p;
            public UpdateHealth(Player p)
            {
                _p = p;
            }
    
            public void run() {
                try
                {
                    Thread.sleep(1000);
                    System.out.println("Player health is now: " + _p.getHealth());
                }
                catch (Exception e)
                {
                    System.out.println("Ay de mi!");
                }
           }
        }
    
    This waits 1 second and then spits out a system message with the new health. The implementation on your listener would be like this:

    Code:
            Thread t = new Thread(new UpdateHealth(event.getPlayer()));
            t.start();
    
    Don't try an instantiate an instance of your thread object and use .run() as that will run it synchronously and wait right where it is. Basically what you want to do is give the server a second to finish processing and then fire off your text update. Obviously you will want to qualify around when you create that thread as you probably don't want to fire it off every time an item is used, only for specific items, but this should meet your needs (if in a jury-rigged manner).
     
  4. Offline

    retsrif

    So basically, we have to detect the closest event to a change in health, then wait a little to let the health update?
     
  5. Offline

    Nohup

    yah, what you said, but you posted while I was typing after I researched and gave specific examples lol But you can't wait directly in your method because if you do that then the health still wouldn't update. You have to create the thread so that you have a foothold out there waiting but your server is still processing.
     
  6. Offline

    retsrif

    You mean that we should make the thread we make sleep, but not the method itself, as causing the method itself to sleep would just postpone everything by 1 second right?
     
  7. Offline

    Nohup

    that's correct.
     
  8. Offline

    retsrif

    Thanks for clarifying :)
     
  9. Offline

    Bobby_Bonsai

    @retsrif, @Nohup: Thanks for replying, but I was hoping not to go down that road. That introduces a lot of questions...f.e. what happens if the player has disconnected during that second? But I guess just trying it out would be the best.

    And if I'm allowed to say that, please do not use Thread.sleep() for those purposes. You'll have blocked threads lingering around, and you don't want that. A thread is an expensive resource on a server. Use a Scheduler or Timer instead, like this:

    Code:
    	private Timer timer = new Timer(true);
    
    	// within a function
    	timer.schedule(new TimerTask() {
    
    		@Override
    		public void run() {
    			// do something here
    		}
    	}, waitInMilliseconds);
    
    It will save much overhead, especially if it is going to run on a big server.
     
  10. Offline

    retsrif

    BukkitScheduler is the way to go for timers really. Also, if the player was disconnected.... well the player isn't there any more, and would be as much as a problem to you as other plugins that are dealing with them. Just ignore that.
     
Thread Status:
Not open for further replies.

Share This Page