Countdown help

Discussion in 'Plugin Development' started by Candle is taken :I, Jul 6, 2015.

Thread Status:
Not open for further replies.
  1. Hey guys, I'm coding a mini-game server and am trying to make a plugin that counts down from 30 seconds once two or more people join the server. When it starts counting down it should say "Game starting in 30 seconds" and once it's finished it should say "Starting game..."
    Unfortunately I'm having a few issues the "Game starting in 30 seconds" is being displayed even with just a single person on the server and the "Starting game..." message is never being displayed at all.

    Here's my code so far...
    main class:
    Code:
    package me.candle;
    
    import org.bukkit.plugin.java.JavaPlugin;
    
    public class Candlexxx extends JavaPlugin {
       
        @Override
        public void onEnable () {
            new countdownListener(this);
    }
       
        @Override
        public void onDisable () {
        }
    }
    countdownListener.java:
    Code:
    package me.candle;
    
    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.player.PlayerJoinEvent;
    import org.bukkit.plugin.Plugin;
    
    public class countdownListener implements Listener {
       
        static int timer1;
        static int loop;
       
        public countdownListener(Candlexxx plugin) {
        plugin.getServer().getPluginManager().registerEvents(this, plugin);
    }
    
        @EventHandler
        public void onJoin(PlayerJoinEvent e) {
            if (Bukkit.getServer().getOnlinePlayers().size() > 1); {
    Bukkit.broadcastMessage(ChatColor.RED + "Game starting in 30 seconds");           
    timer1 = Bukkit.getScheduler().scheduleSyncRepeatingTask((Plugin) this, new Runnable(){
        public void run() {
            if (loop != 30) {
            loop++;
            Bukkit.broadcastMessage("geuegrygryreygerugre");
            } else {
                Bukkit.getScheduler().cancelTask(timer1);
                Bukkit.broadcastMessage(ChatColor.RED + "Starting game...");
            }
            }
    }, 20L, 20L);
    }
        }
    }
    any ideas?
     
  2. @Candle is taken :I
    Don't you need to assign the new countdownListener to an actual object?
    Also, you need to register the events from the count down listener class in your onEnable.
     
  3. @BorisTheTerrible
    I'm actually pretty new to Java and Bukkit, would you mind explaining how to assign countdownListener to an object and register events in the onEnable?
     
  4. Offline

    CraterHater

    I would suggest using this API:
    Just make a new class Called Cooldowns and than you can just do:

    if (Cooldowns.tryCooldown(p, "[NAME]", [SEC x 1000])) {

    and if there is no cooldown it will continue and if there is you can make an else statement:

    }else{
    p.sendMessage("§b§2[Game]:§There are" + (Cooldowns.getCooldown(p, "[NAME]") / 1000) + " seconds left!");

    Code:
    package plugin;
    
    import org.bukkit.entity.Player;
    
    import com.google.common.collect.HashBasedTable;
    import com.google.common.collect.Table;
    
    public class Cooldowns {
        private static Table<String, String, Long> cooldowns = HashBasedTable.create();
       
        /**
         * Retrieve the number of milliseconds left until a given cooldown expires.
         * <p>
         * Check for a negative value to determine if a given cooldown has expired. <br>
         * Cooldowns that have never been defined will return {@link Long#MIN_VALUE}.
         * @param player - the player.
         * @param key - cooldown to locate.
         * @return Number of milliseconds until the cooldown expires.
         */
        public static long getCooldown(Player player, String key) {
            return calculateRemainder(cooldowns.get(player.getName(), key));
        }
       
        /**
         * Update a cooldown for the specified player.
         * @param player - the player.
         * @param key - cooldown to update.
         * @param delay - number of milliseconds until the cooldown will expire again.
         * @return The previous number of milliseconds until expiration.
         */
        public static long setCooldown(Player player, String key, long delay) {
            return calculateRemainder(
                    cooldowns.put(player.getName(), key, System.currentTimeMillis() + delay));
        }
       
        /**
         * Determine if a given cooldown has expired. If it has, refresh the cooldown. If not, do nothing.
         * @param player - the player.
         * @param key - cooldown to update.
         * @param delay - number of milliseconds until the cooldown will expire again.
         * @return TRUE if the cooldown was expired/unset and has now been reset, FALSE otherwise.
         */
        public static boolean tryCooldown(Player player, String key, long delay) {
            if (getCooldown(player, key) <= 0) {
                setCooldown(player, key, delay);
                return true;
            }
            return false;
        }
       
        /**
         * Remove any cooldowns associated with the given player.
         * @param player - the player we will reset.
         */
        public static void removeCooldowns(Player player) {
            cooldowns.row(player.getName()).clear();
        }
       
        private static long calculateRemainder(Long expireTime) {
            return expireTime != null ? expireTime - System.currentTimeMillis() : Long.MIN_VALUE;
        }
    }
    
    Hope I helped
     
  5. @CraterHater
    Thanks, but I'm trying to make a countdown, not a cool down.
     
  6. Offline

    WesJD

  7. Offline

    poepdrolify

    Step 1: Make an integer called time or something like that.
    Step 2: Make a method were you set the time to x and start a scheduler.
    Step 3: In that scheduler, set ticks to 20, and make it remove 1 from time.
    Step 4: Make it check if time is 0 or something like that. (You can also check if it is 10, 5, 4 ,3, 2, 1, etc).
    Step 5: Make a method to stop the timer.
    Step 6: Put in the check if time is 0 something like stopTimer() (Referring to your method).
    Step 7: Add display to your timer (XP Bar, etc).
    Step 8: Go in-game, and test if it works.
    Step 9: If it works, promote me, Poepdrolify on Youtube :D.
    Step 10: Be happy

    Code:
       int time;
    
        public void startTimer() {
            time = 30;
            BukkitScheduler scheduler = Bukkit.getServer().getScheduler();
            scheduler.scheduleSyncRepeatingTask(this, new Runnable() {
                @Override
                public void run() {
                    for (Player p : Bukkit.getOnlinePlayers()) {
                        p.setLevel(time);
                    }
    
                    if (time == 0) {
                        Bukkit.broadcastMessage("The game is starting...");
                        stopTimer();
                        return;
                    }
    
                    if (time == 10 || time == 5 || time == 4 || time == 3
                            || time == 2 || time == 1) {
                        Bukkit.broadcastMessage("The game is starting in " + time
                                + " seconds");
                    }
    
                    time = time - 1;
    
                }
            }, 0L, 20L);
        }
    
        public void stopTimer() {
            Bukkit.getScheduler().cancelAllTasks();
        }
    
        @Override
        public boolean onCommand(CommandSender sender, Command command,
                String label, String[] args) {
            if (command.getName().equalsIgnoreCase("timer")) {
                startTimer();
            }
            return false;
        }
    Something like this, dunno if there are any mistakes...

    EDIT: Add this to set Exp bar, not level:
    Code:
    p.setExp(time / (float) 30);
    And this to play a sound at 0:
    Code:
    for(Player p : Bukkit.getOnlinePlayers()) {
                            p.playSound(p.getLocation(), Sound.ORB_PICKUP, 10, 0);
                        }
    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 12, 2016
  8. Offline

    RoflFrankoc

    as a count down fore games i usually just use this
    Code:
    int times = 0;
    int cd = 10;
    while(times < 10 && cd >= 0){
    player.sendMessage("Count down ends in "+cd+" seconds!");
    times++;
    cd--;
    try{
    Thread.sleep(1000);
    }catch(InterruptedException e){
    
    }
    }
    
     
  9. Offline

    MOMOTHEREAL

    Uh uh, no no. This is a really bad idea, since you are clearly freezing the main server thread. You should use Scheduler Programming, a simple-to-use and safe API, supported by Bukkit.
     
  10. Offline

    RoflFrankoc

  11. Offline

    MOMOTHEREAL

    @RoflFrankoc Maybe, but this is a complete waste of memory and very bad practice. Schedulers are much more safe.
     
Thread Status:
Not open for further replies.

Share This Page