package tc.oc.pgm.fireworks; import java.util.Collections; import java.util.List; import java.util.Set; import java.util.stream.Collectors; import javax.inject.Inject; import com.google.common.collect.ImmutableList; import org.bukkit.Color; import org.bukkit.FireworkEffect; import org.bukkit.FireworkEffect.Type; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import tc.oc.commons.bukkit.util.BukkitUtils; import tc.oc.commons.core.scheduler.Task; import tc.oc.pgm.events.ListenerScope; import tc.oc.pgm.events.MatchEndEvent; import tc.oc.pgm.fireworks.FireworksConfig.PostMatch; import tc.oc.pgm.match.Competitor; import tc.oc.pgm.match.Match; import tc.oc.pgm.match.MatchModule; import tc.oc.pgm.match.MatchPlayer; import tc.oc.pgm.match.MatchScope; import tc.oc.pgm.victory.VictoryMatchModule; @ListenerScope(MatchScope.LOADED) public class PostMatchFireworkListener extends MatchModule implements Listener { private Task task; @Inject PostMatchFireworkListener(Match match) { super(match); } @EventHandler(priority = EventPriority.MONITOR) public void onMatchEnd(final MatchEndEvent event) { if(!PostMatch.enabled()) return; task = match.getScheduler(MatchScope.LOADED).createRepeatingTask( PostMatch.delay(), PostMatch.frequency(), new FireworkRunner(event.getMatch().needMatchModule(VictoryMatchModule.class).winners()) ); } private void cancelTask() { if(this.task != null) { this.task.cancel(); this.task = null; } } public static List<FireworkEffect.Type> AVAILABLE_TYPES = ImmutableList.<FireworkEffect.Type>builder() .add(Type.BALL) .add(Type.BALL_LARGE) .add(Type.BURST) .add(Type.STAR) .build(); public class FireworkRunner implements Runnable { private final Set<Color> colors; private final Set<Competitor> winners; private int iterations = 0; public FireworkRunner(Set<Competitor> winners) { this.winners = winners; this.colors = winners.stream() .map(winner -> BukkitUtils.colorOf(winner.getColor())) .collect(Collectors.toSet()); } @Override public void run() { // Build this list fresh every time, because MatchPlayers can unload, but Competitors can't. final List<MatchPlayer> players = winners.stream() .flatMap(c -> c.getPlayers().stream()) .collect(Collectors.toList()); Collections.shuffle(players); for(int i = 0; i < players.size() && i < PostMatch.number(); i++) { MatchPlayer player = players.get(i); Type type = AVAILABLE_TYPES.get(match.getRandom().nextInt(AVAILABLE_TYPES.size())); FireworkEffect effect = FireworkEffect.builder().with(type).withFlicker().withColor(this.colors).withFade(Color.BLACK).build(); FireworkUtil.spawnFirework(player.getBukkit().getLocation(), effect, PostMatch.power()); } this.iterations++; if(this.iterations >= PostMatch.iterations()) { cancelTask(); } } } }