public void onBowShoot(EntityShootBowEvent event) {
if (!plugin.getConfig().getBoolean("ender_bow.enable")) {
if (!(event.getEntity() instanceof Player)) {
Player player = (Player) event.getEntity();
if (player.isSneaking() || isOnCooldown(player) || playersWithActiveArrows.contains(player.getUniqueId())) {
ItemStack bow = event.getBow();
if (bow == null || !bow.hasItemMeta()) {
PersistentDataContainer bowContainer = bow.getItemMeta().getPersistentDataContainer();
if (bowContainer.has(CustomEnchantsMain.ENDER_BOW_KEY, PersistentDataType.INTEGER)) {
int enchantmentLevel = bowContainer.get(CustomEnchantsMain.ENDER_BOW_KEY, PersistentDataType.INTEGER);
if (enchantmentLevel > 0 && isFlagAllowed(player.getLocation(), enderBowFlag)) {
Entity entity = event.getProjectile();
if (entity instanceof Projectile) {
Projectile projectile = (Projectile) entity;
if (projectile instanceof Arrow || projectile instanceof SpectralArrow) {
handleArrow(player, projectile, bow, enchantmentLevel);
private void handleArrow(Player player, Projectile arrow, ItemStack bow, int enchantmentLevel) {
PersistentDataContainer arrowContainer = arrow.getPersistentDataContainer();
arrowContainer.set(CustomEnchantsMain.ENDER_BOW_KEY, PersistentDataType.INTEGER, enchantmentLevel);
playersWithActiveArrows.add(player.getUniqueId());
arrow.addPassenger(player);
enderBowCooldowns.put(player.getUniqueId(), System.currentTimeMillis() + cooldownTime * 50); // convert ticks to milliseconds
Bukkit.getScheduler().runTaskLater(plugin, () -> {
playersWithActiveArrows.remove(player.getUniqueId());
}, 20L * 20); // 10 seconds
public void onEntityDismount(EntityDismountEvent event) {
if (!(event.getEntity() instanceof Player)) {
if (!(event.getDismounted() instanceof Arrow)) {
Player player = (Player) event.getEntity();
Arrow arrow = (Arrow) event.getDismounted();
// Remove the player's UUID from the active arrows set and remove the arrow
if (playersWithActiveArrows.contains(player.getUniqueId())) {
playersWithActiveArrows.remove(player.getUniqueId());
// If the player is on cooldown, remove the cooldown
if (isOnCooldown(player)) {
enderBowCooldowns.remove(player.getUniqueId());
public void onProjectileHit(ProjectileHitEvent event) {
if (event.getEntity() instanceof Arrow) {
Arrow arrow = (Arrow) event.getEntity();
if (arrow.getPassengers().size() > 0) {
Entity entity = arrow.getPassengers().get(0);
if (entity instanceof Player) {
Player player = (Player) entity;
// Check if arrow is in water
if(arrow.getLocation().getBlock().getType() == Material.WATER) {
// Remove arrow as it's no longer needed
playersWithActiveArrows.remove(player.getUniqueId());