From 51244788783d0f282dd07170e1636fed95f73907 Mon Sep 17 00:00:00 2001 From: tony_all Date: Tue, 1 Nov 2022 14:07:56 +0800 Subject: [PATCH] =?UTF-8?q?=E8=9A=AF=E5=AB=81=E5=9A=8E=E5=9D=8F=E4=BA=8B?= =?UTF-8?q?=E5=81=9A=E5=B0=BD!*2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../blastingcrisis/command/DebugCommand.kt | 10 ++++-- .../cc/maxmc/blastingcrisis/game/Game.kt | 15 +++++++++ .../blastingcrisis/game/GameScoreboard.kt | 22 +++++++++++-- .../cc/maxmc/blastingcrisis/game/GameState.kt | 3 +- .../cc/maxmc/blastingcrisis/game/GameTeam.kt | 3 +- .../cc/maxmc/blastingcrisis/game/GameTimer.kt | 31 ++++++++++++++++++- .../blastingcrisis/listener/GameListener.kt | 18 ++++++----- .../cc/maxmc/blastingcrisis/map/GameMap.kt | 2 +- .../cc/maxmc/blastingcrisis/misc/Area.kt | 8 ++--- src/main/resources/lang/zh_CN.yml | 3 +- 10 files changed, 93 insertions(+), 22 deletions(-) diff --git a/src/main/kotlin/cc/maxmc/blastingcrisis/command/DebugCommand.kt b/src/main/kotlin/cc/maxmc/blastingcrisis/command/DebugCommand.kt index 2d4e5cb..6c2803b 100644 --- a/src/main/kotlin/cc/maxmc/blastingcrisis/command/DebugCommand.kt +++ b/src/main/kotlin/cc/maxmc/blastingcrisis/command/DebugCommand.kt @@ -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") { diff --git a/src/main/kotlin/cc/maxmc/blastingcrisis/game/Game.kt b/src/main/kotlin/cc/maxmc/blastingcrisis/game/Game.kt index 41d6987..9517fb5 100644 --- a/src/main/kotlin/cc/maxmc/blastingcrisis/game/Game.kt +++ b/src/main/kotlin/cc/maxmc/blastingcrisis/game/Game.kt @@ -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) { diff --git a/src/main/kotlin/cc/maxmc/blastingcrisis/game/GameScoreboard.kt b/src/main/kotlin/cc/maxmc/blastingcrisis/game/GameScoreboard.kt index 4ca4a6d..53a671c 100644 --- a/src/main/kotlin/cc/maxmc/blastingcrisis/game/GameScoreboard.kt +++ b/src/main/kotlin/cc/maxmc/blastingcrisis/game/GameScoreboard.kt @@ -21,10 +21,26 @@ class GameScoreboard(val game: Game) { } COUNTING_DOWN -> { - player.asLangText("scoreboard_counting_down", game.players.size, game.map.maxPlayer, game.timer.current) + 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() } diff --git a/src/main/kotlin/cc/maxmc/blastingcrisis/game/GameState.kt b/src/main/kotlin/cc/maxmc/blastingcrisis/game/GameState.kt index 0527063..a26422f 100644 --- a/src/main/kotlin/cc/maxmc/blastingcrisis/game/GameState.kt +++ b/src/main/kotlin/cc/maxmc/blastingcrisis/game/GameState.kt @@ -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 } \ No newline at end of file diff --git a/src/main/kotlin/cc/maxmc/blastingcrisis/game/GameTeam.kt b/src/main/kotlin/cc/maxmc/blastingcrisis/game/GameTeam.kt index e82b2a4..36c1944 100644 --- a/src/main/kotlin/cc/maxmc/blastingcrisis/game/GameTeam.kt +++ b/src/main/kotlin/cc/maxmc/blastingcrisis/game/GameTeam.kt @@ -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.") } } diff --git a/src/main/kotlin/cc/maxmc/blastingcrisis/game/GameTimer.kt b/src/main/kotlin/cc/maxmc/blastingcrisis/game/GameTimer.kt index 2b6019d..0532123 100644 --- a/src/main/kotlin/cc/maxmc/blastingcrisis/game/GameTimer.kt +++ b/src/main/kotlin/cc/maxmc/blastingcrisis/game/GameTimer.kt @@ -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 Unit>>() + private lateinit var timerJob: Job + private lateinit var countdownJob: Job + private var start: Long = 0 var current = GlobalSettings.timeToStart + lateinit var nextEvent: Triple 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`)) + } + } \ No newline at end of file diff --git a/src/main/kotlin/cc/maxmc/blastingcrisis/listener/GameListener.kt b/src/main/kotlin/cc/maxmc/blastingcrisis/listener/GameListener.kt index e28af5a..b3c342f 100644 --- a/src/main/kotlin/cc/maxmc/blastingcrisis/listener/GameListener.kt +++ b/src/main/kotlin/cc/maxmc/blastingcrisis/listener/GameListener.kt @@ -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") } } \ No newline at end of file diff --git a/src/main/kotlin/cc/maxmc/blastingcrisis/map/GameMap.kt b/src/main/kotlin/cc/maxmc/blastingcrisis/map/GameMap.kt index 2914376..327e538 100644 --- a/src/main/kotlin/cc/maxmc/blastingcrisis/map/GameMap.kt +++ b/src/main/kotlin/cc/maxmc/blastingcrisis/map/GameMap.kt @@ -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, val maxPlayersPerTeam: Int) { +class GameMap(val name: String, val area: Area, val wall: Area, val teams: List, val maxPlayersPerTeam: Int) { val maxPlayer: Int get() = maxPlayersPerTeam * teams.size } \ No newline at end of file diff --git a/src/main/kotlin/cc/maxmc/blastingcrisis/misc/Area.kt b/src/main/kotlin/cc/maxmc/blastingcrisis/misc/Area.kt index e1e3566..3f7dab9 100644 --- a/src/main/kotlin/cc/maxmc/blastingcrisis/misc/Area.kt +++ b/src/main/kotlin/cc/maxmc/blastingcrisis/misc/Area.kt @@ -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 } diff --git a/src/main/resources/lang/zh_CN.yml b/src/main/resources/lang/zh_CN.yml index 5760214..532f234 100644 --- a/src/main/resources/lang/zh_CN.yml +++ b/src/main/resources/lang/zh_CN.yml @@ -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