蚯嫁嚎坏事做尽!*2
This commit is contained in:
parent
4f37b3e2b9
commit
5124478878
|
|
@ -6,6 +6,7 @@ import cc.maxmc.blastingcrisis.game.GameState
|
||||||
import cc.maxmc.blastingcrisis.map.GameMap
|
import cc.maxmc.blastingcrisis.map.GameMap
|
||||||
import cc.maxmc.blastingcrisis.map.MapTeam
|
import cc.maxmc.blastingcrisis.map.MapTeam
|
||||||
import cc.maxmc.blastingcrisis.misc.Area
|
import cc.maxmc.blastingcrisis.misc.Area
|
||||||
|
import cc.maxmc.blastingcrisis.misc.GameManager
|
||||||
import cc.maxmc.blastingcrisis.packet.BEntityVillager
|
import cc.maxmc.blastingcrisis.packet.BEntityVillager
|
||||||
import kotlinx.coroutines.cancel
|
import kotlinx.coroutines.cancel
|
||||||
import org.bukkit.Bukkit
|
import org.bukkit.Bukkit
|
||||||
|
|
@ -60,11 +61,16 @@ object DebugCommand {
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
val map = GameMap(
|
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
|
teamRed, teamGreen
|
||||||
), 4
|
),
|
||||||
|
1
|
||||||
)
|
)
|
||||||
game = Game(map)
|
game = Game(map)
|
||||||
|
GameManager.currentGame = game
|
||||||
}
|
}
|
||||||
|
|
||||||
literal("join") {
|
literal("join") {
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,12 @@ package cc.maxmc.blastingcrisis.game
|
||||||
|
|
||||||
import cc.maxmc.blastingcrisis.map.GameMap
|
import cc.maxmc.blastingcrisis.map.GameMap
|
||||||
import cc.maxmc.blastingcrisis.misc.debug
|
import cc.maxmc.blastingcrisis.misc.debug
|
||||||
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.Material
|
||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
|
import taboolib.common.platform.function.submit
|
||||||
import taboolib.platform.util.sendLang
|
import taboolib.platform.util.sendLang
|
||||||
|
import java.time.Duration
|
||||||
|
|
||||||
class Game(
|
class Game(
|
||||||
val map: GameMap,
|
val map: GameMap,
|
||||||
|
|
@ -26,6 +30,7 @@ class Game(
|
||||||
it.sendLang("game_join", player.name)
|
it.sendLang("game_join", player.name)
|
||||||
}
|
}
|
||||||
scoreboard.sendScoreboard()
|
scoreboard.sendScoreboard()
|
||||||
|
checkStart()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun leave(player: Player) {
|
fun leave(player: Player) {
|
||||||
|
|
@ -43,7 +48,16 @@ class Game(
|
||||||
|
|
||||||
fun start() {
|
fun start() {
|
||||||
debug("game ${map.name} started.")
|
debug("game ${map.name} started.")
|
||||||
|
state = GameState.START
|
||||||
timer.startTimer()
|
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()
|
autoJoinTeam()
|
||||||
teams.forEach {
|
teams.forEach {
|
||||||
it.start()
|
it.start()
|
||||||
|
|
@ -68,6 +82,7 @@ class Game(
|
||||||
}
|
}
|
||||||
|
|
||||||
broadcast { it.sendLang("game_end") }
|
broadcast { it.sendLang("game_end") }
|
||||||
|
//TODO restart game logic
|
||||||
}
|
}
|
||||||
|
|
||||||
fun broadcast(action: (Player) -> Unit) {
|
fun broadcast(action: (Player) -> Unit) {
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,24 @@ class GameScoreboard(val game: Game) {
|
||||||
COUNTING_DOWN -> {
|
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()
|
FINISH -> TODO()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,7 @@ enum class GameState {
|
||||||
WAITING,
|
WAITING,
|
||||||
COUNTING_DOWN,
|
COUNTING_DOWN,
|
||||||
START,
|
START,
|
||||||
WALL_FALL,
|
|
||||||
FINISH;
|
FINISH;
|
||||||
|
|
||||||
fun isStarted(): Boolean = this == START || this == WALL_FALL
|
fun isStarted(): Boolean = this == START
|
||||||
}
|
}
|
||||||
|
|
@ -2,6 +2,7 @@ package cc.maxmc.blastingcrisis.game
|
||||||
|
|
||||||
import cc.maxmc.blastingcrisis.listener.GameListener
|
import cc.maxmc.blastingcrisis.listener.GameListener
|
||||||
import cc.maxmc.blastingcrisis.map.MapTeam
|
import cc.maxmc.blastingcrisis.map.MapTeam
|
||||||
|
import cc.maxmc.blastingcrisis.misc.debug
|
||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
import taboolib.platform.util.sendLang
|
import taboolib.platform.util.sendLang
|
||||||
|
|
||||||
|
|
@ -16,7 +17,7 @@ class GameTeam(val game: Game, val teamInfo: MapTeam) {
|
||||||
players.forEach { it.teleport(teamInfo.spawn) }
|
players.forEach { it.teleport(teamInfo.spawn) }
|
||||||
villager.spawn()
|
villager.spawn()
|
||||||
GameListener.interactSubscribed[teamInfo.upgrade] = {
|
GameListener.interactSubscribed[teamInfo.upgrade] = {
|
||||||
|
debug("interact team ${teamInfo.name} upgrade.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package cc.maxmc.blastingcrisis.game
|
package cc.maxmc.blastingcrisis.game
|
||||||
|
|
||||||
import cc.maxmc.blastingcrisis.configuration.GlobalSettings
|
import cc.maxmc.blastingcrisis.configuration.GlobalSettings
|
||||||
|
import cc.maxmc.blastingcrisis.misc.info
|
||||||
import cc.maxmc.blastingcrisis.misc.pluginScope
|
import cc.maxmc.blastingcrisis.misc.pluginScope
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
|
|
@ -9,10 +10,18 @@ import kotlinx.coroutines.launch
|
||||||
import taboolib.common.platform.function.adaptCommandSender
|
import taboolib.common.platform.function.adaptCommandSender
|
||||||
import taboolib.module.lang.getLocaleFile
|
import taboolib.module.lang.getLocaleFile
|
||||||
import taboolib.platform.util.sendLang
|
import taboolib.platform.util.sendLang
|
||||||
|
import kotlin.time.Duration
|
||||||
|
import kotlin.time.DurationUnit
|
||||||
|
import kotlin.time.toDuration
|
||||||
|
|
||||||
class GameTimer(private val game: Game) {
|
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
|
var current = GlobalSettings.timeToStart
|
||||||
|
lateinit var nextEvent: Triple<Duration, String, () -> Unit>
|
||||||
|
private set
|
||||||
|
|
||||||
fun beginCountdown() {
|
fun beginCountdown() {
|
||||||
countdownJob = pluginScope.launch {
|
countdownJob = pluginScope.launch {
|
||||||
|
|
@ -46,6 +55,26 @@ class GameTimer(private val game: Game) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun startTimer() {
|
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`))
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
@ -2,6 +2,7 @@ package cc.maxmc.blastingcrisis.listener
|
||||||
|
|
||||||
import cc.maxmc.blastingcrisis.game.team
|
import cc.maxmc.blastingcrisis.game.team
|
||||||
import cc.maxmc.blastingcrisis.misc.GameManager
|
import cc.maxmc.blastingcrisis.misc.GameManager
|
||||||
|
import cc.maxmc.blastingcrisis.misc.debug
|
||||||
import org.bukkit.Location
|
import org.bukkit.Location
|
||||||
import org.bukkit.event.block.BlockExplodeEvent
|
import org.bukkit.event.block.BlockExplodeEvent
|
||||||
import org.bukkit.event.player.PlayerInteractEvent
|
import org.bukkit.event.player.PlayerInteractEvent
|
||||||
|
|
@ -17,7 +18,8 @@ object GameListener {
|
||||||
val player = event.player
|
val player = event.player
|
||||||
val team = player.team ?: return
|
val team = player.team ?: return
|
||||||
if (!team.teamInfo.teleport.isInArea(event.to)) return
|
if (!team.teamInfo.teleport.isInArea(event.to)) return
|
||||||
|
debug("teleporting ${event.player} to battle field")
|
||||||
|
player.teleport(team.teamInfo.mine.randomLocation())
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
|
|
@ -28,11 +30,13 @@ object GameListener {
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
fun onTNT(tntExplode: BlockExplodeEvent) {
|
fun onTNT(tntExplode: BlockExplodeEvent) {
|
||||||
GameManager.currentGame.teams.forEach {
|
debug("tnt exploded at ${tntExplode.block.location}")
|
||||||
if (!it.teamSurvive) return
|
tntExplode.blockList().clear()
|
||||||
if (!it.teamInfo.home.isInArea(tntExplode.block.location)) return
|
GameManager.currentGame.teams.findLast {
|
||||||
|
it.teamSurvive && it.teamInfo.home.isInArea(tntExplode.block.location)
|
||||||
it.villager.damage()
|
}?.apply {
|
||||||
}
|
villager.damage()
|
||||||
|
debug("team ${teamInfo.name}'s villager damaged")
|
||||||
|
} ?: throw IllegalStateException("TNT Exploded at no team, which shouldn't happen")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2,7 +2,7 @@ package cc.maxmc.blastingcrisis.map
|
||||||
|
|
||||||
import cc.maxmc.blastingcrisis.misc.Area
|
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
|
val maxPlayer: Int
|
||||||
get() = maxPlayersPerTeam * teams.size
|
get() = maxPlayersPerTeam * teams.size
|
||||||
}
|
}
|
||||||
|
|
@ -30,10 +30,10 @@ class Area(loc1: Location, loc2: Location) : ConfigurationSerializable {
|
||||||
* @return true if the location is in this area
|
* @return true if the location is in this area
|
||||||
*/
|
*/
|
||||||
fun isInArea(location: Location): Boolean {
|
fun isInArea(location: Location): Boolean {
|
||||||
if (location.world != locTop.world) return false
|
if (location.world != locTop.world) return debug("world").let { false }
|
||||||
if (location.x !in locTop.x..locMin.x) return false
|
if (location.x !in locTop.x..locMin.x) return debug("x").let { false }
|
||||||
if (location.y !in locTop.y..locMin.y) return false
|
if (location.y !in locTop.y..locMin.y) return debug("y").let { false }
|
||||||
if (location.z !in locTop.z..locMin.z) return false
|
if (location.z !in locTop.z..locMin.z) return debug("z").let { false }
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ scoreboard_counting_down: |-
|
||||||
§a| §7游戏还有 §a{2} §7秒开始.
|
§a| §7游戏还有 §a{2} §7秒开始.
|
||||||
|
|
||||||
§6Play.MaxMC.cc
|
§6Play.MaxMC.cc
|
||||||
scoreboard_counting_start: |-
|
scoreboard_start: |-
|
||||||
§6Blasting§7Crisis
|
§6Blasting§7Crisis
|
||||||
|
|
||||||
§a| §7{0}: §a{1}
|
§a| §7{0}: §a{1}
|
||||||
|
|
@ -63,6 +63,7 @@ game_end: |-
|
||||||
§e|
|
§e|
|
||||||
§e| 游戏结束
|
§e| 游戏结束
|
||||||
§e|
|
§e|
|
||||||
|
game_wall_fall: "§c| §7战争之墙倒下了!"
|
||||||
## end part game
|
## end part game
|
||||||
|
|
||||||
## part team
|
## part team
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue