From 4f37b3e2b913681b6456e6e370c30adb4b2a9255 Mon Sep 17 00:00:00 2001 From: tony_all Date: Tue, 1 Nov 2022 01:37:04 +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!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cc/maxmc/blastingcrisis/BlastingCrisis.kt | 5 +- .../blastingcrisis/command/DebugCommand.kt | 55 ++++++++++++------- .../configuration/GlobalSettings.kt | 7 +++ .../blastingcrisis/factory/BEntityFactory.kt | 19 ------- .../cc/maxmc/blastingcrisis/game/Game.kt | 22 +++++--- .../blastingcrisis/game/GameOreGenerator.kt | 6 +- .../cc/maxmc/blastingcrisis/game/GameTeam.kt | 30 +++++++--- .../maxmc/blastingcrisis/game/TeamVillager.kt | 17 ++++-- .../blastingcrisis/listener/GameListener.kt | 38 +++++++++++++ .../cc/maxmc/blastingcrisis/misc/Area.kt | 23 ++++++++ .../misc/{DebugMessage.kt => LogMessages.kt} | 4 ++ .../blastingcrisis/packet/BEntityVillager.kt | 19 ++++++- src/main/resources/lang/zh_CN.yml | 16 ++++++ src/main/resources/settings.yml | 6 +- 14 files changed, 199 insertions(+), 68 deletions(-) delete mode 100644 src/main/kotlin/cc/maxmc/blastingcrisis/factory/BEntityFactory.kt create mode 100644 src/main/kotlin/cc/maxmc/blastingcrisis/listener/GameListener.kt rename src/main/kotlin/cc/maxmc/blastingcrisis/misc/{DebugMessage.kt => LogMessages.kt} (71%) diff --git a/src/main/kotlin/cc/maxmc/blastingcrisis/BlastingCrisis.kt b/src/main/kotlin/cc/maxmc/blastingcrisis/BlastingCrisis.kt index b52d1bb..85d9a40 100644 --- a/src/main/kotlin/cc/maxmc/blastingcrisis/BlastingCrisis.kt +++ b/src/main/kotlin/cc/maxmc/blastingcrisis/BlastingCrisis.kt @@ -1,6 +1,7 @@ package cc.maxmc.blastingcrisis import cc.maxmc.blastingcrisis.command.DebugCommand +import cc.maxmc.blastingcrisis.misc.info import cc.maxmc.blastingcrisis.misc.pluginScope import kotlinx.coroutines.cancel import taboolib.common.env.RuntimeDependency @@ -9,9 +10,11 @@ import taboolib.common.platform.Plugin @RuntimeDependency( "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4", ) -object BlastingCrisis: Plugin() { +object BlastingCrisis : Plugin() { override fun onEnable() { + info("§a| §7Loading BlastingCrisis") DebugCommand.debug("debugcmd") + info("§a| §7Loading BlastingCrisis") } override fun onDisable() { diff --git a/src/main/kotlin/cc/maxmc/blastingcrisis/command/DebugCommand.kt b/src/main/kotlin/cc/maxmc/blastingcrisis/command/DebugCommand.kt index 14705ab..2d4e5cb 100644 --- a/src/main/kotlin/cc/maxmc/blastingcrisis/command/DebugCommand.kt +++ b/src/main/kotlin/cc/maxmc/blastingcrisis/command/DebugCommand.kt @@ -1,6 +1,5 @@ package cc.maxmc.blastingcrisis.command -import cc.maxmc.blastingcrisis.factory.BEntityFactory import cc.maxmc.blastingcrisis.game.Game import cc.maxmc.blastingcrisis.game.GameOreGenerator import cc.maxmc.blastingcrisis.game.GameState @@ -11,6 +10,7 @@ import cc.maxmc.blastingcrisis.packet.BEntityVillager import kotlinx.coroutines.cancel import org.bukkit.Bukkit import org.bukkit.ChatColor +import org.bukkit.Location import org.bukkit.entity.Player import taboolib.common.platform.ProxyPlayer import taboolib.common.platform.command.command @@ -27,28 +27,41 @@ object DebugCommand { fun debug(cmd: String) = command(cmd) { literal("game") { execute { sender, _, _ -> + fun location(x: Int, y: Int, z: Int) = Location(sender.world, x.toDouble(), y.toDouble(), z.toDouble()) Bukkit.broadcastMessage(sender.name) - val homeArea = Area(sender.location, sender.location.add(10.0, 10.0, 10.0)) - val area1 = Area(sender.location, sender.location.add(5.0, 5.0, 5.0)) - val area2 = Area(sender.location, sender.location.add(5.0, 5.0, 5.0)) - val area3 = Area(sender.location, sender.location.add(5.0, 5.0, 5.0)) - val team = MapTeam( - "testTeam1", - ChatColor.AQUA, - sender.location, - sender.location, - sender.eyeLocation, - homeArea, - area1, - area2, - area2, - listOf(area3), + val teamRed = MapTeam( + "红队", + ChatColor.RED, + location(0, 72, -44), + location(0, 72, -44), + location(-8, 73, -47), + Area(location(14, 72, -48), location(-13, 78, -34)), + Area(location(-13, 78, -33), location(13, 72, -33)), + Area(location(-13, 78, -32), location(13, 71, -1)), + Area(location(7, 72, -45), location(9, 74, -48)), + listOf( + Area(location(15, 72, -1), location(19, 78, -48)), + Area(location(19, 78, -48), location(-15, 72, -1)) + ), + ) + val teamGreen = MapTeam( + "绿队", + ChatColor.GREEN, + location(0, 72, 44), + location(0, 72, 44), + location(8, 73, 47), + Area(location(-14, 72, 48), location(13, 78, 34)), + Area(location(13, 78, 33), location(-13, 72, 33)), + Area(location(13, 78, 32), location(-13, 71, 1)), + Area(location(-7, 72, 45), location(-9, 74, 48)), + listOf( + Area(location(-15, 72, 1), location(-19, 78, 48)), + Area(location(-19, 78, 48), location(15, 72, 1)) + ), ) val map = GameMap( - "test", - homeArea, - listOf( - team + "test", Area(location(20, 70, -49), location(-20, 79, 49)), listOf( + teamRed, teamGreen ), 4 ) game = Game(map) @@ -104,7 +117,7 @@ object DebugCommand { literal("spawnEntity") { execute { sender, _, _ -> val loc = sender.location - villager = BEntityFactory.createVillager(loc) + villager = BEntityVillager.create(loc) villager.addViewer(sender) } } diff --git a/src/main/kotlin/cc/maxmc/blastingcrisis/configuration/GlobalSettings.kt b/src/main/kotlin/cc/maxmc/blastingcrisis/configuration/GlobalSettings.kt index 8f5473b..5c8f908 100644 --- a/src/main/kotlin/cc/maxmc/blastingcrisis/configuration/GlobalSettings.kt +++ b/src/main/kotlin/cc/maxmc/blastingcrisis/configuration/GlobalSettings.kt @@ -10,4 +10,11 @@ object GlobalSettings { val timeToStart get() = settings.getInt("time-to-start") + object GameSettings { + val villagerMaxHealth + get() = settings.getInt("game.villager_max_health") + val villagerDamagePerHealth + get() = settings.getInt("game.damage_per_hurt") + } + } \ No newline at end of file diff --git a/src/main/kotlin/cc/maxmc/blastingcrisis/factory/BEntityFactory.kt b/src/main/kotlin/cc/maxmc/blastingcrisis/factory/BEntityFactory.kt deleted file mode 100644 index 9c56665..0000000 --- a/src/main/kotlin/cc/maxmc/blastingcrisis/factory/BEntityFactory.kt +++ /dev/null @@ -1,19 +0,0 @@ -package cc.maxmc.blastingcrisis.factory - -import cc.maxmc.blastingcrisis.misc.PacketEntityManager -import cc.maxmc.blastingcrisis.misc.debug -import cc.maxmc.blastingcrisis.packet.BEntityVillager -import org.bukkit.Location - -object BEntityFactory { - fun createVillager(loc: Location): BEntityVillager { - val entity = BEntityVillager(loc) - PacketEntityManager.register(entity.entityID, entity) - entity.handleInteract { - debug("Interacting with entity: ${entity.entityID}") - debug("type: ${it.type}") - it.vector?.let { vec -> debug("vector: $vec") } - } - return entity - } -} \ No newline at end of file diff --git a/src/main/kotlin/cc/maxmc/blastingcrisis/game/Game.kt b/src/main/kotlin/cc/maxmc/blastingcrisis/game/Game.kt index 26a05b0..41d6987 100644 --- a/src/main/kotlin/cc/maxmc/blastingcrisis/game/Game.kt +++ b/src/main/kotlin/cc/maxmc/blastingcrisis/game/Game.kt @@ -15,11 +15,9 @@ class Game( var state: GameState = GameState.WAITING private fun autoJoinTeam() { - players.filter { it.team == null } - .shuffled() - .forEach { - teams.minBy { team -> team.players.size }.join(it) - } + players.filter { it.team == null }.shuffled().forEach { + teams.minBy { team -> team.players.size }.join(it) + } } fun join(player: Player) { @@ -46,8 +44,10 @@ class Game( fun start() { debug("game ${map.name} started.") timer.startTimer() - - + autoJoinTeam() + teams.forEach { + it.start() + } } private fun checkStart() { @@ -62,8 +62,12 @@ class Game( } } - private fun checkEnd() { - + fun checkEnd() { + if (teams.filter { it.teamSurvive }.size > 1) { + return + } + + broadcast { it.sendLang("game_end") } } fun broadcast(action: (Player) -> Unit) { diff --git a/src/main/kotlin/cc/maxmc/blastingcrisis/game/GameOreGenerator.kt b/src/main/kotlin/cc/maxmc/blastingcrisis/game/GameOreGenerator.kt index 8589cd8..c35ab59 100644 --- a/src/main/kotlin/cc/maxmc/blastingcrisis/game/GameOreGenerator.kt +++ b/src/main/kotlin/cc/maxmc/blastingcrisis/game/GameOreGenerator.kt @@ -27,7 +27,11 @@ class GameOreGenerator(config: Configuration) { fun enable(area: Area): Job { return pluginScope.launch { while (true) { - generate(area) + val airPercent = area.getAirPercentage() + debug("remain air: $airPercent.") + if (airPercent > 0.5) { + generate(area) + } delay(rate * 50L) } } diff --git a/src/main/kotlin/cc/maxmc/blastingcrisis/game/GameTeam.kt b/src/main/kotlin/cc/maxmc/blastingcrisis/game/GameTeam.kt index 3f128a8..e82b2a4 100644 --- a/src/main/kotlin/cc/maxmc/blastingcrisis/game/GameTeam.kt +++ b/src/main/kotlin/cc/maxmc/blastingcrisis/game/GameTeam.kt @@ -1,16 +1,25 @@ package cc.maxmc.blastingcrisis.game +import cc.maxmc.blastingcrisis.listener.GameListener import cc.maxmc.blastingcrisis.map.MapTeam import org.bukkit.entity.Player import taboolib.platform.util.sendLang class GameTeam(val game: Game, val teamInfo: MapTeam) { - val players = ArrayList() val villager = TeamVillager(this) + val players = ArrayList() var teamSurvive = true private set + fun start() { + players.forEach { it.teleport(teamInfo.spawn) } + villager.spawn() + GameListener.interactSubscribed[teamInfo.upgrade] = { + + } + } + fun join(player: Player) { players += player if (game.state == GameState.COUNTING_DOWN || game.state == GameState.WAITING) { @@ -25,12 +34,19 @@ class GameTeam(val game: Game, val teamInfo: MapTeam) { } } - private fun checkTeamAlive() { - if (players.size != 0) return - game.broadcast { - it.sendLang("team_death", teamInfo.name) + fun checkTeamAlive() { + if (players.size == 0) { + teamSurvive = false + game.broadcast { + it.sendLang("team_death", teamInfo.name) + } } - teamSurvive = false - } + if (villager.health <= 0) { + teamSurvive = false + game.broadcast { + it.sendLang("team_death", teamInfo.name) + } + } + } } \ No newline at end of file diff --git a/src/main/kotlin/cc/maxmc/blastingcrisis/game/TeamVillager.kt b/src/main/kotlin/cc/maxmc/blastingcrisis/game/TeamVillager.kt index a549b9e..7b02c4c 100644 --- a/src/main/kotlin/cc/maxmc/blastingcrisis/game/TeamVillager.kt +++ b/src/main/kotlin/cc/maxmc/blastingcrisis/game/TeamVillager.kt @@ -1,20 +1,22 @@ package cc.maxmc.blastingcrisis.game -import cc.maxmc.blastingcrisis.factory.BEntityFactory +import cc.maxmc.blastingcrisis.configuration.GlobalSettings +import cc.maxmc.blastingcrisis.packet.BEntityVillager import org.bukkit.Bukkit import taboolib.platform.BukkitPlugin import taboolib.platform.util.asLangText class TeamVillager(private val team: GameTeam) { - private val packetVillager = BEntityFactory.createVillager(team.teamInfo.villager) - private var health: Int = 150 + private val packetVillager = BEntityVillager.create(team.teamInfo.villager) + var health: Int = GlobalSettings.GameSettings.villagerMaxHealth + private set init { packetVillager.name = { if (it.team == team) { - it.asLangText("team_villager_name_internal") + it.asLangText("team_villager_name_internal", health) } else { - it.asLangText("team_villager_name_outer") + it.asLangText("team_villager_name_outer", health) } } } @@ -24,14 +26,17 @@ class TeamVillager(private val team: GameTeam) { } fun damage() { - health -= 10 + health -= GlobalSettings.GameSettings.villagerDamagePerHealth if (health <= 0) { packetVillager.dieAnimate() Bukkit.getScheduler().runTaskLater(BukkitPlugin.getInstance(), { packetVillager.destroy() }, 20 * 3) + } packetVillager.hurtAnimate() + team.checkTeamAlive() + team.game.checkEnd() } diff --git a/src/main/kotlin/cc/maxmc/blastingcrisis/listener/GameListener.kt b/src/main/kotlin/cc/maxmc/blastingcrisis/listener/GameListener.kt new file mode 100644 index 0000000..e28af5a --- /dev/null +++ b/src/main/kotlin/cc/maxmc/blastingcrisis/listener/GameListener.kt @@ -0,0 +1,38 @@ +package cc.maxmc.blastingcrisis.listener + +import cc.maxmc.blastingcrisis.game.team +import cc.maxmc.blastingcrisis.misc.GameManager +import org.bukkit.Location +import org.bukkit.event.block.BlockExplodeEvent +import org.bukkit.event.player.PlayerInteractEvent +import org.bukkit.event.player.PlayerMoveEvent +import taboolib.common.platform.event.SubscribeEvent + +object GameListener { + val interactSubscribed = HashMap Unit>() + + @SubscribeEvent + fun onMoveInTeleport(event: PlayerMoveEvent) { + if (!GameManager.currentGame.players.contains(event.player)) return + val player = event.player + val team = player.team ?: return + if (!team.teamInfo.teleport.isInArea(event.to)) return + + } + + @SubscribeEvent + fun onInteract(interactEvent: PlayerInteractEvent) { + val block = interactEvent.clickedBlock ?: return + interactSubscribed[block.location]?.invoke(interactEvent) + } + + @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() + } + } +} \ 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 5013315..e1e3566 100644 --- a/src/main/kotlin/cc/maxmc/blastingcrisis/misc/Area.kt +++ b/src/main/kotlin/cc/maxmc/blastingcrisis/misc/Area.kt @@ -4,6 +4,8 @@ import org.bukkit.Location import org.bukkit.Material import org.bukkit.configuration.serialization.ConfigurationSerializable import org.bukkit.configuration.serialization.SerializableAs +import org.bukkit.util.Vector +import taboolib.common.util.random import kotlin.math.max import kotlin.math.min @@ -61,6 +63,27 @@ class Area(loc1: Location, loc2: Location) : ConfigurationSerializable { return forBlocksInArea().filter { it.block.type != Material.AIR } } + fun getAirPercentage(): Double { + val blocks = forBlocksInArea() + return blocks.filter { it.block.type == Material.AIR }.size.toDouble() / blocks.size.toDouble() + } + + /** + * generate a random Location that player can stand + * + * @return a random Location that player can stand + */ + tailrec fun randomLocation(): Location { + val x = random(locMin.blockX, locTop.blockX) + val z = random(locMin.blockZ, locTop.blockZ) + for (y in locMin.blockY..locTop.blockY) { + val loc = Vector(x, y, z).toLocation(locMin.world) + val add = loc.clone().add(0.0, 1.0, 0.0) + if (loc.block.type == Material.AIR && add.block.type == Material.AIR) return loc + } + return randomLocation() + } + override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false diff --git a/src/main/kotlin/cc/maxmc/blastingcrisis/misc/DebugMessage.kt b/src/main/kotlin/cc/maxmc/blastingcrisis/misc/LogMessages.kt similarity index 71% rename from src/main/kotlin/cc/maxmc/blastingcrisis/misc/DebugMessage.kt rename to src/main/kotlin/cc/maxmc/blastingcrisis/misc/LogMessages.kt index 63e4fa1..4dd4586 100644 --- a/src/main/kotlin/cc/maxmc/blastingcrisis/misc/DebugMessage.kt +++ b/src/main/kotlin/cc/maxmc/blastingcrisis/misc/LogMessages.kt @@ -4,4 +4,8 @@ import taboolib.common.platform.function.console fun debug(message: String) { console().sendMessage("§1DEBUG| §7$message") +} + +fun info(message: String) { + console().sendMessage(message) } \ No newline at end of file diff --git a/src/main/kotlin/cc/maxmc/blastingcrisis/packet/BEntityVillager.kt b/src/main/kotlin/cc/maxmc/blastingcrisis/packet/BEntityVillager.kt index ba1f237..d0165dd 100644 --- a/src/main/kotlin/cc/maxmc/blastingcrisis/packet/BEntityVillager.kt +++ b/src/main/kotlin/cc/maxmc/blastingcrisis/packet/BEntityVillager.kt @@ -1,12 +1,12 @@ package cc.maxmc.blastingcrisis.packet +import cc.maxmc.blastingcrisis.misc.PacketEntityManager +import cc.maxmc.blastingcrisis.misc.debug import net.minecraft.server.v1_8_R3.DataWatcher -import net.minecraft.server.v1_8_R3.PacketPlayOutEntityStatus import org.bukkit.Location import org.bukkit.entity.Player -import taboolib.library.reflex.Reflex.Companion.setProperty -class BEntityVillager(loc: Location) : BEntity(loc, 120) { +class BEntityVillager private constructor(loc: Location) : BEntity(loc, 120) { var name: (Player) -> String get() = nameTag.name set(name) { @@ -46,4 +46,17 @@ class BEntityVillager(loc: Location) : BEntity(loc, 120) { */ a(16, 0) // Villager Type } + + companion object { + fun create(loc: Location): BEntityVillager { + val entity = BEntityVillager(loc) + PacketEntityManager.register(entity.entityID, entity) + entity.handleInteract { + debug("Interacting with entity: ${entity.entityID}") + debug("type: ${it.type}") + it.vector?.let { vec -> debug("vector: $vec") } + } + return entity + } + } } \ No newline at end of file diff --git a/src/main/resources/lang/zh_CN.yml b/src/main/resources/lang/zh_CN.yml index 15a1203..5760214 100644 --- a/src/main/resources/lang/zh_CN.yml +++ b/src/main/resources/lang/zh_CN.yml @@ -15,6 +15,18 @@ scoreboard_counting_down: |- §a| §7游戏还有 §a{2} §7秒开始. §6Play.MaxMC.cc +scoreboard_counting_start: |- + §6Blasting§7Crisis + + §a| §7{0}: §a{1} + + {2} + + §a| §7我方村民剩余血量: {3} + §c| §7击杀数: §c{4} + + §6Play.MaxMC.cc +scoreboard_team_info: "§a| §7{0}: {1}" ## end part scoreboard @@ -47,6 +59,10 @@ game_countdown_reset: - "§c| §7由于人数不足, 无法开始游戏." game_join: "§a| §7玩家 §a{0} §7加入了游戏." game_leave: "§e| §7玩家 §e{0} §7离开了游戏." +game_end: |- + §e| + §e| 游戏结束 + §e| ## end part game ## part team diff --git a/src/main/resources/settings.yml b/src/main/resources/settings.yml index 225a95b..2924f6b 100644 --- a/src/main/resources/settings.yml +++ b/src/main/resources/settings.yml @@ -1,4 +1,8 @@ # Time before game start # Unit: second -time-to-start: 15 \ No newline at end of file +time-to-start: 15 + +game: + villager_max_health: 150 + damage_per_hurt: 10 \ No newline at end of file