98 lines
2.7 KiB
Kotlin
98 lines
2.7 KiB
Kotlin
package cc.maxmc.blastingcrisis.game
|
|
|
|
import cc.maxmc.blastingcrisis.map.GameMap
|
|
import cc.maxmc.blastingcrisis.misc.debug
|
|
import org.bukkit.Material
|
|
import org.bukkit.entity.Player
|
|
import taboolib.common.platform.function.submit
|
|
import taboolib.platform.util.sendLang
|
|
import java.time.Duration
|
|
|
|
class Game(
|
|
val map: GameMap,
|
|
) {
|
|
val teams = map.teams.map { GameTeam(this, it) }
|
|
val scoreboard: GameScoreboard = GameScoreboard(this)
|
|
val timer: GameTimer = GameTimer(this)
|
|
val players = ArrayList<Player>()
|
|
val placeBreakRule = GamePlaceBreakRule(this)
|
|
var state: GameState = GameState.WAITING
|
|
|
|
private fun autoJoinTeam() {
|
|
players.filter { it.team == null }.shuffled().forEach {
|
|
teams.minBy { team -> team.players.size }.join(it)
|
|
}
|
|
}
|
|
|
|
fun join(player: Player) {
|
|
players += player
|
|
broadcast {
|
|
it.sendLang("game_join", player.name)
|
|
}
|
|
scoreboard.sendScoreboard()
|
|
checkStart()
|
|
}
|
|
|
|
fun leave(player: Player) {
|
|
if (state == GameState.WAITING || state == GameState.COUNTING_DOWN) {
|
|
players.remove(player)
|
|
player.team?.removePlayer(player)
|
|
broadcast { it.sendLang("game_leave", player.name) }
|
|
checkStart()
|
|
}
|
|
val team =
|
|
player.team ?: throw IllegalStateException("Player ${player.name} has no team, which shouldn't happen.")
|
|
team.removePlayer(player)
|
|
checkEnd()
|
|
}
|
|
|
|
fun start() {
|
|
debug("game ${map.name} started.")
|
|
placeBreakRule.loadDefaultRule()
|
|
|
|
state = GameState.START
|
|
timer.startTimer()
|
|
timer.submitEvent("wall_fall", Duration.ofMinutes(1)) {
|
|
broadcast { it.sendLang("game_wall_fall") }
|
|
placeBreakRule.addRule("allow_center_wall") { _, _, loc, _ ->
|
|
map.wall.contains(loc)
|
|
}
|
|
submit {
|
|
map.wall.forBlocksInArea().forEach {
|
|
it.block.type = Material.AIR
|
|
}
|
|
}
|
|
}
|
|
|
|
autoJoinTeam()
|
|
teams.forEach {
|
|
it.start()
|
|
}
|
|
}
|
|
|
|
private fun checkStart() {
|
|
if (players.size < map.maxPlayer * 0.5 && state == GameState.COUNTING_DOWN) {
|
|
state = GameState.WAITING
|
|
timer.resetCountdown()
|
|
}
|
|
|
|
if (players.size > map.maxPlayer * 0.75) {
|
|
state = GameState.COUNTING_DOWN
|
|
timer.beginCountdown()
|
|
}
|
|
}
|
|
|
|
fun checkEnd() {
|
|
if (teams.filter { it.teamSurvive }.size > 1) {
|
|
return
|
|
}
|
|
|
|
broadcast { it.sendLang("game_end") }
|
|
//TODO restart game logic
|
|
}
|
|
|
|
fun broadcast(action: (Player) -> Unit) {
|
|
players.forEach(action)
|
|
}
|
|
|
|
} |