@@ -0,0 +1,2060 @@
+package pw.ian.albkit.util;%0A%0Aimport java.util.ArrayList;%0Aimport java.util.List;%0Aimport java.util.Map;%0A%0Aimport java.util.Collections;%0Aimport org.bukkit.scheduler.BukkitRunnable;%0A%0Apublic abstract class Countdown extends BukkitRunnable %7B%0A%0A    private final Map%3CInteger, String%3E messages;%0A%0A    private final List%3CInteger%3E times;%0A%0A    private final long start;%0A%0A    private final int length;%0A%0A    private int current = 0;%0A%0A    /**%0A     * C'tor%0A     *%0A     * @param messages A map that takes in entries of seconds =%3E message.%0A     */%0A    public Countdown(Map%3CInteger, String%3E messages) %7B%0A        this.messages = messages;%0A%0A        times = new ArrayList%3C%3E(messages.keySet());%0A        Collections.sort(times);%0A        length = times.get(times.size() - 1);%0A        start = System.currentTimeMillis();%0A        current = times.size() - 1;%0A    %7D%0A%0A    @Override%0A    public void run() %7B%0A        if (!checkCondition()) %7B%0A            cancel();%0A            return;%0A        %7D%0A%0A        // Expect that the times are in length order%0A        int secsRemaining = length - (((int) (System.currentTimeMillis() - start)) / 1000);%0A%0A        if (current %3C 0) %7B%0A            if (secsRemaining %3C= 0) %7B%0A                onEnd();%0A                cancel();%0A            %7D%0A        %7D else %7B%0A            int nextSecs = times.get(current);%0A            if (secsRemaining %3C= nextSecs) %7B%0A                onCheckpoint(nextSecs, messages.get(nextSecs));%0A                current--;%0A            %7D%0A        %7D%0A    %7D%0A%0A    /**%0A     * A condition method that will be checked on each iteration of the timer.%0A     * If it returns false, the task will be cancelled.%0A     *%0A     * @return False if cancel%0A     */%0A    public boolean checkCondition() %7B%0A        return true;%0A    %7D%0A%0A    /**%0A     * Called whenever a checkpoint is reached.%0A     *%0A     * @param seconds%0A     * @param message%0A     */%0A    public void onCheckpoint(int seconds, String message) %7B%0A    %7D%0A%0A    /**%0A     * Called when the task ends. This isn't called if the timer breaks due to%0A     * the condition check.%0A     */%0A    public void onEnd() %7B%0A    %7D%0A%7D%0A

Add Countdown