// Path: src/com/hpspells/core/util/FireworkEffectPlayer.java
// public class FireworkEffectPlayer {
// 
//     /*
//      * Example use:
//      *
//      * public class FireWorkPlugin implements Listener {
//      *
//      * FireworkEffectPlayer fplayer = new FireworkEffectPlayer();
//      *
//      * @EventHandler
//      * public void onPlayerLogin(PlayerLoginEvent event) {
//      *   fplayer.playFirework(event.getPlayer().getWorld(), event.getPlayer.getLocation(), Util.getRandomFireworkEffect());
//      * }
//      *
//      * }
//      */
// 
//     // internal references, performance improvements
//     private static Method world_getHandle = null, nms_world_broadcastEntityEffect = null, firework_getHandle = null;
// 
//     /**
//      * Play a pretty firework at the location with the FireworkEffect when called
//      *
//      * @param world
//      * @param loc
//      * @param fe
//      * @throws Exception
//      */
//     public static void playFirework(World world, Location loc, FireworkEffect fe) throws Exception {
//         // Bukkity load (CraftFirework)
//         Firework fw = (Firework) world.spawn(loc, Firework.class);
//         // the net.minecraft.server.World
//         Object nms_world = null;
//         Object nms_firework = null;
//         /*
//          * The reflection part, this gives us access to funky ways of messing around with things
//          */
//         if (world_getHandle == null) {
//             // get the methods of the craftbukkit objects
//             world_getHandle = getMethod(world.getClass(), "getHandle");
//             firework_getHandle = getMethod(fw.getClass(), "getHandle");
//         }
//         // invoke with no arguments
//         nms_world = world_getHandle.invoke(world, (Object[]) null);
//         nms_firework = firework_getHandle.invoke(fw, (Object[]) null);
//         // null checks are fast, so having this seperate is ok
//         if (nms_world_broadcastEntityEffect == null) {
//             // get the method of the nms_world
//             nms_world_broadcastEntityEffect = getMethod(nms_world.getClass(), "broadcastEntityEffect");
//         }
//         /*
//          * Now we mess with the metadata, allowing nice clean spawning of a pretty firework (look, pretty lights!)
//          */
//         // metadata load
//         FireworkMeta data = (FireworkMeta) fw.getFireworkMeta();
//         // clear existing
//         data.clearEffects();
//         // power of one
//         data.setPower(1);
//         // add the effect
//         data.addEffect(fe);
//         // set the meta
//         fw.setFireworkMeta(data);
//         /*
//          * Finally, we broadcast the entity effect then kill our fireworks object
//          */
//         // invoke with arguments
//         nms_world_broadcastEntityEffect.invoke(nms_world, new Object[]{nms_firework, (byte) 17});
//         // remove from the game
//         fw.remove();
//     }
//     
//     /**
//      * Fires a firework with an effect at the location specified with a certain power.
//      * 
//      * @param location Location to fire
//      * @param effect Effects that the fireworks should have
//      * @param power The amount of power the firework should have
//      * @see #playFirework(Location, FireworkEffect)
//      */
//     public static void playFirework(Location location, FireworkEffect effect, int power) {
//         Firework fw = (Firework) location.getWorld().spawnEntity(location, EntityType.FIREWORK);
//         FireworkMeta fwm = fw.getFireworkMeta();
//         
//         fwm.setPower(power);
//         fwm.addEffect(effect);
//         
//         fw.setFireworkMeta(fwm);
//     }
//     
//     /**
//      * Fires a firework with an effect at the location specified with a power of 1.
//      * 
//      * @param location Location to fire
//      * @param effect Effects that the fireworks should have
//      */
//     public static void playFirework(Location location, FireworkEffect effect) {
//         playFirework(location, effect, 1);
//     }
// 
// }
// 
// Path: src/com/hpspells/core/util/HPSParticle.java
// public class HPSParticle {
// 	
// 	private Particle particle;
// 	private DustOptions options;
// 	
// 	public HPSParticle(Particle particle) {
// 		this(particle, null);
// 	}
// 	
// 	public HPSParticle(Particle particle, DustOptions options) {
// 		this.particle = particle;
// 		this.options = options;
// 	}
// 	
// 	public Particle getParticle() {
// 		return particle;
// 	}
// 	
// 	public void setParticle(Particle particle) {
// 		this.particle = particle;
// 	}
// 	
// 	public DustOptions getOptions() {
// 		return options;
// 	}
// 	
// 	public void setOptions(DustOptions options) {
// 		this.options = options;
// 	}
// 
// }


