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(
teamRed, teamGreen
),
1
1,
"default"
)
DebugCommand.game = Game(map)
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.GameState
import cc.maxmc.blastingcrisis.misc.Area
import cc.maxmc.blastingcrisis.misc.UniArea
import cc.maxmc.blastingcrisis.packet.BEntityVillager
import kotlinx.coroutines.cancel
import org.bukkit.Bukkit
@ -116,7 +117,7 @@ object DebugCommand {
println("saved")
val config = Configuration.loadFromFile(File(getDataFolder(), "ore-generators/default.yml"))
val gen = GameOreGenerator(config)
val job = gen.enable(area)
val job = gen.enable(UniArea(listOf(area)))
Bukkit.getScheduler().runTaskLater(BukkitPlugin.getInstance(), {
job.cancel("Stop by hand")
}, 60 * 20)

View File

@ -1,7 +1,9 @@
package cc.maxmc.blastingcrisis.game
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 org.bukkit.Material
import org.bukkit.entity.Player
@ -17,7 +19,7 @@ class Game(
val timer: GameTimer = GameTimer(this)
val players = ArrayList<Player>()
val placeBreakRule = GamePlaceBreakRule(this)
val generator = BlockGenManager.getGenerator(map.blockGen)
val generator = BlockGenManager.getGenerator(map.blockGen)!!
var state: GameState = GameState.WAITING
private fun autoJoinTeam() {
@ -51,7 +53,7 @@ class Game(
fun start() {
debug("game ${map.name} started.")
placeBreakRule.loadDefaultRule()
startOreGen()
state = GameState.START
timer.startTimer()
timer.submitEvent("wall_fall", Duration.ofMinutes(1)) {
@ -85,9 +87,12 @@ class Game(
}
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() {

View File

@ -1,9 +1,6 @@
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.pluginScope
import cc.maxmc.blastingcrisis.misc.*
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@ -24,13 +21,14 @@ class GameOreGenerator(config: Configuration) {
}
private val random = WeightRandom(ores.map { it.key to it.value })
fun enable(area: Area): Job {
fun enable(area: UniArea): Job {
return pluginScope.launch {
while (true) {
val airPercent = area.getAirPercentage()
val targetArea = area.randomizer.random()
val airPercent = targetArea.getAirPercentage()
debug("remain air: $airPercent.")
if (airPercent > 0.5) {
generate(area)
generate(targetArea)
}
delay(rate * 50L)
}
@ -54,4 +52,6 @@ class GameOreGenerator(config: Configuration) {
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")
debug("teleporting $player to battle field")
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
*/
tailrec fun randomLocation(): Location {
tailrec fun randomLocationRestrict(): Location {
val x = random(locMin.blockX, locTop.blockX)
val z = random(locMin.blockZ, locTop.blockZ)
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)
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 {
if (this === other) return true
if (javaClass != other?.javaClass) return false

View File

@ -11,7 +11,7 @@ class WeightRandom<K, V : Number>(list: List<Pair<K, V>>) {
init {
Preconditions.checkNotNull(list, "list can NOT be null!")
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
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 {
x = blockX + 0.5
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()
}