Compare commits
21 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
ef8b5c973f | |
|
|
ff96cf59da | |
|
|
a063e8c6dd | |
|
|
be0bc6ffba | |
|
|
439cbccfe2 | |
|
|
31e52382b2 | |
|
|
9f5f657ea1 | |
|
|
45629b0d1b | |
|
|
b462eaa518 | |
|
|
29e9b188b1 | |
|
|
202eb473fa | |
|
|
2aa6761412 | |
|
|
1d753801dd | |
|
|
60295330de | |
|
|
f6e34d8efc | |
|
|
6f1a727691 | |
|
|
3d09b48da8 | |
|
|
9416250e13 | |
|
|
7f4ef2a447 | |
|
|
1053fde43f | |
|
|
f1ae6d7f4c |
|
|
@ -2,3 +2,4 @@
|
||||||
.idea
|
.idea
|
||||||
|
|
||||||
build/
|
build/
|
||||||
|
test_server
|
||||||
12
.space.kts
12
.space.kts
|
|
@ -1,10 +1,16 @@
|
||||||
job("Build and run tests") {
|
job("Build and run tests") {
|
||||||
// run 'gradlew build'
|
// run 'gradlew build'
|
||||||
gradlew("azul/zulu-openjdk:17", "build") {
|
gradlew("azul/zulu-openjdk:17", "build", "--no-daemon") {
|
||||||
|
// mountDir = "/root"
|
||||||
|
// cache {
|
||||||
|
// storeKey = "dot-gradle"
|
||||||
|
// localPath = "/root/.gradle"
|
||||||
|
// }
|
||||||
|
|
||||||
fileArtifacts {
|
fileArtifacts {
|
||||||
localPath = "build"
|
localPath = "build/libs/*"
|
||||||
archive = true
|
archive = true
|
||||||
remotePath = "{{ run:number }}/build.zip"
|
remotePath = "{{ run:number }}/build"
|
||||||
onStatus = OnStatus.SUCCESS
|
onStatus = OnStatus.SUCCESS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
import io.izzel.taboolib.gradle.*
|
||||||
|
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
kotlin("jvm") version "1.7.20"
|
kotlin("jvm") version "2.0.0"
|
||||||
id("io.izzel.taboolib") version "1.50"
|
id("io.izzel.taboolib") version "2.0.11"
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "cc.maxmc.blastingcrisis"
|
group = "cc.maxmc.blastingcrisis"
|
||||||
|
|
@ -11,12 +12,14 @@ version = "1.0-SNAPSHOT"
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
mavenLocal()
|
mavenLocal()
|
||||||
|
maven("https://repo.vip.maxmc.cc:30443/releases")
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(kotlin("stdlib"))
|
implementation(kotlin("stdlib"))
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4")
|
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0-RC")
|
||||||
implementation("ink.ptms.core:v10800:10800")
|
implementation("ink.ptms.core:v10800:10800")
|
||||||
|
// taboo("cc.maxmc.agones:AgonesKt:0.1.3")
|
||||||
// implementation("ink.ptms.core:v11200:11200")
|
// implementation("ink.ptms.core:v11200:11200")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -27,16 +30,22 @@ taboolib {
|
||||||
name("TONY_All")
|
name("TONY_All")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
install("common", "common-5")
|
env {
|
||||||
install("platform-bukkit")
|
// install("common", "common-5")
|
||||||
install("module-nms", "module-nms-util")
|
install(BUKKIT_ALL)
|
||||||
install("module-chat", "module-lang", "module-configuration")
|
install(NMS, NMS_UTIL)
|
||||||
|
install(CHAT, LANG, CONFIGURATION)
|
||||||
|
}
|
||||||
|
|
||||||
classifier = null
|
// classifier = null
|
||||||
options("skip-kotlin-relocate")
|
// options("skip-kotlin-relocate")
|
||||||
version = "6.0.10-12"
|
version {
|
||||||
|
taboolib = "6.1.2-beta2"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.withType<KotlinCompile> {
|
kotlin {
|
||||||
kotlinOptions.jvmTarget = "1.8"
|
compilerOptions {
|
||||||
|
jvmTarget = JvmTarget.JVM_1_8
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
|
|
@ -9,11 +9,13 @@ import cc.maxmc.blastingcrisis.misc.GameManager
|
||||||
import cc.maxmc.blastingcrisis.misc.info
|
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 kotlinx.coroutines.launch
|
||||||
import org.bukkit.Bukkit
|
import org.bukkit.Bukkit
|
||||||
import org.bukkit.ChatColor
|
import org.bukkit.ChatColor
|
||||||
import org.bukkit.Location
|
import org.bukkit.Location
|
||||||
import taboolib.common.env.RuntimeDependency
|
import taboolib.common.env.RuntimeDependency
|
||||||
import taboolib.common.platform.Plugin
|
import taboolib.common.platform.Plugin
|
||||||
|
import taboolib.common.platform.function.submit
|
||||||
|
|
||||||
@RuntimeDependency(
|
@RuntimeDependency(
|
||||||
"org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4",
|
"org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4",
|
||||||
|
|
@ -23,9 +25,21 @@ object BlastingCrisis : Plugin() {
|
||||||
info("§a| §7Loading BlastingCrisis")
|
info("§a| §7Loading BlastingCrisis")
|
||||||
DebugCommand.debug("debugcmd")
|
DebugCommand.debug("debugcmd")
|
||||||
createDefaultGame()
|
createDefaultGame()
|
||||||
|
submit(delay = 1) {
|
||||||
|
pluginScope.launch {
|
||||||
|
// AgonesSDK().use { sdk ->
|
||||||
|
// sdk.ready()
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDisable() {
|
override fun onDisable() {
|
||||||
|
pluginScope.launch {
|
||||||
|
// AgonesSDK().use { sdk ->
|
||||||
|
// sdk.shutdown()
|
||||||
|
// }
|
||||||
|
}
|
||||||
pluginScope.cancel()
|
pluginScope.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -34,18 +48,17 @@ object BlastingCrisis : Plugin() {
|
||||||
Location(Bukkit.getWorlds().first(), x.toDouble(), y.toDouble(), z.toDouble())
|
Location(Bukkit.getWorlds().first(), x.toDouble(), y.toDouble(), z.toDouble())
|
||||||
|
|
||||||
val teamRed = MapTeam(
|
val teamRed = MapTeam(
|
||||||
"红队",
|
name = "红队",
|
||||||
ChatColor.RED,
|
color = ChatColor.RED,
|
||||||
location(0, 72, -44),
|
spawn = location(0, 72, -44),
|
||||||
location(0, 72, -44),
|
villager = location(0, 72, -44),
|
||||||
location(-8, 73, -47),
|
upgrade = location(-8, 73, -47),
|
||||||
Area(location(14, 72, -48), location(-14, 78, -34)),
|
home = Area(location(14, 72, -48), location(-14, 78, -34)),
|
||||||
Area(location(-13, 78, -33), location(13, 72, -33)),
|
wall = Area(location(-13, 78, -33), location(13, 72, -33)),
|
||||||
Area(location(-13, 78, -32), location(13, 72, -1)),
|
mine = Area(location(-13, 78, -32), location(13, 72, -1)),
|
||||||
Area(location(7, 72, -45), location(9, 74, -48)),
|
teleport = Area(location(7, 72, -45), location(9, 74, -48)),
|
||||||
listOf(
|
sides = listOf(
|
||||||
Area(location(15, 72, -1), location(19, 78, -48)),
|
Area(location(15, 72, -1), location(19, 78, -48)), Area(location(-19, 78, -48), location(-15, 72, -1))
|
||||||
Area(location(-19, 78, -48), location(-15, 72, -1))
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
val teamGreen = MapTeam(
|
val teamGreen = MapTeam(
|
||||||
|
|
@ -57,10 +70,10 @@ object BlastingCrisis : Plugin() {
|
||||||
Area(location(-14, 72, 48), location(14, 78, 34)),
|
Area(location(-14, 72, 48), location(14, 78, 34)),
|
||||||
Area(location(13, 78, 33), location(-13, 72, 33)),
|
Area(location(13, 78, 33), location(-13, 72, 33)),
|
||||||
Area(location(13, 78, 32), location(-13, 72, 1)),
|
Area(location(13, 78, 32), location(-13, 72, 1)),
|
||||||
Area(location(-7, 72, 45), location(-9, 74, 48)),
|
Area(location(-7, 71, 48), location(-9, 71, 46)),
|
||||||
|
// Area(location(-7, 72, 45), location(-9, 74, 48)),
|
||||||
listOf(
|
listOf(
|
||||||
Area(location(-15, 72, 1), location(-19, 78, 48)),
|
Area(location(-15, 72, 1), location(-19, 78, 48)), Area(location(19, 78, 48), location(15, 72, 1))
|
||||||
Area(location(19, 78, 48), location(15, 72, 1))
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
val map = GameMap(
|
val map = GameMap(
|
||||||
|
|
@ -70,7 +83,12 @@ object BlastingCrisis : Plugin() {
|
||||||
listOf(
|
listOf(
|
||||||
teamRed, teamGreen
|
teamRed, teamGreen
|
||||||
),
|
),
|
||||||
1
|
1,
|
||||||
|
"default",
|
||||||
|
listOf(
|
||||||
|
location(-5, 72, -44), location(5, 72, -44), location(0, 72, -48),
|
||||||
|
location(-5, 72, 44), location(5, 72, 44), location(0, 72, 48)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
DebugCommand.game = Game(map)
|
DebugCommand.game = Game(map)
|
||||||
GameManager.currentGame = DebugCommand.game
|
GameManager.currentGame = DebugCommand.game
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,11 @@ package cc.maxmc.blastingcrisis.command
|
||||||
|
|
||||||
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.GamePlaceBreakRule.MatchResult
|
||||||
import cc.maxmc.blastingcrisis.game.GameState
|
import cc.maxmc.blastingcrisis.game.GameState
|
||||||
import cc.maxmc.blastingcrisis.misc.Area
|
import cc.maxmc.blastingcrisis.misc.Area
|
||||||
|
import cc.maxmc.blastingcrisis.misc.GameManager
|
||||||
|
import cc.maxmc.blastingcrisis.misc.UniArea
|
||||||
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
|
||||||
|
|
@ -16,11 +19,25 @@ import taboolib.module.configuration.Configuration
|
||||||
import taboolib.platform.BukkitPlugin
|
import taboolib.platform.BukkitPlugin
|
||||||
import taboolib.platform.util.sendActionBar
|
import taboolib.platform.util.sendActionBar
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import java.util.*
|
||||||
|
import cc.maxmc.blastingcrisis.misc.debug as debuglog
|
||||||
|
|
||||||
object DebugCommand {
|
object DebugCommand {
|
||||||
lateinit var game: Game
|
lateinit var game: Game
|
||||||
lateinit var villager: BEntityVillager
|
lateinit var villager: BEntityVillager
|
||||||
|
var autoRespawn = false
|
||||||
|
val builders = ArrayList<UUID>()
|
||||||
|
private val init by lazy {
|
||||||
|
// allow builders
|
||||||
|
debuglog("init builder rule")
|
||||||
|
GameManager.currentGame.placeBreakRule.addRuleFirst("builder") { (player, _, _, _) ->
|
||||||
|
// cc.maxmc.blastingcrisis.misc.debug("matching builder rule")
|
||||||
|
if (builders.contains(player.uniqueId)) MatchResult.ALLOW else MatchResult.DEFAULT
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun debug(cmd: String) = command(cmd) {
|
fun debug(cmd: String) = command(cmd) {
|
||||||
|
|
||||||
literal("game") {
|
literal("game") {
|
||||||
literal("join") {
|
literal("join") {
|
||||||
execute<Player> { sender, _, _ ->
|
execute<Player> { sender, _, _ ->
|
||||||
|
|
@ -77,6 +94,20 @@ object DebugCommand {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
literal("respawn") {
|
||||||
|
execute<Player> { sender, _, _ ->
|
||||||
|
villager.removeViewer(sender)
|
||||||
|
villager.addViewer(sender)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
literal("autoRespawn") {
|
||||||
|
execute<Player> { sender, _, _ ->
|
||||||
|
autoRespawn = !autoRespawn
|
||||||
|
sender.sendMessage("Auto Respawn is now $autoRespawn.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
literal("rename") {
|
literal("rename") {
|
||||||
dynamic {
|
dynamic {
|
||||||
execute<Player> { _, _, arg ->
|
execute<Player> { _, _, arg ->
|
||||||
|
|
@ -116,11 +147,24 @@ object DebugCommand {
|
||||||
println("saved")
|
println("saved")
|
||||||
val config = Configuration.loadFromFile(File(getDataFolder(), "ore-generators/default.yml"))
|
val config = Configuration.loadFromFile(File(getDataFolder(), "ore-generators/default.yml"))
|
||||||
val gen = GameOreGenerator(config)
|
val gen = GameOreGenerator(config)
|
||||||
val job = gen.enable(area)
|
val job = gen.enable(UniArea(listOf(area)))
|
||||||
Bukkit.getScheduler().runTaskLater(BukkitPlugin.getInstance(), {
|
Bukkit.getScheduler().runTaskLater(BukkitPlugin.getInstance(), {
|
||||||
job.cancel("Stop by hand")
|
job.cancel("Stop by hand")
|
||||||
}, 60 * 20)
|
}, 60 * 20)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
literal("build_mode") {
|
||||||
|
execute<Player> { sender, _, _ ->
|
||||||
|
init
|
||||||
|
if (builders.contains(sender.uniqueId)) {
|
||||||
|
builders.remove(sender.uniqueId)
|
||||||
|
sender.sendMessage("U r no longer in build mode")
|
||||||
|
return@execute
|
||||||
|
}
|
||||||
|
sender.sendMessage("U r now in build mode")
|
||||||
|
builders.add(sender.uniqueId)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -8,7 +8,10 @@ object GlobalSettings {
|
||||||
lateinit var settings: Configuration
|
lateinit var settings: Configuration
|
||||||
|
|
||||||
val timeToStart
|
val timeToStart
|
||||||
get() = settings.getInt("time-to-start")
|
get() = settings.getInt("time_to_start")
|
||||||
|
|
||||||
|
val itemGenDelay
|
||||||
|
get() = settings.getLong("item_gen_delay")
|
||||||
|
|
||||||
object GameSettings {
|
object GameSettings {
|
||||||
val villagerMaxHealth
|
val villagerMaxHealth
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,17 @@
|
||||||
package cc.maxmc.blastingcrisis.debug
|
package cc.maxmc.blastingcrisis.debug
|
||||||
|
|
||||||
|
import cc.maxmc.blastingcrisis.command.DebugCommand
|
||||||
|
import cc.maxmc.blastingcrisis.command.DebugCommand.villager
|
||||||
|
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityDestroy
|
||||||
import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntityLiving
|
import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntityLiving
|
||||||
import org.bukkit.Bukkit
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.event.player.PlayerRespawnEvent
|
||||||
import taboolib.common.platform.event.SubscribeEvent
|
import taboolib.common.platform.event.SubscribeEvent
|
||||||
|
import taboolib.common.platform.function.submit
|
||||||
|
import taboolib.library.reflex.Reflex.Companion.getProperty
|
||||||
import taboolib.module.nms.PacketSendEvent
|
import taboolib.module.nms.PacketSendEvent
|
||||||
import taboolib.platform.BukkitPlugin
|
import taboolib.platform.BukkitPlugin
|
||||||
|
import taboolib.platform.util.broadcast
|
||||||
|
|
||||||
object DListener {
|
object DListener {
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
|
|
@ -12,13 +19,29 @@ object DListener {
|
||||||
Bukkit.getScheduler().runTask(BukkitPlugin.getInstance()) {
|
Bukkit.getScheduler().runTask(BukkitPlugin.getInstance()) {
|
||||||
if (it.player.name != "TONY_All") return@runTask
|
if (it.player.name != "TONY_All") return@runTask
|
||||||
// val source = it.packet.source
|
// val source = it.packet.source
|
||||||
if (!it.packet.name.lowercase().contains("entity")) return@runTask
|
// if (!it.packet.name.lowercase().contains("entity")) return@runTask
|
||||||
// println(it.packet.name)
|
val pname = listOf("PacketPlayOutSpawnEntityLiving", "PacketPlayOutEntityDestroy")
|
||||||
if (it.packet.source !is PacketPlayOutSpawnEntityLiving) {
|
if (pname.contains(it.packet.name)) println(it.packet.name)
|
||||||
return@runTask
|
|
||||||
|
if (it.packet.source is PacketPlayOutSpawnEntityLiving) {
|
||||||
|
it.packet.source.getProperty<Int>("a")!!.broadcast()
|
||||||
|
it.packet.source.getProperty<Int>("b")!!.broadcast()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (it.packet.source is PacketPlayOutEntityDestroy) {
|
||||||
|
it.packet.source.getProperty<IntArray>("a")!!.contentToString().broadcast()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
fun debugRespawn(respawnE: PlayerRespawnEvent) {
|
||||||
|
if (DebugCommand.autoRespawn) {
|
||||||
|
submit(delay = 1L) {
|
||||||
|
villager.removeViewer(respawnE.player)
|
||||||
|
"Respawning".broadcast()
|
||||||
|
villager.addViewer(respawnE.player)
|
||||||
}
|
}
|
||||||
// it.packet.source.getProperty<Int>("a")!!.broadcast()
|
|
||||||
// it.packet.source.getProperty<Int>("b")!!.broadcast()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,7 +1,11 @@
|
||||||
package cc.maxmc.blastingcrisis.game
|
package cc.maxmc.blastingcrisis.game
|
||||||
|
|
||||||
import cc.maxmc.blastingcrisis.map.GameMap
|
import cc.maxmc.blastingcrisis.map.GameMap
|
||||||
|
import cc.maxmc.blastingcrisis.misc.Area
|
||||||
|
import cc.maxmc.blastingcrisis.misc.BlockGenManager
|
||||||
|
import cc.maxmc.blastingcrisis.misc.UniArea
|
||||||
import cc.maxmc.blastingcrisis.misc.debug
|
import cc.maxmc.blastingcrisis.misc.debug
|
||||||
|
import kotlinx.coroutines.Job
|
||||||
import org.bukkit.Material
|
import org.bukkit.Material
|
||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
import taboolib.common.platform.function.submit
|
import taboolib.common.platform.function.submit
|
||||||
|
|
@ -16,7 +20,10 @@ class Game(
|
||||||
val timer: GameTimer = GameTimer(this)
|
val timer: GameTimer = GameTimer(this)
|
||||||
val players = ArrayList<Player>()
|
val players = ArrayList<Player>()
|
||||||
val placeBreakRule = GamePlaceBreakRule(this)
|
val placeBreakRule = GamePlaceBreakRule(this)
|
||||||
|
val generator = BlockGenManager.getGenerator(map.blockGen)!!
|
||||||
var state: GameState = GameState.WAITING
|
var state: GameState = GameState.WAITING
|
||||||
|
private lateinit var oreGenJob: Job
|
||||||
|
private lateinit var itemGenJob: List<Job>
|
||||||
|
|
||||||
private fun autoJoinTeam() {
|
private fun autoJoinTeam() {
|
||||||
players.filter { it.team == null }.shuffled().forEach {
|
players.filter { it.team == null }.shuffled().forEach {
|
||||||
|
|
@ -25,6 +32,10 @@ class Game(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun join(player: Player) {
|
fun join(player: Player) {
|
||||||
|
if (players.map { it.uniqueId }.contains(player.uniqueId)) {
|
||||||
|
player.sendLang("game_already_join")
|
||||||
|
return
|
||||||
|
}
|
||||||
players += player
|
players += player
|
||||||
broadcast {
|
broadcast {
|
||||||
it.sendLang("game_join", player.name)
|
it.sendLang("game_join", player.name)
|
||||||
|
|
@ -46,23 +57,31 @@ class Game(
|
||||||
checkEnd()
|
checkEnd()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun respawnPlayer(player: Player) {
|
||||||
|
submit(delay = 1L) {
|
||||||
|
teams.forEach { it.villager.respawn(player) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun start() {
|
fun start() {
|
||||||
debug("game ${map.name} started.")
|
debug("game ${map.name} started.")
|
||||||
placeBreakRule.defaultRule()
|
placeBreakRule.loadDefaultRule()
|
||||||
|
startOreGen()
|
||||||
|
startItemGen()
|
||||||
state = GameState.START
|
state = GameState.START
|
||||||
timer.startTimer()
|
timer.startTimer()
|
||||||
timer.submitEvent("wall_fall", Duration.ofMinutes(1)) {
|
timer.submitEvent("wall_fall", Duration.ofMinutes(1)) {
|
||||||
broadcast { it.sendLang("game_wall_fall") }
|
broadcast { it.sendLang("game_wall_fall") }
|
||||||
|
placeBreakRule.addRuleLast("allow_center_wall") { (_, _, loc, _) ->
|
||||||
|
if (map.wall.contains(loc)) GamePlaceBreakRule.MatchResult.ALLOW else GamePlaceBreakRule.MatchResult.DEFAULT
|
||||||
|
}
|
||||||
submit {
|
submit {
|
||||||
map.wall.forBlocksInArea().forEach {
|
map.wall.forBlocksInArea().forEach {
|
||||||
it.block.type = Material.AIR
|
it.block.type = Material.AIR
|
||||||
}
|
}
|
||||||
placeBreakRule.addRule("allow_center_wall") { _, _, loc ->
|
|
||||||
map.wall.contains(loc)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
autoJoinTeam()
|
autoJoinTeam()
|
||||||
teams.forEach {
|
teams.forEach {
|
||||||
it.start()
|
it.start()
|
||||||
|
|
@ -81,17 +100,34 @@ class Game(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun startOreGen() {
|
||||||
|
val mines = map.teams.fold(ArrayList<Area>()) { list, team ->
|
||||||
|
list += team.mine
|
||||||
|
list += team.sides
|
||||||
|
list
|
||||||
|
}
|
||||||
|
oreGenJob = generator.enable(UniArea(mines))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun startItemGen() {
|
||||||
|
val generator = GameItemGenerator(Material.LOG)
|
||||||
|
itemGenJob = map.itemGen.map {
|
||||||
|
generator.generate(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun checkEnd() {
|
fun checkEnd() {
|
||||||
if (teams.filter { it.teamSurvive }.size > 1) {
|
if (teams.filter { it.teamSurvive }.size > 1) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
broadcast { it.sendLang("game_end") }
|
broadcast {
|
||||||
|
it.sendLang("game_end")
|
||||||
|
}
|
||||||
//TODO restart game logic
|
//TODO restart game logic
|
||||||
}
|
}
|
||||||
|
|
||||||
fun broadcast(action: (Player) -> Unit) {
|
fun broadcast(action: (Player) -> Unit) {
|
||||||
players.forEach(action)
|
players.forEach(action)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
package cc.maxmc.blastingcrisis.game
|
||||||
|
|
||||||
|
import cc.maxmc.blastingcrisis.configuration.GlobalSettings
|
||||||
|
import cc.maxmc.blastingcrisis.misc.debug
|
||||||
|
import cc.maxmc.blastingcrisis.misc.pluginScope
|
||||||
|
import cc.maxmc.blastingcrisis.misc.toEntityLocation
|
||||||
|
import kotlinx.coroutines.Job
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.Location
|
||||||
|
import org.bukkit.Material
|
||||||
|
import org.bukkit.inventory.ItemStack
|
||||||
|
import org.bukkit.util.Vector
|
||||||
|
import taboolib.platform.BukkitPlugin
|
||||||
|
|
||||||
|
class GameItemGenerator(val type: Material) {
|
||||||
|
|
||||||
|
fun generate(location: Location): Job = pluginScope.launch {
|
||||||
|
while (true) {
|
||||||
|
Bukkit.getScheduler().runTask(BukkitPlugin.getInstance()) {
|
||||||
|
val item = location.world.dropItem(location.toEntityLocation(), ItemStack(type))
|
||||||
|
item.teleport(location.toEntityLocation())
|
||||||
|
item.velocity = Vector(0.0, 0.2, 0.0)
|
||||||
|
debug("Generate Item at ${location.toVector()}")
|
||||||
|
}
|
||||||
|
delay(GlobalSettings.itemGenDelay * 50)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,9 +1,6 @@
|
||||||
package cc.maxmc.blastingcrisis.game
|
package cc.maxmc.blastingcrisis.game
|
||||||
|
|
||||||
import cc.maxmc.blastingcrisis.misc.Area
|
import cc.maxmc.blastingcrisis.misc.*
|
||||||
import cc.maxmc.blastingcrisis.misc.WeightRandom
|
|
||||||
import cc.maxmc.blastingcrisis.misc.debug
|
|
||||||
import cc.maxmc.blastingcrisis.misc.pluginScope
|
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
@ -24,13 +21,14 @@ class GameOreGenerator(config: Configuration) {
|
||||||
}
|
}
|
||||||
private val random = WeightRandom(ores.map { it.key to it.value })
|
private val random = WeightRandom(ores.map { it.key to it.value })
|
||||||
|
|
||||||
fun enable(area: Area): Job {
|
fun enable(area: UniArea): Job {
|
||||||
return pluginScope.launch {
|
return pluginScope.launch {
|
||||||
while (true) {
|
while (true) {
|
||||||
val airPercent = area.getAirPercentage()
|
val targetArea = area.randomizer.random()
|
||||||
|
val airPercent = targetArea.getAirPercentage()
|
||||||
debug("remain air: $airPercent.")
|
debug("remain air: $airPercent.")
|
||||||
if (airPercent > 0.5) {
|
if (airPercent > 0.5) {
|
||||||
generate(area)
|
generate(targetArea)
|
||||||
}
|
}
|
||||||
delay(rate * 50L)
|
delay(rate * 50L)
|
||||||
}
|
}
|
||||||
|
|
@ -54,4 +52,5 @@ class GameOreGenerator(config: Configuration) {
|
||||||
return generate(area, times + 1)
|
return generate(area, times + 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,23 +1,43 @@
|
||||||
package cc.maxmc.blastingcrisis.game
|
package cc.maxmc.blastingcrisis.game
|
||||||
|
|
||||||
import cc.maxmc.blastingcrisis.game.GamePlaceBreakRule.ActionType.BREAK
|
import cc.maxmc.blastingcrisis.game.GamePlaceBreakRule.ActionType.BREAK
|
||||||
|
import cc.maxmc.blastingcrisis.game.GamePlaceBreakRule.ActionType.PLACE
|
||||||
|
import cc.maxmc.blastingcrisis.misc.EnhancedLinkedList
|
||||||
import cc.maxmc.blastingcrisis.misc.debug
|
import cc.maxmc.blastingcrisis.misc.debug
|
||||||
import org.bukkit.Location
|
import org.bukkit.Location
|
||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
|
import taboolib.library.xseries.XMaterial
|
||||||
|
|
||||||
|
typealias PlaceBreakRule = (GamePlaceBreakRule.GamePlaceBreakEvent) -> GamePlaceBreakRule.MatchResult
|
||||||
|
|
||||||
|
|
||||||
|
@Suppress("unused") // API
|
||||||
class GamePlaceBreakRule(val game: Game) {
|
class GamePlaceBreakRule(val game: Game) {
|
||||||
|
|
||||||
enum class ActionType {
|
enum class ActionType {
|
||||||
PLACE,
|
PLACE, BREAK
|
||||||
BREAK
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private val rules = HashMap<String, (Player, ActionType, Location) -> Boolean>()
|
enum class MatchResult {
|
||||||
fun matchRule(player: Player, actionType: ActionType, location: Location): Boolean {
|
DEFAULT, ALLOW, DENY
|
||||||
|
}
|
||||||
|
|
||||||
|
data class GamePlaceBreakEvent(
|
||||||
|
val player: Player,
|
||||||
|
val actionType: ActionType,
|
||||||
|
val loc: Location,
|
||||||
|
val type: XMaterial
|
||||||
|
)
|
||||||
|
|
||||||
|
private val rules = HashMap<String, PlaceBreakRule>()
|
||||||
|
private val rulesPriority = EnhancedLinkedList<String>()
|
||||||
|
fun matchRule(player: Player, actionType: ActionType, location: Location, type: XMaterial): Boolean {
|
||||||
// match rules
|
// match rules
|
||||||
rules.forEach { (name, func) ->
|
rules.forEach { (name, func) ->
|
||||||
if (func(player, actionType, location)) {
|
val result = func(GamePlaceBreakEvent(player, actionType, location, type))
|
||||||
|
if (result != MatchResult.DEFAULT) {
|
||||||
debug("Hit rule $name")
|
debug("Hit rule $name")
|
||||||
return true
|
return result == MatchResult.ALLOW
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -25,7 +45,7 @@ class GamePlaceBreakRule(val game: Game) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addRule(name: String, rule: (player: Player, type: ActionType, loc: Location) -> Boolean) {
|
private fun recordRule(name: String, rule: PlaceBreakRule) {
|
||||||
if (rules.containsKey(name)) {
|
if (rules.containsKey(name)) {
|
||||||
throw IllegalArgumentException("Rule $name already exists.")
|
throw IllegalArgumentException("Rule $name already exists.")
|
||||||
}
|
}
|
||||||
|
|
@ -33,27 +53,69 @@ class GamePlaceBreakRule(val game: Game) {
|
||||||
rules[name] = rule
|
rules[name] = rule
|
||||||
}
|
}
|
||||||
|
|
||||||
fun defaultRule() {
|
fun addRuleLast(
|
||||||
|
name: String, rule: PlaceBreakRule
|
||||||
|
) {
|
||||||
|
recordRule(name, rule)
|
||||||
|
rulesPriority.addLast(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addRuleFirst(
|
||||||
|
name: String, rule: PlaceBreakRule
|
||||||
|
) {
|
||||||
|
recordRule(name, rule)
|
||||||
|
rulesPriority.addFirst(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addRuleBefore(
|
||||||
|
base: String, name: String, rule: PlaceBreakRule
|
||||||
|
) {
|
||||||
|
recordRule(name, rule)
|
||||||
|
rulesPriority.addBefore(base, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun addRuleAfter(
|
||||||
|
base: String, name: String, rule: PlaceBreakRule
|
||||||
|
) {
|
||||||
|
recordRule(name, rule)
|
||||||
|
rulesPriority.addAfter(base, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun loadDefaultRule() {
|
||||||
// allow mine
|
// allow mine
|
||||||
addRule("allow_mine") { _, _, loc ->
|
addRuleLast("allow_mine") { (_, _, loc, _) ->
|
||||||
game.map.teams.flatMap {
|
val result = game.map.teams.flatMap {
|
||||||
it.sides + it.mine
|
it.sides + it.mine
|
||||||
}.map {
|
}.map {
|
||||||
it.containsBlock(loc)
|
it.containsBlock(loc)
|
||||||
}.reduce { a, b -> a || b }
|
}.reduce { a, b -> a || b }
|
||||||
|
if (result) MatchResult.ALLOW else MatchResult.DEFAULT
|
||||||
}
|
}
|
||||||
|
|
||||||
// allow enemy wall
|
// allow enemy wall
|
||||||
addRule("allow_wall_conditional") { player, type, loc ->
|
addRuleLast("allow_wall_conditional") { (player, actionType, loc, _) ->
|
||||||
val team = player.team ?: return@addRule false
|
val team = player.team ?: return@addRuleLast MatchResult.DENY
|
||||||
val isWall = game.teams
|
val isWall = game.teams.map {
|
||||||
.map {
|
it.teamInfo.wall.containsBlock(loc)
|
||||||
it.teamInfo.wall.containsBlock(loc).also { result -> debug("area ${it.teamInfo.wall} contains $loc is $result") }
|
.also { result -> debug("area ${it.teamInfo.wall} contains $loc is $result") }
|
||||||
}
|
}.reduce { a, b -> a || b }
|
||||||
.reduce { a, b -> a || b }
|
if (!isWall) return@addRuleLast MatchResult.DEFAULT
|
||||||
if (!isWall) return@addRule false
|
|
||||||
val isHome = team.teamInfo.wall.containsBlock(loc)
|
val isHome = team.teamInfo.wall.containsBlock(loc)
|
||||||
(type == BREAK) xor isHome
|
if ((actionType == BREAK) xor isHome) MatchResult.ALLOW else MatchResult.DENY
|
||||||
|
}
|
||||||
|
|
||||||
|
// allow tnt in enemy's home
|
||||||
|
addRuleFirst("allow_tnt_conditional") { (player, actionType, loc, type) ->
|
||||||
|
if (type != XMaterial.TNT) return@addRuleFirst MatchResult.DEFAULT
|
||||||
|
val team = player.team ?: return@addRuleFirst MatchResult.DENY
|
||||||
|
val isHome = game.teams.map {
|
||||||
|
it.teamInfo.home.containsBlock(loc)
|
||||||
|
.also { result -> debug("area ${it.teamInfo.home} contains $loc is $result") }
|
||||||
|
}.reduce { a, b -> a || b }
|
||||||
|
if (!isHome) return@addRuleFirst MatchResult.DENY
|
||||||
|
val isSelf = team.teamInfo.home.containsBlock(loc)
|
||||||
|
if ((actionType == PLACE) xor isSelf) MatchResult.ALLOW else MatchResult.DENY
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -29,9 +29,10 @@ class GameScoreboard(val game: Game) {
|
||||||
appendLine(player.asLangText("scoreboard_team_info", it.teamInfo.name, it.villager.health))
|
appendLine(player.asLangText("scoreboard_team_info", it.teamInfo.name, it.villager.health))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
val eventName = player.asLangText("event_${event.second}")
|
||||||
player.asLangText(
|
player.asLangText(
|
||||||
"scoreboard_start",
|
"scoreboard_start",
|
||||||
event.second,
|
eventName,
|
||||||
"${event.first.inWholeMinutes}:${event.first.inWholeSeconds}",
|
"${event.first.inWholeMinutes}:${event.first.inWholeSeconds}",
|
||||||
teamMessage,
|
teamMessage,
|
||||||
player.team?.villager?.health ?: throw IllegalStateException("player ${player.name} has no team."),
|
player.team?.villager?.health ?: throw IllegalStateException("player ${player.name} has no team."),
|
||||||
|
|
@ -43,7 +44,5 @@ class GameScoreboard(val game: Game) {
|
||||||
}
|
}
|
||||||
|
|
||||||
player.sendScoreboard(*scoreboardText.lines().toTypedArray())
|
player.sendScoreboard(*scoreboardText.lines().toTypedArray())
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -3,7 +3,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 cc.maxmc.blastingcrisis.misc.debug
|
||||||
import cc.maxmc.blastingcrisis.misc.toPlayerLocation
|
import cc.maxmc.blastingcrisis.misc.toEntityLocation
|
||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
import taboolib.platform.util.sendLang
|
import taboolib.platform.util.sendLang
|
||||||
|
|
||||||
|
|
@ -15,7 +15,7 @@ class GameTeam(val game: Game, val teamInfo: MapTeam) {
|
||||||
private set
|
private set
|
||||||
|
|
||||||
fun start() {
|
fun start() {
|
||||||
players.forEach { it.teleport(teamInfo.spawn.toPlayerLocation()) }
|
players.forEach { it.teleport(teamInfo.spawn.toEntityLocation()) }
|
||||||
villager.spawn()
|
villager.spawn()
|
||||||
GameListener.interactSubscribed[teamInfo.upgrade] = {
|
GameListener.interactSubscribed[teamInfo.upgrade] = {
|
||||||
debug("interact team ${teamInfo.name} upgrade.")
|
debug("interact team ${teamInfo.name} upgrade.")
|
||||||
|
|
@ -24,7 +24,7 @@ class GameTeam(val game: Game, val teamInfo: MapTeam) {
|
||||||
val player = it.player ?: throw IllegalStateException("Bukkit API LOL")
|
val player = it.player ?: throw IllegalStateException("Bukkit API LOL")
|
||||||
debug("teleporting $player to battle field")
|
debug("teleporting $player to battle field")
|
||||||
val team = player.team ?: throw IllegalStateException("Player ${player.name} should have a team")
|
val team = player.team ?: throw IllegalStateException("Player ${player.name} should have a team")
|
||||||
player.teleport(team.teamInfo.mine.randomLocation().toPlayerLocation())
|
player.teleport(team.teamInfo.mine.randomLocationRestrict().toEntityLocation())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,16 @@
|
||||||
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.toPlayerLocation
|
import cc.maxmc.blastingcrisis.misc.debug
|
||||||
|
import cc.maxmc.blastingcrisis.misc.toEntityLocation
|
||||||
import cc.maxmc.blastingcrisis.packet.BEntityVillager
|
import cc.maxmc.blastingcrisis.packet.BEntityVillager
|
||||||
import org.bukkit.Bukkit
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.entity.Player
|
||||||
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 = BEntityVillager.create(team.teamInfo.villager.toPlayerLocation())
|
private val packetVillager = BEntityVillager.create(team.teamInfo.villager.toEntityLocation())
|
||||||
var health: Int = GlobalSettings.GameSettings.villagerMaxHealth
|
var health: Int = GlobalSettings.GameSettings.villagerMaxHealth
|
||||||
private set
|
private set
|
||||||
|
|
||||||
|
|
@ -40,5 +42,10 @@ class TeamVillager(private val team: GameTeam) {
|
||||||
team.game.checkEnd()
|
team.game.checkEnd()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun respawn(player: Player) {
|
||||||
|
debug("respawning for ${player.name}")
|
||||||
|
packetVillager.respawnForPlayer(player)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,16 +1,28 @@
|
||||||
package cc.maxmc.blastingcrisis.listener
|
package cc.maxmc.blastingcrisis.listener
|
||||||
|
|
||||||
import cc.maxmc.blastingcrisis.game.GamePlaceBreakRule
|
import cc.maxmc.blastingcrisis.game.GamePlaceBreakRule
|
||||||
|
import cc.maxmc.blastingcrisis.game.team
|
||||||
import cc.maxmc.blastingcrisis.misc.Area
|
import cc.maxmc.blastingcrisis.misc.Area
|
||||||
import cc.maxmc.blastingcrisis.misc.GameManager
|
import cc.maxmc.blastingcrisis.misc.GameManager
|
||||||
import cc.maxmc.blastingcrisis.misc.debug
|
import cc.maxmc.blastingcrisis.misc.debug
|
||||||
|
import cc.maxmc.blastingcrisis.misc.toEntityLocation
|
||||||
import org.bukkit.Location
|
import org.bukkit.Location
|
||||||
|
import org.bukkit.Material
|
||||||
|
import org.bukkit.entity.EntityType
|
||||||
|
import org.bukkit.entity.Player
|
||||||
import org.bukkit.event.block.BlockBreakEvent
|
import org.bukkit.event.block.BlockBreakEvent
|
||||||
import org.bukkit.event.block.BlockPlaceEvent
|
import org.bukkit.event.block.BlockPlaceEvent
|
||||||
import org.bukkit.event.entity.EntityExplodeEvent
|
import org.bukkit.event.entity.EntityDamageEvent
|
||||||
|
import org.bukkit.event.entity.ExplosionPrimeEvent
|
||||||
|
import org.bukkit.event.entity.FoodLevelChangeEvent
|
||||||
import org.bukkit.event.player.PlayerInteractEvent
|
import org.bukkit.event.player.PlayerInteractEvent
|
||||||
import org.bukkit.event.player.PlayerMoveEvent
|
import org.bukkit.event.player.PlayerMoveEvent
|
||||||
|
import org.bukkit.event.player.PlayerQuitEvent
|
||||||
|
import org.bukkit.event.player.PlayerRespawnEvent
|
||||||
|
import taboolib.common.platform.event.EventPriority
|
||||||
import taboolib.common.platform.event.SubscribeEvent
|
import taboolib.common.platform.event.SubscribeEvent
|
||||||
|
import taboolib.library.xseries.XMaterial
|
||||||
|
import taboolib.platform.util.buildItem
|
||||||
import taboolib.platform.util.sendLang
|
import taboolib.platform.util.sendLang
|
||||||
|
|
||||||
object GameListener {
|
object GameListener {
|
||||||
|
|
@ -32,33 +44,100 @@ object GameListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
fun onTNT(tntExplode: EntityExplodeEvent) {
|
fun onTNT(tntExplode: ExplosionPrimeEvent) {
|
||||||
debug("${tntExplode.entityType} exploded at ${tntExplode.location}")
|
debug("${tntExplode.entityType} exploded at ${tntExplode.entity.location}")
|
||||||
tntExplode.blockList().clear()
|
tntExplode.radius = 0.0f
|
||||||
if (!GameManager.currentGame.state.isStarted()) return
|
if (!GameManager.currentGame.state.isStarted()) return
|
||||||
GameManager.currentGame.teams.findLast {
|
GameManager.currentGame.teams.findLast {
|
||||||
it.teamSurvive && it.teamInfo.home.contains(tntExplode.location)
|
it.teamSurvive && it.teamInfo.home.contains(tntExplode.entity.location)
|
||||||
}?.apply {
|
}?.apply {
|
||||||
villager.damage()
|
villager.damage()
|
||||||
debug("team ${teamInfo.name}'s villager damaged")
|
debug("team ${teamInfo.name}'s villager damaged")
|
||||||
} ?: throw IllegalStateException("TNT Exploded at no team, which shouldn't happen")
|
} ?: return run {
|
||||||
|
debug("§cTNT Exploded at no team, which shouldn't happen")
|
||||||
|
tntExplode.isCancelled = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent(priority = EventPriority.LOW)
|
||||||
fun onBreak(breakEvent: BlockBreakEvent) {
|
fun onBreak(breakEvent: BlockBreakEvent) {
|
||||||
val loc = breakEvent.block.location ?: return
|
val loc = breakEvent.block.location ?: return
|
||||||
val player = breakEvent.player ?: return
|
val player = breakEvent.player ?: return
|
||||||
if (GameManager.currentGame.placeBreakRule.matchRule(player, GamePlaceBreakRule.ActionType.BREAK, loc)) return
|
if (GameManager.currentGame.placeBreakRule.matchRule(
|
||||||
|
player,
|
||||||
|
GamePlaceBreakRule.ActionType.BREAK,
|
||||||
|
loc,
|
||||||
|
XMaterial.matchXMaterial(breakEvent.block.type)
|
||||||
|
)
|
||||||
|
) return
|
||||||
breakEvent.isCancelled = true
|
breakEvent.isCancelled = true
|
||||||
player.sendLang("game_cant_break_block")
|
player.sendLang("game_cant_break_block")
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent(priority = EventPriority.LOW)
|
||||||
fun onPlace(placeEvent: BlockPlaceEvent) {
|
fun onPlace(placeEvent: BlockPlaceEvent) {
|
||||||
val loc = placeEvent.block.location ?: return
|
val loc = placeEvent.block.location ?: return
|
||||||
val player = placeEvent.player ?: return
|
val player = placeEvent.player ?: return
|
||||||
if (GameManager.currentGame.placeBreakRule.matchRule(player, GamePlaceBreakRule.ActionType.PLACE, loc)) return
|
if (GameManager.currentGame.placeBreakRule.matchRule(
|
||||||
|
player,
|
||||||
|
GamePlaceBreakRule.ActionType.PLACE,
|
||||||
|
loc,
|
||||||
|
XMaterial.matchXMaterial(placeEvent.blockPlaced.type)
|
||||||
|
)
|
||||||
|
) return
|
||||||
placeEvent.isCancelled = true
|
placeEvent.isCancelled = true
|
||||||
player.sendLang("game_cant_place_block")
|
player.sendLang("game_cant_place_block")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
fun onRespawn(respawnEvent: PlayerRespawnEvent) {
|
||||||
|
val team = respawnEvent.player.team ?: return // ignore none game player
|
||||||
|
respawnEvent.respawnLocation = team.teamInfo.spawn.toEntityLocation()
|
||||||
|
GameManager.currentGame.respawnPlayer(respawnEvent.player)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @SubscribeEvent
|
||||||
|
fun protectDamageBeforeGame(damageEvent: EntityDamageEvent) {
|
||||||
|
if (damageEvent.entity !is Player) return // ignore none player entity
|
||||||
|
if (GameManager.currentGame.state.isStarted()) return
|
||||||
|
damageEvent.isCancelled = true
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
fun protectHunger(hungerEvent: FoodLevelChangeEvent) {
|
||||||
|
hungerEvent.isCancelled = true
|
||||||
|
(hungerEvent.entity as Player).run {
|
||||||
|
foodLevel = 20
|
||||||
|
saturation = 20f
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent(EventPriority.HIGH, true)
|
||||||
|
fun tntIgnite(tntPlace: BlockPlaceEvent) {
|
||||||
|
if (tntPlace.blockPlaced.type != Material.TNT) return
|
||||||
|
val loc = tntPlace.blockPlaced.location
|
||||||
|
tntPlace.block.type = Material.AIR
|
||||||
|
loc.world.spawnEntity(loc.clone().apply { y += 0.5 }, EntityType.PRIMED_TNT)
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
fun onLeft(leftEvent: PlayerQuitEvent) {
|
||||||
|
if (!GameManager.currentGame.players.contains(leftEvent.player)) return
|
||||||
|
GameManager.currentGame.leave(leftEvent.player)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val ores = mapOf(Material.IRON_ORE to Material.IRON_INGOT, Material.GOLD_ORE to Material.GOLD_INGOT)
|
||||||
|
|
||||||
|
@SubscribeEvent(ignoreCancelled = true)
|
||||||
|
fun autoSmelt(breakEvent: BlockBreakEvent) {
|
||||||
|
if (!GameManager.currentGame.players.contains(breakEvent.player)) return
|
||||||
|
val type = breakEvent.block.type
|
||||||
|
val loc = breakEvent.block.location
|
||||||
|
if (!ores.containsKey(type)) return
|
||||||
|
debug("Auto Smelting: ${breakEvent.block.type}")
|
||||||
|
breakEvent.block.type = Material.AIR
|
||||||
|
breakEvent.isCancelled = true
|
||||||
|
loc.world.dropItemNaturally(loc.toEntityLocation().apply { y += 0.5 }, buildItem(ores[type]!!))
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,13 +1,16 @@
|
||||||
package cc.maxmc.blastingcrisis.map
|
package cc.maxmc.blastingcrisis.map
|
||||||
|
|
||||||
import cc.maxmc.blastingcrisis.misc.Area
|
import cc.maxmc.blastingcrisis.misc.Area
|
||||||
|
import org.bukkit.Location
|
||||||
|
|
||||||
class GameMap(
|
class GameMap(
|
||||||
val name: String,
|
val name: String,
|
||||||
val area: Area,
|
val area: Area,
|
||||||
val wall: Area,
|
val wall: Area,
|
||||||
val teams: List<MapTeam>,
|
val teams: List<MapTeam>,
|
||||||
val maxPlayersPerTeam: Int
|
val maxPlayersPerTeam: Int,
|
||||||
|
val blockGen: String,
|
||||||
|
val itemGen: List<Location>
|
||||||
) {
|
) {
|
||||||
val maxPlayer: Int
|
val maxPlayer: Int
|
||||||
get() = maxPlayersPerTeam * teams.size
|
get() = maxPlayersPerTeam * teams.size
|
||||||
|
|
|
||||||
|
|
@ -32,9 +32,9 @@ class Area(loc1: Location, loc2: Location) : ConfigurationSerializable {
|
||||||
*/
|
*/
|
||||||
fun contains(location: Location): Boolean {
|
fun contains(location: Location): Boolean {
|
||||||
if (location.world != locTop.world) return false
|
if (location.world != locTop.world) return false
|
||||||
if (location.x !in (locMin.x - 1)..(locTop.x + 1)) return false
|
if (location.x !in (locMin.x)..(locTop.x + 1)) return false
|
||||||
if (location.y !in locMin.y..locTop.y + 1) return false
|
if (location.y !in locMin.y..locTop.y + 1) return false
|
||||||
return location.z in (locMin.z - 1)..(locTop.z + 1)
|
return location.z in (locMin.z)..(locTop.z + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun containsBlock(location: Location): Boolean {
|
fun containsBlock(location: Location): Boolean {
|
||||||
|
|
@ -80,7 +80,7 @@ class Area(loc1: Location, loc2: Location) : ConfigurationSerializable {
|
||||||
*
|
*
|
||||||
* @return a random Location that player can stand
|
* @return a random Location that player can stand
|
||||||
*/
|
*/
|
||||||
tailrec fun randomLocation(): Location {
|
tailrec fun randomLocationRestrict(): Location {
|
||||||
val x = random(locMin.blockX, locTop.blockX)
|
val x = random(locMin.blockX, locTop.blockX)
|
||||||
val z = random(locMin.blockZ, locTop.blockZ)
|
val z = random(locMin.blockZ, locTop.blockZ)
|
||||||
for (y in locMin.blockY..locTop.blockY) {
|
for (y in locMin.blockY..locTop.blockY) {
|
||||||
|
|
@ -88,9 +88,21 @@ class Area(loc1: Location, loc2: Location) : ConfigurationSerializable {
|
||||||
val add = loc.clone().add(0.0, 1.0, 0.0)
|
val add = loc.clone().add(0.0, 1.0, 0.0)
|
||||||
if (loc.block.type == Material.AIR && add.block.type == Material.AIR) return loc
|
if (loc.block.type == Material.AIR && add.block.type == Material.AIR) return loc
|
||||||
}
|
}
|
||||||
return randomLocation()
|
return randomLocationRestrict()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tailrec fun randomLocationAny(): Location {
|
||||||
|
val x = random(locMin.blockX, locTop.blockX)
|
||||||
|
val y = random(locMin.blockY, locTop.blockY)
|
||||||
|
val z = random(locMin.blockZ, locTop.blockZ)
|
||||||
|
val loc = Vector(x, y, z).toLocation(locMin.world)
|
||||||
|
if (loc.block.type == Material.AIR) return loc
|
||||||
|
return randomLocationAny()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun volume(): Int =
|
||||||
|
(locTop.blockX - locMin.blockX) * (locTop.blockY - locMin.blockY) * (locTop.blockZ - locMin.blockZ)
|
||||||
|
|
||||||
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
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
package cc.maxmc.blastingcrisis.misc
|
||||||
|
|
||||||
|
import cc.maxmc.blastingcrisis.game.GameOreGenerator
|
||||||
|
import taboolib.common.platform.function.getDataFolder
|
||||||
|
import taboolib.module.configuration.Configuration
|
||||||
|
|
||||||
|
object BlockGenManager {
|
||||||
|
private val generators = HashMap<String, GameOreGenerator>()
|
||||||
|
|
||||||
|
init {
|
||||||
|
load()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun load() {
|
||||||
|
getDataFolder().resolve("ore-generators").listFiles()!!.forEach {
|
||||||
|
try {
|
||||||
|
generators[it.nameWithoutExtension] = GameOreGenerator(Configuration.loadFromFile(it))
|
||||||
|
} catch (e: Exception) {
|
||||||
|
info("§c| §7加载矿石生成器 §c${it.nameWithoutExtension} §7时出现错误,已跳过.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getGenerator(name: String): GameOreGenerator? = generators[name]
|
||||||
|
}
|
||||||
|
|
@ -11,7 +11,7 @@ class WeightRandom<K, V : Number>(list: List<Pair<K, V>>) {
|
||||||
init {
|
init {
|
||||||
Preconditions.checkNotNull(list, "list can NOT be null!")
|
Preconditions.checkNotNull(list, "list can NOT be null!")
|
||||||
for (pair in list) {
|
for (pair in list) {
|
||||||
Preconditions.checkArgument(pair.second.toDouble() > 0, "非法权重值:pair=$pair")
|
// Preconditions.checkArgument(pair.second.toDouble() > 0, "非法权重值:pair=$pair")
|
||||||
val lastWeight: Double = if (weightMap.size == 0) 0.0 else weightMap.lastKey().toDouble() //统一转为double
|
val lastWeight: Double = if (weightMap.size == 0) 0.0 else weightMap.lastKey().toDouble() //统一转为double
|
||||||
weightMap[pair.second.toDouble() + lastWeight] = pair.first //权重累加
|
weightMap[pair.second.toDouble() + lastWeight] = pair.first //权重累加
|
||||||
}
|
}
|
||||||
|
|
@ -24,7 +24,11 @@ class WeightRandom<K, V : Number>(list: List<Pair<K, V>>) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Location.toPlayerLocation(): Location = clone().apply {
|
fun <K, V : Number> List<Pair<K, V>>.weightedRandom(): WeightRandom<K, V> {
|
||||||
|
return WeightRandom(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Location.toEntityLocation(): Location = clone().apply {
|
||||||
x = blockX + 0.5
|
x = blockX + 0.5
|
||||||
y = blockY.toDouble()
|
y = blockY.toDouble()
|
||||||
z = blockZ + 0.5
|
z = blockZ + 0.5
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
package cc.maxmc.blastingcrisis.misc
|
||||||
|
|
||||||
|
|
||||||
|
class UniArea(subArea: List<Area>) {
|
||||||
|
val randomizer = subArea.map { it to it.volume() }.weightedRandom()
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package cc.maxmc.blastingcrisis.packet
|
package cc.maxmc.blastingcrisis.packet
|
||||||
|
|
||||||
import cc.maxmc.blastingcrisis.listener.BEntityInteract
|
import cc.maxmc.blastingcrisis.listener.BEntityInteract
|
||||||
|
import cc.maxmc.blastingcrisis.misc.debug
|
||||||
import gnu.trove.TDecorators
|
import gnu.trove.TDecorators
|
||||||
import gnu.trove.map.hash.TIntObjectHashMap
|
import gnu.trove.map.hash.TIntObjectHashMap
|
||||||
import net.minecraft.server.v1_8_R3.*
|
import net.minecraft.server.v1_8_R3.*
|
||||||
|
|
@ -11,6 +12,7 @@ import taboolib.library.reflex.Reflex.Companion.getProperty
|
||||||
import taboolib.library.reflex.Reflex.Companion.setProperty
|
import taboolib.library.reflex.Reflex.Companion.setProperty
|
||||||
import taboolib.library.reflex.Reflex.Companion.unsafeInstance
|
import taboolib.library.reflex.Reflex.Companion.unsafeInstance
|
||||||
import taboolib.module.nms.sendPacket
|
import taboolib.module.nms.sendPacket
|
||||||
|
import taboolib.module.nms.sendPacketBlocking
|
||||||
import java.util.concurrent.atomic.AtomicInteger
|
import java.util.concurrent.atomic.AtomicInteger
|
||||||
import java.util.concurrent.locks.ReentrantReadWriteLock
|
import java.util.concurrent.locks.ReentrantReadWriteLock
|
||||||
|
|
||||||
|
|
@ -58,7 +60,7 @@ abstract class BEntity(var loc: Location, val entityType: Int) {
|
||||||
}
|
}
|
||||||
packet.setProperty("l", dataWatcher)
|
packet.setProperty("l", dataWatcher)
|
||||||
|
|
||||||
viewers.forEach { it.sendPacket(packet) }
|
player.sendPacketBlocking(packet)
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun addViewer(viewer: Player) {
|
open fun addViewer(viewer: Player) {
|
||||||
|
|
@ -67,10 +69,18 @@ abstract class BEntity(var loc: Location, val entityType: Int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun removeViewer(viewer: Player) {
|
open fun removeViewer(viewer: Player) {
|
||||||
viewer.sendPacket(PacketPlayOutEntityDestroy(entityID))
|
viewer.sendPacketBlocking(PacketPlayOutEntityDestroy(entityID))
|
||||||
viewers.remove(viewer)
|
viewers.remove(viewer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun respawnForPlayer(player: Player) {
|
||||||
|
debug(viewers.toString())
|
||||||
|
if (!viewers.contains(player)) return
|
||||||
|
debug("Respawning?")
|
||||||
|
removeViewer(player)
|
||||||
|
addViewer(player)
|
||||||
|
}
|
||||||
|
|
||||||
fun destroy() {
|
fun destroy() {
|
||||||
ArrayList(viewers).forEach { removeViewer(it) }
|
ArrayList(viewers).forEach { removeViewer(it) }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ class BEntityVillager private constructor(loc: Location) : BEntity(loc, 120) {
|
||||||
nameTag.removeViewer(viewer)
|
nameTag.removeViewer(viewer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun DataWatcher.initEntity() {
|
override fun DataWatcher.initEntity() {
|
||||||
a(6, 1.0f) // Health
|
a(6, 1.0f) // Health
|
||||||
a(7, 0) // Potion Effect Color
|
a(7, 0) // Potion Effect Color
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
|
|
||||||
# Time before game start
|
# Time before game start
|
||||||
# Unit: second
|
# Unit: second
|
||||||
time-to-start: 15
|
time_to_start: 15
|
||||||
|
|
||||||
|
# Unit: tick
|
||||||
|
item_gen_delay: 20
|
||||||
|
|
||||||
game:
|
game:
|
||||||
villager_max_health: 150
|
villager_max_health: 150
|
||||||
|
|
|
||||||
Binary file not shown.
Loading…
Reference in New Issue