import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import org.bukkit.Color;
import org.bukkit.Effect;
import org.bukkit.FireworkEffect;
import org.bukkit.Location;
import org.bukkit.Particle;
import org.bukkit.Particle.DustOptions;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.Vector;
import com.hpspells.core.util.FireworkEffectPlayer;
import com.hpspells.core.util.HPSParticle;
                }

                if (!loc.getBlock().getType().isTransparent()) {
                    onHit.hitBlock(loc.getBlock());
                    cancel();
                    return;
                }

                List<LivingEntity> list = getNearbyEntities(loc, 2, caster);
                if (list.size() != 0) {
                    onHit.hitEntity(list.get(0));
                    cancel();
                    return;
                }
                tickTracker++;
                if (tickTracker > maxTicks && !(maxTicks == -1)) {
                    cancel();
                }
            }
        }.run();
    }

    /**
     * Registers a new {@link SpellHitEvent} to be called when a spell hits something using the default offset and count.
     *
     * @param caster        the player who cast the spell
     * @param onHit         the SpellHitEvent to call when the spell hits something
     * @param spellSpeed    the vector multiplier for the movement of the spell
     * @param hpsParticle   the {@link HPSParticle} to play during the movement of the spell
     */
// Path: src/com/hpspells/core/util/FireworkEffectPlayer.java
// public class FireworkEffectPlayer {
// 
//     /*
//      * Example use:
//      *
//      * public class FireWorkPlugin implements Listener {
//      *
//      * FireworkEffectPlayer fplayer = new FireworkEffectPlayer();
//      *
//      * @EventHandler
//      * public void onPlayerLogin(PlayerLoginEvent event) {
//      *   fplayer.playFirework(event.getPlayer().getWorld(), event.getPlayer.getLocation(), Util.getRandomFireworkEffect());
//      * }
//      *
//      * }
//      */
// 
//     // internal references, performance improvements
//     private static Method world_getHandle = null, nms_world_broadcastEntityEffect = null, firework_getHandle = null;
// 
//     /**
//      * Play a pretty firework at the location with the FireworkEffect when called
//      *
//      * @param world
//      * @param loc
//      * @param fe
//      * @throws Exception
//      */
//     public static void playFirework(World world, Location loc, FireworkEffect fe) throws Exception {
//         // Bukkity load (CraftFirework)
//         Firework fw = (Firework) world.spawn(loc, Firework.class);
//         // the net.minecraft.server.World
//         Object nms_world = null;
//         Object nms_firework = null;
//         /*
//          * The reflection part, this gives us access to funky ways of messing around with things
//          */
//         if (world_getHandle == null) {
//             // get the methods of the craftbukkit objects
//             world_getHandle = getMethod(world.getClass(), "getHandle");
//             firework_getHandle = getMethod(fw.getClass(), "getHandle");
//         }
//         // invoke with no arguments
//         nms_world = world_getHandle.invoke(world, (Object[]) null);
//         nms_firework = firework_getHandle.invoke(fw, (Object[]) null);
//         // null checks are fast, so having this seperate is ok
//         if (nms_world_broadcastEntityEffect == null) {
//             // get the method of the nms_world
//             nms_world_broadcastEntityEffect = getMethod(nms_world.getClass(), "broadcastEntityEffect");
//         }
//         /*
//          * Now we mess with the metadata, allowing nice clean spawning of a pretty firework (look, pretty lights!)
//          */
//         // metadata load
//         FireworkMeta data = (FireworkMeta) fw.getFireworkMeta();
//         // clear existing
//         data.clearEffects();
//         // power of one
//         data.setPower(1);
//         // add the effect
//         data.addEffect(fe);
//         // set the meta
//         fw.setFireworkMeta(data);
//         /*
//          * Finally, we broadcast the entity effect then kill our fireworks object
//          */
//         // invoke with arguments
//         nms_world_broadcastEntityEffect.invoke(nms_world, new Object[]{nms_firework, (byte) 17});
//         // remove from the game
//         fw.remove();
//     }
//     
//     /**
//      * Fires a firework with an effect at the location specified with a certain power.
//      * 
//      * @param location Location to fire
//      * @param effect Effects that the fireworks should have
//      * @param power The amount of power the firework should have
//      * @see #playFirework(Location, FireworkEffect)
//      */
//     public static void playFirework(Location location, FireworkEffect effect, int power) {
//         Firework fw = (Firework) location.getWorld().spawnEntity(location, EntityType.FIREWORK);
//         FireworkMeta fwm = fw.getFireworkMeta();
//         
//         fwm.setPower(power);
//         fwm.addEffect(effect);
//         
//         fw.setFireworkMeta(fwm);
//     }
//     
//     /**
//      * Fires a firework with an effect at the location specified with a power of 1.
//      * 
//      * @param location Location to fire
//      * @param effect Effects that the fireworks should have
//      */
//     public static void playFirework(Location location, FireworkEffect effect) {
//         playFirework(location, effect, 1);
//     }
// 
// }
// 
// Path: src/com/hpspells/core/util/HPSParticle.java
// public class HPSParticle {
// 	
// 	private Particle particle;
// 	private DustOptions options;
// 	
// 	public HPSParticle(Particle particle) {
// 		this(particle, null);
// 	}
// 	
// 	public HPSParticle(Particle particle, DustOptions options) {
// 		this.particle = particle;
// 		this.options = options;
// 	}
// 	
// 	public Particle getParticle() {
// 		return particle;
// 	}
// 	
// 	public void setParticle(Particle particle) {
// 		this.particle = particle;
// 	}
// 	
// 	public DustOptions getOptions() {
// 		return options;
// 	}
// 	
// 	public void setOptions(DustOptions options) {
// 		this.options = options;
// 	}
// 
// }


