123 lines
3.9 KiB
Kotlin
123 lines
3.9 KiB
Kotlin
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.*
|
|
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>()
|
|
val interactHandlers = ArrayList<(BEntityInteract) -> Unit>()
|
|
|
|
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 destroy() {
|
|
ArrayList(viewers).forEach { removeViewer(it) }
|
|
}
|
|
|
|
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() {
|
|
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) } }
|
|
}
|
|
|
|
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))
|
|
|
|
fun getEID() = incrementEntityID.addAndGet(1)
|
|
}
|
|
} |