/**
 * The MIT License Copyright (c) 2015 Teal Cube Games
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
 * associated documentation files (the "Software"), to deal in the Software without restriction,
 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or
 * substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
 * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
package info.faceland.strife.listeners.combat;

import static info.faceland.strife.stats.StrifeStat.MULTISHOT;
import static info.faceland.strife.util.ProjectileUtil.createArrow;
import static info.faceland.strife.util.ProjectileUtil.createTrident;

import info.faceland.strife.StrifePlugin;
import info.faceland.strife.data.StrifeMob;
import info.faceland.strife.data.ability.EntityAbilitySet.TriggerAbilityType;
import info.faceland.strife.stats.StrifeStat;
import info.faceland.strife.util.LogUtil;
import info.faceland.strife.util.ProjectileUtil;
import java.util.Objects;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Trident;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.ProjectileHitEvent;
import org.bukkit.event.entity.ProjectileLaunchEvent;

public class ShootListener implements Listener {

  private final StrifePlugin plugin;

  public ShootListener(StrifePlugin plugin) {
    this.plugin = plugin;
  }

  @EventHandler(priority = EventPriority.HIGH)
  public void onEntityShoot(ProjectileLaunchEvent event) {
    if (!(event.getEntity().getShooter() instanceof LivingEntity)) {
      return;
    }

    StrifeMob mob = plugin.getStrifeMobManager()
        .getStatMob((LivingEntity) event.getEntity().getShooter());

    event.setCancelled(true);

    if (mob.getAbilitySet() != null
        && mob.getAbilitySet().getAbilities(TriggerAbilityType.SHOOT) != null) {
      boolean triggered = plugin.getAbilityManager().abilityCast(mob, TriggerAbilityType.SHOOT);
      if (triggered) {
        return;
      }
    }

    double attackMultiplier = plugin.getAttackSpeedManager().getAttackMultiplier(mob);
    attackMultiplier = Math.pow(attackMultiplier, 1.5D);

    if (attackMultiplier <= 0.05) {
      event.setCancelled(true);
      return;
    }

    float projectileSpeed = 2.5f * (1 + (mob.getStat(StrifeStat.PROJECTILE_SPEED) / 100));
    int projectiles = ProjectileUtil.getTotalProjectiles(1, mob.getStat(MULTISHOT));

    createArrow(mob.getEntity(), attackMultiplier, projectileSpeed, 0, 0.17);
    projectiles--;

    for (int i = projectiles; i > 0; i--) {
      createArrow(mob.getEntity(), attackMultiplier, projectileSpeed, randomOffset(projectiles),
          0.17);
    }
    mob.getEntity().getWorld()
        .playSound(mob.getEntity().getLocation(), Sound.ENTITY_ARROW_SHOOT, 1f, 1f);
  }

  @EventHandler(priority = EventPriority.HIGH)
  public void onPlayerTridentThrow(ProjectileLaunchEvent event) {
    if (!(event.getEntity().getShooter() instanceof Player)) {
      return;
    }
    if (!(event.getEntity() instanceof Trident)) {
      return;
    }

    event.setCancelled(true);

    Player player = (Player) event.getEntity().getShooter();
    StrifeMob pStats = plugin.getStrifeMobManager().getStatMob(player);
    float attackMultiplier = plugin.getAttackSpeedManager().getAttackMultiplier(pStats);
    attackMultiplier = (float) Math.pow(attackMultiplier, 1.5D);

    ((Player) event.getEntity().getShooter()).setCooldown(Material.TRIDENT, 50);

    if (attackMultiplier <= 0.05) {
      event.setCancelled(true);
      return;
    }

    plugin.getChampionManager().updateEquipmentStats(
        plugin.getChampionManager().getChampion(player));

    double speedMult = 1 + (pStats.getStat(StrifeStat.PROJECTILE_SPEED) / 100);

    createTrident((Player) event.getEntity().getShooter(), (Trident) event.getEntity(),
        attackMultiplier, speedMult);

    player.getWorld().playSound(player.getLocation(), Sound.ITEM_TRIDENT_THROW, 1f, 1f);
    plugin.getSneakManager().tempDisableSneak(player);
  }

  @EventHandler(priority = EventPriority.MONITOR)
  public void onGroundEffectProjectileHit(final ProjectileHitEvent event) {
    if (event.getHitBlock() == null) {
      return;
    }
    if (!event.getEntity().hasMetadata("GROUND_TRIGGER")) {
      return;
    }
    StrifeMob caster = plugin.getStrifeMobManager()
        .getStatMob((LivingEntity) Objects.requireNonNull(event.getEntity().getShooter()));

    String[] effects = event.getEntity().getMetadata("EFFECT_PROJECTILE").get(0).asString()
        .split("~");
    if (effects.length == 0) {
      LogUtil
          .printWarning("A handled GroundProjectile was missing effect meta... something's wrong");
      return;
    }
    Location loc = event.getEntity().getLocation().clone()
        .add(event.getEntity().getLocation().getDirection().multiply(-0.25));
    for (String s : effects) {
      StrifePlugin.getInstance().getEffectManager()
          .execute(StrifePlugin.getInstance().getEffectManager().getEffect(s), caster, loc);
    }
  }

  private double randomOffset(double magnitude) {
    return 0.11 + magnitude * 0.005;
  }
}
@@ -1779,16 +1779,48 @@
 .Sound;%0A
+import org.bukkit.entity.Arrow;%0A
 import o
@@ -2470,16 +2470,66 @@
 gEntity)
+ %7C%7C !(event%0A        .getEntity() instanceof Arrow)
 ) %7B%0A    

Fixing all shot projectiles being converted to arrows