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.CreativeModeTab
|
||||||
import net.minecraft.world.item.ItemStack
|
import net.minecraft.world.item.ItemStack
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import quaedam.projection.*
|
import quaedam.projection.ProjectionCommand
|
||||||
|
import quaedam.projection.ProjectionEffectType
|
||||||
import quaedam.projection.misc.NoiseProjection
|
import quaedam.projection.misc.NoiseProjection
|
||||||
import quaedam.projection.misc.SkylightProjection
|
import quaedam.projection.misc.SkylightProjection
|
||||||
import quaedam.projection.misc.SoundProjection
|
import quaedam.projection.misc.SoundProjection
|
||||||
|
@ -1,59 +1,32 @@
|
|||||||
package quaedam.projection
|
package quaedam.projection
|
||||||
|
|
||||||
|
import dev.architectury.registry.registries.DeferredSupplier
|
||||||
import net.minecraft.core.BlockPos
|
import net.minecraft.core.BlockPos
|
||||||
import net.minecraft.world.entity.LivingEntity
|
import net.minecraft.server.level.ServerLevel
|
||||||
import net.minecraft.world.item.ItemStack
|
|
||||||
import net.minecraft.world.level.Level
|
import net.minecraft.world.level.Level
|
||||||
import net.minecraft.world.level.LevelAccessor
|
import net.minecraft.world.level.block.EntityBlock
|
||||||
import net.minecraft.world.level.block.Block
|
import net.minecraft.world.level.block.entity.BlockEntityType
|
||||||
import net.minecraft.world.level.block.state.BlockState
|
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),
|
abstract class EntityProjectionBlock<P : ProjectionEffect>(properties: Properties = createProperties()) :
|
||||||
ProjectionProvider<P> {
|
ProjectionBlock<P>(properties), EntityBlock {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun createProperties(): Properties = Properties.of()
|
fun createProperties(): Properties = ProjectionBlock.createProperties()
|
||||||
.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()
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("OVERRIDE_DEPRECATION")
|
abstract val blockEntity: DeferredSupplier<BlockEntityType<SimpleProjectionEntity<P>>>
|
||||||
override fun getDrops(blockState: BlockState, builder: LootParams.Builder) = listOf(ItemStack(asItem()))
|
|
||||||
|
|
||||||
override fun setPlacedBy(
|
override fun newBlockEntity(pos: BlockPos, state: BlockState) = blockEntity.get().create(pos, state)
|
||||||
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 destroy(level: LevelAccessor, pos: BlockPos, state: BlockState) {
|
@Suppress("UNCHECKED_CAST")
|
||||||
super.destroy(level, pos, state)
|
fun getProjection(level: Level, pos: BlockPos) = (level.getBlockEntity(pos) as SimpleProjectionEntity<P>).projection
|
||||||
if (level is Level && !level.isClientSide) {
|
|
||||||
findNearbyProjectors(level, pos)
|
override fun applyProjectionEffect(level: ServerLevel, state: BlockState, pos: BlockPos) = getProjection(level, pos)
|
||||||
.forEach { (level.getBlockEntity(it) as ProjectorBlockEntity).checkUpdate() }
|
|
||||||
}
|
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
|
itemStack: ItemStack
|
||||||
) {
|
) {
|
||||||
super.setPlacedBy(level, pos, state, placer, 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) {
|
if (!level.isClientSide) {
|
||||||
findNearbyProjectors(level, pos)
|
findNearbyProjectors(level, pos)
|
||||||
.forEach { (level.getBlockEntity(it) as ProjectorBlockEntity).checkUpdate() }
|
.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> {
|
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
|
package quaedam.projection.misc
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos
|
|
||||||
import net.minecraft.nbt.CompoundTag
|
import net.minecraft.nbt.CompoundTag
|
||||||
import net.minecraft.server.level.ServerLevel
|
|
||||||
import net.minecraft.world.item.BlockItem
|
import net.minecraft.world.item.BlockItem
|
||||||
import net.minecraft.world.item.Item
|
import net.minecraft.world.item.Item
|
||||||
import net.minecraft.world.level.block.state.BlockState
|
|
||||||
import quaedam.Quaedam
|
import quaedam.Quaedam
|
||||||
import quaedam.projection.ProjectionBlock
|
import quaedam.projection.EntityProjectionBlock
|
||||||
import quaedam.projection.ProjectionEffect
|
import quaedam.projection.ProjectionEffect
|
||||||
import quaedam.projection.ProjectionEffectType
|
import quaedam.projection.ProjectionEffectType
|
||||||
|
import quaedam.projection.SimpleProjectionEntity
|
||||||
|
|
||||||
object NoiseProjection {
|
object NoiseProjection {
|
||||||
|
|
||||||
@ -29,15 +27,15 @@ object NoiseProjection {
|
|||||||
ProjectionEffectType { NoiseProjectionEffect() }
|
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(
|
override val blockEntity = NoiseProjection.blockEntity
|
||||||
level: ServerLevel,
|
|
||||||
state: BlockState,
|
|
||||||
pos: BlockPos
|
|
||||||
) = NoiseProjectionEffect()
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,15 +1,13 @@
|
|||||||
package quaedam.projection.misc
|
package quaedam.projection.misc
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos
|
|
||||||
import net.minecraft.nbt.CompoundTag
|
import net.minecraft.nbt.CompoundTag
|
||||||
import net.minecraft.server.level.ServerLevel
|
|
||||||
import net.minecraft.world.item.BlockItem
|
import net.minecraft.world.item.BlockItem
|
||||||
import net.minecraft.world.item.Item
|
import net.minecraft.world.item.Item
|
||||||
import net.minecraft.world.level.block.state.BlockState
|
|
||||||
import quaedam.Quaedam
|
import quaedam.Quaedam
|
||||||
import quaedam.projection.ProjectionBlock
|
import quaedam.projection.EntityProjectionBlock
|
||||||
import quaedam.projection.ProjectionEffect
|
import quaedam.projection.ProjectionEffect
|
||||||
import quaedam.projection.ProjectionEffectType
|
import quaedam.projection.ProjectionEffectType
|
||||||
|
import quaedam.projection.SimpleProjectionEntity
|
||||||
|
|
||||||
object SkylightProjection {
|
object SkylightProjection {
|
||||||
|
|
||||||
@ -29,15 +27,15 @@ object SkylightProjection {
|
|||||||
ProjectionEffectType { SkylightProjectionEffect() }
|
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(
|
override val blockEntity = SkylightProjection.blockEntity
|
||||||
level: ServerLevel,
|
|
||||||
state: BlockState,
|
|
||||||
pos: BlockPos
|
|
||||||
) = SkylightProjectionEffect()
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,15 +1,13 @@
|
|||||||
package quaedam.projection.misc
|
package quaedam.projection.misc
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos
|
|
||||||
import net.minecraft.nbt.CompoundTag
|
import net.minecraft.nbt.CompoundTag
|
||||||
import net.minecraft.server.level.ServerLevel
|
|
||||||
import net.minecraft.world.item.BlockItem
|
import net.minecraft.world.item.BlockItem
|
||||||
import net.minecraft.world.item.Item
|
import net.minecraft.world.item.Item
|
||||||
import net.minecraft.world.level.block.state.BlockState
|
|
||||||
import quaedam.Quaedam
|
import quaedam.Quaedam
|
||||||
import quaedam.projection.ProjectionBlock
|
import quaedam.projection.EntityProjectionBlock
|
||||||
import quaedam.projection.ProjectionEffect
|
import quaedam.projection.ProjectionEffect
|
||||||
import quaedam.projection.ProjectionEffectType
|
import quaedam.projection.ProjectionEffectType
|
||||||
|
import quaedam.projection.SimpleProjectionEntity
|
||||||
|
|
||||||
object SoundProjection {
|
object SoundProjection {
|
||||||
|
|
||||||
@ -29,15 +27,15 @@ object SoundProjection {
|
|||||||
ProjectionEffectType { SoundProjectionEffect }
|
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(
|
override val blockEntity = SoundProjection.blockEntity
|
||||||
level: ServerLevel,
|
|
||||||
state: BlockState,
|
|
||||||
pos: BlockPos
|
|
||||||
) = SoundProjectionEffect
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import net.minecraft.world.item.BlockItem
|
|||||||
import net.minecraft.world.item.Item
|
import net.minecraft.world.item.Item
|
||||||
import quaedam.Quaedam
|
import quaedam.Quaedam
|
||||||
import quaedam.projection.ProjectionEffectType
|
import quaedam.projection.ProjectionEffectType
|
||||||
|
import quaedam.projection.SimpleProjectionEntity
|
||||||
|
|
||||||
object SwarmProjection {
|
object SwarmProjection {
|
||||||
|
|
||||||
@ -23,6 +24,10 @@ object SwarmProjection {
|
|||||||
ProjectionEffectType { SwarmProjectionEffect() }
|
ProjectionEffectType { SwarmProjectionEffect() }
|
||||||
}!!
|
}!!
|
||||||
|
|
||||||
|
val blockEntity = Quaedam.blockEntities.register(ID) {
|
||||||
|
SimpleProjectionEntity.createBlockEntityType(block, ::SwarmProjectionEffect)
|
||||||
|
}!!
|
||||||
|
|
||||||
init {
|
init {
|
||||||
ProjectedPersonEntity
|
ProjectedPersonEntity
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,9 @@
|
|||||||
package quaedam.projection.swarm
|
package quaedam.projection.swarm
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos
|
import quaedam.projection.EntityProjectionBlock
|
||||||
import net.minecraft.server.level.ServerLevel
|
|
||||||
import net.minecraft.world.level.block.state.BlockState
|
|
||||||
import quaedam.projection.ProjectionBlock
|
|
||||||
|
|
||||||
object SwarmProjectionBlock : ProjectionBlock<SwarmProjectionEffect>() {
|
object SwarmProjectionBlock : EntityProjectionBlock<SwarmProjectionEffect>() {
|
||||||
|
|
||||||
override fun createProjectionEffect(
|
override val blockEntity = SwarmProjection.blockEntity
|
||||||
level: ServerLevel,
|
|
||||||
state: BlockState,
|
|
||||||
pos: BlockPos
|
|
||||||
) = SwarmProjectionEffect()
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -132,7 +132,7 @@ class ProjectorBlockEntity(pos: BlockPos, state: BlockState) :
|
|||||||
val blockState = level.getBlockState(pos)
|
val blockState = level.getBlockState(pos)
|
||||||
val block = blockState.block
|
val block = blockState.block
|
||||||
if (block is ProjectionProvider<*>) {
|
if (block is ProjectionProvider<*>) {
|
||||||
val projection = block.createProjectionEffect(level, blockState, pos)
|
val projection = block.applyProjectionEffect(level, blockState, pos)
|
||||||
if (projection != null) {
|
if (projection != null) {
|
||||||
effects[projection.type] = projection
|
effects[projection.type] = projection
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user