finish ore generate part (Part Of MAXMC-T-4)

This commit is contained in:
TONY_All 2023-06-25 02:15:01 +08:00
parent 31e52382b2
commit 439cbccfe2
Signed by: tony_all
GPG Key ID: 08A2261D5D6F746A
8 changed files with 46 additions and 17 deletions

View File

@ -70,7 +70,8 @@ object BlastingCrisis : Plugin() {
listOf( listOf(
teamRed, teamGreen teamRed, teamGreen
), ),
1 1,
"default"
) )
DebugCommand.game = Game(map) DebugCommand.game = Game(map)
GameManager.currentGame = DebugCommand.game GameManager.currentGame = DebugCommand.game

View File

@ -4,6 +4,7 @@ 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
import cc.maxmc.blastingcrisis.misc.Area import cc.maxmc.blastingcrisis.misc.Area
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
@ -116,7 +117,7 @@ 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)

View File

@ -1,7 +1,9 @@
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.BlockGenManager
import cc.maxmc.blastingcrisis.misc.UniArea
import cc.maxmc.blastingcrisis.misc.debug import cc.maxmc.blastingcrisis.misc.debug
import org.bukkit.Material import org.bukkit.Material
import org.bukkit.entity.Player import org.bukkit.entity.Player
@ -17,7 +19,7 @@ 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) val generator = BlockGenManager.getGenerator(map.blockGen)!!
var state: GameState = GameState.WAITING var state: GameState = GameState.WAITING
private fun autoJoinTeam() { private fun autoJoinTeam() {
@ -51,7 +53,7 @@ class Game(
fun start() { fun start() {
debug("game ${map.name} started.") debug("game ${map.name} started.")
placeBreakRule.loadDefaultRule() placeBreakRule.loadDefaultRule()
startOreGen()
state = GameState.START state = GameState.START
timer.startTimer() timer.startTimer()
timer.submitEvent("wall_fall", Duration.ofMinutes(1)) { timer.submitEvent("wall_fall", Duration.ofMinutes(1)) {
@ -85,9 +87,12 @@ class Game(
} }
private fun startOreGen() { private fun startOreGen() {
map.teams.forEach { val mines = map.teams.fold(ArrayList<Area>()) { list, team ->
list += team.mine
list += team.sides
list
} }
generator.enable(UniArea(mines))
} }
fun checkEnd() { fun checkEnd() {

View File

@ -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,6 @@ class GameOreGenerator(config: Configuration) {
return generate(area, times + 1) return generate(area, times + 1)
} }
} }
} }

View File

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

View File

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

View File

@ -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,6 +24,10 @@ class WeightRandom<K, V : Number>(list: List<Pair<K, V>>) {
} }
} }
fun <K, V : Number> List<Pair<K, V>>.weightedRandom(): WeightRandom<K, V> {
return WeightRandom(this)
}
fun Location.toPlayerLocation(): Location = clone().apply { fun Location.toPlayerLocation(): Location = clone().apply {
x = blockX + 0.5 x = blockX + 0.5
y = blockY.toDouble() y = blockY.toDouble()

View File

@ -0,0 +1,6 @@
package cc.maxmc.blastingcrisis.misc
class UniArea(subArea: List<Area>) {
val randomizer = subArea.map { it to it.volume() }.weightedRandom()
}