Solved Get location of impact from arrow

Discussion in 'Plugin Development' started by trg601, Dec 2, 2013.

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

    trg601

    I have been trying to make a plugin that makes a 'portal gun'
    Not really like those fancy ones that create portals but it simply fires and arrow and teleports you to it when it hits something.

    I have this (found off another thread, modified quite a bit though):
    Code:java
    1. @EventHandler
    2. public void arrowEvent(ProjectileHitEvent event) {
    3. if(event.getEntity() instanceof Arrow) {
    4. Arrow arrow = (Arrow)event.getEntity();
    5. Entity shooter = arrow.getShooter();
    6.  
    7. if(shooter instanceof Player) {
    8. Player player = (Player)shooter;
    9. if (player.getItemInHand().getItemMeta().getDisplayName().equals("§1Portal Gun")) {
    10. if(player.getInventory().getItemInHand().getType().equals(Material.BLAZE_ROD)){
    11. Location loc = arrow.getLocation();
    12. player.teleport(loc);
    13. }
    14. }
    15. }
    16. }
    17. }

    All this does is teleport the player one block higher but X and Z stay the same.
    And, for firing the arrow(This method I made works for all my guns in the plugin):
    Code:java
    1. player.launchProjectile(Arrow.class).setVelocity(player.getLocation().getDirection().multiply(50));


    So, does anyone know how to fix this?
    I'm thinking from the first codebox I might just be getting the location of the wrong class?
    I don't know!
    Please help, I appreciate it :D
     
  2. Offline

    krazytraynz

    Try using the code from this thread and see what you can do with it.
     
  3. Offline

    trg601

    krazytraynz
    Thank you for the reply!

    I am fiddling around with that a bit, here is what I got:
    Code:java
    1. @EventHandler
    2. private void onArrowHitBlock(ArrowHitBlockEvent event) {
    3. Arrow arrow = event.getArrow();
    4. Block block = event.getBlock();
    5. Location loc = block.getLocation();
    6. Entity shooter = arrow.getShooter();
    7. if(shooter instanceof Player) {
    8. Player player = (Player)shooter;
    9. if (player.getItemInHand().getItemMeta().getDisplayName().equals("§1Portal Gun")) {
    10. if(player.getInventory().getItemInHand().getType().equals(Material.BLAZE_ROD)){
    11. player.teleport(loc);
    12. }
    13. }
    14. }
    15. }

    Currently, that does nothing?
    If anybody knows how to fix this, that would be great :D
     
  4. Offline

    krazytraynz

    Make sure the event is registered in your main class, and add some debug statements to ensure that all of the if statements pass.

    EDIT: Rather than using the ArrowHitEvent, try using the method using reflection, but like the author said be sure to put it inside of a Bukkit runnable with no delay.

    Code:
    //Inside of ProjectileHitEvent
    World world = arrow.getWorld();
     
                net.minecraft.server.EntityArrow entityArrow = ((CraftArrow)arrow).getHandle();
     
                Field fieldX = net.minecraft.server.EntityArrow.class.getDeclaredField("e");
                Field fieldY = net.minecraft.server.EntityArrow.class.getDeclaredField("f");
                Field fieldZ = net.minecraft.server.EntityArrow.class.getDeclaredField("g");
     
                fieldX.setAccessible(true);
                fieldY.setAccessible(true);
                fieldZ.setAccessible(true);
     
                int x = fieldX.getInt(entityArrow);
                int y = fieldY.getInt(entityArrow);
                int z = fieldZ.getInt(entityArrow);
     
                Block block = world.getBlockAt(x, y, z);
     
    trg601 likes this.
  5. Offline

    trg601

    krazytraynz
    EDIT: I fixed this! (Solved)
    Working code:
    Show Spoiler

    Code:java
    1. @EventHandler
    2. public void onHit(ProjectileHitEvent event) {
    3. if (event.getEntity() instanceof Arrow) {
    4. if (event.getEntity().getShooter() instanceof Player){
    5. Entity entity = event.getEntity();
    6. BlockIterator iterator = new BlockIterator(entity.getWorld(), entity.getLocation().toVector(), entity.getVelocity().normalize(), 0, 4);
    7. Block hitBlock = null;
    8.  
    9. while(iterator.hasNext()) {
    10. hitBlock = iterator.next();
    11. if(hitBlock.getTypeId()!=0) {
    12. break;
    13. }
    14. }
    15.  
    16. LivingEntity liv = event.getEntity().getShooter();
    17. Player p = (Player)liv;
    18. if (p.getItemInHand().getItemMeta().getDisplayName().equals("§1Portal Gun")||p.getItemInHand().getItemMeta().getDisplayName().equals("§1Portal Bow")){
    19. if(p.getInventory().getItemInHand().getType().equals(Material.BLAZE_ROD)||p.getInventory().getItemInHand().getType().equals(Material.BOW)){
    20. //Projectile proj = (Projectile) event.getEntity();
    21. int tpX = (int) hitBlock.getLocation().getX();
    22. int tpY = (int) hitBlock.getLocation().getY();
    23. int tpZ = (int) hitBlock.getLocation().getZ();
    24. int tpyaw = (int) p.getLocation().getYaw();
    25. int tppitch = (int) p.getLocation().getPitch();
    26. Location loc = new Location(p.getWorld(),tpX,tpY,tpZ,tpyaw,tppitch);
    27. p.teleport(loc);
    28. }
    29. }
    30. }
    31. }
    32. }



    Sorry, I don't quite understand, //Inside of ProjectileHitEvent
    How to I put stuff inside an event? (Sorry, i'm a noob when it comes to bukkit)

    But, I did get this going:
    Show Spoiler
    Code:java
    1. @EventHandler
    2. public void onHit(ProjectileHitEvent event) {
    3. if (event.getEntity() instanceof Arrow) {
    4. if (event.getEntity().getShooter() instanceof Player);
    5. LivingEntity liv = event.getEntity().getShooter();
    6. Player p = (Player)liv;
    7. if (p.getItemInHand().getItemMeta().getDisplayName().equals("§1Portal Gun")) {
    8. if(p.getInventory().getItemInHand().getType().equals(Material.BLAZE_ROD)){
    9. Projectile proj = (Projectile) event.getEntity();
    10. int tpX = (int) proj.getLocation().getX();
    11. int tpY = (int) proj.getLocation().getY();
    12. int tpZ = (int) proj.getLocation().getZ();
    13. int tpyaw = (int) p.getLocation().getYaw();
    14. int tppitch = (int) p.getLocation().getPitch();
    15. Location loc = new Location(p.getWorld(),tpX,tpY,tpZ,tpyaw,tppitch);
    16. p.teleport(loc);
    17. }
    18. }
    19. }
    20. }
    [/spoiler
    This, unfortunately does around the same thing.
    It does however run when an arrow is shot, just pushes the player backwards a bit.

    How do you get the location of the arrow? or block it hit?

    Thanks!
     
    krazytraynz likes this.
Thread Status:
Not open for further replies.

Share This Page