BlastingCrisis/src/main/kotlin/cc/maxmc/blastingcrisis/game/GameTimer.kt

79 lines
2.5 KiB
Kotlin

package cc.maxmc.blastingcrisis.game
import cc.maxmc.blastingcrisis.configuration.GlobalSettings
import cc.maxmc.blastingcrisis.misc.pluginScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import taboolib.common.platform.function.adaptCommandSender
import taboolib.module.lang.getLocaleFile
import taboolib.platform.util.sendLang
import kotlin.time.Duration
import kotlin.time.DurationUnit
import kotlin.time.toDuration
class GameTimer(private val game: Game) {
private val events = ArrayList<Triple<Long, String, () -> Unit>>()
private lateinit var timerJob: Job
private lateinit var countdownJob: Job
private var start: Long = 0
var current = GlobalSettings.timeToStart
lateinit var nextEvent: Triple<Duration, String, () -> Unit>
private set
fun beginCountdown() {
countdownJob = pluginScope.launch {
while (current > 0) {
if (!isActive) {
return@launch
}
countdown()
current--
delay(1000)
}
game.start()
}
}
private fun countdown() {
game.scoreboard.sendScoreboard()
game.broadcast {
val locale = adaptCommandSender(it).getLocaleFile()!!
if (locale.nodes.containsKey("game_countdown_${current}")) {
it.sendLang("game_countdown_${current}")
}
}
}
fun resetCountdown() {
game.broadcast {
it.sendLang("time_reset")
}
current = GlobalSettings.timeToStart
}
fun startTimer() {
start = System.nanoTime()
timerJob = pluginScope.launch {
while (true) {
val toDos = events.filter { it.first <= System.nanoTime() }
toDos.forEach { (_, _, toDo) -> toDo() }
events.removeAll(toDos.toSet())
events.minByOrNull { it.first }?.also {
val duration = (it.first - System.nanoTime()).toDuration(DurationUnit.NANOSECONDS)
nextEvent = Triple(duration, it.second, it.third)
} ?: let { nextEvent = Triple(Duration.INFINITE, "end") {} }
game.scoreboard.sendScoreboard()
delay(1000)
}
}
}
fun submitEvent(name: String, time: java.time.Duration, `do`: () -> Unit) {
events.add(Triple(time.toNanos() + start, name, `do`))
}
}