// Path: src/com/hpspells/core/SpellTargeter.java
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import org.bukkit.Color;
import org.bukkit.Effect;
import org.bukkit.FireworkEffect;
import org.bukkit.Location;
import org.bukkit.Particle;
import org.bukkit.Particle.DustOptions;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.Vector;
import com.hpspells.core.util.FireworkEffectPlayer;
import com.hpspells.core.util.HPSParticle;

                }

                if (!loc.getBlock().getType().isTransparent()) {
                    onHit.hitBlock(loc.getBlock());
                    cancel();
                    return;
                }

                List<LivingEntity> list = getNearbyEntities(loc, 2, caster);
                if (list.size() != 0) {
                    onHit.hitEntity(list.get(0));
                    cancel();
                    return;
                }
                tickTracker++;
                if (tickTracker > maxTicks && !(maxTicks == -1)) {
                    cancel();
                }
            }
        }.run();
    }

    /**
     * Registers a new {@link SpellHitEvent} to be called when a spell hits something using the default offset and count.
     *
     * @param caster        the player who cast the spell
     * @param onHit         the SpellHitEvent to call when the spell hits something
     * @param spellSpeed    the vector multiplier for the movement of the spell
     * @param hpsParticle   the {@link HPSParticle} to play during the movement of the spell
     */
    public void register(final Player caster, final SpellHitEvent onHit, final double spellSpeed, final HPSParticle hpsParticle) {