Solved Getting nearby entities of an item.

Discussion in 'Plugin Help/Development/Requests' started by oceantheskatr, Apr 11, 2015.

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

    oceantheskatr

    Hi, I am currently working on a "wands" plugin. In this plugin players have access to different types of wands (I use the stick item) that do different things. One of them, on right click, shoots a flint item. I want to make it so that when it hits a player (or comes within one block of a player) then the flint will despawn and set them on fire.

    I am sure that I can figure out despawning the item and setting the player on fire, but I'm not sure how to get nearby entities. I've searched around on the internet and have found threads relating to getting entities near a location, but not an item.

    Here is the code that is used to spawn and "shoot" the flint:


    Code:
    Location loc = player.getEyeLocation();
    int x = loc.getBlockX();
    double y = loc.getBlockY() - 0.5;
    int z = loc.getBlockZ();
    
    Location newLoc = new Location(player.getWorld(), x, y, z);
    
    Entity drop = (Entity) player.getWorld().dropItemNaturally(newLoc, new ItemStack(Material.FLINT));
    drop.setVelocity(e.getPlayer().getLocation().getDirection().multiply(4));

    Not sure how to track if there are any entities nearby though, any help is appreciated! :)
     
  2. Offline

    I Al Istannen

  3. Offline

    oceantheskatr

  4. Offline

    pie_flavor

    @oceantheskatr Tip: Use [code=java] instead of [code] for syntax highlighting.
    As to your problem, run a sync repeating BukkitRunnable that checks for nearby entites. When it hits the ground, cancel the runnable.
     
  5. Offline

    oceantheskatr

    Thanks for the tip! :)

    Also based on what you said, I should be able to better research how to do this, thank you :)

    ---

    @pie_flavor I feel that I am quite close, yet I am getting an error. My code below gives me an error in the line:

    WandsMain.plugin.getServer().getScheduler().cancelTask(shoot);

    When I mouse over "shoot", it says "The local variable shoot may not have been initialized".

    The quickfix initializes the variable and changes "final int shoot;" to "final int shoot = 0;".

    Next, "shoot = WandsMain.plugin.getServer().getScheduler().scheduleSyncRepeatingTask(WandsMain.plugin, new Runnable() {" gets the error "The final local variable shoot cannot be assigned. It must be blank and not using a compound assignment".

    The quickfix asks me to remove final, to which we're back at the start saying that the variable "shoot" isn't initialized

    Here is my code below, I would really appreciate it if you could let me know what I can do to fix this :)

    Code:
    final Entity drop = (Entity) player.getWorld().dropItemNaturally(newLoc, new ItemStack(Material.FLINT));
                        drop.setVelocity(e.getPlayer().getLocation().getDirection().multiply(4));
                      
                        final int shoot;
                      
                        shoot = WandsMain.plugin.getServer().getScheduler().scheduleSyncRepeatingTask(WandsMain.plugin, new Runnable() {
                              public void run() {
                                  Player player = e.getPlayer();
                                  List<Entity> nearby =  drop.getNearbyEntities(2,2,2);
                                  for (Entity enemy: nearby)
                                     if (enemy instanceof Damageable) {
                                         enemy.setFireTicks(100);
                                         drop.remove();
                                         WandsMain.plugin.getServer().getScheduler().cancelTask(shoot);
                                     }
                              }
                            }, 2L, 1L);

    {{Posts merged by Myrathi}}
     
    Last edited by a moderator: Apr 14, 2015
  6. Offline

    I Al Istannen

    @oceantheskatr I am not sure, but don't you get the TaskID when the tasdk was successfully sheduled? That way you dont know the TaskId at the creation time of the new Runnable.

    What I did, altough there is probably a better way, is creating a new Class implementing Runnable, and intialise this class.

    Code:
    import org.bukkit.event.player.PlayerInteractEvent;
    
    public class Runnner implements Runnable {
    
       private int taskId;
       private PlayerInteractEvent e;
      
       public Runnner(PlayerInteractEvent e) {
         this.e = e;    
       }
      
       @Override
      public void run() {
         //your stuff
      }
      
      
      public void setTaskId(int id) {
         this.taskId = id;
      }
    
    }
    
    And then use this:
    Code:
        Runnner runner = new Runnner(event);
        int shootTask = this.getServer().getScheduler().scheduleSyncRepeatingTask(this,runner, 2L, 1L);
        runner.setTaskId(shootTask);
    
     
    Last edited: Apr 12, 2015
  7. Offline

    oceantheskatr

    Thank you very much for writing this for me, however I do still have one issue. I'm not sure how to use my variable "drop" in the other class. Here is my current implementation of your code:

    NetherWand.java (where the wand is):
    Code:
                       Location newLoc = new Location(player.getWorld(), x, y, z);
                     
                        Entity drop = (Entity) player.getWorld().dropItemNaturally(newLoc, new ItemStack(Material.FLINT));
                        drop.setVelocity(e.getPlayer().getLocation().getDirection().multiply(4));
                     
                        Flintshot fs = new Flintshot(e);
                        int shootTask = WandsMain.plugin.getServer().getScheduler().scheduleSyncRepeatingTask((Plugin) this,fs, 2L, 1L);
                        fs.setTaskId(shootTask);
    Flintshot.java (where Runnable is):
    Code:
    public class Flintshot implements Runnable {
    
        private int taskId;
           private PlayerInteractEvent e;
      
           public Flintshot(PlayerInteractEvent e) {
             this.e = e; 
           }
      
           @Override
          public void run() {
             //your stuff
               Player player = e.getPlayer();
                  List<Entity> nearby =  drop.getNearbyEntities(2,2,2);
                  for (Entity enemy: nearby)
                     if (enemy instanceof Damageable) {
                         enemy.setFireTicks(100);
                         drop.remove();
                     }
          }
      
      
          public void setTaskId(int id) {
             this.taskId = id;
          }
    
    }
    It says "drop can not be resolved" when I hover my mouse on "drop". Obviously this is because there is no "drop" variable in this class though.

    Again, thank you for helping me out! :)
     
  8. Offline

    I Al Istannen

    @oceantheskatr You have to pass every variable you need. You can just adjust the constructor (Line 6-8) to take everything you need. So you could do sth. like:
    Code:
           public Flintshot(PlayerInteractEvent e,int drop) {
             this.e = e;
             this.drop = drop;
           }
    
    and change your creation of the Runnable to pass all the vars you need.

    EDIT: And i just saw i deleted your code in the Runnable at Line 18/19:
    Code:java
    1. WandsMain.plugin.getServer().getScheduler().cancelTask(taskId);
     
    Last edited: Apr 12, 2015
  9. Offline

    oceantheskatr

  10. Offline

    I Al Istannen

    oceantheskatr likes this.
Thread Status:
Not open for further replies.

Share This Page