Bukkit/CraftBukkit — pull request #1195 by LordRalex (2013-07-12 08:58:50+00:00)
Title: [B+C] Implement Firework.detonate(). Adds BUKKIT-4538

**The Issue:**

Currently, fireworks use a expected time to live number to determine when they need to explode. If you would like to detonate a firework, you would have to set the power level of the firework to 0, but this still leaves a small delay if the firework was very recently launched. Server code will add 1 power to the one provided, multiply that by 10, then add up to 11 more ticks. This causes the firework to only explode at least 10 ticks after being created. This leaves a small chance of the firework not exploding when the plugin wants it to.

**Justification for this PR:**

Power that is given to a firework results into a randomized value which is then used to set the life expectancy the firework. By default, the server will add 10 ticks to the power and then randomly up to 11 more ticks. This allows a plugin to explicitly detonate the firework without having to rely on the "randomness" and delay that the server adds to the firework's expected life time.

**PR Breakdown:**

This PR implements the newly created detonate() method created by the relevant PR in the CraftFirework class. Because the EntityFirework does not provide access to some of the variables needed to have the CraftFirework detonate it, a detonate() method was also created in the EntityFirework class. This method calls the this.world.broadcastEntityEffect(this, (byte) 17) and the this.die() method that the server uses to explode the firework. Rather than expose the variables needed, this was felt to be the best approach.

**Testing Results and Materials:**

A plugin was made that would utilize this new method. It would create a new firework on command, set the power to 120, which would mean the firework would expect to detonate at least 1200 ticks later. A scheduled task that was set to run 60 ticks later would call the firework.detonate() method.

```java
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (!(sender instanceof Player)) {
return true;
}
Firework firework = ((Player) sender).getWorld().spawn(((Player) sender).getLocation(), Firework.class);
FireworkMeta meta = firework.getFireworkMeta();
meta.setPower(120);
meta.addEffect(FireworkEffect.builder().with(FireworkEffect.Type.BALL).withColor(Color.WHITE).build());
firework.setFireworkMeta(meta);
Bukkit.getScheduler().runTaskLater(this, new Explode(firework), 60);
return true;
}

private class Explode extends BukkitRunnable {

private final Firework firework;

public Explode(Firework fire) {
super();
firework = fire;
}

@Override
public void run() {
Bukkit.broadcastMessage("Detonating firework now");
firework.detonate();
Bukkit.broadcastMessage("Detonated");
}
}
```
Full plugin source: http://www.mediafire.com/download/4t75ecn729n4ak9/src.zip
Compiled binary: http://www.mediafire.com/download/xqcgwbpl22ucwkn/TestPlugin-1.0-SNAPSHOT.jar

**Relevant PRs**

https://github.com/Bukkit/Bukkit/pull/900

**JIRA Ticket**

https://bukkit.atlassian.net/browse/BUKKIT-4538