sync code
This commit is contained in:
parent
94295d7f44
commit
b19752154e
|
|
@ -1,4 +1,4 @@
|
|||
.gradle
|
||||
.idea
|
||||
|
||||
./build
|
||||
build/
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
|||
|
||||
plugins {
|
||||
kotlin("jvm") version "1.7.20"
|
||||
id("io.izzel.taboolib") version "1.42"
|
||||
id("io.izzel.taboolib") version "1.50"
|
||||
}
|
||||
|
||||
group = "cc.maxmc.blastingcrisis"
|
||||
|
|
@ -20,9 +20,9 @@ repositories {
|
|||
|
||||
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:Adyeshach:1.5.12")
|
||||
}
|
||||
|
||||
taboolib {
|
||||
|
|
@ -34,10 +34,11 @@ taboolib {
|
|||
}
|
||||
install("common", "common-5")
|
||||
install("platform-bukkit")
|
||||
install("module-nms", "module-nms-util", "module-chat")
|
||||
install("module-nms", "module-nms-util")
|
||||
install("module-chat", "module-lang", "module-configuration")
|
||||
|
||||
options("skip-kotlin-relocate")
|
||||
version = "6.0.9-117"
|
||||
version = "6.0.10-12"
|
||||
}
|
||||
|
||||
tasks.withType<KotlinCompile> {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,15 @@
|
|||
package cc.maxmc.blastingcrisis
|
||||
|
||||
import cc.maxmc.blastingcrisis.command.DebugCommand
|
||||
import taboolib.common.env.RuntimeDependency
|
||||
import taboolib.common.platform.Plugin
|
||||
|
||||
@RuntimeDependency(
|
||||
"org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4",
|
||||
)
|
||||
object BlastingCrisis: Plugin() {
|
||||
|
||||
override fun onEnable() {
|
||||
|
||||
DebugCommand.debug("debugcmd")
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,18 +1,149 @@
|
|||
package cc.maxmc.blastingcrisis.command
|
||||
|
||||
import cc.maxmc.blastingcrisis.game.Game
|
||||
import cc.maxmc.blastingcrisis.game.GameOreGenerator
|
||||
import cc.maxmc.blastingcrisis.game.GameState
|
||||
import cc.maxmc.blastingcrisis.map.GameMap
|
||||
import cc.maxmc.blastingcrisis.map.MapTeam
|
||||
import cc.maxmc.blastingcrisis.misc.Area
|
||||
import cc.maxmc.blastingcrisis.packet.BEntityVillager
|
||||
import kotlinx.coroutines.cancel
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.Location
|
||||
import org.bukkit.entity.Blaze
|
||||
import org.bukkit.entity.EntityType
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.entity.Player
|
||||
import taboolib.common.platform.ProxyPlayer
|
||||
import taboolib.common.platform.command.command
|
||||
import taboolib.common.platform.function.adaptCommandSender
|
||||
import taboolib.common.platform.function.getDataFolder
|
||||
import taboolib.module.configuration.Configuration
|
||||
import taboolib.platform.BukkitPlugin
|
||||
import taboolib.platform.util.sendActionBar
|
||||
import java.io.File
|
||||
|
||||
object DebugCommand {
|
||||
lateinit var game: Game
|
||||
lateinit var villager: BEntityVillager
|
||||
fun debug(cmd: String) = command(cmd) {
|
||||
literal("game") {
|
||||
|
||||
execute<Player> { sender, _, _ ->
|
||||
Bukkit.broadcastMessage(sender.name)
|
||||
val homeArea = Area(sender.location, sender.location.add(10.0, 10.0, 10.0))
|
||||
val area1 = Area(sender.location, sender.location.add(5.0, 5.0, 5.0))
|
||||
val area2 = Area(sender.location, sender.location.add(5.0, 5.0, 5.0))
|
||||
val area3 = Area(sender.location, sender.location.add(5.0, 5.0, 5.0))
|
||||
val team = MapTeam(
|
||||
"testTeam1",
|
||||
ChatColor.AQUA,
|
||||
sender.location,
|
||||
homeArea,
|
||||
area1,
|
||||
area2,
|
||||
listOf(area3),
|
||||
area2,
|
||||
sender.eyeLocation
|
||||
)
|
||||
val map = GameMap(
|
||||
"test", listOf(
|
||||
team
|
||||
), 4
|
||||
)
|
||||
game = Game(map)
|
||||
game.join(sender)
|
||||
}
|
||||
|
||||
literal("state") {
|
||||
dynamic {
|
||||
execute<Player> { sender, ctx, argument ->
|
||||
if (!GameState.values().map { it.name }
|
||||
.contains(argument.uppercase())) return@execute sender.sendMessage("NO STATE")
|
||||
val state = GameState.valueOf(argument.uppercase())
|
||||
game.state = state
|
||||
sender.sendMessage("changed to $argument")
|
||||
}
|
||||
suggestion<Player> { _, _ ->
|
||||
GameState.values().map { it.name }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
literal("timer") {
|
||||
execute<Player> { sender, ctx, argument ->
|
||||
game.timer.beginCountdown()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
literal("scoreboard") {
|
||||
execute { sender, context, argument ->
|
||||
game.scoreboard.sendScoreboardPlayer(sender)
|
||||
}
|
||||
}
|
||||
|
||||
literal("title") {
|
||||
execute<Player> { sender, _, _ ->
|
||||
val adapt = adaptCommandSender(sender) as ProxyPlayer
|
||||
adapt.sendTitle("Title", "sub", 20, 20, 20)
|
||||
}
|
||||
}
|
||||
|
||||
literal("actionBar") {
|
||||
execute<Player> { sender, _, _ ->
|
||||
sender.sendActionBar("This is an action bar msg")
|
||||
}
|
||||
}
|
||||
|
||||
literal("spawnEntity") {
|
||||
execute<Player> { sender, _, _ ->
|
||||
val loc = sender.location
|
||||
villager = BEntityVillager(loc)
|
||||
villager.addViewer(sender)
|
||||
}
|
||||
}
|
||||
|
||||
// literal("rename") {
|
||||
// dynamic {
|
||||
// execute<Player> { _, _, arg ->
|
||||
// villager.name = arg
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// literal("destroy") {
|
||||
// execute { sender, _, _ ->
|
||||
// villager.removeViewer(sender)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// literal("hurt") {
|
||||
// execute<Player> { _, _, _ ->
|
||||
// villager.hurtAnimate()
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// literal("die") {
|
||||
// execute<Player> { _, _, _ ->
|
||||
// villager.dieAnimate()
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// literal("update") {
|
||||
// execute<Player> { _, _, _ ->
|
||||
// villager.update()
|
||||
// }
|
||||
// }
|
||||
|
||||
literal("genOre") {
|
||||
execute<Player> { sender, _, _ ->
|
||||
val area = Area(sender.location.block.location, sender.location.block.location.add(20.0, 20.0, 20.0))
|
||||
BukkitPlugin.getInstance().saveResource("ore-generators/default.yml", false)
|
||||
println("saved")
|
||||
val config = Configuration.loadFromFile(File(getDataFolder(), "ore-generators/default.yml"))
|
||||
val gen = GameOreGenerator(config)
|
||||
val job = gen.enable(area)
|
||||
Bukkit.getScheduler().runTaskLater(BukkitPlugin.getInstance(), {
|
||||
job.cancel("Stop by hand")
|
||||
} ,60 * 20)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
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
|
||||
fun onPacket(it: PacketSendEvent) {
|
||||
Bukkit.getScheduler().runTask(BukkitPlugin.getInstance()) {
|
||||
if (it.player.name != "TONY_All") return@runTask
|
||||
// val source = it.packet.source
|
||||
if (!it.packet.name.lowercase().contains("entity")) return@runTask
|
||||
// println(it.packet.name)
|
||||
if( it.packet.source !is PacketPlayOutSpawnEntityLiving ) {
|
||||
return@runTask
|
||||
}
|
||||
// it.packet.source.getProperty<Int>("a")!!.broadcast()
|
||||
// it.packet.source.getProperty<Int>("b")!!.broadcast()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,14 +1,65 @@
|
|||
package cc.maxmc.blastingcrisis.game
|
||||
|
||||
import cc.maxmc.blastingcrisis.map.GameMap
|
||||
import cc.maxmc.blastingcrisis.misc.debug
|
||||
import org.bukkit.entity.Player
|
||||
import taboolib.platform.util.sendLang
|
||||
|
||||
class Game(val map: GameMap, val teams: List<GameTeam>, val state: GameState, scoreboard: GameScoreboard) {
|
||||
val players: List<Player>
|
||||
get() {
|
||||
val all = ArrayList<Player>()
|
||||
teams.map { it.players }.forEach { all.addAll(it) }
|
||||
return all
|
||||
class Game(
|
||||
val map: GameMap,
|
||||
) {
|
||||
val teams = map.teams.map { GameTeam(this, it) }
|
||||
val scoreboard: GameScoreboard = GameScoreboard(this)
|
||||
val timer: GameTimer = GameTimer(this)
|
||||
val players = ArrayList<Player>()
|
||||
var state: GameState = GameState.WAITING
|
||||
|
||||
private fun autoJoinTeam() {
|
||||
players.filter { it.team == null }
|
||||
.shuffled()
|
||||
.forEach {
|
||||
teams.minBy { team -> team.players.size }.join(it)
|
||||
}
|
||||
}
|
||||
|
||||
fun join(player: Player) {
|
||||
players += player
|
||||
broadcast {
|
||||
it.sendLang("game_join", player.name)
|
||||
}
|
||||
scoreboard.sendScoreboard()
|
||||
}
|
||||
|
||||
fun leave(player: Player) {
|
||||
if (state == GameState.WAITING || state == GameState.COUNTING_DOWN) {
|
||||
players.remove(player)
|
||||
checkStart()
|
||||
}
|
||||
val team =
|
||||
player.team ?: throw IllegalStateException("Player ${player.name} has no team, which shouldn't happen.")
|
||||
team.checkTeamAlive()
|
||||
team.players.remove(player)
|
||||
checkEnd()
|
||||
}
|
||||
|
||||
fun start() {
|
||||
debug("game ${map.name} started.")
|
||||
|
||||
}
|
||||
|
||||
private fun checkStart() {
|
||||
if (players.size > map.maxPlayer * 0.75) {
|
||||
state = GameState.COUNTING_DOWN
|
||||
timer.beginCountdown()
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkEnd() {
|
||||
|
||||
}
|
||||
|
||||
fun broadcast(action: (Player) -> Unit) {
|
||||
players.forEach(action)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
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 kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.Material
|
||||
import taboolib.common.util.random
|
||||
import taboolib.library.xseries.XMaterial
|
||||
import taboolib.module.configuration.Configuration
|
||||
import taboolib.platform.BukkitPlugin
|
||||
|
||||
class GameOreGenerator(config: Configuration) {
|
||||
private val rate: Int = config.getInt("rate")
|
||||
private val ores: MutableMap<XMaterial, Int> = HashMap<XMaterial, Int>().also {
|
||||
config.getConfigurationSection("ores")!!.getKeys(false).forEach { key ->
|
||||
it += XMaterial.valueOf(key) to (config["ores.$key"]!! as Int)
|
||||
}
|
||||
}
|
||||
private val random = WeightRandom(ores.map { it.key to it.value })
|
||||
|
||||
fun enable(area: Area): Job {
|
||||
return pluginScore.launch {
|
||||
while (true) {
|
||||
generate(area)
|
||||
delay(rate * 50L)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private tailrec fun generate(area: Area) {
|
||||
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)
|
||||
val block = area.locMin.world.getBlockAt(x, y, z)
|
||||
debug("trying generate at ($x, $y, $z) - ${block.type}")
|
||||
|
||||
if (block.type == Material.AIR) {
|
||||
Bukkit.getScheduler().runTask(BukkitPlugin.getInstance()) {
|
||||
block.type = random.random().parseMaterial()
|
||||
debug("generating ${block.type} at ($x, $y, $z)")
|
||||
}
|
||||
} else {
|
||||
return generate(area)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,2 +1,9 @@
|
|||
package cc.maxmc.blastingcrisis.game
|
||||
|
||||
import cc.maxmc.blastingcrisis.misc.GameManager
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
val Player.team: GameTeam?
|
||||
get() = GameManager.currentGame.teams.findLast {
|
||||
it.players.contains(this)
|
||||
}
|
||||
|
|
@ -1,28 +1,27 @@
|
|||
package cc.maxmc.blastingcrisis.game
|
||||
|
||||
import cc.maxmc.blastingcrisis.game.GameState.*
|
||||
import cc.maxmc.blastingcrisis.misc.debug
|
||||
import org.bukkit.entity.Player
|
||||
import taboolib.module.nms.sendScoreboard
|
||||
import taboolib.platform.util.asLangText
|
||||
|
||||
class GameScoreboard(val game: Game) {
|
||||
fun sendScoreboard() {
|
||||
game.teams.forEach { g ->
|
||||
g.players.forEach {
|
||||
game.broadcast {
|
||||
sendScoreboardPlayer(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun sendScoreboardPlayer(player: Player) {
|
||||
|
||||
debug("sending Scoreboard to ${player.name}")
|
||||
val scoreboardText = when (game.state) {
|
||||
WAITING -> {
|
||||
player.asLangText("scoreboard_waiting", game.players.size, game.map.maxPlayer)
|
||||
}
|
||||
|
||||
COUNTING_DOWN -> {
|
||||
player.asLangText("scoreboard_counting_down", game.players.size, game.map.maxPlayer)
|
||||
player.asLangText("scoreboard_counting_down", game.players.size, game.map.maxPlayer, game.timer.current)
|
||||
}
|
||||
START -> TODO()
|
||||
WALL_FALL -> TODO()
|
||||
|
|
|
|||
|
|
@ -3,6 +3,16 @@ package cc.maxmc.blastingcrisis.game
|
|||
import cc.maxmc.blastingcrisis.map.MapTeam
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
class GameTeam(val team: MapTeam, val players: List<Player>) {
|
||||
class GameTeam(val game: Game, val team: MapTeam) {
|
||||
val players = ArrayList<Player>()
|
||||
|
||||
fun join(player: Player) {
|
||||
players += player
|
||||
|
||||
|
||||
}
|
||||
fun checkTeamAlive() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,10 +1,49 @@
|
|||
package cc.maxmc.blastingcrisis.game
|
||||
|
||||
class GameTimer(val game: Game) {
|
||||
val time2Start = 2
|
||||
import cc.maxmc.blastingcrisis.misc.pluginScore
|
||||
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
|
||||
|
||||
fun beginCountdown() {
|
||||
countdownJob = pluginScore.launch {
|
||||
while (current > 0) {
|
||||
if (!isActive) {
|
||||
return@launch
|
||||
}
|
||||
countdown()
|
||||
current--
|
||||
delay(1000)
|
||||
}
|
||||
game.start()
|
||||
}
|
||||
}
|
||||
|
||||
private fun countdown() {
|
||||
game.scoreboard.sendScoreboard()
|
||||
game.broadcast {
|
||||
val locale = adaptCommandSender(it).getLocaleFile()!!
|
||||
if (locale.nodes.containsKey("game_countdown_${current}")) {
|
||||
it.sendLang("game_countdown_${current}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun resetCountdown() {
|
||||
game.broadcast {
|
||||
it.sendLang("time_reset")
|
||||
}
|
||||
current = timeToStart
|
||||
}
|
||||
|
||||
fun startTimer() {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
package cc.maxmc.blastingcrisis.misc
|
||||
|
||||
import kotlinx.coroutines.CoroutineExceptionHandler
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
|
||||
val pluginScore = CoroutineScope(SupervisorJob() + CoroutineExceptionHandler { job, exception ->
|
||||
IllegalStateException("在执行 Job $job 时出线异常", exception).printStackTrace()
|
||||
})
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package cc.maxmc.blastingcrisis.misc
|
||||
|
||||
import taboolib.common.platform.function.console
|
||||
|
||||
fun debug(message: String) {
|
||||
console().sendMessage("§1DEBUG| §7$message")
|
||||
}
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
package cc.maxmc.blastingcrisis.misc
|
||||
|
||||
object GameManager {
|
||||
import cc.maxmc.blastingcrisis.game.Game
|
||||
|
||||
object GameManager {
|
||||
lateinit var currentGame : Game
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package cc.maxmc.blastingcrisis.misc
|
||||
|
||||
import com.google.common.base.Preconditions
|
||||
import java.util.*
|
||||
|
||||
|
||||
class WeightRandom<K, V : Number>(list: List<Pair<K, V>>) {
|
||||
private val weightMap = TreeMap<Double, K>()
|
||||
|
||||
init {
|
||||
Preconditions.checkNotNull(list, "list can NOT be null!")
|
||||
for (pair in list) {
|
||||
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 //权重累加
|
||||
}
|
||||
}
|
||||
|
||||
fun random(): K {
|
||||
val randomWeight = weightMap.lastKey() * Math.random()
|
||||
val tailMap: SortedMap<Double, K> = weightMap.tailMap(randomWeight, false)
|
||||
return weightMap[tailMap.firstKey()]!!
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
package cc.maxmc.blastingcrisis.packet
|
||||
|
||||
import gnu.trove.TDecorators
|
||||
import gnu.trove.map.hash.TIntObjectHashMap
|
||||
import net.minecraft.server.v1_8_R3.*
|
||||
import org.bukkit.Location
|
||||
import org.bukkit.entity.Player
|
||||
import taboolib.common.util.random
|
||||
import taboolib.library.reflex.Reflex.Companion.getProperty
|
||||
import taboolib.library.reflex.Reflex.Companion.setProperty
|
||||
import taboolib.library.reflex.Reflex.Companion.unsafeInstance
|
||||
import taboolib.module.nms.sendPacket
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock
|
||||
|
||||
abstract class BEntity(var loc: Location, val entityType: Int) {
|
||||
private val dataWatcher = (DataWatcher::class.java.unsafeInstance() as DataWatcher).apply {
|
||||
setProperty("b", true)
|
||||
setProperty("dataValues", TIntObjectHashMap<Any?>(10, 0.5f, -1))
|
||||
setProperty("d", TDecorators.wrap(getProperty<TIntObjectHashMap<Any>>("dataValues")!!))
|
||||
setProperty("f", ReentrantReadWriteLock())
|
||||
}.apply {
|
||||
/*
|
||||
0x01 On Fire
|
||||
0x02 Crouched
|
||||
0x08 Sprinting
|
||||
0x10 Eating/Drinking/Blocking
|
||||
0x20 Invisible
|
||||
*/
|
||||
a(0, 0.toByte())
|
||||
a(1, 300.toShort()) // Air
|
||||
a(2, "") // Name Tag
|
||||
a(3, 0.toByte()) // Always Show Name Tag
|
||||
a(4, 0.toByte()) // Silent
|
||||
initEntity()
|
||||
}
|
||||
val entityID: Int = getEID()
|
||||
val viewers = ArrayList<Player>()
|
||||
|
||||
abstract fun DataWatcher.initEntity()
|
||||
|
||||
open fun spawnForPlayer(player: Player) {
|
||||
val packet = PacketPlayOutSpawnEntityLiving()
|
||||
packet.apply {
|
||||
setProperty("a", entityID)
|
||||
setProperty("b", entityType)
|
||||
setProperty("c", MathHelper.floor(loc.x * 32.0))
|
||||
setProperty("d", MathHelper.floor(loc.y * 32.0))
|
||||
setProperty("e", MathHelper.floor(loc.z * 32.0))
|
||||
setProperty("f", 0.toShort())
|
||||
setProperty("g", 0.toShort())
|
||||
setProperty("h", 0.toShort())
|
||||
setProperty("i", (loc.yaw * 256.0f / 360.0f).toInt().toByte())
|
||||
setProperty("j", (loc.pitch * 256.0f / 360.0f).toInt().toByte())
|
||||
setProperty("k", (loc.yaw * 256.0f / 360.0f).toInt().toByte())
|
||||
}
|
||||
packet.setProperty("l", dataWatcher)
|
||||
|
||||
viewers.forEach { it.sendPacket(packet) }
|
||||
}
|
||||
|
||||
open fun addViewer(viewer: Player) {
|
||||
viewers.add(viewer)
|
||||
spawnForPlayer(viewer)
|
||||
}
|
||||
|
||||
open fun removeViewer(viewer: Player) {
|
||||
viewer.sendPacket(PacketPlayOutEntityDestroy(entityID))
|
||||
viewers.remove(viewer)
|
||||
}
|
||||
|
||||
fun update() {
|
||||
val packet = PacketPlayOutEntityMetadata(entityID, dataWatcher, true)
|
||||
viewers.forEach { it.sendPacket(packet) }
|
||||
}
|
||||
|
||||
fun updateData(toDo: DataWatcher.() -> Unit) {
|
||||
toDo(dataWatcher)
|
||||
update()
|
||||
}
|
||||
|
||||
fun hurtAnimate() {
|
||||
PacketPlayOutEntityStatus().apply {
|
||||
setProperty("a", entityID)
|
||||
setProperty("b", 2.toByte())
|
||||
}.let { viewers.forEach { p -> p.sendPacket(it) } }
|
||||
}
|
||||
|
||||
fun dieAnimate() {
|
||||
PacketPlayOutEntityStatus().apply {
|
||||
setProperty("a", entityID)
|
||||
setProperty("b", 3.toByte())
|
||||
}.let { viewers.forEach { p -> p.sendPacket(it) } }
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val incrementEntityID = AtomicInteger(197827 + random(0, 549))
|
||||
|
||||
fun getEID() = incrementEntityID.addAndGet(1)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
package cc.maxmc.blastingcrisis.packet
|
||||
|
||||
import net.minecraft.server.v1_8_R3.DataWatcher
|
||||
import net.minecraft.server.v1_8_R3.MathHelper
|
||||
import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntity
|
||||
import org.bukkit.Location
|
||||
import org.bukkit.entity.Player
|
||||
import taboolib.library.reflex.Reflex.Companion.setProperty
|
||||
import taboolib.module.nms.sendPacket
|
||||
import kotlin.experimental.or
|
||||
|
||||
class BEntityNameTag(loc: Location) : BEntity(loc, 78) {
|
||||
var name: String = ""
|
||||
set(name) {
|
||||
updateData {
|
||||
getWatchableObject(2).a(name)
|
||||
}
|
||||
}
|
||||
|
||||
override fun DataWatcher.initEntity() {
|
||||
getWatchableObject(0).a(getByte(0) or 0x20)
|
||||
getWatchableObject(2).a("")
|
||||
getWatchableObject(3).a(1.toByte())
|
||||
}
|
||||
|
||||
override fun spawnForPlayer(player: Player) {
|
||||
val packet = PacketPlayOutSpawnEntity()
|
||||
packet.apply {
|
||||
setProperty("a", entityID)
|
||||
setProperty("b", MathHelper.floor(loc.x * 32.0))
|
||||
setProperty("c", MathHelper.floor(loc.y * 32.0))
|
||||
setProperty("d", MathHelper.floor(loc.z * 32.0))
|
||||
setProperty("e", 0)
|
||||
setProperty("f", 0)
|
||||
setProperty("g", 0)
|
||||
setProperty("h", 0)
|
||||
setProperty("i", 0)
|
||||
setProperty("j", entityType)
|
||||
setProperty("k", 0)
|
||||
}
|
||||
|
||||
player.sendPacket(packet)
|
||||
update()
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
package cc.maxmc.blastingcrisis.packet
|
||||
|
||||
import net.minecraft.server.v1_8_R3.DataWatcher
|
||||
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityStatus
|
||||
import org.bukkit.Location
|
||||
import org.bukkit.entity.Player
|
||||
import taboolib.library.reflex.Reflex.Companion.setProperty
|
||||
|
||||
class BEntityVillager(loc: Location) : BEntity(loc, 120) {
|
||||
var name: String
|
||||
get() = nameTag.name
|
||||
set(name) {
|
||||
nameTag.name = name
|
||||
}
|
||||
|
||||
private val nameTag = BEntityNameTag(loc)
|
||||
|
||||
override fun addViewer(viewer: Player) {
|
||||
super.addViewer(viewer)
|
||||
nameTag.addViewer(viewer)
|
||||
}
|
||||
|
||||
override fun spawnForPlayer(player: Player) {
|
||||
super.spawnForPlayer(player)
|
||||
nameTag.spawnForPlayer(player)
|
||||
}
|
||||
|
||||
override fun removeViewer(viewer: Player) {
|
||||
super.removeViewer(viewer)
|
||||
nameTag.removeViewer(viewer)
|
||||
}
|
||||
|
||||
override fun DataWatcher.initEntity() {
|
||||
a(6, 1.0f) // Health
|
||||
a(7, 0) // Potion Effect Color
|
||||
a(8, 0.toByte()) // Is Potion Effect Ambient
|
||||
a(9, 0.toByte()) // Number of Arrows in Entity
|
||||
a(12, 1.toByte()) // Age (0 - child, 1 - adult)
|
||||
a(15, 0.toByte()) // AI
|
||||
/*
|
||||
0 Farmer
|
||||
1 Librarian
|
||||
2 Priest
|
||||
3 Blacksmith
|
||||
4 Butcher
|
||||
*/
|
||||
a(16, 0) // Villager Type
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package cc.maxmc.blastingcrisis.packet
|
||||
|
||||
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<DataWatcher.WatchableObject>("j", id) ?: throw IllegalStateException("Object not exists.")
|
||||
|
||||
|
|
@ -5,4 +5,39 @@ scoreboard_waiting: |-
|
|||
|
||||
§a| §7等待中...
|
||||
|
||||
§aplay.maxmc.cc
|
||||
§6Play.MaxMC.cc
|
||||
scoreboard_counting_down: |-
|
||||
§6Blasting§7Crisis
|
||||
|
||||
§a| §7当前玩家: §a{0}/{1}
|
||||
|
||||
§a| §7游戏还有 §a{2} §7秒开始.
|
||||
|
||||
§6Play.MaxMC.cc
|
||||
game_countdown_15:
|
||||
- "§e| §7游戏还有 §e15 §7秒开始."
|
||||
game_countdown_10:
|
||||
- type: title
|
||||
title: "§c10"
|
||||
- "§e| §7游戏还有 §e10 §7秒开始."
|
||||
game_countdown_5:
|
||||
- type: title
|
||||
title: "§c5"
|
||||
- "§e| §7游戏还有 §e5 §7秒开始."
|
||||
game_countdown_3:
|
||||
- type: title
|
||||
title: "§c3"
|
||||
- "§e| §7游戏还有 §e3 §7秒开始."
|
||||
game_countdown_2:
|
||||
- type: title
|
||||
title: "§e2"
|
||||
- "§e| §7游戏还有 §e2 §7秒开始."
|
||||
game_countdown_1:
|
||||
- type: title
|
||||
title: "§a1"
|
||||
- "§e| §7游戏还有 §e1 §7秒开始."
|
||||
game_countdown_reset:
|
||||
- type: title
|
||||
text: "§c人数不足"
|
||||
- "§c| §7由于人数不足, 无法开始游戏."
|
||||
game_join: "§a| §7玩家 §a{0} §7加入了游戏"
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
rate: 20 # tick per generate
|
||||
ores:
|
||||
# ORE: weight
|
||||
COAL_ORE: 50
|
||||
IRON_ORE: 25
|
||||
REDSTONE_ORE: 15
|
||||
DIAMOND_ORE: 10
|
||||
EMERALD_ORE: 5
|
||||
Loading…
Reference in New Issue