Launch Arrows Code?

Discussion in 'Spigot Plugin Development' started by DeadlyDeath001, May 4, 2015.

  1. I want to fire 7 arrows while right clicking a item. If player stops Right clicking during firing arrows event will cancel, but will only fire 3 or 4 hours when half way there. So like in 7 seconds, every second will fire 1 arrow. Then it will have a cooldown of 4 seconds before it can be used again. How would I write this code? Here is what i have.
    Code (Text):
        @EventHandler
        public void onPlayerInteract(PlayerInteractEvent event) {
              Player player = event.getPlayer();
                if(player.getInventory().getItemInHand().getType() == Material.STICK) {
                    if (event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK) {
                        player.launchProjectile(Arrow.class);
                        player.playSound(player.getLocation(), Sound.SHOOT_ARROW, 1, 0);
     
  2. gigosaurus

    Supporter

    PlayerInteractEvent will keep firing while you hold down left/right click, at a rate of 5 times a second (so every 4 ticks). Think you can figure it out from there?
     
  3. Nope I'm lost I would be big help if you guys can solve this
     
  4. gigosaurus

    Supporter

    This is how I would go about doing it:

    You will need to keep track of two things about each player. You could do this using Maps or a custom object.
    1. How many times they've caused a PlayerInteractEvent in a row (the amount of time they've held down right click).
    2. If a player is on cooldown or not.

    In PlayerInteractEvent, first check if a player is currently on cooldown. If they are, return (and possibly send them a message saying they're on cooldown) so no arrow is launched.
    Next, check how many times they've already fired PlayerInteractEvent. If it's 0 times (assuming you want an arrow to fire instantly) or a multiple of 5 that is less than 35 (because that would be an 8th arrow), fire an arrow. Increment a counter which is counting how many times they've already fired PlayerInteractEvent. If the counter equals 35, don't fire an arrow.
    On the first click (fired count is 0) schedule a repeating task which runs every 4 ticks, offset by 1. Each time this task is run, check if the fired count has been incremented. If it hasn't, the player has stopped right clicking, and so you should set their fired count to 0, cooldown on and cancel the task. If the counter has reached 35 you should do the same. Also make a new task that runs in 4 seconds (or your desired cooldown length) which turns off the cooldown for this player.

    If you want the cooldown to be able to mention how long left until you can do it again, change the cooldown to an int instead of a boolean, and adjust the task to run every second instead, and minus one from this cooldown value until it's 0 again.
     
  5. I Give up spoon feed me the code please
     
  6. gigosaurus

    Supporter

    Show your attempt(s) first, they might be closer than you think.
     
    #6 gigosaurus, May 4, 2015
    Last edited: May 4, 2015
  7. The player interact event is called 4 times a second (every 5 ticks) if a player is holding right click. That does not, however leave room for latency. What I would do is store the last time a player clicked in a hashmap with the key being the players UUID and the value being the System.currentTimeMillis() of when they last clicked. Then every time a playerinteractevent is called, check the hashmap. If it contains the value, get it. Then check if it is less than 500. That accounts for 250 milliseconds of lag (which hopefully people don't have). If it is less than 500 then they are most likely holding down right click and you can perform your action.
     
  8. Code (Text):

            @EventHandler
            public void onPlayerInteract(PlayerInteractEvent e) {
                    if (!(e.getAction() == Action.RIGHT_CLICK_AIR)) return;
                 
                    if (!(e.getItem().getType() == Material.IRON_SPADE)) return;
                 
                    Fireball f = e.getPlayer().launchProjectile(Fireball.class);
                    f.setIsIncendiary(false);
                    f.setYield(0);
       }
            @EventHandler
            public void onEntityDamage(EntityDamageByEntityEvent e) {
                    if (e.getDamager() instanceof Fireball) {
                            Fireball f = (Fireball) e.getDamager();
                            if (f.getShooter() instanceof Player) {
                                    Player shooter = (Player) f.getShooter();
                                    if (shooter.getItemInHand().getType() == Material.IRON_SPADE) {
                                            e.setDamage(10.0);
    Why don't this work?
    Error:
    [​IMG]
     
  9. Urrggg. Why is nothing working. How do u make a gun!
     
  10. Try doing a for loop that runs 5 times.
     
  11. Solved I was spigot 1.7.10 and 1.8 External Jar. I was suppose to use 1.7.10 Jar file :p
     
  12. Well, that would fix it! :p
     
  13. I give up again, I can't code this at all. How do I make a gun I Want??????????
     
  14. ((Projectile) f).getShooter() ?
     
  15. Try player.launchArrow(); it's depricated but still works
     
  16. Actually this is better:
    Code (Text):
    player.launchProjectile(Arrow.class);