feat: custom projection radius

This commit is contained in:
xtex 2023-08-01 14:44:11 +08:00
parent e18b4d78fb
commit c6edaac2e1
Signed by: xtex
GPG Key ID: B918086ED8045B91
2 changed files with 23 additions and 18 deletions

View File

@ -34,7 +34,7 @@ object Projector {
fun findNearbyProjectors(level: Level, pos: BlockPos) = level.getChunksNearby(pos, currentEffectRadius) fun findNearbyProjectors(level: Level, pos: BlockPos) = level.getChunksNearby(pos, currentEffectRadius)
.flatMap { .flatMap {
it.blockEntities.filter { (_, v) -> v is ProjectorBlockEntity } it.blockEntities.filter { (_, v) -> v is ProjectorBlockEntity && pos in v }
.keys .keys
.filterNotNull() .filterNotNull()
} }

View File

@ -1,6 +1,7 @@
package quaedam.projector package quaedam.projector
import net.minecraft.core.BlockPos import net.minecraft.core.BlockPos
import net.minecraft.core.SectionPos
import net.minecraft.core.Vec3i import net.minecraft.core.Vec3i
import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.CompoundTag
import net.minecraft.network.protocol.Packet import net.minecraft.network.protocol.Packet
@ -17,32 +18,23 @@ import quaedam.projection.ProjectionEffect
import quaedam.projection.ProjectionEffectType import quaedam.projection.ProjectionEffectType
import quaedam.projection.ProjectionProvider import quaedam.projection.ProjectionProvider
import quaedam.utils.sendBlockUpdated import quaedam.utils.sendBlockUpdated
import kotlin.math.max
import kotlin.math.min
class ProjectorBlockEntity(pos: BlockPos, state: BlockState) : class ProjectorBlockEntity(pos: BlockPos, state: BlockState) :
BlockEntity(Projector.blockEntity.get(), pos, state) { BlockEntity(Projector.blockEntity.get(), pos, state) {
companion object { companion object {
const val TAG_EFFECT_RADIUS = "EffectRadius"
const val TAG_PROJECTION_EFFECTS = "ProjectionEffects" const val TAG_PROJECTION_EFFECTS = "ProjectionEffects"
} }
val effectAreaChunk by lazy { var effectRadius: Int = 0
val chunk = level!!.getChunk(pos).pos lateinit var effectArea: BoundingBox
ChunkPos(chunk.x - Projector.currentEffectRadius, chunk.z - Projector.currentEffectRadius) to lateinit var effectAreaAABB: AABB
ChunkPos(chunk.x + Projector.currentEffectRadius, chunk.z + Projector.currentEffectRadius)
}
val effectArea: BoundingBox by lazy { init {
val (minChunk, maxChunk) = effectAreaChunk updateEffectArea(Projector.currentEffectRadius)
val minBlock = BlockPos(minChunk.minBlockX, level!!.minBuildHeight, minChunk.minBlockZ)
val maxBlock = BlockPos(maxChunk.maxBlockX, level!!.maxBuildHeight, maxChunk.maxBlockZ)
BoundingBox.fromCorners(minBlock, maxBlock)
}
val effectAreaAABB by lazy {
val (minChunk, maxChunk) = effectAreaChunk
val minBlock = BlockPos(minChunk.minBlockX, level!!.minBuildHeight, minChunk.minBlockZ)
val maxBlock = BlockPos(maxChunk.maxBlockX, level!!.maxBuildHeight, maxChunk.maxBlockZ)
AABB(minBlock, maxBlock)
} }
val checkArea: BoundingBox by lazy { val checkArea: BoundingBox by lazy {
@ -57,11 +49,13 @@ class ProjectorBlockEntity(pos: BlockPos, state: BlockState) :
effects.map { (type, effect) -> effects.map { (type, effect) ->
effectsTag.put(type.id.toString(), effect.toNbt()) effectsTag.put(type.id.toString(), effect.toNbt())
} }
tag.putInt(TAG_EFFECT_RADIUS, effectRadius)
tag.put(TAG_PROJECTION_EFFECTS, effectsTag) tag.put(TAG_PROJECTION_EFFECTS, effectsTag)
} }
override fun load(tag: CompoundTag) { override fun load(tag: CompoundTag) {
super.load(tag) super.load(tag)
updateEffectArea(max(min(tag.getInt(TAG_EFFECT_RADIUS), Projector.currentEffectRadius), 0))
val effectsTag = tag[TAG_PROJECTION_EFFECTS] val effectsTag = tag[TAG_PROJECTION_EFFECTS]
val effects = mutableMapOf<ProjectionEffectType<*>, ProjectionEffect>() val effects = mutableMapOf<ProjectionEffectType<*>, ProjectionEffect>()
if (effectsTag != null && effectsTag is CompoundTag) { if (effectsTag != null && effectsTag is CompoundTag) {
@ -76,6 +70,17 @@ class ProjectorBlockEntity(pos: BlockPos, state: BlockState) :
updateEffects(effects, notify = false) updateEffects(effects, notify = false)
} }
private fun updateEffectArea(radius: Int) {
effectRadius = radius
val chunk = ChunkPos(SectionPos.blockToSectionCoord(blockPos.x), SectionPos.blockToSectionCoord(blockPos.z))
val minChunk = ChunkPos(chunk.x - radius, chunk.z - radius)
val maxChunk = ChunkPos(chunk.x + radius, chunk.z + radius)
val minBlock = BlockPos(minChunk.minBlockX, Int.MIN_VALUE, minChunk.minBlockZ)
val maxBlock = BlockPos(maxChunk.maxBlockX, Int.MAX_VALUE, maxChunk.maxBlockZ)
effectArea = BoundingBox.fromCorners(minBlock, maxBlock)
effectAreaAABB = AABB(minBlock, maxBlock)
}
override fun getUpdateTag(): CompoundTag = saveWithoutMetadata() override fun getUpdateTag(): CompoundTag = saveWithoutMetadata()
override fun getUpdatePacket(): Packet<ClientGamePacketListener> = ClientboundBlockEntityDataPacket.create(this) override fun getUpdatePacket(): Packet<ClientGamePacketListener> = ClientboundBlockEntityDataPacket.create(this)