蚯嫁嚎坏事做尽!*2

This commit is contained in:
tony_all 2022-11-01 14:07:56 +08:00
parent 4f37b3e2b9
commit 5124478878
10 changed files with 93 additions and 22 deletions

View File

@ -6,6 +6,7 @@ import cc.maxmc.blastingcrisis.game.GameState
import cc.maxmc.blastingcrisis.map.GameMap
import cc.maxmc.blastingcrisis.map.MapTeam
import cc.maxmc.blastingcrisis.misc.Area
import cc.maxmc.blastingcrisis.misc.GameManager
import cc.maxmc.blastingcrisis.packet.BEntityVillager
import kotlinx.coroutines.cancel
import org.bukkit.Bukkit
@ -60,11 +61,16 @@ object DebugCommand {
),
)
val map = GameMap(
"test", Area(location(20, 70, -49), location(-20, 79, 49)), listOf(
"test",
Area(location(20, 70, -49), location(-20, 79, 49)),
Area(location(-13, 78, 0), location(13, 72, 0)),
listOf(
teamRed, teamGreen
), 4
),
1
)
game = Game(map)
GameManager.currentGame = game
}
literal("join") {

View File

@ -2,8 +2,12 @@ package cc.maxmc.blastingcrisis.game
import cc.maxmc.blastingcrisis.map.GameMap
import cc.maxmc.blastingcrisis.misc.debug
import org.bukkit.Bukkit
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,
@ -26,6 +30,7 @@ class Game(
it.sendLang("game_join", player.name)
}
scoreboard.sendScoreboard()
checkStart()
}
fun leave(player: Player) {
@ -43,7 +48,16 @@ class Game(
fun start() {
debug("game ${map.name} started.")
state = GameState.START
timer.startTimer()
timer.submitEvent("wall_fall", Duration.ofMinutes(1)) {
broadcast { it.sendLang("game_wall_fall") }
submit(now = true) {
map.wall.forBlocksInArea().forEach {
it.block.type = Material.AIR
}
}
}
autoJoinTeam()
teams.forEach {
it.start()
@ -68,6 +82,7 @@ class Game(
}
broadcast { it.sendLang("game_end") }
//TODO restart game logic
}
fun broadcast(action: (Player) -> Unit) {

View File

@ -23,8 +23,24 @@ class GameScoreboard(val game: Game) {
COUNTING_DOWN -> {
player.asLangText("scoreboard_counting_down", game.players.size, game.map.maxPlayer, game.timer.current)
}
START -> TODO()
WALL_FALL -> TODO()
START -> {
val event = game.timer.nextEvent
val teamMessage = buildString {
game.teams.forEach {
appendLine(player.asLangText("scoreboard_team_info", it.teamInfo.name, it.villager.health))
}
}
player.asLangText(
"scoreboard_start",
event.second,
"${event.first.inWholeMinutes}:${event.first.inWholeSeconds}",
teamMessage,
player.team?.villager?.health ?: throw IllegalStateException("player ${player.name} has no team."),
0, // TODO Kill counter
)
}
FINISH -> TODO()
}

View File

@ -4,8 +4,7 @@ enum class GameState {
WAITING,
COUNTING_DOWN,
START,
WALL_FALL,
FINISH;
fun isStarted(): Boolean = this == START || this == WALL_FALL
fun isStarted(): Boolean = this == START
}

View File

@ -2,6 +2,7 @@ package cc.maxmc.blastingcrisis.game
import cc.maxmc.blastingcrisis.listener.GameListener
import cc.maxmc.blastingcrisis.map.MapTeam
import cc.maxmc.blastingcrisis.misc.debug
import org.bukkit.entity.Player
import taboolib.platform.util.sendLang
@ -16,7 +17,7 @@ class GameTeam(val game: Game, val teamInfo: MapTeam) {
players.forEach { it.teleport(teamInfo.spawn) }
villager.spawn()
GameListener.interactSubscribed[teamInfo.upgrade] = {
debug("interact team ${teamInfo.name} upgrade.")
}
}

View File

@ -1,6 +1,7 @@
package cc.maxmc.blastingcrisis.game
import cc.maxmc.blastingcrisis.configuration.GlobalSettings
import cc.maxmc.blastingcrisis.misc.info
import cc.maxmc.blastingcrisis.misc.pluginScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
@ -9,10 +10,18 @@ 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) {
lateinit var countdownJob: Job
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 {
@ -46,6 +55,26 @@ class GameTimer(private val game: Game) {
}
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`))
}
}
}

View File

@ -2,6 +2,7 @@ package cc.maxmc.blastingcrisis.listener
import cc.maxmc.blastingcrisis.game.team
import cc.maxmc.blastingcrisis.misc.GameManager
import cc.maxmc.blastingcrisis.misc.debug
import org.bukkit.Location
import org.bukkit.event.block.BlockExplodeEvent
import org.bukkit.event.player.PlayerInteractEvent
@ -17,7 +18,8 @@ object GameListener {
val player = event.player
val team = player.team ?: return
if (!team.teamInfo.teleport.isInArea(event.to)) return
debug("teleporting ${event.player} to battle field")
player.teleport(team.teamInfo.mine.randomLocation())
}
@SubscribeEvent
@ -28,11 +30,13 @@ object GameListener {
@SubscribeEvent
fun onTNT(tntExplode: BlockExplodeEvent) {
GameManager.currentGame.teams.forEach {
if (!it.teamSurvive) return
if (!it.teamInfo.home.isInArea(tntExplode.block.location)) return
it.villager.damage()
}
debug("tnt exploded at ${tntExplode.block.location}")
tntExplode.blockList().clear()
GameManager.currentGame.teams.findLast {
it.teamSurvive && it.teamInfo.home.isInArea(tntExplode.block.location)
}?.apply {
villager.damage()
debug("team ${teamInfo.name}'s villager damaged")
} ?: throw IllegalStateException("TNT Exploded at no team, which shouldn't happen")
}
}

View File

@ -2,7 +2,7 @@ package cc.maxmc.blastingcrisis.map
import cc.maxmc.blastingcrisis.misc.Area
class GameMap(val name: String, val area: Area, val teams: List<MapTeam>, val maxPlayersPerTeam: Int) {
class GameMap(val name: String, val area: Area, val wall: Area, val teams: List<MapTeam>, val maxPlayersPerTeam: Int) {
val maxPlayer: Int
get() = maxPlayersPerTeam * teams.size
}

View File

@ -30,10 +30,10 @@ class Area(loc1: Location, loc2: Location) : ConfigurationSerializable {
* @return true if the location is in this area
*/
fun isInArea(location: Location): Boolean {
if (location.world != locTop.world) return false
if (location.x !in locTop.x..locMin.x) return false
if (location.y !in locTop.y..locMin.y) return false
if (location.z !in locTop.z..locMin.z) return false
if (location.world != locTop.world) return debug("world").let { false }
if (location.x !in locTop.x..locMin.x) return debug("x").let { false }
if (location.y !in locTop.y..locMin.y) return debug("y").let { false }
if (location.z !in locTop.z..locMin.z) return debug("z").let { false }
return true
}

View File

@ -15,7 +15,7 @@ scoreboard_counting_down: |-
§a| §7游戏还有 §a{2} §7秒开始.
§6Play.MaxMC.cc
scoreboard_counting_start: |-
scoreboard_start: |-
§6Blasting§7Crisis
§a| §7{0}: §a{1}
@ -63,6 +63,7 @@ game_end: |-
§e|
§e| 游戏结束
§e|
game_wall_fall: "§c| §7战争之墙倒下了!"
## end part game
## part team