Solved dropped item hit detection

Discussion in 'Plugin Development' started by Loogeh, Sep 24, 2012.

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

    Loogeh

    Hi, does anyone know how to register hit detection from when a dropped item thrown by a player (tomahawk) and then deal damage to them?
    - Loogeh
    Thanks
     
  2. Offline

    HON95

    Dropped? And deal damage to "them"? When you're launching a projectile at someone and it hits them you mean?
     
  3. Offline

    Loogeh

    No, like. I throw the item in my hand by world.dropItem(stuffhere) and the make it go further with grenade.setVelocity(player.getLocation.getDirection)
    So I need to register when it hits a player and then deal a specified amount of damage to them.
     
  4. Offline

    HON95

    So you throw an item, give it a higher vector, and want it to deal damage to whoever it hits? Well, you could check the item's position every server tick and check if it's inside a player. Would be a little buggy though since items doesn't really "hit" players, just travels straight through them. If you then threw a little of math into it, you could make it work better.
     
  5. Offline

    Loogeh

    That's a good idea.
    Would you be able to provide a little example? If that's possible.
     
  6. Offline

    HON95

    I can give you a few hints: Use a scheduledSyncTask to check the distance to every nearby player every server tick. If the distance is below some specific number, you can assume it "hit them" and kill it's velocity. You can save the items thrown in a set or something, and remove it and cancle the task when it has hit someone.
     
  7. Offline

    Loogeh

    Okay, I'm not really sure what i'm doing as I had no idea how to do that lol. I gave it a shot though with what i know but it didn't work

    Code:
     @EventHandler
    public void tomahawk(PlayerInteractEvent event) {
    final Player player = event.getPlayer();
    final World world = player.getWorld();
    if(player.hasPermission("mci.grenade")) {
    if(player.getItemInHand().getType() == Material.STONE_AXE) {
    if(event.getAction() == Action.LEFT_CLICK_AIR) {
    final Item grenade = world.dropItem(player.getEyeLocation(), new ItemStack(Material.MAGMA_CREAM));
    grenade.setVelocity(player.getEyeLocation().getDirection());
    int amount = player.getPlayer().getItemInHand().getAmount();
      player.getItemInHand().setAmount(amount-1);
      plugin.getServer().getScheduler().scheduleAsyncRepeatingTask(plugin, new Runnable() {
     
      @Override
      public void run() {
      for(Player pls : utilServer.getPlayers()) {
      if(grenade.getLocation().equals(pls.getLocation())) {
      Bukkit.getServer().broadcastMessage("HIT DETECTED!");
     
      }
      }
      }
      }, 1L, 1L);
    }
    }
    }
    }
    I don't think I even got close to what I need.
     
  8. Offline

    HON95

    How I would have done it:

    Code:JAVA
    1. // Store a predefined key, and the scheduler key
    2. final HashMap<Integer, Integer> grenades = new HashMap<Integer, Integer>();
    3.  
    4. @EventHandler
    5. public void tomahawk(PlayerInteractEvent event) {
    6.  
    7. final Player player = event.getPlayer();
    8.  
    9. if (!(player.hasPermission("mci.grenade") || player.isOp()))
    10. return;
    11. if (player.getItemInHand().getType() != Material.STONE_AXE)
    12. return;
    13. if (event.getAction() != Action.LEFT_CLICK_AIR)
    14. return;
    15.  
    16. final Item grenade = player.getWorld().dropItem(player.getEyeLocation(), new ItemStack(Material.MAGMA_CREAM));
    17. grenade.setVelocity(player.getEyeLocation().getDirection());
    18. int amount = player.getPlayer().getItemInHand().getAmount();
    19. player.getItemInHand().setAmount(amount - 1);
    20.  
    21. int tKey = 0;
    22. while (grenades.containsKey(tKey))
    23. tKey++;
    24. final int pKey = tKey;
    25.  
    26. // Use scheduleSyncRepeatingTask instead of scheduleAsyncRepeatingTask
    27. int sKey = PLUGIN.getServer().getScheduler().scheduleSyncRepeatingTask(PLUGIN, new Runnable() {
    28.  
    29. public void run() {
    30.  
    31. if (grenade.isDead()) {
    32. PLUGIN.getServer().getScheduler().cancelTask(grenades.get(pKey));
    33. } else {
    34. World w = grenade.getWorld();
    35. Location l1 = grenade.getLocation();
    36. for (Player pls : Bukkit.getOnlinePlayers()) {
    37.  
    38. if (pls == player || pls.getWorld() != w)
    39. continue;
    40.  
    41. Location l2 = pls.getLocation();
    42.  
    43. double d = (l1.getX() > l2.getX() ? l1.getX() - l2.getX() : l2.getX() - l1.getX());
    44. if (d > .5)
    45. continue;
    46. d = (l1.getZ() > l2.getZ() ? l1.getZ() - l2.getZ() : l2.getZ() - l1.getZ());
    47. if (d > .5)
    48. continue;
    49. d = l1.getY() - l2.getY();
    50. if (d > 2 || d < 0)
    51. continue;
    52.  
    53. grenade.getWorld().createExplosion(grenade.getLocation(), .5F);
    54. PLUGIN.getServer().getScheduler().cancelTask(grenades.get(pKey));
    55. break;
    56. }
    57. }
    58. }
    59. }, 1L, 1L);
    60.  
    61. grenades.put(pKey, sKey);
    62. }


    One annoying bug though, the player you're trying to hit might pick the item up before it hits him.
     
    Muddr and Loogeh like this.
  9. Offline

    kroltan

    Look at those "Item display" plugins (those that create floating unpickable items somewhere) and see how they work.
     
  10. Offline

    HON95

    Fixing it isn't harder than extending the no-pickup timer or listening for when the item is being picked up. :)
     
  11. Offline

    Loogeh

    Thank you so much!
     
  12. Offline

    HON95

    Oh, one thing: I don't think line 19 of the code I provided will do you much good.
     
Thread Status:
Not open for further replies.

Share This Page