refactor: block entity based projection block
This commit is contained in:
parent
82de489963
commit
c80859d643
@ -9,7 +9,8 @@ import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.world.item.CreativeModeTab
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import org.slf4j.LoggerFactory
|
||||
import quaedam.projection.*
|
||||
import quaedam.projection.ProjectionCommand
|
||||
import quaedam.projection.ProjectionEffectType
|
||||
import quaedam.projection.misc.NoiseProjection
|
||||
import quaedam.projection.misc.SkylightProjection
|
||||
import quaedam.projection.misc.SoundProjection
|
||||
|
@ -1,59 +1,32 @@
|
||||
package quaedam.projection
|
||||
|
||||
import dev.architectury.registry.registries.DeferredSupplier
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.world.level.Level
|
||||
import net.minecraft.world.level.LevelAccessor
|
||||
import net.minecraft.world.level.block.Block
|
||||
import net.minecraft.world.level.block.EntityBlock
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import net.minecraft.world.level.material.MapColor
|
||||
import net.minecraft.world.level.storage.loot.LootParams
|
||||
import quaedam.projector.ProjectorBlockEntity
|
||||
import quaedam.utils.getChunksNearby
|
||||
|
||||
abstract class EntityProjectionBlock<P : ProjectionEffect>(properties: Properties = createProperties()) : Block(properties),
|
||||
ProjectionProvider<P> {
|
||||
abstract class EntityProjectionBlock<P : ProjectionEffect>(properties: Properties = createProperties()) :
|
||||
ProjectionBlock<P>(properties), EntityBlock {
|
||||
|
||||
companion object {
|
||||
fun createProperties(): Properties = Properties.of()
|
||||
.strength(3.5f)
|
||||
.requiresCorrectToolForDrops()
|
||||
.mapColor(MapColor.COLOR_GRAY)
|
||||
|
||||
fun findNearbyProjectors(level: Level, pos: BlockPos) = level.getChunksNearby(pos, 1)
|
||||
.flatMap {
|
||||
it.blockEntities.filter { (_, v) -> v is ProjectorBlockEntity }
|
||||
.keys
|
||||
.filterNotNull()
|
||||
}
|
||||
.toSet()
|
||||
|
||||
fun createProperties(): Properties = ProjectionBlock.createProperties()
|
||||
}
|
||||
|
||||
@Suppress("OVERRIDE_DEPRECATION")
|
||||
override fun getDrops(blockState: BlockState, builder: LootParams.Builder) = listOf(ItemStack(asItem()))
|
||||
abstract val blockEntity: DeferredSupplier<BlockEntityType<SimpleProjectionEntity<P>>>
|
||||
|
||||
override fun setPlacedBy(
|
||||
level: Level,
|
||||
pos: BlockPos,
|
||||
state: BlockState,
|
||||
placer: LivingEntity?,
|
||||
itemStack: ItemStack
|
||||
) {
|
||||
super.setPlacedBy(level, pos, state, placer, itemStack)
|
||||
if (!level.isClientSide) {
|
||||
findNearbyProjectors(level, pos)
|
||||
.forEach { (level.getBlockEntity(it) as ProjectorBlockEntity).checkUpdate() }
|
||||
}
|
||||
}
|
||||
override fun newBlockEntity(pos: BlockPos, state: BlockState) = blockEntity.get().create(pos, state)
|
||||
|
||||
override fun destroy(level: LevelAccessor, pos: BlockPos, state: BlockState) {
|
||||
super.destroy(level, pos, state)
|
||||
if (level is Level && !level.isClientSide) {
|
||||
findNearbyProjectors(level, pos)
|
||||
.forEach { (level.getBlockEntity(it) as ProjectorBlockEntity).checkUpdate() }
|
||||
}
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun getProjection(level: Level, pos: BlockPos) = (level.getBlockEntity(pos) as SimpleProjectionEntity<P>).projection
|
||||
|
||||
override fun applyProjectionEffect(level: ServerLevel, state: BlockState, pos: BlockPos) = getProjection(level, pos)
|
||||
|
||||
inline fun applyChange(level: Level, pos: BlockPos, func: P.() -> Unit) {
|
||||
getProjection(level, pos).apply(func)
|
||||
sendUpdateToProjectors(level, pos)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -42,18 +42,21 @@ abstract class ProjectionBlock<P : ProjectionEffect>(properties: Properties = cr
|
||||
itemStack: ItemStack
|
||||
) {
|
||||
super.setPlacedBy(level, pos, state, placer, itemStack)
|
||||
sendUpdateToProjectors(level, pos)
|
||||
}
|
||||
|
||||
override fun destroy(level: LevelAccessor, pos: BlockPos, state: BlockState) {
|
||||
super.destroy(level, pos, state)
|
||||
if (level is Level) {
|
||||
sendUpdateToProjectors(level, pos)
|
||||
}
|
||||
}
|
||||
|
||||
fun sendUpdateToProjectors(level: Level, pos: BlockPos) {
|
||||
if (!level.isClientSide) {
|
||||
findNearbyProjectors(level, pos)
|
||||
.forEach { (level.getBlockEntity(it) as ProjectorBlockEntity).checkUpdate() }
|
||||
}
|
||||
}
|
||||
|
||||
override fun destroy(level: LevelAccessor, pos: BlockPos, state: BlockState) {
|
||||
super.destroy(level, pos, state)
|
||||
if (level is Level && !level.isClientSide) {
|
||||
findNearbyProjectors(level, pos)
|
||||
.forEach { (level.getBlockEntity(it) as ProjectorBlockEntity).checkUpdate() }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -57,5 +57,5 @@ data class ProjectionEffectType<T : ProjectionEffect>(val constructor: () -> T)
|
||||
}
|
||||
|
||||
interface ProjectionProvider<P : ProjectionEffect> {
|
||||
fun createProjectionEffect(level: ServerLevel, state: BlockState, pos: BlockPos): P?
|
||||
fun applyProjectionEffect(level: ServerLevel, state: BlockState, pos: BlockPos): P?
|
||||
}
|
||||
|
@ -0,0 +1,51 @@
|
||||
package quaedam.projection
|
||||
|
||||
import dev.architectury.registry.registries.RegistrySupplier
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.network.protocol.Packet
|
||||
import net.minecraft.network.protocol.game.ClientGamePacketListener
|
||||
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket
|
||||
import net.minecraft.world.level.block.entity.BlockEntity
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
|
||||
class SimpleProjectionEntity<P : ProjectionEffect>(
|
||||
type: BlockEntityType<SimpleProjectionEntity<P>>,
|
||||
pos: BlockPos,
|
||||
state: BlockState,
|
||||
val projection: P
|
||||
) : BlockEntity(type, pos, state) {
|
||||
|
||||
companion object {
|
||||
const val TAG_PROJECTION_EFFECT = "ProjectionEffect"
|
||||
|
||||
fun <P : ProjectionEffect, B: ProjectionBlock<P>> createBlockEntityType(
|
||||
block: RegistrySupplier<B>,
|
||||
default: () -> P,
|
||||
): BlockEntityType<SimpleProjectionEntity<P>> {
|
||||
val type = ValueContainer<BlockEntityType<SimpleProjectionEntity<P>>>()
|
||||
type.inner = BlockEntityType.Builder.of({ pos, state ->
|
||||
SimpleProjectionEntity(type.inner!!, pos, state, default())
|
||||
}, block.get()).build(null)
|
||||
return type.inner!!
|
||||
}
|
||||
}
|
||||
|
||||
data class ValueContainer<E>(var inner: E? = null)
|
||||
|
||||
override fun saveAdditional(tag: CompoundTag) {
|
||||
super.saveAdditional(tag)
|
||||
tag.put(TAG_PROJECTION_EFFECT, projection.toNbt())
|
||||
}
|
||||
|
||||
override fun load(tag: CompoundTag) {
|
||||
super.load(tag)
|
||||
projection.fromNbt(tag.getCompound(TAG_PROJECTION_EFFECT))
|
||||
}
|
||||
|
||||
override fun getUpdateTag(): CompoundTag = saveWithoutMetadata()
|
||||
|
||||
override fun getUpdatePacket(): Packet<ClientGamePacketListener> = ClientboundBlockEntityDataPacket.create(this)
|
||||
|
||||
}
|
@ -1,15 +1,13 @@
|
||||
package quaedam.projection.misc
|
||||
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.world.item.BlockItem
|
||||
import net.minecraft.world.item.Item
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import quaedam.Quaedam
|
||||
import quaedam.projection.ProjectionBlock
|
||||
import quaedam.projection.EntityProjectionBlock
|
||||
import quaedam.projection.ProjectionEffect
|
||||
import quaedam.projection.ProjectionEffectType
|
||||
import quaedam.projection.SimpleProjectionEntity
|
||||
|
||||
object NoiseProjection {
|
||||
|
||||
@ -29,15 +27,15 @@ object NoiseProjection {
|
||||
ProjectionEffectType { NoiseProjectionEffect() }
|
||||
}!!
|
||||
|
||||
val blockEntity = Quaedam.blockEntities.register(ID) {
|
||||
SimpleProjectionEntity.createBlockEntityType(block, ::NoiseProjectionEffect)
|
||||
}!!
|
||||
|
||||
}
|
||||
|
||||
object NoiseProjectionBlock : ProjectionBlock<NoiseProjectionEffect>(createProperties().lightLevel { 3 }) {
|
||||
object NoiseProjectionBlock : EntityProjectionBlock<NoiseProjectionEffect>(createProperties().lightLevel { 3 }) {
|
||||
|
||||
override fun createProjectionEffect(
|
||||
level: ServerLevel,
|
||||
state: BlockState,
|
||||
pos: BlockPos
|
||||
) = NoiseProjectionEffect()
|
||||
override val blockEntity = NoiseProjection.blockEntity
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,15 +1,13 @@
|
||||
package quaedam.projection.misc
|
||||
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.world.item.BlockItem
|
||||
import net.minecraft.world.item.Item
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import quaedam.Quaedam
|
||||
import quaedam.projection.ProjectionBlock
|
||||
import quaedam.projection.EntityProjectionBlock
|
||||
import quaedam.projection.ProjectionEffect
|
||||
import quaedam.projection.ProjectionEffectType
|
||||
import quaedam.projection.SimpleProjectionEntity
|
||||
|
||||
object SkylightProjection {
|
||||
|
||||
@ -29,15 +27,15 @@ object SkylightProjection {
|
||||
ProjectionEffectType { SkylightProjectionEffect() }
|
||||
}!!
|
||||
|
||||
val blockEntity = Quaedam.blockEntities.register(ID) {
|
||||
SimpleProjectionEntity.createBlockEntityType(block, ::SkylightProjectionEffect)
|
||||
}!!
|
||||
|
||||
}
|
||||
|
||||
object SkylightProjectionBlock : ProjectionBlock<SkylightProjectionEffect>(createProperties().lightLevel { 3 }) {
|
||||
object SkylightProjectionBlock : EntityProjectionBlock<SkylightProjectionEffect>(createProperties().lightLevel { 3 }) {
|
||||
|
||||
override fun createProjectionEffect(
|
||||
level: ServerLevel,
|
||||
state: BlockState,
|
||||
pos: BlockPos
|
||||
) = SkylightProjectionEffect()
|
||||
override val blockEntity = SkylightProjection.blockEntity
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,15 +1,13 @@
|
||||
package quaedam.projection.misc
|
||||
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.world.item.BlockItem
|
||||
import net.minecraft.world.item.Item
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import quaedam.Quaedam
|
||||
import quaedam.projection.ProjectionBlock
|
||||
import quaedam.projection.EntityProjectionBlock
|
||||
import quaedam.projection.ProjectionEffect
|
||||
import quaedam.projection.ProjectionEffectType
|
||||
import quaedam.projection.SimpleProjectionEntity
|
||||
|
||||
object SoundProjection {
|
||||
|
||||
@ -29,15 +27,15 @@ object SoundProjection {
|
||||
ProjectionEffectType { SoundProjectionEffect }
|
||||
}!!
|
||||
|
||||
val blockEntity = Quaedam.blockEntities.register(ID) {
|
||||
SimpleProjectionEntity.createBlockEntityType(block) { SoundProjectionEffect }
|
||||
}!!
|
||||
|
||||
}
|
||||
|
||||
object SoundProjectionBlock : ProjectionBlock<SoundProjectionEffect>(createProperties().lightLevel { 3 }) {
|
||||
object SoundProjectionBlock : EntityProjectionBlock<SoundProjectionEffect>(createProperties().lightLevel { 3 }) {
|
||||
|
||||
override fun createProjectionEffect(
|
||||
level: ServerLevel,
|
||||
state: BlockState,
|
||||
pos: BlockPos
|
||||
) = SoundProjectionEffect
|
||||
override val blockEntity = SoundProjection.blockEntity
|
||||
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,7 @@ import net.minecraft.world.item.BlockItem
|
||||
import net.minecraft.world.item.Item
|
||||
import quaedam.Quaedam
|
||||
import quaedam.projection.ProjectionEffectType
|
||||
import quaedam.projection.SimpleProjectionEntity
|
||||
|
||||
object SwarmProjection {
|
||||
|
||||
@ -23,6 +24,10 @@ object SwarmProjection {
|
||||
ProjectionEffectType { SwarmProjectionEffect() }
|
||||
}!!
|
||||
|
||||
val blockEntity = Quaedam.blockEntities.register(ID) {
|
||||
SimpleProjectionEntity.createBlockEntityType(block, ::SwarmProjectionEffect)
|
||||
}!!
|
||||
|
||||
init {
|
||||
ProjectedPersonEntity
|
||||
}
|
||||
|
@ -1,16 +1,9 @@
|
||||
package quaedam.projection.swarm
|
||||
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import quaedam.projection.ProjectionBlock
|
||||
import quaedam.projection.EntityProjectionBlock
|
||||
|
||||
object SwarmProjectionBlock : ProjectionBlock<SwarmProjectionEffect>() {
|
||||
object SwarmProjectionBlock : EntityProjectionBlock<SwarmProjectionEffect>() {
|
||||
|
||||
override fun createProjectionEffect(
|
||||
level: ServerLevel,
|
||||
state: BlockState,
|
||||
pos: BlockPos
|
||||
) = SwarmProjectionEffect()
|
||||
override val blockEntity = SwarmProjection.blockEntity
|
||||
|
||||
}
|
||||
|
@ -132,7 +132,7 @@ class ProjectorBlockEntity(pos: BlockPos, state: BlockState) :
|
||||
val blockState = level.getBlockState(pos)
|
||||
val block = blockState.block
|
||||
if (block is ProjectionProvider<*>) {
|
||||
val projection = block.createProjectionEffect(level, blockState, pos)
|
||||
val projection = block.applyProjectionEffect(level, blockState, pos)
|
||||
if (projection != null) {
|
||||
effects[projection.type] = projection
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user