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
}
}