EnderPearl Throw Event

Discussion in 'Spigot Plugin Development' started by bmac20, Jun 22, 2016.

  1. Hello. I am trying to make a plugin and I need to do something once the event happened. I tried PlayerTeleportEvent and checked to see if they teleported by pearl, but I need to disable them throwing pearls instead of teleporting by pearl.
     
    • Optimistic Optimistic x 1
  2. ProjectileLaunchEvent most likely
     
    • Agree Agree x 1
  3. Created this quick class, I have no idea whatsoever if it would work:

    Code (Text):
    package us.universalpvp.l.events;

    import org.bukkit.entity.EnderPearl;
    import org.bukkit.entity.Player;
    import org.bukkit.event.Event;
    import org.bukkit.event.HandlerList;

    /**
    * Created by avigh on 6/21/2016.
    */
    public class EnderPearlThrowEvent extends Event {

        private Player thrower;
        private EnderPearl pearl;
        private boolean cancelled;
        private static final HandlerList handlers = new HandlerList();

        public EnderPearlThrowEvent(Player thrower, EnderPearl pearl) {
            this.thrower = thrower;
            this.pearl = pearl;
        }

        public Player getThrower() {
            return thrower;
        }

        public EnderPearl getPearl() {
            return pearl;
        }

        public boolean isCancelled() {
            return cancelled;
        }

        public void setCancelled(boolean cancelled) {
            this.cancelled = cancelled;
        }

        @Override
        public String getEventName() {
            return super.getEventName();
        }

        public HandlerList getHandlers() {
            return handlers;
        }

        public static HandlerList getHandlerList() {
            return handlers;
        }
    }
     
    its a custom event.
     
  4. um, you would still have to somehow detect the enderpearl throwing and call the custom event lol
     
  5. Exactly.
     
  6. Just check the PlayerInteractEvent? If it's a right click with an ender pearl, and it's not cancelled, then it's likely you're throwing an enderpearl.
     
  7. ProjectileLaunchEvent if entity is ender pearl then do x y z
     
  8. Choco

    Moderator

    That's not necessarily true. Ender pearls have a cooldown in 1.9 ;) ProjectileLaunchEvent is what the OP wants
     
    • Agree Agree x 1
  9. Thanks guys I figured it out. I am trying to make a cooldown to throw enderpearls:
    Code (Text):
        @EventHandler
        public void onPlayerInteract(PlayerInteractEvent e) {
           
            final Player p = e.getPlayer();
           
        if(cooldown.contains(p)){
            p.sendMessage(ChatColor.AQUA + "TheColossal " + ChatColor.DARK_GRAY + ">> " + ChatColor.GRAY + "You must wait 12 seconds before throwing another EnderPearl.");
            e.setCancelled(true);
        }
            if(e.getMaterial() == Material.ENDER_PEARL){
                cooldown.add(p);
                Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable(){
                    public void run(){
                        cooldown.remove(p);
                    }
                }, 200);
            }
           

        }
    I have a 10 second delay to throw them, but once the player is in the cooldown, and they throw an enderpearl, it resets the time. How can I make it so that when they are in the cooldown, it cancels the throwing, but the cooldown does not reset?
     
    • Optimistic Optimistic x 1
  10. Add "return;" after e.setCancelled(true);. This is so that it returns there and stops executing the other bits of the code that add and remove the cooldown, which is what you don't want.
     
  11. Thanks. I don't know why I didn't try that haha. Do you know how to show the exact time the cool down has remaining?
     
  12. Change it to a concurrenthashmap and have a runnable reduce the time as it goes
     
    • Creative Creative x 1
  13. Choco

    Moderator

    Or... skip the Runnable all together and use System.currentTimeMillis() to compare your time in milliseconds. Use a Map<UUID, Long> to store the time at which players are allowed to throw their ender pearls again (System.currentTimeMillis() + 10_000); 10,000 = 10 milliseconds. When a Player clicks on an ender pearl, check if System.currentTimeMillis() is less than what's in the Map. If it is, they're still on a cooldown, tell them they have x amount of seconds left, otherwise, set their new value in the Map
     
    • Agree Agree x 2
    • Funny Funny x 1
  14. Regardless of post above (which is the answer OP should be using), why would you use a ConcurrentHashMap over a regular HashMap? You're only adding overhead, since OP is using a sync runnable (and doesn't do anything heavy that would require an async runnable)
     
    • Agree Agree x 1
    • Useful Useful x 1
  15. I was told it's better for when the map is being updated more often than not.
     
    • Agree Agree x 1
  16. Concurrent is the key word, which means multiple thread support. The amount of times it is updated doesn't change anything. Since OP is sticking to one thread, a normal HashMap would do just fine.
     
    • Agree Agree x 1