Solved Poison Water?

Discussion in 'Plugin Development' started by GRocksMc, Mar 21, 2017.

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

    GRocksMc

    Hey, I would like to know how make poison water. By that I mean, if a player is in water, then wait a second, then do damage.

    I've tried with the PlayerMoveEvent, but they are always moving which makes them constantly get hurt.

    Make sense? If so, please help. If not, please ask for clarification.
     
  2. Offline

    rj3824

    I have no idea if this would work but, you could try to for loop through all online players, get their locations, get the block in the location, if that block equals water, then do whatever


    Sent from my iPad using Tapatalk
     
  3. You were right in using the on player move event. Test if the block they moved to was water, then either give them the poison effect, or schedule a sync repeating task. If you need any more help tahg me :)
     
    mehboss likes this.
  4. Offline

    GRocksMc

    @CreeperFace0777

    I tried that, I don't know how to use a sync repeating task (nevertheless know what it does.)

    I used a delayed task, but that continuously dealt damage after 2 seconds.
     
  5. Offline

    Drkmaster83

    I'd create a HashMap that contains the player and a time value of how long they've been in the water. Then, in your onEnable(), have a repeating task
    Code:
    onEnable() {
        new BukkitRunnable() {
            @Override
            public void run() {
                //increment time in hashmap using a for-loop of all online players, checking if they're in the water, if they are increasing it, if they're not removing them.
            }
        }.runTaskTimer(this, 0L, 20L); //Repeats what's in the middle every second (20 ticks = 1 second)
    }
    Such as that which is provided above. In the middle of that, after increasing it, check if their time in the water is past a threshold, then damage them.

    Note: whether the player is in water could be determined by the block's type being water at their location of their feet.
     
  6. Sync Repeated Task is very similar to a delayed one:
    Code:
    Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, runnable, time between repeats in ticks. I suggest 5 as the player move event is called every 5 ticks 
    So when the player moves, check if the block below them is type water. If it is run the task
    I'm the runnable, check if the block below the player is still water and if it is set their health to their current health minus whatever you want [/CODE]
     
  7. Offline

    GRocksMc

    @CreeperFace0777

    Would this do it?
    Code:java
    1.  
    2. @EventHandler
    3. public void waterDamage(PlayerMoveEvent e){
    4. Player p = e.getPlayer();
    5. Material m = p.getLocation().getBlock().getType();
    6. if(p.getWorld().getName().equals("MurderMystery-1")){
    7. if (m == Material.STATIONARY_WATER || m == Material.WATER) {
    8. Bukkit.getScheduler().scheduleSyncRepeatingTask(main, new Runnable(){
    9. public void run(){
    10. if(e.getTo().getBlock().getType() == Material.WATER || e.getTo().getBlock().getType() == Material.STATIONARY_WATER){
    11. p.damage(1);
    12. }
    13. }
    14. }, 40, 5);
    15. }
    16. }
    17. }
    18.  

    It still does the same thing.
     
  8. Hmm I see. Put the players into a map/hashmap. So you put the player into a hashmap once the runnable starts. And then test if the player is in the hashmap. If they are then return.
     
  9. Don't use PlayerMoveEvent.

    It's much simpler and efficient to create a repeating task (only create one in onEnable) that runs every 20 ticks (=1 second), loop through all players, check if the block at their locations is water, then damage the player using .damage(amount).
     
    ipodtouch0218 likes this.
  10. Offline

    GRocksMc

    @FisheyLP

    How exactly would I do this? I can't get the online players into a loop.

    EDIT: Would this work:
    Code:java
    1.  
    2. public void onEnable(){
    3. Bukkit.getScheduler().scheduleSyncRepeatingTask(main, new Runnable(){
    4. public void run(){
    5. String[] players = (String[]) Bukkit.getOnlinePlayers().toArray();
    6. int playersInt = Bukkit.getOnlinePlayers().size();
    7. for(int i = 0; i <= playersInt; i++){
    8. Player p = Bukkit.getPlayerExact(players"["i"]"); //Bukkit.org italicized everything
    9. if(p.getLocation().getBlock().getType() == Material.WATER || p.getLocation().getBlock().getType() == Material.STATIONARY_WATER){
    10. Bukkit.getScheduler().scheduleSyncDelayedTask(main, new Runnable(){
    11. public void run(){
    12. p.damage(1);
    13. }
    14. }, 20);
    15. }
    16. }
    17. }
    18. }, 20, 0);
    19. }
    20.  


    Because.. Well... It's not working.
     
    Last edited: Mar 22, 2017
  11. Online

    timtower Administrator Administrator Moderator

    @GRocksMc getOnlinePlayers returns player obejcts, not strings.
     
  12. Offline

    GRocksMc

  13. Offline

    Protophite

    Loop through online players in a repeating task set at 20ticks. 1 tick is equal to 1/20 of a second.

    if(!understood){
    google.search();
    }
     
  14. Code:
    for (Player player : Bukkit.getOnlinePlayers()) {
    Keep in mind that this is basic java and if you're having problems with such things, it won't be as fun/fast to develop plugins...
     
  15. Offline

    GRocksMc

    @FisheyLP @Protophite @timtower

    This still isn't working (probably some stupid mistake):
    Code:java
    1.  
    2. @EventHandler
    3. public void onEnable(){
    4. Bukkit.getScheduler().scheduleSyncRepeatingTask(main, new Runnable(){
    5. public void run(){
    6. for(Player p : Bukkit.getOnlinePlayers()){
    7. if(p.getLocation().getBlock().getType() == Material.WATER || p.getLocation().getBlock().getType() == Material.STATIONARY_WATER){
    8. Bukkit.getScheduler().scheduleSyncDelayedTask(main, new Runnable(){
    9. public void run(){
    10. p.damage(1);
    11. }
    12. }, 20);
    13. }
    14. }
    15. }
    16. }, 20, 0);
    17. }
    18. }
    19.  
     
  16. Online

    timtower Administrator Administrator Moderator

    @GRocksMc Try sending a message as well, see if it shows up
     
  17. Maybe because there is an event handler annotation above your on enable?

    Edit: this could also be as the player loop should be inside the runnable
     
  18. Offline

    Caderape2

    @GRocksMc

    }, 20, 0); you are running ur scheduler every 0 ticks. replace it by 20.

    Why there's an @eventHandler if it's your onEnable method ?
     
  19. Online

    timtower Administrator Administrator Moderator

    That EventHandler does no harm there. Ugly, but not breaking.
    And loop is in runnable.
     
  20. Offline

    GRocksMc

    @timtower @Caderape2 @CreeperFace0777

    I've changed my code to:
    Code:java
    1.  
    2. @Override
    3. public void run() {
    4. for(Player p : Bukkit.getOnlinePlayers()){
    5. if(p.getLocation().getBlock().getType() == Material.WATER || p.getLocation().getBlock().getType() == Material.STATIONARY_WATER){
    6. Bukkit.getScheduler().scheduleSyncDelayedTask(main, new Runnable(){
    7. public void run(){
    8. p.damage(1);
    9. }
    10. }, 20);
    11. }
    12. }
    13.  
    14. }
    15.  


    Main:
    Code:java
    1.  
    2. @SuppressWarnings("unused")
    3. @Override
    4. public void onEnable(){
    5. BukkitTask TaskName = new poisonWater(this).runTaskTimer(this, 20, 20);
    6. }
    7. }
    8.  


    Still isn't doing damage to the player. It is actually running the task now though.

    Oh, and when using a repeating task, what are the 2 numbers at the end?
     
    Last edited: Mar 23, 2017
  21. Offline

    Caderape2

    @GRocksMc What is not working ? show your two full class.
     
  22. Offline

    GRocksMc

    @timtower @CreeperFace0777 @Caderape2

    Main class is setup perfectly, go to my other threads to see.

    Only other thing in the poison water class is that it extends BukkitRunnable and sets anew instance for the main class.
     
  23. Offline

    mehboss

    @GRocksMc
    Can I see your plugin.yml? Is your plugin being enabled?

    Also, instead of doing your runnable like that, I prefer doing this way:
    Code:
    /**
    * don't forget to extend JavaPlugin
    */
    
        @Override
        public void onEnable(){
    
            new BukkitRunnable() {
    
             int time = 0;
    
               public void run() {
    
                 if (time >= 5) { //a self cancel implement if wanted - 5 seconds
                     this.cancel();
    
                 } else {
    
                   player.damage(1);
                   time++;
                    }
                }.runTaskTimer(this, 20L);
     
    Last edited: Mar 23, 2017
  24. Offline

    GRocksMc

    @mehboss

    The plugin is being enable, the poison water is not the only part. Everything else is working fine.

    EDIT: Welp, I don't know what was wrong, but it just started working. (I didn't use your way @mehboss )
     
    Last edited: Mar 23, 2017
  25. Offline

    mehboss

    Try that
     
Thread Status:
Not open for further replies.

Share This Page