feat: projections
This commit is contained in:
parent
482e4af4e7
commit
47e8b22a87
@ -0,0 +1,19 @@
|
|||||||
|
package quaedam.mixin;
|
||||||
|
|
||||||
|
import net.minecraft.core.registries.BuiltInRegistries;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
import quaedam.projection.ProjectionEffectType;
|
||||||
|
|
||||||
|
@Mixin(BuiltInRegistries.class)
|
||||||
|
public class MixinBuiltInRegistries {
|
||||||
|
|
||||||
|
@Inject(at = @At("HEAD"), method = "bootStrap()V")
|
||||||
|
private static void bootStrap(CallbackInfo info) {
|
||||||
|
// init projection effect type registry
|
||||||
|
ProjectionEffectType.Companion.getRegistry();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,63 +0,0 @@
|
|||||||
package quaedam
|
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos
|
|
||||||
import net.minecraft.server.level.ServerLevel
|
|
||||||
import net.minecraft.util.RandomSource
|
|
||||||
import net.minecraft.world.InteractionHand
|
|
||||||
import net.minecraft.world.InteractionResult
|
|
||||||
import net.minecraft.world.entity.player.Player
|
|
||||||
import net.minecraft.world.item.BlockItem
|
|
||||||
import net.minecraft.world.item.Item
|
|
||||||
import net.minecraft.world.level.Level
|
|
||||||
import net.minecraft.world.level.block.Block
|
|
||||||
import net.minecraft.world.level.block.state.BlockState
|
|
||||||
import net.minecraft.world.level.material.MapColor
|
|
||||||
import net.minecraft.world.phys.BlockHitResult
|
|
||||||
|
|
||||||
object Projector {
|
|
||||||
|
|
||||||
const val ID = "projector"
|
|
||||||
|
|
||||||
val block = Quaedam.blocks.register(ID) { ProjectorBlock }
|
|
||||||
|
|
||||||
val item = Quaedam.items.register(ID) {
|
|
||||||
BlockItem(
|
|
||||||
ProjectorBlock, Item.Properties()
|
|
||||||
.stacksTo(1)
|
|
||||||
.`arch$tab`(Quaedam.creativeModeTab)
|
|
||||||
)
|
|
||||||
}!!
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
object ProjectorBlock : Block(Properties.of()
|
|
||||||
.jumpFactor(0.8f)
|
|
||||||
.lightLevel { 3 }
|
|
||||||
.mapColor(MapColor.COLOR_BLACK)
|
|
||||||
.randomTicks()
|
|
||||||
.strength(4.0f)
|
|
||||||
.requiresCorrectToolForDrops()) {
|
|
||||||
|
|
||||||
@Suppress("OVERRIDE_DEPRECATION")
|
|
||||||
override fun use(
|
|
||||||
blockState: BlockState,
|
|
||||||
level: Level,
|
|
||||||
blockPos: BlockPos,
|
|
||||||
player: Player,
|
|
||||||
interactionHand: InteractionHand,
|
|
||||||
blockHitResult: BlockHitResult
|
|
||||||
): InteractionResult {
|
|
||||||
return InteractionResult.SUCCESS
|
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("OVERRIDE_DEPRECATION")
|
|
||||||
override fun randomTick(
|
|
||||||
blockState: BlockState,
|
|
||||||
serverLevel: ServerLevel,
|
|
||||||
blockPos: BlockPos,
|
|
||||||
randomSource: RandomSource
|
|
||||||
) {
|
|
||||||
// @TODO: call projectorRandomTick
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -6,10 +6,11 @@ import dev.architectury.registry.registries.RegistrySupplier
|
|||||||
import net.minecraft.core.registries.Registries
|
import net.minecraft.core.registries.Registries
|
||||||
import net.minecraft.network.chat.Component
|
import net.minecraft.network.chat.Component
|
||||||
import net.minecraft.world.item.CreativeModeTab
|
import net.minecraft.world.item.CreativeModeTab
|
||||||
import net.minecraft.world.item.Item
|
|
||||||
import net.minecraft.world.item.ItemStack
|
import net.minecraft.world.item.ItemStack
|
||||||
import net.minecraft.world.item.Items
|
import net.minecraft.world.item.Items
|
||||||
|
import quaedam.projection.ProjectionEffectType
|
||||||
import quaedam.projection.SkylightProjection
|
import quaedam.projection.SkylightProjection
|
||||||
|
import quaedam.projector.Projector
|
||||||
|
|
||||||
object Quaedam {
|
object Quaedam {
|
||||||
|
|
||||||
@ -18,6 +19,8 @@ object Quaedam {
|
|||||||
val creativeModeTabs = DeferredRegister.create(ID, Registries.CREATIVE_MODE_TAB)!!
|
val creativeModeTabs = DeferredRegister.create(ID, Registries.CREATIVE_MODE_TAB)!!
|
||||||
val items = DeferredRegister.create(ID, Registries.ITEM)!!
|
val items = DeferredRegister.create(ID, Registries.ITEM)!!
|
||||||
val blocks = DeferredRegister.create(ID, Registries.BLOCK)!!
|
val blocks = DeferredRegister.create(ID, Registries.BLOCK)!!
|
||||||
|
val blockEntities = DeferredRegister.create(ID, Registries.BLOCK_ENTITY_TYPE)!!
|
||||||
|
val projectionEffects = DeferredRegister.create(ID, ProjectionEffectType.registryKey)!!
|
||||||
|
|
||||||
val creativeModeTab: RegistrySupplier<CreativeModeTab> = creativeModeTabs.register("quaedam") {
|
val creativeModeTab: RegistrySupplier<CreativeModeTab> = creativeModeTabs.register("quaedam") {
|
||||||
CreativeTabRegistry.create(Component.translatable("category.quaedam")) {
|
CreativeTabRegistry.create(Component.translatable("category.quaedam")) {
|
||||||
@ -28,9 +31,12 @@ object Quaedam {
|
|||||||
fun init() {
|
fun init() {
|
||||||
Projector
|
Projector
|
||||||
SkylightProjection
|
SkylightProjection
|
||||||
|
|
||||||
creativeModeTabs.register()
|
creativeModeTabs.register()
|
||||||
items.register()
|
items.register()
|
||||||
blocks.register()
|
blocks.register()
|
||||||
|
blockEntities.register()
|
||||||
|
projectionEffects.register()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,15 +1,19 @@
|
|||||||
package quaedam.projection
|
package quaedam.projection
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos
|
import net.minecraft.core.BlockPos
|
||||||
import net.minecraft.server.level.ServerLevel
|
import net.minecraft.world.entity.LivingEntity
|
||||||
import net.minecraft.util.RandomSource
|
|
||||||
import net.minecraft.world.item.ItemStack
|
import net.minecraft.world.item.ItemStack
|
||||||
|
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.Block
|
||||||
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.material.MapColor
|
||||||
import net.minecraft.world.level.storage.loot.LootParams
|
import net.minecraft.world.level.storage.loot.LootParams
|
||||||
|
import quaedam.projector.ProjectorBlockEntity
|
||||||
|
import quaedam.utils.getChunksNearby
|
||||||
|
|
||||||
abstract class ProjectionBlock(properties: Properties = createProperties()) : Block(properties) {
|
abstract class ProjectionBlock<P : ProjectionEffect>(properties: Properties = createProperties()) : Block(properties),
|
||||||
|
ProjectionProvider<P> {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun createProperties(): Properties = Properties.of()
|
fun createProperties(): Properties = Properties.of()
|
||||||
@ -17,18 +21,39 @@ abstract class ProjectionBlock(properties: Properties = createProperties()) : Bl
|
|||||||
.requiresCorrectToolForDrops()
|
.requiresCorrectToolForDrops()
|
||||||
.mapColor(MapColor.COLOR_GRAY)
|
.mapColor(MapColor.COLOR_GRAY)
|
||||||
|
|
||||||
|
fun findNearbyProjectors(level: Level, pos: BlockPos) = level.getChunksNearby(pos, 1)
|
||||||
|
.flatMap {
|
||||||
|
it.blockEntities.filter { (k, v) -> v is ProjectorBlockEntity }
|
||||||
|
.keys
|
||||||
|
.filterNotNull()
|
||||||
|
}
|
||||||
|
.toSet()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("OVERRIDE_DEPRECATION")
|
@Suppress("OVERRIDE_DEPRECATION")
|
||||||
override fun getDrops(blockState: BlockState, builder: LootParams.Builder) = listOf(ItemStack(asItem()))
|
override fun getDrops(blockState: BlockState, builder: LootParams.Builder) = listOf(ItemStack(asItem()))
|
||||||
|
|
||||||
fun projectionActivated(level: ServerLevel, projectorPos: BlockPos, projectionPos: BlockPos) {
|
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() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun projectionDeactivated(level: ServerLevel, projectorPos: BlockPos, projectionPos: BlockPos) {
|
override fun destroy(level: LevelAccessor, pos: BlockPos, state: BlockState) {
|
||||||
}
|
super.destroy(level, pos, state)
|
||||||
|
if (level is Level && !level.isClientSide) {
|
||||||
fun projectorRandomTick(level: ServerLevel, projectorPos: BlockPos, projectionPos: BlockPos, random: RandomSource) {
|
findNearbyProjectors(level, pos)
|
||||||
|
.forEach { (level.getBlockEntity(it) as ProjectorBlockEntity).checkUpdate() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
package quaedam.projection
|
||||||
|
|
||||||
|
import net.minecraft.core.BlockPos
|
||||||
|
import net.minecraft.core.Registry
|
||||||
|
import net.minecraft.core.registries.BuiltInRegistries
|
||||||
|
import net.minecraft.nbt.CompoundTag
|
||||||
|
import net.minecraft.resources.ResourceKey
|
||||||
|
import net.minecraft.resources.ResourceLocation
|
||||||
|
import net.minecraft.server.level.ServerLevel
|
||||||
|
import net.minecraft.util.RandomSource
|
||||||
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
|
|
||||||
|
abstract class ProjectionEffect {
|
||||||
|
|
||||||
|
abstract val type: ProjectionEffectType<*>
|
||||||
|
|
||||||
|
abstract fun toNbt(tag: CompoundTag)
|
||||||
|
|
||||||
|
abstract fun fromNbt(tag: CompoundTag)
|
||||||
|
|
||||||
|
fun toNbt() = CompoundTag().apply { toNbt(this) }
|
||||||
|
|
||||||
|
override fun equals(other: Any?) = other === this
|
||||||
|
|
||||||
|
override fun hashCode() = type.hashCode()
|
||||||
|
|
||||||
|
fun activated(level: ServerLevel, projectorPos: BlockPos) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fun deactivated(level: ServerLevel, projectorPos: BlockPos) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fun randomTick(level: ServerLevel, projectorPos: BlockPos, random: RandomSource) {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
data class ProjectionEffectType<T : ProjectionEffect>(val constructor: () -> T) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
val registryKey: ResourceKey<Registry<ProjectionEffectType<*>>> =
|
||||||
|
ResourceKey.createRegistryKey(ResourceLocation("quaedam", "projection_effect"))
|
||||||
|
val registry: Registry<ProjectionEffectType<*>> = BuiltInRegistries.registerSimple(registryKey) { null }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
val id by lazy { registry.getResourceKey(this).get().location()!! }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ProjectionProvider<P : ProjectionEffect> {
|
||||||
|
fun createProjectionEffect(level: ServerLevel, state: BlockState, pos: BlockPos): P?
|
||||||
|
}
|
@ -1,14 +1,18 @@
|
|||||||
package quaedam.projection
|
package quaedam.projection
|
||||||
|
|
||||||
|
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.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
|
||||||
|
|
||||||
object SkylightProjection {
|
object SkylightProjection {
|
||||||
|
|
||||||
const val ID = "skylight_projection"
|
const val ID = "skylight_projection"
|
||||||
|
|
||||||
val block = Quaedam.blocks.register(ID) { SkylightProjectionBlock }
|
val block = Quaedam.blocks.register(ID) { SkylightProjectionBlock }!!
|
||||||
|
|
||||||
val item = Quaedam.items.register(ID) {
|
val item = Quaedam.items.register(ID) {
|
||||||
BlockItem(
|
BlockItem(
|
||||||
@ -17,6 +21,31 @@ object SkylightProjection {
|
|||||||
)
|
)
|
||||||
}!!
|
}!!
|
||||||
|
|
||||||
|
val effect = Quaedam.projectionEffects.register(ID) {
|
||||||
|
ProjectionEffectType { SkylightProjectionEffect }
|
||||||
|
}!!
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
object SkylightProjectionBlock : ProjectionBlock(createProperties().lightLevel { 3 })
|
object SkylightProjectionBlock : ProjectionBlock<SkylightProjectionEffect>(createProperties().lightLevel { 3 }) {
|
||||||
|
|
||||||
|
override fun createProjectionEffect(
|
||||||
|
level: ServerLevel,
|
||||||
|
state: BlockState,
|
||||||
|
pos: BlockPos
|
||||||
|
) = SkylightProjectionEffect
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
object SkylightProjectionEffect : ProjectionEffect() {
|
||||||
|
|
||||||
|
override val type
|
||||||
|
get() = SkylightProjection.effect.get()!!
|
||||||
|
|
||||||
|
override fun toNbt(tag: CompoundTag) {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun fromNbt(tag: CompoundTag) {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
26
common/src/main/kotlin/quaedam/projector/Projector.kt
Normal file
26
common/src/main/kotlin/quaedam/projector/Projector.kt
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
package quaedam.projector
|
||||||
|
|
||||||
|
import net.minecraft.world.item.BlockItem
|
||||||
|
import net.minecraft.world.item.Item
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntityType
|
||||||
|
import quaedam.Quaedam
|
||||||
|
|
||||||
|
object Projector {
|
||||||
|
|
||||||
|
const val ID = "projector"
|
||||||
|
|
||||||
|
val block = Quaedam.blocks.register(ID) { ProjectorBlock }!!
|
||||||
|
|
||||||
|
val item = Quaedam.items.register(ID) {
|
||||||
|
BlockItem(
|
||||||
|
ProjectorBlock, Item.Properties()
|
||||||
|
.stacksTo(1)
|
||||||
|
.`arch$tab`(Quaedam.creativeModeTab)
|
||||||
|
)
|
||||||
|
}!!
|
||||||
|
|
||||||
|
val blockEntity = Quaedam.blockEntities.register(ID) {
|
||||||
|
BlockEntityType.Builder.of(::ProjectorBlockEntity, block.get()).build(null)
|
||||||
|
}!!
|
||||||
|
|
||||||
|
}
|
84
common/src/main/kotlin/quaedam/projector/ProjectorBlock.kt
Normal file
84
common/src/main/kotlin/quaedam/projector/ProjectorBlock.kt
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
package quaedam.projector
|
||||||
|
|
||||||
|
import net.minecraft.core.BlockPos
|
||||||
|
import net.minecraft.server.level.ServerLevel
|
||||||
|
import net.minecraft.util.RandomSource
|
||||||
|
import net.minecraft.world.InteractionHand
|
||||||
|
import net.minecraft.world.InteractionResult
|
||||||
|
import net.minecraft.world.entity.LivingEntity
|
||||||
|
import net.minecraft.world.entity.player.Player
|
||||||
|
import net.minecraft.world.item.ItemStack
|
||||||
|
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.state.BlockState
|
||||||
|
import net.minecraft.world.level.material.MapColor
|
||||||
|
import net.minecraft.world.phys.BlockHitResult
|
||||||
|
import quaedam.projection.ProjectionBlock
|
||||||
|
|
||||||
|
object ProjectorBlock : Block(Properties.of()
|
||||||
|
.jumpFactor(0.8f)
|
||||||
|
.lightLevel { 3 }
|
||||||
|
.mapColor(MapColor.COLOR_BLACK)
|
||||||
|
.randomTicks()
|
||||||
|
.strength(4.0f)
|
||||||
|
.requiresCorrectToolForDrops()), EntityBlock {
|
||||||
|
|
||||||
|
fun checkUpdate(level: Level, pos: BlockPos) {
|
||||||
|
if (!level.isClientSide) {
|
||||||
|
(level.getBlockEntity(pos) as ProjectorBlockEntity).checkUpdate()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("OVERRIDE_DEPRECATION")
|
||||||
|
override fun use(
|
||||||
|
blockState: BlockState,
|
||||||
|
level: Level,
|
||||||
|
blockPos: BlockPos,
|
||||||
|
player: Player,
|
||||||
|
interactionHand: InteractionHand,
|
||||||
|
blockHitResult: BlockHitResult
|
||||||
|
): InteractionResult {
|
||||||
|
checkUpdate(level, blockPos)
|
||||||
|
return InteractionResult.SUCCESS
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun newBlockEntity(pos: BlockPos, state: BlockState) = ProjectorBlockEntity(pos, state)
|
||||||
|
|
||||||
|
@Suppress("OVERRIDE_DEPRECATION")
|
||||||
|
override fun randomTick(
|
||||||
|
state: BlockState,
|
||||||
|
level: ServerLevel,
|
||||||
|
pos: BlockPos,
|
||||||
|
random: RandomSource
|
||||||
|
) {
|
||||||
|
// @TODO: call projectorRandomTick
|
||||||
|
checkUpdate(level, pos)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("DEPRECATION", "OVERRIDE_DEPRECATION")
|
||||||
|
override fun neighborChanged(
|
||||||
|
state: BlockState,
|
||||||
|
level: Level,
|
||||||
|
pos: BlockPos,
|
||||||
|
sourceBlock: Block,
|
||||||
|
sourcePos: BlockPos,
|
||||||
|
notify: Boolean
|
||||||
|
) {
|
||||||
|
super.neighborChanged(state, level, pos, sourceBlock, sourcePos, notify)
|
||||||
|
checkUpdate(level, pos)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setPlacedBy(
|
||||||
|
level: Level,
|
||||||
|
pos: BlockPos,
|
||||||
|
state: BlockState,
|
||||||
|
placer: LivingEntity?,
|
||||||
|
itemStack: ItemStack
|
||||||
|
) {
|
||||||
|
super.setPlacedBy(level, pos, state, placer, itemStack)
|
||||||
|
checkUpdate(level, pos)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
126
common/src/main/kotlin/quaedam/projector/ProjectorBlockEntity.kt
Normal file
126
common/src/main/kotlin/quaedam/projector/ProjectorBlockEntity.kt
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
package quaedam.projector
|
||||||
|
|
||||||
|
import net.minecraft.core.BlockPos
|
||||||
|
import net.minecraft.core.Vec3i
|
||||||
|
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.resources.ResourceLocation
|
||||||
|
import net.minecraft.server.level.ServerLevel
|
||||||
|
import net.minecraft.world.level.ChunkPos
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntity
|
||||||
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
|
import net.minecraft.world.level.levelgen.structure.BoundingBox
|
||||||
|
import quaedam.projection.ProjectionEffect
|
||||||
|
import quaedam.projection.ProjectionEffectType
|
||||||
|
import quaedam.projection.ProjectionProvider
|
||||||
|
import quaedam.utils.sendBlockUpdated
|
||||||
|
|
||||||
|
class ProjectorBlockEntity(pos: BlockPos, state: BlockState) :
|
||||||
|
BlockEntity(Projector.blockEntity.get(), pos, state) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val EFFECT_RADIUS = 4
|
||||||
|
}
|
||||||
|
|
||||||
|
val effectAreaChunk by lazy {
|
||||||
|
val chunk = level!!.getChunk(pos).pos
|
||||||
|
ChunkPos(chunk.x - EFFECT_RADIUS, chunk.z - EFFECT_RADIUS) to
|
||||||
|
ChunkPos(chunk.x + EFFECT_RADIUS, chunk.z + EFFECT_RADIUS)
|
||||||
|
}
|
||||||
|
|
||||||
|
val effectArea: BoundingBox by lazy {
|
||||||
|
val chunk = level!!.getChunk(pos).pos
|
||||||
|
val (minChunk, maxChunk) = effectAreaChunk
|
||||||
|
val minBlock = BlockPos(minChunk.minBlockX, level!!.minBuildHeight, minChunk.minBlockZ)
|
||||||
|
val maxBlock = BlockPos(maxChunk.maxBlockX, level!!.maxBuildHeight, maxChunk.maxBlockZ)
|
||||||
|
BoundingBox.fromCorners(minBlock, maxBlock)
|
||||||
|
}
|
||||||
|
|
||||||
|
val checkArea: BoundingBox by lazy {
|
||||||
|
BoundingBox.fromCorners(pos.offset(-2, -1, -2), pos.offset(2, -2, 2))
|
||||||
|
}
|
||||||
|
|
||||||
|
var effects: Map<ProjectionEffectType<*>, ProjectionEffect> = emptyMap()
|
||||||
|
|
||||||
|
override fun saveAdditional(tag: CompoundTag) {
|
||||||
|
super.saveAdditional(tag)
|
||||||
|
val effectsTag = CompoundTag()
|
||||||
|
effects.map { (type, effect) ->
|
||||||
|
effectsTag.put(type.id.toString(), effect.toNbt())
|
||||||
|
}
|
||||||
|
tag.put("ProjectionEffects", effectsTag)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun load(tag: CompoundTag) {
|
||||||
|
super.load(tag)
|
||||||
|
val effectsTag = tag["ProjectionEffects"]
|
||||||
|
val effects = mutableMapOf<ProjectionEffectType<*>, ProjectionEffect>()
|
||||||
|
if (effectsTag != null && effectsTag is CompoundTag) {
|
||||||
|
effectsTag.allKeys.forEach { id ->
|
||||||
|
val type = ProjectionEffectType.registry[ResourceLocation(id)]
|
||||||
|
if (type != null) {
|
||||||
|
val effect = type.constructor().apply { fromNbt(effectsTag[id] as CompoundTag) }
|
||||||
|
effects[type] = effect
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updateEffects(effects)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getUpdateTag(): CompoundTag = saveWithoutMetadata()
|
||||||
|
|
||||||
|
override fun getUpdatePacket(): Packet<ClientGamePacketListener> = ClientboundBlockEntityDataPacket.create(this)
|
||||||
|
|
||||||
|
override fun setRemoved() {
|
||||||
|
super.setRemoved()
|
||||||
|
updateEffects(emptyMap(), notify = false)
|
||||||
|
}
|
||||||
|
|
||||||
|
operator fun contains(pos: Vec3i) = effectArea.isInside(pos)
|
||||||
|
|
||||||
|
operator fun contains(pos: ChunkPos) =
|
||||||
|
this.contains(Vec3i(pos.middleBlockX, level!!.minBuildHeight, pos.middleBlockZ))
|
||||||
|
|
||||||
|
fun checkUpdate() {
|
||||||
|
if (level!!.isClientSide)
|
||||||
|
return
|
||||||
|
val effects = collectEffects()
|
||||||
|
updateEffects(effects)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updateEffects(effects: Map<ProjectionEffectType<*>, ProjectionEffect>, notify: Boolean = true) {
|
||||||
|
if (effects != this.effects) {
|
||||||
|
this.effects = effects
|
||||||
|
if (!level!!.isClientSide) {
|
||||||
|
sendBlockUpdated()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun collectEffects(): Map<ProjectionEffectType<*>, ProjectionEffect> {
|
||||||
|
val level = level!! as ServerLevel
|
||||||
|
if (!level.getBlockState(blockPos.below()).isAir) {
|
||||||
|
return emptyMap()
|
||||||
|
}
|
||||||
|
val effects = mutableMapOf<ProjectionEffectType<*>, ProjectionEffect>()
|
||||||
|
for (x in checkArea.minX()..checkArea.maxX()) {
|
||||||
|
for (y in checkArea.minY()..checkArea.maxY()) {
|
||||||
|
for (z in checkArea.minZ()..checkArea.maxZ()) {
|
||||||
|
val pos = BlockPos(x, y, z)
|
||||||
|
val blockState = level.getBlockState(pos)
|
||||||
|
val block = blockState.block
|
||||||
|
if (block is ProjectionProvider<*>) {
|
||||||
|
val projection = block.createProjectionEffect(level, blockState, pos)
|
||||||
|
if (projection != null) {
|
||||||
|
effects[projection.type] = projection
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return effects
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
7
common/src/main/kotlin/quaedam/utils/BlockEntity.kt
Normal file
7
common/src/main/kotlin/quaedam/utils/BlockEntity.kt
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package quaedam.utils
|
||||||
|
|
||||||
|
import net.minecraft.world.level.block.Block
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntity
|
||||||
|
|
||||||
|
fun BlockEntity.sendBlockUpdated() =
|
||||||
|
level!!.sendBlockUpdated(blockPos, blockState, blockState, Block.UPDATE_CLIENTS)
|
16
common/src/main/kotlin/quaedam/utils/Chunks.kt
Normal file
16
common/src/main/kotlin/quaedam/utils/Chunks.kt
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
package quaedam.utils
|
||||||
|
|
||||||
|
import net.minecraft.core.BlockPos
|
||||||
|
import net.minecraft.core.SectionPos
|
||||||
|
import net.minecraft.world.level.Level
|
||||||
|
import net.minecraft.world.level.chunk.LevelChunk
|
||||||
|
|
||||||
|
fun Level.getChunksNearby(pos: BlockPos, radius: Int): Set<LevelChunk> {
|
||||||
|
val chunkX = SectionPos.blockToSectionCoord(pos.x)
|
||||||
|
val chunkZ = SectionPos.blockToSectionCoord(pos.z)
|
||||||
|
return (chunkX - radius..chunkX + radius).flatMap { x ->
|
||||||
|
(chunkZ - radius..chunkZ + radius).map { z ->
|
||||||
|
getChunk(x, z)
|
||||||
|
}
|
||||||
|
}.toSet()
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"parent": "quaedam:block/skylight_projection"
|
||||||
|
}
|
@ -5,6 +5,7 @@
|
|||||||
"client": [
|
"client": [
|
||||||
],
|
],
|
||||||
"mixins": [
|
"mixins": [
|
||||||
|
"MixinBuiltInRegistries"
|
||||||
],
|
],
|
||||||
"injectors": {
|
"injectors": {
|
||||||
"defaultRequire": 1
|
"defaultRequire": 1
|
||||||
|
@ -1 +1,3 @@
|
|||||||
accessWidener v2 named
|
accessWidener v2 named
|
||||||
|
# Custom Registry for ProjectionEffect
|
||||||
|
accessible method net/minecraft/core/registries/BuiltInRegistries registerSimple (Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/core/registries/BuiltInRegistries$RegistryBootstrap;)Lnet/minecraft/core/Registry;
|
||||||
|
Loading…
Reference in New Issue
Block a user