Newer
Older
ChallengeSystem / src / main / java / de / fanta / challenges / Timer.java
@fanta fanta on 7 Sep 2023 7 KB some fixes
package de.fanta.challenges;

import de.fanta.challenges.events.TimerChangedEvent;
import de.fanta.challenges.schedular.CancellableTask;
import de.fanta.challenges.utils.ChatUtil;
import de.fanta.challenges.utils.Config;
import de.fanta.challenges.utils.SaveWorldUtils;
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;

public class Timer {

    private final Challenges plugin;
    private CancellableTask actionBarTaskId;
    private CancellableTask idleActionBarTaskId;
    private long time; // milliseconds
    private TimerMode mode;
    private long countingSinceTimestamp;

    private static final int[] baseColorsTimer = new int[]{0xFF6668, 0xFFB566, 0xFFED66, 0x66FF75, 0x66B8FF, 0xE666FF};
    private static final int[] baseColorsReserveTimer = new int[]{0x7FD4E0, 0x947DFF, 0xFF88F1, 0xFF7D7D};

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

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

    public void startTimer() {
        countingSinceTimestamp = System.currentTimeMillis();
        if (idleActionBarTaskId != null) {
            idleActionBarTaskId.cancel();
            idleActionBarTaskId = null;
        }
        actionBarTaskId = plugin.getScheduler().runGlobalAtFixedRate(() -> {
            if (mode == TimerMode.DOWN) {
                if (time <= 0) {
                    if (Config.getBoolean("event.enabled")) {
                        for (Player p : Bukkit.getOnlinePlayers()) {
                            p.setGameMode(GameMode.SPECTATOR);
                        }
                        ChatUtil.sendTitleToAll("Event", "Die Zeit ist abgelaufen!", ChatUtil.GREEN);
                    } else {
                        for (Player p : Bukkit.getOnlinePlayers()) {
                            p.setGameMode(GameMode.SPECTATOR);
                            p.sendTitle(ChatUtil.RED + "ZEIT ABGELAUFEN!", ChatUtil.RED + "Challenge fehlgeschlagen", 10, 60, 10);
                        }
                        ChatUtil.sendBrodcastMessage(ChatUtil.RED + "Die Zeit ist abgelaufen und die Challenge somit fehlgeschlagen!");
                        ChatUtil.sendBrodcastMessage("Seed: " + ChatUtil.BLUE + Bukkit.getWorlds().get(0).getSeed());
                    }
                    stopTimer();
                } else {
                    time -= (System.currentTimeMillis() - countingSinceTimestamp);
                    countingSinceTimestamp = System.currentTimeMillis();
                    sendTimerActionBar(true);
                }
            } else {
                time += (System.currentTimeMillis() - countingSinceTimestamp);
                countingSinceTimestamp = System.currentTimeMillis();
                sendTimerActionBar(false);
            }
        }, 1L, 1L);
        if (!Config.getBoolean("firsttimerstart")) {
            Config.setValue("firsttimerstart", true, false);
        }
        Bukkit.getPluginManager().callEvent(new TimerChangedEvent(true));
    }

    public void stopTimer() {
        if (actionBarTaskId != null) {
            actionBarTaskId.cancel();
            actionBarTaskId = null;
            sendIdleActionBar();
        }
        for (Player pp : Bukkit.getOnlinePlayers()) {
            plugin.getScheduler().runDelayedOnEntity(pp, () -> {
                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);
                        }
                    }
                }
            }, 1);
        }
        Bukkit.getPluginManager().callEvent(new TimerChangedEvent(false));
    }

    private void sendIdleActionBar() {
        idleActionBarTaskId = plugin.getScheduler().runGlobalAtFixedRate(() -> {
            for (Player p : Bukkit.getOnlinePlayers()) {
                if (!plugin.getVanish().isVanish(p)) {
                    sendFormatedTimerActionBarToPlayer(p, 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(Boolean reverse) {
        for (Player p : Bukkit.getOnlinePlayers()) {
            if (!plugin.getVanish().isVanish(p)) {
                if (Config.getBoolean("showtimer")) {
                    //p.sendActionBar(formatTime(color));
                    sendFormatedTimerActionBarToPlayer(p, formateRainbowTime(!Config.getBoolean("editsettings")));
                }

            }
        }
    }

    private void sendFormatedTimerActionBarToPlayer(Player player, String text) {
        player.sendActionBar(text + (SaveWorldUtils.isCopyWorld ? ChatUtil.GREEN + " Save: " + SaveWorldUtils.getProgressBar(SaveWorldUtils.progress) : ""));
    }

    public String formatTime(ChatColor color) {
        return color + formatTime();
    }

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

    public String formateRainbowTime() {
        return formateRainbowTime(false);
    }

    public String formateRainbowTime(boolean speedRun) {
        return plugin.getColorUtils().addChatColorToString((speedRun ? "SpeedRun " : "") + formatTime(), mode == TimerMode.UP ? baseColorsTimer : baseColorsReserveTimer, 1.5);
    }

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

    public boolean isRunning() {
        return actionBarTaskId != null;
    }

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

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

    public long getTimeInMs() {
        return time;
    }

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

    public void addTime(int seconds) {
        this.time = Math.max(time + (seconds * 1000L), 0);
        this.countingSinceTimestamp = System.currentTimeMillis();
        Config.setValue("editsettings", true);

    }

    public void removeTime(int seconds) {
        this.time = Math.max(time - (seconds * 1000L), 0);
        this.countingSinceTimestamp = System.currentTimeMillis();
        Config.setValue("editsettings", true);
    }

    public TimerMode getMode() {
        return mode;
    }

    public enum TimerMode {
        UP,
        DOWN
    }

}