package me.gtacraft.plugins.melondrop.util; import java.lang.reflect.Method; import org.bukkit.FireworkEffect; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.entity.Firework; import org.bukkit.inventory.meta.FireworkMeta; /** * FireworkEffectPlayer v1.0 * * FireworkEffectPlayer provides a thread-safe and (reasonably) version independant way to instantly explode a FireworkEffect at a given location. * You are welcome to use, redistribute, modify and destroy your own copies of this source with the following conditions: * * 1. No warranty is given or implied. * 2. All damage is your own responsibility. * 3. You provide credit publicly to the original source should you release the plugin. * * @author codename_B */ 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 Method world_getHandle = null; private Method nms_world_broadcastEntityEffect = null; private Method firework_getHandle = null; /** * Play a pretty firework at the location with the FireworkEffect when called * @param world * @param loc * @param fe * @throws Exception */ public 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(); } /** * Internal method, used as shorthand to grab our method in a nice friendly manner * @param cl * @param method * @return Method (or null) */ private static Method getMethod(Class<?> cl, String method) { for(Method m : cl.getMethods()) { if(m.getName().equals(method)) { return m; } } return null; } }