Newer
Older
ChallengeSystem / src / main / java / de / fanta / challenges / Timer.java
package de.fanta.challenges;

import de.fanta.challenges.challenges.MLGChallenge;
import de.fanta.challenges.events.TimerChangedEvent;
import de.fanta.challenges.utils.ChatUtil;
import de.fanta.challenges.utils.guiutils.GUIUtils;
import de.iani.cubesideutils.StringUtil;
import net.md_5.bungee.api.ChatColor;
import org.bukkit.Bukkit;
import org.bukkit.Effect;
import org.bukkit.GameMode;
import org.bukkit.entity.Creature;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;

import java.util.Random;

public class Timer {

    private final Challenges plugin;
    private final Random random;
    private int actionBarTaskId;
    private int idleActionBarTaskId;

    private long time; // milliseconds
    private TimerMode mode;
    private long countingSinceTimestamp;

    public Timer(Challenges plugin) {
        this.plugin = plugin;
        this.random = new Random();
        this.mode = TimerMode.UP;

        if (!isRunning()) {
            sendIdleActionBar();
        }
    }

    public void startTimer() {
        countingSinceTimestamp = System.currentTimeMillis();
        if (idleActionBarTaskId > 0) {
            Bukkit.getScheduler().cancelTask(idleActionBarTaskId);
            idleActionBarTaskId = -1;
        }
        actionBarTaskId = Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, () -> {
            int random = this.random.nextInt(750);
            MLGChallenge.timeSinceMLG++;
            if (random == 638 || MLGChallenge.timeSinceMLG >= MLGChallenge.maxMLGTime) {
                MLGChallenge.triggerMLG();
            }

            if (mode == TimerMode.DOWN) {
                if (time <= 0) {
                    if (plugin.getConfig().getBoolean("event.enabled")) {
                        for (Player p : Bukkit.getOnlinePlayers()) {
                            p.setGameMode(GameMode.SPECTATOR);
                        }
                        GUIUtils.sendTitleToAll("Event", "Die Zeit ist abgelaufen!", ChatUtil.GREEN);
                    } else {
                        for (Player p : Bukkit.getOnlinePlayers()) {
                            p.setGameMode(GameMode.SPECTATOR);
                            p.sendTitle(ChatColor.DARK_RED + "ZEIT ABGELAUFEN!", ChatUtil.RED + "Challenge fehgeschlagen", 10, 60, 10);
                        }
                        ChatUtil.sendBrodcastMessage(ChatColor.DARK_RED + "Die Zeit ist abgelaufen und die Challenge somit fehlgeschlagen!");
                        ChatUtil.sendBrodcastMessage("Seed: " + ChatColor.AQUA + Bukkit.getWorlds().get(0).getSeed());
                    }
                    stopTimer();
                } else {
                    time -= (System.currentTimeMillis() - countingSinceTimestamp);
                    countingSinceTimestamp = System.currentTimeMillis();
                    sendTimerActionBar(ChatUtil.BLUE);
                }
            } else {
                time += (System.currentTimeMillis() - countingSinceTimestamp);
                countingSinceTimestamp = System.currentTimeMillis();
                sendTimerActionBar(ChatUtil.GREEN);
            }
        }, 20L, 20L);
        if (!plugin.getConfig().getBoolean("firsttimerstart")) {
            GUIUtils.setConfig("firsttimerstart", true);
        }
        Bukkit.getPluginManager().callEvent(new TimerChangedEvent(true));
    }

    public void stopTimer() {
        if (actionBarTaskId > 0) {
            Bukkit.getScheduler().cancelTask(actionBarTaskId);
            actionBarTaskId = -1;
            sendIdleActionBar();
        }
        for (Player pp : Bukkit.getOnlinePlayers()) {
            for (final Entity entity : pp.getNearbyEntities(100, 100, 100)) {
                if ((entity instanceof final Creature creature)) {
                    if ((creature.getTarget() != null) && creature.getTarget().equals(pp)) {
                        creature.setTarget(null);
                    }
                }
            }
        }
        Bukkit.getPluginManager().callEvent(new TimerChangedEvent(false));
    }

    private void sendIdleActionBar() {
        idleActionBarTaskId = Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, () -> {
            for (Player p : Bukkit.getOnlinePlayers()) {
                if (!plugin.getVanish().isVanish(p)) {
                    p.sendActionBar(ChatUtil.RED + "" + ChatColor.BOLD + "Der Timer ist pausiert.");
                    if (p.getGameMode() != GameMode.SPECTATOR) {
                        p.getWorld().playEffect(p.getLocation(), Effect.ENDER_SIGNAL, 2);
                    }
                }
            }
        }, 20L, 20L);
    }

    private void sendTimerActionBar(ChatColor color) {
        for (Player p : Bukkit.getOnlinePlayers()) {
            if (!plugin.getVanish().isVanish(p)) {
                if (plugin.getConfig().getBoolean("showtimer")) {
                    p.sendActionBar(formatTime(color));
                }

            }
        }
    }

    public String formatTime(ChatColor color) {
        String formattime = StringUtil.formatTimespan((time / 1000) * 1000, " Tage, ", ":", "", "", "", ":", false, true);
        if (formattime.startsWith("1 Tage")) {
            return color + StringUtil.formatTimespan((time / 1000) * 1000, " Tag, ", ":", "", "", "", ":", false, true);
        }
        return color + formattime;
    }

    public String formatTime() {
        String formattime = StringUtil.formatTimespan((time / 1000) * 1000, "1 Tage, ", ":", "", "", "", ":", false, true);
        if (formattime.startsWith("1 Tage")) {
            return StringUtil.formatTimespan((time / 1000) * 1000, " Tag, ", ":", "", "", "", ":", false, true);
        }
        return formattime;
    }

    public void reverseTimer() {
        if (mode == TimerMode.DOWN) {
            mode = TimerMode.UP;
        } else {
            mode = TimerMode.DOWN;
        }
        if (isRunning()) {
            countingSinceTimestamp = System.currentTimeMillis();
        }
    }

    public boolean isRunning() {
        return actionBarTaskId > 0;
    }

    public boolean isReverse() {
        return mode == TimerMode.DOWN;
    }

    public long getTime() {
        return time / 1000;
    }

    public void setTime(int seconds) {
        this.time = seconds * 1000L;
        this.countingSinceTimestamp = System.currentTimeMillis();
    }

    private enum TimerMode {
        UP,
        DOWN;
    }

}