Move black hole block entity to field synchronizer
This commit is contained in:
parent
284e4d404a
commit
60cd9d5bef
@ -34,7 +34,7 @@ import ru.dbotthepony.mc.otm.network.FieldSynchronizer
|
||||
import ru.dbotthepony.mc.otm.network.WorldNetworkChannel
|
||||
import ru.dbotthepony.mc.otm.oncePre
|
||||
|
||||
abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: BlockPos, p_155230_: BlockState) : BlockEntity(p_155228_, p_155229_, p_155230_), MenuProvider {
|
||||
abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: BlockPos, p_155230_: BlockState) : SynchronizedBlockEntity(p_155228_, p_155229_, p_155230_), MenuProvider {
|
||||
var customDisplayName: Component? = null
|
||||
var redstoneSignal = 0
|
||||
set(level) {
|
||||
@ -74,52 +74,6 @@ abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: Bloc
|
||||
}
|
||||
}
|
||||
|
||||
val synchronizer = FieldSynchronizer()
|
||||
|
||||
init {
|
||||
synchronizer.defaultEndpoint.markUnused()
|
||||
}
|
||||
|
||||
open val synchronizationRadius: Double = 32.0
|
||||
|
||||
// TODO: Optimize, if required
|
||||
fun synchronizeToPlayers() {
|
||||
if (synchronizationRadius <= 0.0 || synchronizer.isEmpty) {
|
||||
return
|
||||
}
|
||||
|
||||
val server = level?.server ?: return
|
||||
|
||||
if (server.playerCount <= 0) {
|
||||
return
|
||||
}
|
||||
|
||||
val (xi, yi, zi) = blockPos
|
||||
val bx = xi + 0.5
|
||||
val by = yi + 0.5
|
||||
val bz = zi + 0.5
|
||||
|
||||
val double = synchronizationRadius * synchronizationRadius
|
||||
|
||||
server.playerList.players.stream().filter {
|
||||
if (!it.isAlive || it.level != level) {
|
||||
return@filter false
|
||||
}
|
||||
|
||||
val (x, y, z) = it.position
|
||||
|
||||
(x - bx) * (x - bx) +
|
||||
(y - by) * (y - by) +
|
||||
(z - bz) * (z - bz) <= double
|
||||
}.forEach {
|
||||
val payload = synchronizer.computeEndpointFor(it).collectNetworkPayload()
|
||||
|
||||
if (payload != null) {
|
||||
WorldNetworkChannel.send(it, BlockEntitySyncPacket(blockPos, payload.array, payload.length))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected open val defaultDisplayName: Component
|
||||
get() = level?.getBlockState(blockPos)?.block?.name ?: TextComponent("null at $blockPos")
|
||||
|
||||
|
@ -0,0 +1,62 @@
|
||||
package ru.dbotthepony.mc.otm.block.entity
|
||||
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.world.level.block.entity.BlockEntity
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import ru.dbotthepony.mc.otm.core.component1
|
||||
import ru.dbotthepony.mc.otm.core.component2
|
||||
import ru.dbotthepony.mc.otm.core.component3
|
||||
import ru.dbotthepony.mc.otm.core.position
|
||||
import ru.dbotthepony.mc.otm.network.BlockEntitySyncPacket
|
||||
import ru.dbotthepony.mc.otm.network.FieldSynchronizer
|
||||
import ru.dbotthepony.mc.otm.network.WorldNetworkChannel
|
||||
|
||||
abstract class SynchronizedBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: BlockPos, p_155230_: BlockState) : BlockEntity(p_155228_, p_155229_, p_155230_) {
|
||||
val synchronizer = FieldSynchronizer()
|
||||
|
||||
init {
|
||||
synchronizer.defaultEndpoint.markUnused()
|
||||
}
|
||||
|
||||
open val synchronizationRadius: Double = 32.0
|
||||
|
||||
// TODO: Optimize, if required
|
||||
fun synchronizeToPlayers() {
|
||||
if (synchronizationRadius <= 0.0 || synchronizer.isEmpty) {
|
||||
return
|
||||
}
|
||||
|
||||
val server = level?.server ?: return
|
||||
|
||||
if (server.playerCount <= 0) {
|
||||
return
|
||||
}
|
||||
|
||||
val (xi, yi, zi) = blockPos
|
||||
val bx = xi + 0.5
|
||||
val by = yi + 0.5
|
||||
val bz = zi + 0.5
|
||||
|
||||
val double = synchronizationRadius * synchronizationRadius
|
||||
|
||||
server.playerList.players.stream().filter {
|
||||
if (!it.isAlive || it.level != level) {
|
||||
return@filter false
|
||||
}
|
||||
|
||||
val (x, y, z) = it.position
|
||||
|
||||
(x - bx) * (x - bx) +
|
||||
(y - by) * (y - by) +
|
||||
(z - bz) * (z - bz) <= double
|
||||
}.forEach {
|
||||
val payload = synchronizer.computeEndpointFor(it).collectNetworkPayload()
|
||||
|
||||
if (payload != null) {
|
||||
WorldNetworkChannel.send(it, BlockEntitySyncPacket(blockPos, payload.array, payload.length))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -24,6 +24,7 @@ import net.minecraft.world.phys.AABB
|
||||
import net.minecraft.world.phys.Vec3
|
||||
import ru.dbotthepony.mc.otm.block.BlackHoleBlock
|
||||
import ru.dbotthepony.mc.otm.block.entity.GravitationStabilizerBlockEntity
|
||||
import ru.dbotthepony.mc.otm.block.entity.SynchronizedBlockEntity
|
||||
import ru.dbotthepony.mc.otm.block.entity.blackhole.ExplosionQueue.Companion.queueForLevel
|
||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||
import ru.dbotthepony.mc.otm.core.plus
|
||||
@ -32,55 +33,53 @@ import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||
import ru.dbotthepony.mc.otm.registry.MItems
|
||||
import ru.dbotthepony.mc.otm.registry.MRegistry
|
||||
import ru.dbotthepony.mc.otm.core.getSphericalBlockPositions
|
||||
import ru.dbotthepony.mc.otm.core.mapIf
|
||||
import ru.dbotthepony.mc.otm.core.set
|
||||
import kotlin.math.pow
|
||||
import kotlin.math.roundToInt
|
||||
import kotlin.math.sqrt
|
||||
|
||||
class BlackHoleBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : BlockEntity(MBlockEntities.BLACK_HOLE, p_155229_, p_155230_) {
|
||||
var mass = BASELINE_MASS
|
||||
set(mass) {
|
||||
if (mass <= ImpreciseFraction.ZERO) {
|
||||
collapse()
|
||||
return
|
||||
}
|
||||
|
||||
field = mass
|
||||
|
||||
setChanged()
|
||||
|
||||
var massForDiv = mass
|
||||
|
||||
when (if (level?.isClientSide == false) stabilizers.size else stabilizerClientCount) {
|
||||
1 -> {massForDiv /= 4}
|
||||
2 -> {massForDiv /= 16}
|
||||
3 -> {massForDiv /= 64}
|
||||
4 -> {massForDiv /= 512}
|
||||
5 -> {massForDiv /= 2048}
|
||||
6 -> {massForDiv /= 16384}
|
||||
}
|
||||
|
||||
gravitationStrength = sqrt(massForDiv.div(BASELINE_MASS).toDouble()).coerceAtMost(20.0).coerceAtLeast(0.2)
|
||||
|
||||
val level = level
|
||||
|
||||
if (level != null && !level.isClientSide && !suppressUpdates)
|
||||
level.sendBlockUpdated(blockPos, blockState, blockState, Block.UPDATE_CLIENTS)
|
||||
|
||||
affectedBounds = BoundingBox(
|
||||
(-30 * gravitationStrength).toInt(),
|
||||
(-30 * gravitationStrength).toInt(),
|
||||
(-30 * gravitationStrength).toInt(),
|
||||
(30 * gravitationStrength).toInt(),
|
||||
(30 * gravitationStrength).toInt(),
|
||||
(30 * gravitationStrength).toInt()
|
||||
).move(
|
||||
blockPos
|
||||
)
|
||||
|
||||
affectedBoundsAABB = AABB.of(affectedBounds)
|
||||
class BlackHoleBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : SynchronizedBlockEntity(MBlockEntities.BLACK_HOLE, p_155229_, p_155230_) {
|
||||
var mass by synchronizer.fraction(BASELINE_MASS, setter = setter@{ mass, field, setByRemote ->
|
||||
if (mass <= ImpreciseFraction.ZERO) {
|
||||
collapse()
|
||||
return@setter
|
||||
}
|
||||
|
||||
field.write(mass)
|
||||
setChanged()
|
||||
var massForDiv = mass
|
||||
|
||||
when (if (level?.isClientSide == false) stabilizers.size else stabilizerClientCount) {
|
||||
1 -> {massForDiv /= 4}
|
||||
2 -> {massForDiv /= 16}
|
||||
3 -> {massForDiv /= 64}
|
||||
4 -> {massForDiv /= 512}
|
||||
5 -> {massForDiv /= 2048}
|
||||
6 -> {massForDiv /= 16384}
|
||||
}
|
||||
|
||||
gravitationStrength = sqrt(massForDiv.div(BASELINE_MASS).toDouble()).coerceAtMost(20.0).coerceAtLeast(0.2)
|
||||
|
||||
val level = level
|
||||
|
||||
if (level != null && !level.isClientSide && !suppressUpdates)
|
||||
level.sendBlockUpdated(blockPos, blockState, blockState, Block.UPDATE_CLIENTS)
|
||||
|
||||
affectedBounds = BoundingBox(
|
||||
(-30 * gravitationStrength).toInt(),
|
||||
(-30 * gravitationStrength).toInt(),
|
||||
(-30 * gravitationStrength).toInt(),
|
||||
(30 * gravitationStrength).toInt(),
|
||||
(30 * gravitationStrength).toInt(),
|
||||
(30 * gravitationStrength).toInt()
|
||||
).moved(
|
||||
blockPos.x, blockPos.y, blockPos.z
|
||||
)
|
||||
|
||||
affectedBoundsAABB = AABB.of(affectedBounds)
|
||||
})
|
||||
|
||||
override fun getRenderBoundingBox(): AABB {
|
||||
return AABB(blockPos.offset(-GravitationStabilizerBlockEntity.RANGE, -GravitationStabilizerBlockEntity.RANGE, -GravitationStabilizerBlockEntity.RANGE), blockPos.offset(GravitationStabilizerBlockEntity.RANGE, GravitationStabilizerBlockEntity.RANGE, GravitationStabilizerBlockEntity.RANGE))
|
||||
}
|
||||
@ -152,59 +151,18 @@ class BlackHoleBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : BlockEn
|
||||
}
|
||||
}
|
||||
|
||||
// shared functions
|
||||
fun writeBlackHoleData(tag: CompoundTag): CompoundTag {
|
||||
tag["mass"] = mass.serializeNBT()
|
||||
tag["spin_direction"] = spin_direction
|
||||
return tag
|
||||
}
|
||||
|
||||
fun readBlackHoleData(tag: CompoundTag) {
|
||||
tag["mass"]?.let {
|
||||
mass = ImpreciseFraction.deserializeNBT(it)
|
||||
}
|
||||
|
||||
spin_direction = tag.getBoolean("spin_direction")
|
||||
}
|
||||
|
||||
// disk io
|
||||
public override fun saveAdditional(nbt: CompoundTag) {
|
||||
super.saveAdditional(nbt)
|
||||
writeBlackHoleData(nbt)
|
||||
nbt["mass"] = mass.serializeNBT()
|
||||
nbt["spin_direction"] = spin_direction
|
||||
}
|
||||
|
||||
override val synchronizationRadius: Double = 256.0
|
||||
|
||||
override fun load(tag: CompoundTag) {
|
||||
super.load(tag)
|
||||
readBlackHoleData(tag)
|
||||
}
|
||||
|
||||
// received either by game engine (from getUpdateTag on ClientLevelPacket)
|
||||
// or by onDataPacket
|
||||
override fun handleUpdateTag(tag: CompoundTag) {
|
||||
stabilizerClientCount = (tag["stabilizers"] as IntTag).asInt
|
||||
super.handleUpdateTag(tag)
|
||||
readBlackHoleData(tag)
|
||||
}
|
||||
|
||||
// called by game engine for ClientLevelPacket
|
||||
override fun getUpdateTag(): CompoundTag {
|
||||
return writeBlackHoleData(super.getUpdateTag()).also {
|
||||
it["stabilizers"] = stabilizers.size
|
||||
}
|
||||
}
|
||||
|
||||
// called by game engine on block updates
|
||||
override fun getUpdatePacket(): ClientboundBlockEntityDataPacket? {
|
||||
return ClientboundBlockEntityDataPacket.create(this)
|
||||
}
|
||||
|
||||
// called by game engine by forge patches when ClientboundBlockEntityDataPacket is received
|
||||
override fun onDataPacket(net: Connection, pkt: ClientboundBlockEntityDataPacket) {
|
||||
super.onDataPacket(net, pkt)
|
||||
|
||||
if (net.receiving == PacketFlow.CLIENTBOUND) {
|
||||
handleUpdateTag(pkt.tag!!)
|
||||
}
|
||||
mass = tag.mapIf("mass", ImpreciseFraction::deserializeNBT) ?: BASELINE_MASS
|
||||
spin_direction = tag.getBoolean("spin_direction")
|
||||
}
|
||||
|
||||
var affectedBounds = BoundingBox(0, 0, 0, 1, 1, 1)
|
||||
@ -255,6 +213,8 @@ class BlackHoleBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : BlockEn
|
||||
}
|
||||
|
||||
fun tick() {
|
||||
synchronizeToPlayers()
|
||||
|
||||
sleepTicks--
|
||||
if (sleepTicks > 0) return
|
||||
val level = level as? ServerLevel ?: return
|
||||
@ -365,4 +325,4 @@ class BlackHoleBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : BlockEn
|
||||
val BASELINE_MASS = ImpreciseFraction(1_000)
|
||||
val HAWKING_MASS_LOSE_STEP = ImpreciseFraction("-0.1")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import net.minecraft.network.FriendlyByteBuf
|
||||
import net.minecraftforge.network.NetworkDirection
|
||||
import net.minecraftforge.network.NetworkEvent
|
||||
import ru.dbotthepony.mc.otm.android.feature.ItemEntityDataPacket
|
||||
import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity
|
||||
import ru.dbotthepony.mc.otm.block.entity.SynchronizedBlockEntity
|
||||
import ru.dbotthepony.mc.otm.client.minecraft
|
||||
import java.util.function.Supplier
|
||||
|
||||
@ -21,7 +21,7 @@ class BlockEntitySyncPacket(val position: BlockPos, val buffer: ByteArray, val v
|
||||
|
||||
context.enqueueWork {
|
||||
val level = minecraft.player?.level ?: return@enqueueWork
|
||||
val blockEntity = level.getBlockEntity(position) as? MatteryBlockEntity ?: return@enqueueWork
|
||||
val blockEntity = level.getBlockEntity(position) as? SynchronizedBlockEntity ?: return@enqueueWork
|
||||
blockEntity.synchronizer.applyNetworkPayload(FastByteArrayInputStream(buffer, 0, validBytes))
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user