Dispenser --> ProjectileLaunchEvent problem

Discussion in 'Plugin Development' started by CreeperShift, Apr 4, 2013.

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

    CreeperShift

    I feel like I ran straight into a wall and can't figure out how to get around it:

    I have a few arrows that have lore, when they are shot through the dispenser, their type gets added to a hashmap, along with the location of the dispenser.

    Now my problem is, I can detect these arrows in ProjectileLaunchEvent, but only by checking if event.getEntity().getShooter() is null, which means I can't check the location, or ANYTHING of the shooter.

    Now I have no way of checking from which dispenser the arrow came from, but I also can't check which arrow type the dispenser shot.

    Which basically means I can't know if it's a normal arrow or a special arrow, and also can't take the UUID and store both that and the type in a hashmap (And do stuff with the special arrows on the Hit events etc)

    I can't come up with any solutions, so.. ummm.. help plox? :3
     
  2. Offline

    WolfGangSen

    could you show some code please?
     
  3. Offline

    CreeperShift

    Huh? What code? The point is that I can't figure out how to retrieve anything about the dispenser on the ProjectileLaunchEvent because it's "null":

    http://jd.bukkit.org/beta/apidocs/org/bukkit/entity/Projectile.html
    You see, because the "shooter", in this case the dispenser is shown as "null", I can't get information such as location or block or anything about it because it will return a nullpointerexception. Unlike when a player shoots the arrow, I can get the name, compare it with the one in the hashmap, retrieve the arrow associated to his name, and then store the UUID + the arrowtype in another hashmap.


    Here's the code just to show you what I mean:


    Code:
      @EventHandler
      public void DispenserShoot(BlockDispenseEvent event){
         
          ItemStack i = event.getItem();
         
          if(i.getType() == Material.ARROW){
            Location block = event.getBlock().getLocation();
             
            List<?> lore = i.getItemMeta().hasLore() ? i.getItemMeta().getLore() : new ArrayList<Object>();
            if ((lore.size() < 1) || (!i.getEnchantments().isEmpty()))
            {
              this.ArrowUsedBlock.put(block, "STANDARD");
            }
            else if (i.getEnchantments().isEmpty())
            {
              this.ArrowUsedBlock.put(block, (String)lore.get(0));
            }
           
          }
           }
    This part registers the arrow in the hashmap, along with the location of the dispenser.

    Code:
          @EventHandler
          public void onShootArrow(ProjectileLaunchEvent event) {
              final UUID uuid = event.getEntity().getUniqueId();
     
     
    if(event.getEntity().getShooter() == null){
     
    //arrow is shot by a dispenser
     
    }
     
     
    
    this part gets fired when it's shot by a dispenser.

    now event.getEntity().getShooter().getLocation(); will return null because the shooter is null.

    This is the problem :/
     
  4. Offline

    nisovin

    I imagine you could get the location of the arrow to determine which dispenser it was fired from. Or, I suspect those two events are fired in sequence, so you could just use a temporary variable to associate the two events.
     
  5. Offline

    CreeperShift

    Oh you mean something like, reverting the direction of the arrow and tracing back to see if it finds any dispenser? hmmm. Interesting.

    As for the second approach, what do you mean by a temporary variable? You mean just checking if the event was right after the other? What would happen if several dispensers shoot at the same time? :/
     
  6. Offline

    nisovin

    Well, they can't really fire at the same time. Multiple dispensers could fire in the same tick, but they'd still have to fire one after the other. As long as both events are fired before moving on to the next dispenser, it wouldn't be a problem. It's something you'd have to test though.
     
    CreeperShift likes this.
  7. Offline

    CreeperShift

    Hmm very true, if it works it would certainly be more reliable than the tracing back method.

    Just to clear things up, by temporary variable you mean,

    dispenser shoots --> store it in a hashmap, launchevent picks up first entry in the hashmap and assumes it's the right one?
     
  8. Offline

    nisovin

    Yes, that's the basic idea, though you don't necessarily need a HashMap, since you only need to store one at a time.
     
    CreeperShift likes this.
  9. Offline

    CreeperShift

    True, but just in case another dispenser fires very shortly after that, I could assign some numeric value that automatically increases so I can keep track of which dispenser fired first, that might just work :O

    Thanks! :)
     
Thread Status:
Not open for further replies.

Share This Page