Custom Event Help

Discussion in 'Plugin Development' started by L33m4n123, Apr 6, 2013.

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

    L33m4n123

    Hey guys,

    Had no Idea how to propperly name the Thread so sorry for that :(

    My Issue is as follows. I want that a player regenerates health slowly underwater. [Ignore the fact with the air since that is working]

    Code:java
    1.  
    2.  
    3. @EventHandler
    4. public final void onDrownEvent(final PlayerMoveEvent event) {
    5. final Player p = event.getPlayer();
    6. int foodLevel;
    7. if (p.getRemainingAir() < p.getMaximumAir()) {
    8. p.setRemainingAir(p.getMaximumAir());
    9. foodLevel = p.getFoodLevel() + 1;
    10. p.setFoodLevel(foodLevel);
    11. }
    12.  
    13. }
    14.  
    15.  


    Here the issue is that he regenerates TOO fast. Problem is that the FoodLevel within bukkit only accepts values of the type Integer. This means I cannot go ahaed and let it regenerate it 0.1 every time the event is triggered.

    Now I need to find a solution to either store a certain ammount / after a certain ammounts of triggering the event the food level raises by one.. The issue is if I try something like this it won't work


    Code:java
    1.  
    2.  
    3. @EventHandler
    4. public final void onDrownEvent(final PlayerMoveEvent event) {
    5. final Player p = event.getPlayer();
    6. int foodLevel;
    7. int delay = 0;
    8. if (p.getRemainingAir() < p.getMaximumAir()) {
    9. p.setRemainingAir(p.getMaximumAir());
    10. delay += 1;
    11. if (delay == 5) {
    12. foodLevel = p.getFoodLevel() + 1;
    13. p.setFoodLevel(foodLevel);
    14. delay = 0;
    15. }
    16. }
    17. }
    18.  
    19.  


    I can totaly understand why this does not work. So. How would I do it that it counts for each individual player how often he triggered that event and how to set that to 0 then again once destinated point is arrived so the player gets the foodRegeneration.

    Or would anyone suggest me using a different way to solve this issue?
     
  2. Offline

    chasechocolate

    If you want them to regenerate health/hunger slower, you will have to use a scheduler. If that's what you're wanting, I can give an example.
     
    L33m4n123 likes this.
  3. Offline

    L33m4n123

    chasechocolate thanks :3

    Never worked with scheduler. But this should do the trick or?

    Code:java
    1.  
    2. @EventHandler
    3. public final void onDrownEvent(final PlayerMoveEvent event) {
    4. if (p.getRemainingAir() < p.getMaximumAir()) {
    5. p.setRemainingAir(p.getMaximumAir());
    6. plugin.getServer().getScheduler().scheduleSyncDelayedTask(
    7. plugin, new Runnable() {
    8. public void run() {
    9. p.setFoodLevel(p.getFoodLevel() + 1);
    10. }
    11. }, 10L);
    12. }
    13. }
    14.  


    Edit: Ok. It does work semi.

    This is the current status.. If the player moves underwater it waits the 10 ticks and then it keeps repeating the

    p.setFoodLevel(p.getFoodLevel() + 1);

    How can I make it that it waits the 10 ticks, run it ONCE, wait the 10 ticks again run it ONCE, and so on?
     
  4. Offline

    kabbage

    To make it so it runs less often, make it so the player has to lose more air before incrementing the player's food level.

    Code:
    @EventHandler
    public final void onDrownEvent(final PlayerMoveEvent event) {
    if (p.getRemainingAir() < p.getMaximumAir() - 20) {
    p.setRemainingAir(p.getMaximumAir());
    p.setFoodLevel(p.getFoodLevel() + 1);
    }
    }
    The change is at
    Code:
    p.getRemainingAir() < p.getMaximumAir() - 20
    Set - 20 higher or lower until you're satisfied.
     
    L33m4n123 likes this.
  5. Offline

    L33m4n123

    kabbage Ok. your adjustment is good. Will need to work a bit on that until it satisfy my need :D

    However
    I entered a
    Code:java
    1. p.sentMessage("ok");
    in the run() method and I figured out once started it runs endless, even if I am above the water D:

    Edit: Never mind what I posted above. It runs it in total the ammount of the breath was set to maximum again.

    Means if the delay is so big that the breath was set 7times back to maximum the regenerate event will run 7 times no matter if I am not underwater anymore. I will see if I can fix that :3

    If someone has an Idea how it satisfies my needs then He/She is welcome to post.
     
  6. Offline

    kabbage

    Make it so the player has to be underwater for it to work.
     
  7. Offline

    L33m4n123

    If you tell me how that works that would be great? Thats why I did the "workarround" with the remaining health to check if he is underwater or not :p
     
  8. Offline

    chasechocolate

    Code:java
    1. Location loc = player.getLocation();
    2. Block feet = player.getLocation().getBlock();
    3. Block head = player.getLocation().add(0, 1, 0).getBlock();
    4.  
    5. if((feet.getType() == Material.WATER || feet.getType() == Material.STATIONARY_WATER) && (head.getType() == Material.WATER || head.getType() == Material.STATIONARY_WATER)){
    6. //They are in water
    7. }
     
    L33m4n123 likes this.
  9. Offline

    L33m4n123

    Wow thanks :3

    Now after looking at it I feel somehow stupid not comming up with that Idea but making the breath work arround. lol. Thanks!

    Ok. Sorry to bother again. It's not solved yet..

    Now it gets when I am underwater. But the code withing the run() runs for the first time after the delay is over. BUT continues from there on WITHOUT delay as often as the event was triggered..

    What I want (and I have no Idea how to do it)

    everything within

    Code:java
    1. public void run() {
    2. }


    should run after the delay ONCE, then get a delay again then run again ONCE and ONLY if the player is under water. However. Following Code makes as descriped at the top of this post. It "stacks" up and then run even outside of the water

    Code:java
    1. @EventHandler
    2. public final void onDrownEvent(final PlayerMoveEvent event) {
    3. final int delay = 100;
    4. final Player p = event.getPlayer();
    5. final Location loc = p.getLocation();
    6. final Block feet = loc.getBlock();
    7. final Block head = loc.add(0, 1, 0).getBlock();
    8.  
    9. if ((feet.getType() == Material.WATER
    10. || feet.getType() == Material.STATIONARY_WATER)
    11. && (head.getType() == Material.WATER
    12. || head.getType() == Material.STATIONARY_WATER)) {
    13. //They are in water
    14. p.setRemainingAir(p.getMaximumAir());
    15. plugin.getServer().getScheduler().scheduleSyncDelayedTask(
    16. plugin, new Runnable() {
    17. public void run() {
    18. p.setFoodLevel(p.getFoodLevel() + 1);
    19. }
    20. }, delay);
    21. }
    22. }

    I got the feeling that I most likely need to use a different Event than PlayerMoveEvent.

    If I do it as mentioned earlyer only if certain amount of air is gone it makes the delay between each usage. But However. it will still run while the player is outside the water (without affecting the foodbar though). Is there a way to prevent that or do I have to live with it?

    Ok. To bump it I will not edit my Post. This is my current situation now.

    I got it to work that between each of the run() method is a delay that way

    Code:java
    1. @EventHandler
    2. public void underWaterFoodRegeneration(final PlayerMoveEvent event) {
    3. final Player player = event.getPlayer();
    4. final long delay = 200;
    5. final Location loc = player.getLocation();
    6. final Block feet = loc.getBlock();
    7. final Block head = loc.add(0, 1, 0).getBlock();
    8.  
    9. if ((feet.getType() == Material.WATER
    10. || feet.getType() == Material.STATIONARY_WATER)
    11. && (head.getType() == Material.WATER
    12. || head.getType() == Material.STATIONARY_WATER)) {
    13. // They are in water
    14.  
    15. plugin.getServer().getScheduler()
    16. .runTaskTimer(plugin, new Runnable() {
    17. public void run() {
    18. player.setFoodLevel(player.getFoodLevel() + 1);
    19. plugin.getServer().getScheduler()
    20. .cancelTasks(plugin);
    21. }
    22. }, delay, delay);
    23. }
    24.  
    25. }


    Now it would be great, that all scheduled tasks get canceled in the second the player is NOT underneath the water anymore. Is that possible?

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 31, 2016
Thread Status:
Not open for further replies.

Share This Page