蚯嫁嚎坏事做尽!

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
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() {

View File

@ -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<Player> { 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<Player> { sender, _, _ ->
val loc = sender.location
villager = BEntityFactory.createVillager(loc)
villager = BEntityVillager.create(loc)
villager.addViewer(sender)
}
}

View File

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

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,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) {

View File

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

View File

@ -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<Player>()
val villager = TeamVillager(this)
val players = ArrayList<Player>()
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)
}
}
}
}

View File

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

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.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

View File

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

View File

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

View File

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

View File

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