Projectile -> getLocation - > getY

Discussion in 'Plugin Development' started by Limeth, Aug 7, 2012.

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

    Limeth

    Hello, I'm having problems with coding headshots for my plugin,
    I can't seem to find method "getLocation" for the projectile. :c

    Code:java
    1. @EventHandler
    2. public boolean onProjectileHit(ProjectileHitEvent event) {
    3. if(event.getEntity().getLocation().getY() + 1 < VICTIM LOCATION HERE) {
    4.  
    5. }
    6. }

    or
    Code:java
    1. public void onEntityDamageByEntity(EntityDamageByEntityEvent event) {
    2. if(plugin.redTeam.contains(event.getDamager()) && plugin.redTeam.contains((Player) event.getEntity()) || plugin.blueTeam.contains(event.getDamager()) && plugin.blueTeam.contains((Player) event.getEntity())) {
    3. event.setCancelled(true);
    4. ((Player) event.getDamager()).sendMessage(ChatColor.RED + "That player is on your team!");
    5. } else if(event.getCause().equals(DamageCause.PROJECTILE)) {
    6. if(((Player) event.getEntity()).getLocation().getY() + 1 < PROJECTILE LOCATION HERE){
    7. ((Player)event.getEntity()).setHealth(0);
    8. }
    9. }
    10. }

    Thanks to everybody that is trying to help me, Limeth
     
  2. Offline

    Courier

    The "entity" from event.getEntity() IS the projectile. It is called even when an arrow hits a block.
    I think you might want to use EntityDamageByEntityEvent instead, but I'm not sure.
     
  3. Offline

    Limeth

    Courier
    Would you give me an example, please?
     
  4. Offline

    Courier

    Like I said, I'm not sure. Experiment by adding an even listener for EntityDamageByEntityEvent, use event.getDamager() and see if it is the projectile, or the entity which shot the projectile. I'm guessing it is the projectile, but I'm not sure.
     
  5. Offline

    Limeth

    So now I can't get the location of arrow, location of victim found. =(

    Code:java
    1. @EventHandler
    2. public void onEntityDamageByEntity(EntityDamageByEntityEvent event) {
    3. if(plugin.redTeam.contains(event.getDamager()) && plugin.redTeam.contains((Player) event.getEntity()) || plugin.blueTeam.contains(event.getDamager()) && plugin.blueTeam.contains((Player) event.getEntity())) {
    4. event.setCancelled(true);
    5. ((Player) event.getDamager()).sendMessage(ChatColor.RED + "That player is on your team!");
    6. } else if(event.getCause().equals(DamageCause.PROJECTILE)) {
    7. if(((Player) event.getEntity()).getLocation().getY() + 1 < event.getCause()) //event.getCause is the only thing that could help me, I think, but It seems like it doesn't lead anywhere :c
    8. }
    9. }


    Courier
    The damager is the player who shot the arrow

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 27, 2016
  6. Offline

    Courier

    I wrote up a quick sample and got it to work. It is pretty effective.
    Code:java
    1. public final class MainPlugin extends JavaPlugin implements Listener
    2. {
    3. @Override
    4. public void onEnable()
    5. {
    6. super.onEnable();
    7. getServer().getPluginManager().registerEvents(this, this);
    8. }
    9.  
    10. @EventHandler(ignoreCancelled = true)
    11. public void onShot(EntityDamageByEntityEvent event)
    12. {
    13. //only interested in projetile damage
    14. if(event.getCause() != DamageCause.PROJECTILE)
    15. return;
    16.  
    17. Projectile proj = (Projectile)event.getDamager();
    18. //could be skeleton or dispenser, we only want player
    19. if(!(proj.getShooter() instanceof Player))
    20. return;
    21.  
    22. Entity victim = event.getEntity();
    23. EntityType victimType = victim.getType();
    24.  
    25. double projY = proj.getLocation().getY();
    26. double victimY = victim.getLocation().getY();
    27. boolean headshot = projY - victimY > getBodyHeight(victimType);
    28.  
    29. if(headshot)
    30. {
    31. //do whatever you want to do if there was a headshot
    32. }
    33.  
    34. //print a message to the shooter
    35. StringBuilder messageShooter = new StringBuilder(headshot ?
    36. (ChatColor.GREEN + "Headshot on ") :
    37. (ChatColor.YELLOW + "Bodyshot on ")
    38. );
    39. messageShooter.append(victimType);
    40. if(victimType == EntityType.PLAYER)
    41. messageShooter.append(" (" + ((Player)victim).getName() + ")");
    42.  
    43. ((Player)proj.getShooter()).sendMessage(messageShooter.toString());
    44. }
    45.  
    46. private double getBodyHeight(EntityType type)
    47. {
    48. switch(type)
    49. {
    50. //humanoid
    51. case CREEPER: case ZOMBIE: case SKELETON: case PLAYER: case PIG_ZOMBIE: case VILLAGER:
    52. return 1.35d;
    53. // case HEROBRINE:
    54. // getServer().shutdown();
    55. // return Float.NaN;
    56. default:
    57. return Float.POSITIVE_INFINITY;
    58. }
    59. }
    60. }
     
    wesley27, Bench3 and Limeth like this.
  7. Offline

    Limeth

    Courier
    Amazing, thank you.
    A little off-topic: How to set for example Double 'd' to number random from 0 to 2?
     
  8. Offline

    Courier

    Code:java
    1. //Math.random() returns [0-1)
    2. double d = Math.random() * 2;
     
    Limeth likes this.
  9. Offline

    Limeth

    Courier
    Is there any way to check if the bow was fully charged?
    EDIT: I can also headshot with eggs and snowballs :c
     
  10. Offline

    one4me

    To make headshots only work with arrows just check whether the projectile is an arrow
    Code:
    if(proj.getType() != EntityType.ARROW) return;
    
     
    Limeth likes this.
  11. Offline

    GizmoRay

    I believe there may be a logic error with this, if the shooting entity is above the victim the event will occur every single time you shoot, while this may have something to do with Minecraft's system, it does make it a little iffy.

    Let me know if I'm wrong!

    Thank you!
     
  12. Offline

    Courier

    I tested it out (when I first posted it) and it worked pretty well. It looks at where the projectile is when it hits the entity, not where the shooter is.
     
  13. Offline

    Limeth

    I agree, I use arrows with a high velocity and whenever the shooter is above the victim, the victim gets headshotted.
    If the shooter is below, the victim does not get headshotted.
     
  14. Offline

    Courier

    Alright, I tested it out again and I see what you mean. It works when you are near the same y as the entity, but when you get too far up or down, the results are more and more skewed. I improved it a bit, and it seems to work well now. Let me know what you think of it with this change:
    Code:java
    1. //old line:
    2. //double projY = proj.getLocation().getY();
    3. //new line:
    4. double projY = proj.getLocation().getY() + proj.getVelocity().getY() / 2d;
     
    GizmoRay likes this.
  15. Offline

    GizmoRay

    Much better! Great job!

    Thanks!
     
  16. Offline

    Limeth

    Umm it still acts weird, now the player gets headshotted when fireing from below, doesn't matter on which part of body the arrow lands.
    Code:java
    1.  
    2. Double speed = 250.0;
    3. proj.setVelocity(new Vector(vec.getX() * speed, vec.getY() * speed, vec.getZ() * speed));
    4.  
     
  17. Offline

    Barinade

    Damage by entity, check if arrow, check if within .2 of victim's eye location
     
Thread Status:
Not open for further replies.

Share This Page