Help with firing arrows.

Discussion in 'Plugin Development' started by HeyShibby, Apr 22, 2014.

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

    HeyShibby

    Sorry for low quality post on my phone as i'm away and can't get any internet other then my 3g, I'm needing help with when firing an arrow.

    What I need is help with when I fire an arrow I need it to shoot and stay flying in a straight line.

    I need this to be very low memory use as well, as this will be being used by about 20 people at once on only small servers :)

    thanks in advance
     
  2. Try using Vectors for setting what the arrow does? Also if it is going to go in a straight line, you should remember to kill off the arrow eventually or else it will go on forever.
     
  3. Offline

    HeyShibby

    I have got vectors for firing the arrow, it's just working out how to keep the arrow flying in a straight line without much memory use.
     
  4. Oh, I understand now. I can't help out with that as I have no idea how to better performance :p Sorry
     
  5. Offline

    Slikey

    WD_MUFFINFLUFFER This might have the effect, that the arrow is extremely fast.

    Since there is no EntityPhysicsEvent, we have to do some maths here. First, we need to put up a method, to get the position of the arrow, in dependency of the current tick.
    Run a task on the scheduler every tick, or every second tick, which causes the arrow to change it's position to that one on your line. After doing that, you should reset the velocity of the arrow.
    While doing that, you might want to put all these arrows on an Map<Arrow, BukkitTask>. Listen the ProjectileHitEvent and if the arrow hits something, you cancle your BukkitTask, so that it doesn't move anymore.

    This sounds very performance-sucking, but if you do it well, it is no matter for performance.

    PS: Running an arrow forever can cause a bug, when the arrow runs out of a loaded chunk. So you might have to load the chuck, the arrw is in. But then, you will have a baaaad time, because of performance. Maybe destroy the arrow when it hits an unloaded chunk, or goes above a defined height of 256?
     
    WD_MUFFINFLUFFER likes this.
  6. Offline

    HeyShibby

    I was recommended to getvelocity.sety(0) for every tick or so is this what you're recommending?

    As for the arrow continuing on I will worry later but i'm sure i'll just set a region and if an arrow leaves it it will instantly get deleted.
     
  7. Offline

    Slikey

    HeyShibby I don't know if Entity.getVelocity.setY(0) is what you want. You might get trouble with physics, because Minecraft applies physics in an, for me unknown, way.
    And if you just setY to 0, you will fire the arrow just horizontal and you X and Z values change because of the physics.

    If you want, I'll put up an example.
     
  8. Offline

    HeyShibby

    sure, things I seem to be trying out at the moment aren't the best of ways and help is needed :)
     
  9. Offline

    Slikey

    Remember that this is untested. You need to test it yourself..^^

    Code:java
    1. import java.util.HashMap;
    2. import java.util.Map;
    3.  
    4. import org.bukkit.Bukkit;
    5. import org.bukkit.Location;
    6. import org.bukkit.entity.Arrow;
    7. import org.bukkit.event.EventHandler;
    8. import org.bukkit.event.HandlerList;
    9. import org.bukkit.event.Listener;
    10. import org.bukkit.event.entity.ProjectileHitEvent;
    11. import org.bukkit.event.entity.ProjectileLaunchEvent;
    12. import org.bukkit.plugin.java.JavaPlugin;
    13. import org.bukkit.scheduler.BukkitTask;
    14. import org.bukkit.util.Vector;
    15.  
    16. public class ArrowHolder extends JavaPlugin implements Listener {
    17. private Map<Arrow, BukkitTask> arrows;
    18.  
    19. @Override
    20. public void onEnable() {
    21. arrows = new HashMap<Arrow, BukkitTask>();
    22. getServer().getPluginManager().registerEvents(this, this);
    23. }
    24.  
    25. @Override
    26. public void onDisable() {
    27. HandlerList.unregisterAll((Listener) this);
    28. arrows.clear();
    29. };
    30.  
    31. @EventHandler
    32. public void onArrowLaunch(ProjectileLaunchEvent event) {
    33. if (!(event.getEntity() instanceof Arrow))
    34. return;
    35. final Arrow arrow = (Arrow) event.getEntity();
    36. BukkitTask task = Bukkit.getScheduler().runTaskTimer(this, new Runnable() {
    37. private Vector velocity = null;
    38. private Location origin = null;
    39. private int ticks = 0;
    40.  
    41. @Override
    42. public void run() {
    43. if (origin == null) {
    44. origin = arrow.getLocation();
    45. velocity = arrow.getVelocity();
    46. } else {
    47. Location position = origin.clone().add(velocity.multiply(ticks));
    48. arrow.teleport(position);
    49. arrow.setVelocity(velocity);
    50. }
    51. ticks++;
    52. }
    53.  
    54. }, 0, 1);
    55. this.arrows.put(arrow, task);
    56. }
    57.  
    58. @EventHandler
    59. public void onArrowImpact(ProjectileHitEvent event) {
    60. if (!(event.getEntity() instanceof Arrow))
    61. return;
    62. Arrow arrow = (Arrow) event.getEntity();
    63. if (!arrows.containsKey(arrow))
    64. return;
    65. this.arrows.get(arrow).cancel();
    66. this.arrows.remove(arrow);
    67. }
    68.  
    69. }
     
  10. Offline

    HeyShibby

    Thank you, I'll be sure to test this out tomorrow morning! To see the differences in performances, some tweaks by the looks could be possible but of course it will have it's flaws so i'll give feedback later on :)
     
Thread Status:
Not open for further replies.

Share This Page