From 3145fc1586e206af982e66828e0cb04d7e6624e9 Mon Sep 17 00:00:00 2001 From: TONY_All Date: Fri, 28 Oct 2022 16:30:46 +0800 Subject: [PATCH] sync code --- build.gradle.kts | 2 +- .../cc/maxmc/blastingcrisis/BlastingCrisis.kt | 5 ++ .../blastingcrisis/command/DebugCommand.kt | 89 ++++++++++--------- .../configuration/GlobalSettings.kt | 13 +++ .../maxmc/blastingcrisis/debug/DListener.kt | 4 +- .../blastingcrisis/factory/BEntityFactory.kt | 19 ++++ .../cc/maxmc/blastingcrisis/game/Game.kt | 14 ++- .../blastingcrisis/game/GameOreGenerator.kt | 10 ++- .../cc/maxmc/blastingcrisis/game/GameState.kt | 2 + .../cc/maxmc/blastingcrisis/game/GameTeam.kt | 26 +++++- .../cc/maxmc/blastingcrisis/game/GameTimer.kt | 11 ++- .../maxmc/blastingcrisis/game/TeamVillager.kt | 38 ++++++++ .../listener/PacketEntityListener.kt | 30 +++++++ .../cc/maxmc/blastingcrisis/map/GameMap.kt | 4 +- .../cc/maxmc/blastingcrisis/map/MapTeam.kt | 5 +- .../cc/maxmc/blastingcrisis/misc/Area.kt | 4 +- .../maxmc/blastingcrisis/misc/Coroutines.kt | 2 +- .../misc/PacketEntityManager.kt | 14 +++ .../cc/maxmc/blastingcrisis/packet/BEntity.kt | 34 +++++-- .../blastingcrisis/packet/BEntityNameTag.kt | 7 +- .../blastingcrisis/packet/BEntityVillager.kt | 2 +- .../packet/ExternalDataWatcher.kt | 3 +- src/main/resources/lang/zh_CN.yml | 16 +++- src/main/resources/settings.yml | 4 + 24 files changed, 278 insertions(+), 80 deletions(-) create mode 100644 src/main/kotlin/cc/maxmc/blastingcrisis/configuration/GlobalSettings.kt create mode 100644 src/main/kotlin/cc/maxmc/blastingcrisis/factory/BEntityFactory.kt create mode 100644 src/main/kotlin/cc/maxmc/blastingcrisis/game/TeamVillager.kt create mode 100644 src/main/kotlin/cc/maxmc/blastingcrisis/listener/PacketEntityListener.kt create mode 100644 src/main/kotlin/cc/maxmc/blastingcrisis/misc/PacketEntityManager.kt create mode 100644 src/main/resources/settings.yml diff --git a/build.gradle.kts b/build.gradle.kts index 1e9d46d..94be40d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -22,7 +22,7 @@ dependencies { implementation(kotlin("stdlib")) implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4") implementation("ink.ptms.core:v10800:10800") - implementation("ink.ptms.core:v11200:11200") +// implementation("ink.ptms.core:v11200:11200") } taboolib { diff --git a/src/main/kotlin/cc/maxmc/blastingcrisis/BlastingCrisis.kt b/src/main/kotlin/cc/maxmc/blastingcrisis/BlastingCrisis.kt index 7844f4c..b52d1bb 100644 --- a/src/main/kotlin/cc/maxmc/blastingcrisis/BlastingCrisis.kt +++ b/src/main/kotlin/cc/maxmc/blastingcrisis/BlastingCrisis.kt @@ -1,6 +1,8 @@ package cc.maxmc.blastingcrisis import cc.maxmc.blastingcrisis.command.DebugCommand +import cc.maxmc.blastingcrisis.misc.pluginScope +import kotlinx.coroutines.cancel import taboolib.common.env.RuntimeDependency import taboolib.common.platform.Plugin @@ -12,4 +14,7 @@ object BlastingCrisis: Plugin() { DebugCommand.debug("debugcmd") } + override fun onDisable() { + pluginScope.cancel() + } } \ No newline at end of file diff --git a/src/main/kotlin/cc/maxmc/blastingcrisis/command/DebugCommand.kt b/src/main/kotlin/cc/maxmc/blastingcrisis/command/DebugCommand.kt index 6db1c7a..14705ab 100644 --- a/src/main/kotlin/cc/maxmc/blastingcrisis/command/DebugCommand.kt +++ b/src/main/kotlin/cc/maxmc/blastingcrisis/command/DebugCommand.kt @@ -1,5 +1,6 @@ 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 @@ -35,25 +36,33 @@ object DebugCommand { "testTeam1", ChatColor.AQUA, sender.location, + sender.location, + sender.eyeLocation, homeArea, area1, area2, - listOf(area3), area2, - sender.eyeLocation + listOf(area3), ) val map = GameMap( - "test", listOf( + "test", + homeArea, + listOf( team ), 4 ) game = Game(map) - game.join(sender) + } + + literal("join") { + execute { sender, _, _ -> + game.join(sender) + } } literal("state") { dynamic { - execute { sender, ctx, argument -> + execute { sender, _, argument -> if (!GameState.values().map { it.name } .contains(argument.uppercase())) return@execute sender.sendMessage("NO STATE") val state = GameState.valueOf(argument.uppercase()) @@ -67,14 +76,14 @@ object DebugCommand { } literal("timer") { - execute { sender, ctx, argument -> + execute { _, _, _ -> game.timer.beginCountdown() } } } literal("scoreboard") { - execute { sender, context, argument -> + execute { sender, _, _ -> game.scoreboard.sendScoreboardPlayer(sender) } } @@ -95,42 +104,42 @@ object DebugCommand { literal("spawnEntity") { execute { sender, _, _ -> val loc = sender.location - villager = BEntityVillager(loc) + villager = BEntityFactory.createVillager(loc) villager.addViewer(sender) } } -// literal("rename") { -// dynamic { -// execute { _, _, arg -> -// villager.name = arg -// } -// } -// } -// -// literal("destroy") { -// execute { sender, _, _ -> -// villager.removeViewer(sender) -// } -// } -// -// literal("hurt") { -// execute { _, _, _ -> -// villager.hurtAnimate() -// } -// } -// -// literal("die") { -// execute { _, _, _ -> -// villager.dieAnimate() -// } -// } -// -// literal("update") { -// execute { _, _, _ -> -// villager.update() -// } -// } + literal("rename") { + dynamic { + execute { _, _, arg -> + villager.name = { it.name + ":" + arg } + } + } + } + + literal("destroy") { + execute { sender, _, _ -> + villager.removeViewer(sender) + } + } + + literal("hurt") { + execute { _, _, _ -> + villager.hurtAnimate() + } + } + + literal("die") { + execute { _, _, _ -> + villager.dieAnimate() + } + } + + literal("update") { + execute { _, _, _ -> + villager.update() + } + } literal("genOre") { execute { sender, _, _ -> @@ -142,7 +151,7 @@ object DebugCommand { val job = gen.enable(area) Bukkit.getScheduler().runTaskLater(BukkitPlugin.getInstance(), { job.cancel("Stop by hand") - } ,60 * 20) + }, 60 * 20) } } } diff --git a/src/main/kotlin/cc/maxmc/blastingcrisis/configuration/GlobalSettings.kt b/src/main/kotlin/cc/maxmc/blastingcrisis/configuration/GlobalSettings.kt new file mode 100644 index 0000000..8f5473b --- /dev/null +++ b/src/main/kotlin/cc/maxmc/blastingcrisis/configuration/GlobalSettings.kt @@ -0,0 +1,13 @@ +package cc.maxmc.blastingcrisis.configuration + +import taboolib.module.configuration.Config +import taboolib.module.configuration.Configuration + +object GlobalSettings { + @Config("settings.yml") + lateinit var settings: Configuration + + val timeToStart + get() = settings.getInt("time-to-start") + +} \ No newline at end of file diff --git a/src/main/kotlin/cc/maxmc/blastingcrisis/debug/DListener.kt b/src/main/kotlin/cc/maxmc/blastingcrisis/debug/DListener.kt index 5093c76..c33987f 100644 --- a/src/main/kotlin/cc/maxmc/blastingcrisis/debug/DListener.kt +++ b/src/main/kotlin/cc/maxmc/blastingcrisis/debug/DListener.kt @@ -3,10 +3,8 @@ package cc.maxmc.blastingcrisis.debug import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntityLiving import org.bukkit.Bukkit import taboolib.common.platform.event.SubscribeEvent -import taboolib.library.reflex.Reflex.Companion.getProperty import taboolib.module.nms.PacketSendEvent import taboolib.platform.BukkitPlugin -import taboolib.platform.util.broadcast object DListener { @SubscribeEvent @@ -16,7 +14,7 @@ object DListener { // val source = it.packet.source if (!it.packet.name.lowercase().contains("entity")) return@runTask // println(it.packet.name) - if( it.packet.source !is PacketPlayOutSpawnEntityLiving ) { + if (it.packet.source !is PacketPlayOutSpawnEntityLiving) { return@runTask } // it.packet.source.getProperty("a")!!.broadcast() diff --git a/src/main/kotlin/cc/maxmc/blastingcrisis/factory/BEntityFactory.kt b/src/main/kotlin/cc/maxmc/blastingcrisis/factory/BEntityFactory.kt new file mode 100644 index 0000000..9c56665 --- /dev/null +++ b/src/main/kotlin/cc/maxmc/blastingcrisis/factory/BEntityFactory.kt @@ -0,0 +1,19 @@ +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 8ea8e27..26a05b0 100644 --- a/src/main/kotlin/cc/maxmc/blastingcrisis/game/Game.kt +++ b/src/main/kotlin/cc/maxmc/blastingcrisis/game/Game.kt @@ -33,21 +33,29 @@ class Game( fun leave(player: Player) { if (state == GameState.WAITING || state == GameState.COUNTING_DOWN) { players.remove(player) + player.team?.removePlayer(player) + broadcast { it.sendLang("game_leave", player.name) } checkStart() } val team = player.team ?: throw IllegalStateException("Player ${player.name} has no team, which shouldn't happen.") - team.checkTeamAlive() - team.players.remove(player) + team.removePlayer(player) checkEnd() } fun start() { debug("game ${map.name} started.") + timer.startTimer() + } private fun checkStart() { + if (players.size < map.maxPlayer * 0.5 && state == GameState.COUNTING_DOWN) { + state = GameState.WAITING + timer.resetCountdown() + } + if (players.size > map.maxPlayer * 0.75) { state = GameState.COUNTING_DOWN timer.beginCountdown() @@ -55,7 +63,7 @@ class Game( } private fun checkEnd() { - + } 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 bab34b3..8589cd8 100644 --- a/src/main/kotlin/cc/maxmc/blastingcrisis/game/GameOreGenerator.kt +++ b/src/main/kotlin/cc/maxmc/blastingcrisis/game/GameOreGenerator.kt @@ -3,7 +3,7 @@ package cc.maxmc.blastingcrisis.game import cc.maxmc.blastingcrisis.misc.Area import cc.maxmc.blastingcrisis.misc.WeightRandom import cc.maxmc.blastingcrisis.misc.debug -import cc.maxmc.blastingcrisis.misc.pluginScore +import cc.maxmc.blastingcrisis.misc.pluginScope import kotlinx.coroutines.Job import kotlinx.coroutines.delay import kotlinx.coroutines.launch @@ -16,6 +16,7 @@ import taboolib.platform.BukkitPlugin class GameOreGenerator(config: Configuration) { private val rate: Int = config.getInt("rate") + private val maxTry: Int = config.getInt("try") private val ores: MutableMap = HashMap().also { config.getConfigurationSection("ores")!!.getKeys(false).forEach { key -> it += XMaterial.valueOf(key) to (config["ores.$key"]!! as Int) @@ -24,7 +25,7 @@ class GameOreGenerator(config: Configuration) { private val random = WeightRandom(ores.map { it.key to it.value }) fun enable(area: Area): Job { - return pluginScore.launch { + return pluginScope.launch { while (true) { generate(area) delay(rate * 50L) @@ -32,7 +33,8 @@ class GameOreGenerator(config: Configuration) { } } - private tailrec fun generate(area: Area) { + private tailrec fun generate(area: Area, times: Int = 0) { + if (times > maxTry) return val x = random(area.locMin.blockX, area.locTop.blockX) val y = random(area.locMin.blockY, area.locTop.blockY) val z = random(area.locMin.blockZ, area.locTop.blockZ) @@ -45,7 +47,7 @@ class GameOreGenerator(config: Configuration) { debug("generating ${block.type} at ($x, $y, $z)") } } else { - return generate(area) + return generate(area, times + 1) } } } \ No newline at end of file diff --git a/src/main/kotlin/cc/maxmc/blastingcrisis/game/GameState.kt b/src/main/kotlin/cc/maxmc/blastingcrisis/game/GameState.kt index 6967648..0527063 100644 --- a/src/main/kotlin/cc/maxmc/blastingcrisis/game/GameState.kt +++ b/src/main/kotlin/cc/maxmc/blastingcrisis/game/GameState.kt @@ -6,4 +6,6 @@ enum class GameState { START, WALL_FALL, FINISH; + + fun isStarted(): Boolean = this == START || this == WALL_FALL } \ 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 394d059..3f128a8 100644 --- a/src/main/kotlin/cc/maxmc/blastingcrisis/game/GameTeam.kt +++ b/src/main/kotlin/cc/maxmc/blastingcrisis/game/GameTeam.kt @@ -2,17 +2,35 @@ package cc.maxmc.blastingcrisis.game import cc.maxmc.blastingcrisis.map.MapTeam import org.bukkit.entity.Player +import taboolib.platform.util.sendLang -class GameTeam(val game: Game, val team: MapTeam) { +class GameTeam(val game: Game, val teamInfo: MapTeam) { val players = ArrayList() + val villager = TeamVillager(this) + + var teamSurvive = true + private set fun join(player: Player) { players += player - - + if (game.state == GameState.COUNTING_DOWN || game.state == GameState.WAITING) { + player.sendLang("team_join", teamInfo.name) + } } - fun checkTeamAlive() { + fun removePlayer(player: Player) { + players -= player + if (game.state.isStarted()) { + checkTeamAlive() + } + } + + private fun checkTeamAlive() { + if (players.size != 0) return + game.broadcast { + it.sendLang("team_death", teamInfo.name) + } + teamSurvive = false } } \ No newline at end of file diff --git a/src/main/kotlin/cc/maxmc/blastingcrisis/game/GameTimer.kt b/src/main/kotlin/cc/maxmc/blastingcrisis/game/GameTimer.kt index f1600b6..2b6019d 100644 --- a/src/main/kotlin/cc/maxmc/blastingcrisis/game/GameTimer.kt +++ b/src/main/kotlin/cc/maxmc/blastingcrisis/game/GameTimer.kt @@ -1,22 +1,21 @@ package cc.maxmc.blastingcrisis.game -import cc.maxmc.blastingcrisis.misc.pluginScore +import cc.maxmc.blastingcrisis.configuration.GlobalSettings +import cc.maxmc.blastingcrisis.misc.pluginScope import kotlinx.coroutines.Job import kotlinx.coroutines.delay import kotlinx.coroutines.isActive import kotlinx.coroutines.launch import taboolib.common.platform.function.adaptCommandSender import taboolib.module.lang.getLocaleFile -import taboolib.platform.util.asLangTextOrNull import taboolib.platform.util.sendLang class GameTimer(private val game: Game) { - val timeToStart = 15 lateinit var countdownJob: Job - var current = timeToStart + var current = GlobalSettings.timeToStart fun beginCountdown() { - countdownJob = pluginScore.launch { + countdownJob = pluginScope.launch { while (current > 0) { if (!isActive) { return@launch @@ -43,7 +42,7 @@ class GameTimer(private val game: Game) { game.broadcast { it.sendLang("time_reset") } - current = timeToStart + current = GlobalSettings.timeToStart } fun startTimer() { diff --git a/src/main/kotlin/cc/maxmc/blastingcrisis/game/TeamVillager.kt b/src/main/kotlin/cc/maxmc/blastingcrisis/game/TeamVillager.kt new file mode 100644 index 0000000..a549b9e --- /dev/null +++ b/src/main/kotlin/cc/maxmc/blastingcrisis/game/TeamVillager.kt @@ -0,0 +1,38 @@ +package cc.maxmc.blastingcrisis.game + +import cc.maxmc.blastingcrisis.factory.BEntityFactory +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 + + init { + packetVillager.name = { + if (it.team == team) { + it.asLangText("team_villager_name_internal") + } else { + it.asLangText("team_villager_name_outer") + } + } + } + + fun spawn() { + team.game.broadcast(packetVillager::addViewer) + } + + fun damage() { + health -= 10 + if (health <= 0) { + packetVillager.dieAnimate() + Bukkit.getScheduler().runTaskLater(BukkitPlugin.getInstance(), { + packetVillager.destroy() + }, 20 * 3) + } + packetVillager.hurtAnimate() + } + + +} \ No newline at end of file diff --git a/src/main/kotlin/cc/maxmc/blastingcrisis/listener/PacketEntityListener.kt b/src/main/kotlin/cc/maxmc/blastingcrisis/listener/PacketEntityListener.kt new file mode 100644 index 0000000..45f05fe --- /dev/null +++ b/src/main/kotlin/cc/maxmc/blastingcrisis/listener/PacketEntityListener.kt @@ -0,0 +1,30 @@ +package cc.maxmc.blastingcrisis.listener + +import cc.maxmc.blastingcrisis.misc.PacketEntityManager +import net.minecraft.server.v1_8_R3.PacketPlayInUseEntity +import org.bukkit.util.Vector +import taboolib.common.platform.event.SubscribeEvent +import taboolib.library.reflex.Reflex.Companion.getProperty +import taboolib.module.nms.PacketReceiveEvent + +object PacketEntityListener { + @SubscribeEvent + fun onClick(e: PacketReceiveEvent) { + if (e.packet.name != "PacketPlayInUseEntity") return + val packet = e.packet.source as PacketPlayInUseEntity + val id = packet.getProperty("a")!! + val bEntity = PacketEntityManager.getEntity(id) ?: return + val direction = packet.b() + bEntity.onInteract(BEntityInteract(map(packet.a()), direction?.let { Vector(it.a, it.b, it.c) })) + e.isCancelled = true + } + + private fun map(action: PacketPlayInUseEntity.EnumEntityUseAction) = EntityUseAction.values()[action.ordinal] + + enum class EntityUseAction { + INTERACT, ATTACK, INTERACT_AT; + } + +} + +data class BEntityInteract(val type: PacketEntityListener.EntityUseAction, val vector: Vector?) diff --git a/src/main/kotlin/cc/maxmc/blastingcrisis/map/GameMap.kt b/src/main/kotlin/cc/maxmc/blastingcrisis/map/GameMap.kt index 6442fbd..2914376 100644 --- a/src/main/kotlin/cc/maxmc/blastingcrisis/map/GameMap.kt +++ b/src/main/kotlin/cc/maxmc/blastingcrisis/map/GameMap.kt @@ -1,6 +1,8 @@ package cc.maxmc.blastingcrisis.map -class GameMap(val name: String, val teams: List, val maxPlayersPerTeam: Int) { +import cc.maxmc.blastingcrisis.misc.Area + +class GameMap(val name: String, val area: 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/map/MapTeam.kt b/src/main/kotlin/cc/maxmc/blastingcrisis/map/MapTeam.kt index 7d65c54..12e19cb 100644 --- a/src/main/kotlin/cc/maxmc/blastingcrisis/map/MapTeam.kt +++ b/src/main/kotlin/cc/maxmc/blastingcrisis/map/MapTeam.kt @@ -8,10 +8,11 @@ data class MapTeam( val name: String, val color: ChatColor, val spawn: Location, + val villager: Location, + val upgrade: Location, val home: Area, val wall: Area, val mine: Area, - val sides: List, val teleport: Area, - val upgrade: Location, + val sides: List, ) \ 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 5d8ac9c..5013315 100644 --- a/src/main/kotlin/cc/maxmc/blastingcrisis/misc/Area.kt +++ b/src/main/kotlin/cc/maxmc/blastingcrisis/misc/Area.kt @@ -53,9 +53,9 @@ class Area(loc1: Location, loc2: Location) : ConfigurationSerializable { } /** - * get all locations of the non air blocks in this area + * get all locations of the non-air blocks in this area * - * @return all locations of the non air blocks in this area + * @return all locations of the non-air blocks in this area */ fun forBlocksWithoutAir(): List { return forBlocksInArea().filter { it.block.type != Material.AIR } diff --git a/src/main/kotlin/cc/maxmc/blastingcrisis/misc/Coroutines.kt b/src/main/kotlin/cc/maxmc/blastingcrisis/misc/Coroutines.kt index 0240d2b..5e3733b 100644 --- a/src/main/kotlin/cc/maxmc/blastingcrisis/misc/Coroutines.kt +++ b/src/main/kotlin/cc/maxmc/blastingcrisis/misc/Coroutines.kt @@ -4,6 +4,6 @@ import kotlinx.coroutines.CoroutineExceptionHandler import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.SupervisorJob -val pluginScore = CoroutineScope(SupervisorJob() + CoroutineExceptionHandler { job, exception -> +val pluginScope = CoroutineScope(SupervisorJob() + CoroutineExceptionHandler { job, exception -> IllegalStateException("在执行 Job $job 时出线异常", exception).printStackTrace() }) \ No newline at end of file diff --git a/src/main/kotlin/cc/maxmc/blastingcrisis/misc/PacketEntityManager.kt b/src/main/kotlin/cc/maxmc/blastingcrisis/misc/PacketEntityManager.kt new file mode 100644 index 0000000..9cfda4c --- /dev/null +++ b/src/main/kotlin/cc/maxmc/blastingcrisis/misc/PacketEntityManager.kt @@ -0,0 +1,14 @@ +package cc.maxmc.blastingcrisis.misc + +import cc.maxmc.blastingcrisis.packet.BEntity + +object PacketEntityManager { + private val entities = HashMap() + + fun register(id: Int, entity: BEntity) { + entities[id] = entity + } + + fun getEntity(id: Int): BEntity? = entities[id] + +} \ No newline at end of file diff --git a/src/main/kotlin/cc/maxmc/blastingcrisis/packet/BEntity.kt b/src/main/kotlin/cc/maxmc/blastingcrisis/packet/BEntity.kt index 12aeeb5..4a797a7 100644 --- a/src/main/kotlin/cc/maxmc/blastingcrisis/packet/BEntity.kt +++ b/src/main/kotlin/cc/maxmc/blastingcrisis/packet/BEntity.kt @@ -1,5 +1,6 @@ package cc.maxmc.blastingcrisis.packet +import cc.maxmc.blastingcrisis.listener.BEntityInteract import gnu.trove.TDecorators import gnu.trove.map.hash.TIntObjectHashMap import net.minecraft.server.v1_8_R3.* @@ -36,6 +37,7 @@ abstract class BEntity(var loc: Location, val entityType: Int) { } val entityID: Int = getEID() val viewers = ArrayList() + val interactHandlers = ArrayList<(BEntityInteract) -> Unit>() abstract fun DataWatcher.initEntity() @@ -69,14 +71,26 @@ abstract class BEntity(var loc: Location, val entityType: Int) { viewers.remove(viewer) } - fun update() { - val packet = PacketPlayOutEntityMetadata(entityID, dataWatcher, true) - viewers.forEach { it.sendPacket(packet) } + fun destroy() { + ArrayList(viewers).forEach { removeViewer(it) } } - fun updateData(toDo: DataWatcher.() -> Unit) { - toDo(dataWatcher) - update() + fun update() { + viewers.forEach { + updateFor(it) + } + } + + fun updateFor(player: Player) { + val packet = PacketPlayOutEntityMetadata(entityID, dataWatcher, true) + player.sendPacket(packet) + } + + fun updateData(toDo: DataWatcher.(Player) -> Unit) { + viewers.forEach { + toDo(dataWatcher, it) + updateFor(it) + } } fun hurtAnimate() { @@ -93,6 +107,14 @@ abstract class BEntity(var loc: Location, val entityType: Int) { }.let { viewers.forEach { p -> p.sendPacket(it) } } } + fun handleInteract(handler: (BEntityInteract) -> Unit) { + interactHandlers.add(handler) + } + + fun onInteract(interact: BEntityInteract) { + interactHandlers.forEach { it(interact) } + } + companion object { private val incrementEntityID = AtomicInteger(197827 + random(0, 549)) diff --git a/src/main/kotlin/cc/maxmc/blastingcrisis/packet/BEntityNameTag.kt b/src/main/kotlin/cc/maxmc/blastingcrisis/packet/BEntityNameTag.kt index 9f99b46..ac87fe4 100644 --- a/src/main/kotlin/cc/maxmc/blastingcrisis/packet/BEntityNameTag.kt +++ b/src/main/kotlin/cc/maxmc/blastingcrisis/packet/BEntityNameTag.kt @@ -10,10 +10,11 @@ import taboolib.module.nms.sendPacket import kotlin.experimental.or class BEntityNameTag(loc: Location) : BEntity(loc, 78) { - var name: String = "" + var name: (Player) -> String = { "" } set(name) { + field = name updateData { - getWatchableObject(2).a(name) + getWatchableObject(2).a(name(it)) } } @@ -40,7 +41,7 @@ class BEntityNameTag(loc: Location) : BEntity(loc, 78) { } player.sendPacket(packet) - update() + updateFor(player) } } \ 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 ee1a492..ba1f237 100644 --- a/src/main/kotlin/cc/maxmc/blastingcrisis/packet/BEntityVillager.kt +++ b/src/main/kotlin/cc/maxmc/blastingcrisis/packet/BEntityVillager.kt @@ -7,7 +7,7 @@ import org.bukkit.entity.Player import taboolib.library.reflex.Reflex.Companion.setProperty class BEntityVillager(loc: Location) : BEntity(loc, 120) { - var name: String + var name: (Player) -> String get() = nameTag.name set(name) { nameTag.name = name diff --git a/src/main/kotlin/cc/maxmc/blastingcrisis/packet/ExternalDataWatcher.kt b/src/main/kotlin/cc/maxmc/blastingcrisis/packet/ExternalDataWatcher.kt index 274ebbc..505df8b 100644 --- a/src/main/kotlin/cc/maxmc/blastingcrisis/packet/ExternalDataWatcher.kt +++ b/src/main/kotlin/cc/maxmc/blastingcrisis/packet/ExternalDataWatcher.kt @@ -4,5 +4,4 @@ import net.minecraft.server.v1_8_R3.DataWatcher import taboolib.library.reflex.Reflex.Companion.invokeMethod import java.lang.IllegalStateException -fun DataWatcher.getWatchableObject(id: Int): DataWatcher.WatchableObject = this.invokeMethod("j", id) ?: throw IllegalStateException("Object not exists.") - +fun DataWatcher.getWatchableObject(id: Int): DataWatcher.WatchableObject = this.invokeMethod("j", id) ?: throw IllegalStateException("Object not exists.") \ 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 1d64277..15a1203 100644 --- a/src/main/resources/lang/zh_CN.yml +++ b/src/main/resources/lang/zh_CN.yml @@ -1,3 +1,4 @@ +## part scoreboard scoreboard_waiting: |- §6Blasting§7Crisis @@ -14,6 +15,10 @@ scoreboard_counting_down: |- §a| §7游戏还有 §a{2} §7秒开始. §6Play.MaxMC.cc +## end part scoreboard + + +## part game game_countdown_15: - "§e| §7游戏还有 §e15 §7秒开始." game_countdown_10: @@ -40,4 +45,13 @@ game_countdown_reset: - type: title text: "§c人数不足" - "§c| §7由于人数不足, 无法开始游戏." -game_join: "§a| §7玩家 §a{0} §7加入了游戏" \ No newline at end of file +game_join: "§a| §7玩家 §a{0} §7加入了游戏." +game_leave: "§e| §7玩家 §e{0} §7离开了游戏." +## end part game + +## part team +team_join: "§a| §7你加入了 §a{0}" +team_death: "§e| §7队伍 §e{0} §7已淘汰." +team_villager_name_internal: "本队村民 {0}" +team_villager_name_outer: "{0}队村民 {1}" +## end part team \ No newline at end of file diff --git a/src/main/resources/settings.yml b/src/main/resources/settings.yml new file mode 100644 index 0000000..225a95b --- /dev/null +++ b/src/main/resources/settings.yml @@ -0,0 +1,4 @@ + +# Time before game start +# Unit: second +time-to-start: 15 \ No newline at end of file