蚯嫁嚎坏事做尽!

This commit is contained in:
tony_all 2022-11-01 01:37:04 +08:00
parent 3145fc1586
commit 4f37b3e2b9
14 changed files with 199 additions and 68 deletions

View File

@ -1,6 +1,7 @@
package cc.maxmc.blastingcrisis package cc.maxmc.blastingcrisis
import cc.maxmc.blastingcrisis.command.DebugCommand import cc.maxmc.blastingcrisis.command.DebugCommand
import cc.maxmc.blastingcrisis.misc.info
import cc.maxmc.blastingcrisis.misc.pluginScope import cc.maxmc.blastingcrisis.misc.pluginScope
import kotlinx.coroutines.cancel import kotlinx.coroutines.cancel
import taboolib.common.env.RuntimeDependency import taboolib.common.env.RuntimeDependency
@ -11,7 +12,9 @@ import taboolib.common.platform.Plugin
) )
object BlastingCrisis : Plugin() { object BlastingCrisis : Plugin() {
override fun onEnable() { override fun onEnable() {
info("§a| §7Loading BlastingCrisis")
DebugCommand.debug("debugcmd") DebugCommand.debug("debugcmd")
info("§a| §7Loading BlastingCrisis")
} }
override fun onDisable() { override fun onDisable() {

View File

@ -1,6 +1,5 @@
package cc.maxmc.blastingcrisis.command package cc.maxmc.blastingcrisis.command
import cc.maxmc.blastingcrisis.factory.BEntityFactory
import cc.maxmc.blastingcrisis.game.Game import cc.maxmc.blastingcrisis.game.Game
import cc.maxmc.blastingcrisis.game.GameOreGenerator import cc.maxmc.blastingcrisis.game.GameOreGenerator
import cc.maxmc.blastingcrisis.game.GameState import cc.maxmc.blastingcrisis.game.GameState
@ -11,6 +10,7 @@ import cc.maxmc.blastingcrisis.packet.BEntityVillager
import kotlinx.coroutines.cancel import kotlinx.coroutines.cancel
import org.bukkit.Bukkit import org.bukkit.Bukkit
import org.bukkit.ChatColor import org.bukkit.ChatColor
import org.bukkit.Location
import org.bukkit.entity.Player import org.bukkit.entity.Player
import taboolib.common.platform.ProxyPlayer import taboolib.common.platform.ProxyPlayer
import taboolib.common.platform.command.command import taboolib.common.platform.command.command
@ -27,28 +27,41 @@ object DebugCommand {
fun debug(cmd: String) = command(cmd) { fun debug(cmd: String) = command(cmd) {
literal("game") { literal("game") {
execute<Player> { sender, _, _ -> execute<Player> { sender, _, _ ->
fun location(x: Int, y: Int, z: Int) = Location(sender.world, x.toDouble(), y.toDouble(), z.toDouble())
Bukkit.broadcastMessage(sender.name) Bukkit.broadcastMessage(sender.name)
val homeArea = Area(sender.location, sender.location.add(10.0, 10.0, 10.0)) val teamRed = MapTeam(
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)) ChatColor.RED,
val area3 = Area(sender.location, sender.location.add(5.0, 5.0, 5.0)) location(0, 72, -44),
val team = MapTeam( location(0, 72, -44),
"testTeam1", location(-8, 73, -47),
ChatColor.AQUA, Area(location(14, 72, -48), location(-13, 78, -34)),
sender.location, Area(location(-13, 78, -33), location(13, 72, -33)),
sender.location, Area(location(-13, 78, -32), location(13, 71, -1)),
sender.eyeLocation, Area(location(7, 72, -45), location(9, 74, -48)),
homeArea, listOf(
area1, Area(location(15, 72, -1), location(19, 78, -48)),
area2, Area(location(19, 78, -48), location(-15, 72, -1))
area2, ),
listOf(area3), )
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( val map = GameMap(
"test", "test", Area(location(20, 70, -49), location(-20, 79, 49)), listOf(
homeArea, teamRed, teamGreen
listOf(
team
), 4 ), 4
) )
game = Game(map) game = Game(map)
@ -104,7 +117,7 @@ object DebugCommand {
literal("spawnEntity") { literal("spawnEntity") {
execute<Player> { sender, _, _ -> execute<Player> { sender, _, _ ->
val loc = sender.location val loc = sender.location
villager = BEntityFactory.createVillager(loc) villager = BEntityVillager.create(loc)
villager.addViewer(sender) villager.addViewer(sender)
} }
} }

View File

@ -10,4 +10,11 @@ object GlobalSettings {
val timeToStart val timeToStart
get() = settings.getInt("time-to-start") 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")
}
} }

View File

@ -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
}
}

View File

@ -15,9 +15,7 @@ class Game(
var state: GameState = GameState.WAITING var state: GameState = GameState.WAITING
private fun autoJoinTeam() { private fun autoJoinTeam() {
players.filter { it.team == null } players.filter { it.team == null }.shuffled().forEach {
.shuffled()
.forEach {
teams.minBy { team -> team.players.size }.join(it) teams.minBy { team -> team.players.size }.join(it)
} }
} }
@ -46,8 +44,10 @@ class Game(
fun start() { fun start() {
debug("game ${map.name} started.") debug("game ${map.name} started.")
timer.startTimer() timer.startTimer()
autoJoinTeam()
teams.forEach {
it.start()
}
} }
private fun checkStart() { 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) { fun broadcast(action: (Player) -> Unit) {

View File

@ -27,7 +27,11 @@ class GameOreGenerator(config: Configuration) {
fun enable(area: Area): Job { fun enable(area: Area): Job {
return pluginScope.launch { return pluginScope.launch {
while (true) { while (true) {
val airPercent = area.getAirPercentage()
debug("remain air: $airPercent.")
if (airPercent > 0.5) {
generate(area) generate(area)
}
delay(rate * 50L) delay(rate * 50L)
} }
} }

View File

@ -1,16 +1,25 @@
package cc.maxmc.blastingcrisis.game package cc.maxmc.blastingcrisis.game
import cc.maxmc.blastingcrisis.listener.GameListener
import cc.maxmc.blastingcrisis.map.MapTeam import cc.maxmc.blastingcrisis.map.MapTeam
import org.bukkit.entity.Player import org.bukkit.entity.Player
import taboolib.platform.util.sendLang import taboolib.platform.util.sendLang
class GameTeam(val game: Game, val teamInfo: MapTeam) { class GameTeam(val game: Game, val teamInfo: MapTeam) {
val players = ArrayList<Player>()
val villager = TeamVillager(this) val villager = TeamVillager(this)
val players = ArrayList<Player>()
var teamSurvive = true var teamSurvive = true
private set private set
fun start() {
players.forEach { it.teleport(teamInfo.spawn) }
villager.spawn()
GameListener.interactSubscribed[teamInfo.upgrade] = {
}
}
fun join(player: Player) { fun join(player: Player) {
players += player players += player
if (game.state == GameState.COUNTING_DOWN || game.state == GameState.WAITING) { 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() { fun checkTeamAlive() {
if (players.size != 0) return if (players.size == 0) {
teamSurvive = false
game.broadcast { game.broadcast {
it.sendLang("team_death", teamInfo.name) it.sendLang("team_death", teamInfo.name)
} }
teamSurvive = false
} }
if (villager.health <= 0) {
teamSurvive = false
game.broadcast {
it.sendLang("team_death", teamInfo.name)
}
}
}
} }

View File

@ -1,20 +1,22 @@
package cc.maxmc.blastingcrisis.game 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 org.bukkit.Bukkit
import taboolib.platform.BukkitPlugin import taboolib.platform.BukkitPlugin
import taboolib.platform.util.asLangText import taboolib.platform.util.asLangText
class TeamVillager(private val team: GameTeam) { class TeamVillager(private val team: GameTeam) {
private val packetVillager = BEntityFactory.createVillager(team.teamInfo.villager) private val packetVillager = BEntityVillager.create(team.teamInfo.villager)
private var health: Int = 150 var health: Int = GlobalSettings.GameSettings.villagerMaxHealth
private set
init { init {
packetVillager.name = { packetVillager.name = {
if (it.team == team) { if (it.team == team) {
it.asLangText("team_villager_name_internal") it.asLangText("team_villager_name_internal", health)
} else { } 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() { fun damage() {
health -= 10 health -= GlobalSettings.GameSettings.villagerDamagePerHealth
if (health <= 0) { if (health <= 0) {
packetVillager.dieAnimate() packetVillager.dieAnimate()
Bukkit.getScheduler().runTaskLater(BukkitPlugin.getInstance(), { Bukkit.getScheduler().runTaskLater(BukkitPlugin.getInstance(), {
packetVillager.destroy() packetVillager.destroy()
}, 20 * 3) }, 20 * 3)
} }
packetVillager.hurtAnimate() packetVillager.hurtAnimate()
team.checkTeamAlive()
team.game.checkEnd()
} }

View File

@ -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<Location, (PlayerInteractEvent) -> 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()
}
}
}

View File

@ -4,6 +4,8 @@ import org.bukkit.Location
import org.bukkit.Material import org.bukkit.Material
import org.bukkit.configuration.serialization.ConfigurationSerializable import org.bukkit.configuration.serialization.ConfigurationSerializable
import org.bukkit.configuration.serialization.SerializableAs import org.bukkit.configuration.serialization.SerializableAs
import org.bukkit.util.Vector
import taboolib.common.util.random
import kotlin.math.max import kotlin.math.max
import kotlin.math.min import kotlin.math.min
@ -61,6 +63,27 @@ class Area(loc1: Location, loc2: Location) : ConfigurationSerializable {
return forBlocksInArea().filter { it.block.type != Material.AIR } 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 { override fun equals(other: Any?): Boolean {
if (this === other) return true if (this === other) return true
if (javaClass != other?.javaClass) return false if (javaClass != other?.javaClass) return false

View File

@ -5,3 +5,7 @@ import taboolib.common.platform.function.console
fun debug(message: String) { fun debug(message: String) {
console().sendMessage("§1DEBUG| §7$message") console().sendMessage("§1DEBUG| §7$message")
} }
fun info(message: String) {
console().sendMessage(message)
}

View File

@ -1,12 +1,12 @@
package cc.maxmc.blastingcrisis.packet 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.DataWatcher
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityStatus
import org.bukkit.Location import org.bukkit.Location
import org.bukkit.entity.Player 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 var name: (Player) -> String
get() = nameTag.name get() = nameTag.name
set(name) { set(name) {
@ -46,4 +46,17 @@ class BEntityVillager(loc: Location) : BEntity(loc, 120) {
*/ */
a(16, 0) // Villager Type 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
}
}
} }

View File

@ -15,6 +15,18 @@ scoreboard_counting_down: |-
§a| §7游戏还有 §a{2} §7秒开始. §a| §7游戏还有 §a{2} §7秒开始.
§6Play.MaxMC.cc §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 ## end part scoreboard
@ -47,6 +59,10 @@ game_countdown_reset:
- "§c| §7由于人数不足, 无法开始游戏." - "§c| §7由于人数不足, 无法开始游戏."
game_join: "§a| §7玩家 §a{0} §7加入了游戏." game_join: "§a| §7玩家 §a{0} §7加入了游戏."
game_leave: "§e| §7玩家 §e{0} §7离开了游戏." game_leave: "§e| §7玩家 §e{0} §7离开了游戏."
game_end: |-
§e|
§e| 游戏结束
§e|
## end part game ## end part game
## part team ## part team

View File

@ -2,3 +2,7 @@
# Time before game start # Time before game start
# Unit: second # Unit: second
time-to-start: 15 time-to-start: 15
game:
villager_max_health: 150
damage_per_hurt: 10