79 lines
2.5 KiB
Kotlin
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`))
|
|
}
|
|
|
|
} |