feat: simple projection updater
This commit is contained in:
parent
7308a478b8
commit
e7aa4f4c30
@ -21,7 +21,10 @@ subprojects {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
"minecraft"("com.mojang:minecraft:${project.property("minecraft_version")}")
|
"minecraft"("com.mojang:minecraft:${project.property("minecraft_version")}")
|
||||||
"mappings"(loom.officialMojangMappings())
|
"mappings"(loom.layered {
|
||||||
|
officialMojangMappings()
|
||||||
|
parchment("org.parchmentmc.data:parchment-${project.property("minecraft_version")}:${project.property("parchment_version")}@zip")
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,6 +38,13 @@ allprojects {
|
|||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
group = "quaedam"
|
group = "quaedam"
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
maven {
|
||||||
|
name = "ParchmentMC"
|
||||||
|
setUrl("https://maven.parchmentmc.org")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compileOnly("org.jetbrains.kotlin:kotlin-stdlib")
|
compileOnly("org.jetbrains.kotlin:kotlin-stdlib")
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import net.minecraft.world.item.ItemStack
|
|||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import quaedam.projection.ProjectionCommand
|
import quaedam.projection.ProjectionCommand
|
||||||
import quaedam.projection.ProjectionEffectType
|
import quaedam.projection.ProjectionEffectType
|
||||||
|
import quaedam.projection.SimpleProjectionUpdate
|
||||||
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
|
||||||
@ -48,6 +49,7 @@ object Quaedam {
|
|||||||
SoundProjection
|
SoundProjection
|
||||||
NoiseProjection
|
NoiseProjection
|
||||||
ProjectionCommand
|
ProjectionCommand
|
||||||
|
SimpleProjectionUpdate
|
||||||
|
|
||||||
creativeModeTabs.register()
|
creativeModeTabs.register()
|
||||||
items.register()
|
items.register()
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
package quaedam.projection
|
package quaedam.projection
|
||||||
|
|
||||||
import dev.architectury.registry.registries.DeferredSupplier
|
import dev.architectury.registry.registries.DeferredSupplier
|
||||||
|
import net.minecraft.client.Minecraft
|
||||||
import net.minecraft.core.BlockPos
|
import net.minecraft.core.BlockPos
|
||||||
import net.minecraft.server.level.ServerLevel
|
import net.minecraft.server.level.ServerLevel
|
||||||
import net.minecraft.world.level.Level
|
import net.minecraft.world.level.Level
|
||||||
import net.minecraft.world.level.block.EntityBlock
|
import net.minecraft.world.level.block.EntityBlock
|
||||||
import net.minecraft.world.level.block.entity.BlockEntityType
|
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 quaedam.utils.sendBlockUpdated
|
||||||
|
|
||||||
abstract class EntityProjectionBlock<P : ProjectionEffect>(properties: Properties = createProperties()) :
|
abstract class EntityProjectionBlock<P : ProjectionEffect>(properties: Properties = createProperties()) :
|
||||||
ProjectionBlock<P>(properties), EntityBlock {
|
ProjectionBlock<P>(properties), EntityBlock {
|
||||||
@ -17,16 +19,25 @@ abstract class EntityProjectionBlock<P : ProjectionEffect>(properties: Propertie
|
|||||||
|
|
||||||
abstract val blockEntity: DeferredSupplier<BlockEntityType<SimpleProjectionEntity<P>>>
|
abstract val blockEntity: DeferredSupplier<BlockEntityType<SimpleProjectionEntity<P>>>
|
||||||
|
|
||||||
override fun newBlockEntity(pos: BlockPos, state: BlockState) = blockEntity.get().create(pos, state)
|
override fun newBlockEntity(pos: BlockPos, state: BlockState) = blockEntity.get().create(pos, state)!!
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
fun getProjection(level: Level, pos: BlockPos) = (level.getBlockEntity(pos) as SimpleProjectionEntity<P>).projection
|
fun getBlockEntity(level: Level, pos: BlockPos) = (level.getBlockEntity(pos) as SimpleProjectionEntity<P>)
|
||||||
|
|
||||||
override fun applyProjectionEffect(level: ServerLevel, state: BlockState, pos: BlockPos) = getProjection(level, pos)
|
override fun applyProjectionEffect(level: ServerLevel, state: BlockState, pos: BlockPos) =
|
||||||
|
getBlockEntity(level, pos).cloneProjection()
|
||||||
|
|
||||||
inline fun applyChange(level: Level, pos: BlockPos, func: P.() -> Unit) {
|
fun applyChange(level: Level, pos: BlockPos, func: P.() -> Unit) {
|
||||||
getProjection(level, pos).apply(func)
|
val entity = getBlockEntity(level, pos)
|
||||||
sendUpdateToProjectors(level, pos)
|
val projection = entity.projection
|
||||||
|
projection.apply(func)
|
||||||
|
if (level.isClientSide) {
|
||||||
|
check(level == Minecraft.getInstance().player!!.level())
|
||||||
|
SimpleProjectionUpdate.send(pos, projection.toNbt())
|
||||||
|
} else {
|
||||||
|
getBlockEntity(level, pos).sendBlockUpdated()
|
||||||
|
sendUpdateToProjectors(level, pos)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,13 @@ abstract class ProjectionBlock<P : ProjectionEffect>(properties: Properties = cr
|
|||||||
}
|
}
|
||||||
.toSet()
|
.toSet()
|
||||||
|
|
||||||
|
fun sendUpdateToProjectors(level: Level, pos: BlockPos) {
|
||||||
|
if (!level.isClientSide) {
|
||||||
|
findNearbyProjectors(level, pos)
|
||||||
|
.forEach { (level.getBlockEntity(it) as ProjectorBlockEntity).checkUpdate() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("OVERRIDE_DEPRECATION")
|
@Suppress("OVERRIDE_DEPRECATION")
|
||||||
@ -52,11 +59,4 @@ abstract class ProjectionBlock<P : ProjectionEffect>(properties: Properties = cr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun sendUpdateToProjectors(level: Level, pos: BlockPos) {
|
|
||||||
if (!level.isClientSide) {
|
|
||||||
findNearbyProjectors(level, pos)
|
|
||||||
.forEach { (level.getBlockEntity(it) as ProjectorBlockEntity).checkUpdate() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -10,17 +10,17 @@ import net.minecraft.server.level.ServerLevel
|
|||||||
import net.minecraft.world.level.Level
|
import net.minecraft.world.level.Level
|
||||||
import net.minecraft.world.level.block.state.BlockState
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
|
|
||||||
abstract class ProjectionEffect {
|
abstract class ProjectionEffect : Cloneable {
|
||||||
|
|
||||||
abstract val type: ProjectionEffectType<*>
|
abstract val type: ProjectionEffectType<*>
|
||||||
|
|
||||||
abstract fun toNbt(tag: CompoundTag)
|
abstract fun toNbt(tag: CompoundTag)
|
||||||
|
|
||||||
abstract fun fromNbt(tag: CompoundTag, trusted: Boolean)
|
abstract fun fromNbt(tag: CompoundTag, trusted: Boolean = true)
|
||||||
|
|
||||||
fun toNbt() = CompoundTag().apply { toNbt(this) }
|
fun toNbt() = CompoundTag().apply { toNbt(this) }
|
||||||
|
|
||||||
override fun equals(other: Any?) = other === this
|
override fun equals(other: Any?): Boolean = other === this
|
||||||
|
|
||||||
override fun hashCode() = type.hashCode()
|
override fun hashCode() = type.hashCode()
|
||||||
|
|
||||||
|
@ -14,19 +14,20 @@ class SimpleProjectionEntity<P : ProjectionEffect>(
|
|||||||
type: BlockEntityType<SimpleProjectionEntity<P>>,
|
type: BlockEntityType<SimpleProjectionEntity<P>>,
|
||||||
pos: BlockPos,
|
pos: BlockPos,
|
||||||
state: BlockState,
|
state: BlockState,
|
||||||
val projection: P
|
var projection: P,
|
||||||
|
val default: () -> P,
|
||||||
) : BlockEntity(type, pos, state) {
|
) : BlockEntity(type, pos, state) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG_PROJECTION_EFFECT = "ProjectionEffect"
|
const val TAG_PROJECTION_EFFECT = "ProjectionEffect"
|
||||||
|
|
||||||
fun <P : ProjectionEffect, B: ProjectionBlock<P>> createBlockEntityType(
|
fun <P : ProjectionEffect, B : ProjectionBlock<P>> createBlockEntityType(
|
||||||
block: RegistrySupplier<B>,
|
block: RegistrySupplier<B>,
|
||||||
default: () -> P,
|
default: () -> P,
|
||||||
): BlockEntityType<SimpleProjectionEntity<P>> {
|
): BlockEntityType<SimpleProjectionEntity<P>> {
|
||||||
val type = ValueContainer<BlockEntityType<SimpleProjectionEntity<P>>>()
|
val type = ValueContainer<BlockEntityType<SimpleProjectionEntity<P>>>()
|
||||||
type.inner = BlockEntityType.Builder.of({ pos, state ->
|
type.inner = BlockEntityType.Builder.of({ pos, state ->
|
||||||
SimpleProjectionEntity(type.inner!!, pos, state, default())
|
SimpleProjectionEntity(type.inner!!, pos, state, default(), default)
|
||||||
}, block.get()).build(null)
|
}, block.get()).build(null)
|
||||||
return type.inner!!
|
return type.inner!!
|
||||||
}
|
}
|
||||||
@ -41,11 +42,15 @@ class SimpleProjectionEntity<P : ProjectionEffect>(
|
|||||||
|
|
||||||
override fun load(tag: CompoundTag) {
|
override fun load(tag: CompoundTag) {
|
||||||
super.load(tag)
|
super.load(tag)
|
||||||
projection.fromNbt(tag.getCompound(TAG_PROJECTION_EFFECT), true)
|
if (TAG_PROJECTION_EFFECT in tag) {
|
||||||
|
projection.fromNbt(tag.getCompound(TAG_PROJECTION_EFFECT))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
|
fun cloneProjection() = default().apply { fromNbt(projection.toNbt()) }
|
||||||
|
|
||||||
}
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
package quaedam.projection
|
||||||
|
|
||||||
|
import dev.architectury.networking.NetworkManager
|
||||||
|
import dev.architectury.networking.NetworkManager.PacketContext
|
||||||
|
import io.netty.buffer.Unpooled
|
||||||
|
import net.minecraft.core.BlockPos
|
||||||
|
import net.minecraft.nbt.CompoundTag
|
||||||
|
import net.minecraft.network.FriendlyByteBuf
|
||||||
|
import net.minecraft.network.chat.Component
|
||||||
|
import net.minecraft.resources.ResourceLocation
|
||||||
|
import net.minecraft.server.level.ServerPlayer
|
||||||
|
import quaedam.Quaedam
|
||||||
|
import quaedam.utils.sendBlockUpdated
|
||||||
|
|
||||||
|
object SimpleProjectionUpdate {
|
||||||
|
|
||||||
|
val id = ResourceLocation("quaedam", "simple_projection_update")
|
||||||
|
|
||||||
|
init {
|
||||||
|
NetworkManager.registerReceiver(NetworkManager.Side.C2S, id, ::handle)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handle(buf: FriendlyByteBuf, ctx: PacketContext) {
|
||||||
|
val player = ctx.player!! as ServerPlayer
|
||||||
|
val level = player.level()
|
||||||
|
|
||||||
|
val pos = buf.readBlockPos()
|
||||||
|
val data = buf.readNbt()!!
|
||||||
|
|
||||||
|
if (player.blockPosition().distSqr(pos) > 10 * 10) {
|
||||||
|
Quaedam.logger.info("Player ${player.name} tried to update a projection block far away")
|
||||||
|
if (player.blockPosition().distSqr(pos) > 50 * 50) {
|
||||||
|
player.connection.disconnect(Component.literal("[Quaedam] wth r u doing? why not waiting for server?"))
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
level.server!!.execute {
|
||||||
|
val entity = level.getBlockEntity(pos) ?: return@execute
|
||||||
|
val blockEntity = entity as SimpleProjectionEntity<*>
|
||||||
|
try {
|
||||||
|
blockEntity.projection.fromNbt(data, trusted = false)
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
Quaedam.logger.error(
|
||||||
|
"Player ${player.name} tried to update projection " +
|
||||||
|
"at $pos but caused error: $data", e
|
||||||
|
)
|
||||||
|
player.connection.disconnect(Component.literal("[Quaedam] ? wait what did you send to the server?"))
|
||||||
|
return@execute
|
||||||
|
}
|
||||||
|
blockEntity.sendBlockUpdated()
|
||||||
|
ProjectionBlock.sendUpdateToProjectors(level, pos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun send(pos: BlockPos, data: CompoundTag) {
|
||||||
|
val buf = FriendlyByteBuf(Unpooled.buffer())
|
||||||
|
buf.writeBlockPos(pos)
|
||||||
|
buf.writeNbt(data)
|
||||||
|
NetworkManager.sendToServer(id, buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,8 +1,15 @@
|
|||||||
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.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.BlockItem
|
||||||
import net.minecraft.world.item.Item
|
import net.minecraft.world.item.Item
|
||||||
|
import net.minecraft.world.level.Level
|
||||||
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
|
import net.minecraft.world.phys.BlockHitResult
|
||||||
import quaedam.Quaedam
|
import quaedam.Quaedam
|
||||||
import quaedam.projection.EntityProjectionBlock
|
import quaedam.projection.EntityProjectionBlock
|
||||||
import quaedam.projection.ProjectionEffect
|
import quaedam.projection.ProjectionEffect
|
||||||
@ -38,6 +45,26 @@ object SkylightProjectionBlock : EntityProjectionBlock<SkylightProjectionEffect>
|
|||||||
|
|
||||||
override val blockEntity = SkylightProjection.blockEntity
|
override val blockEntity = SkylightProjection.blockEntity
|
||||||
|
|
||||||
|
override fun use(
|
||||||
|
blockState: BlockState,
|
||||||
|
level: Level,
|
||||||
|
blockPos: BlockPos,
|
||||||
|
player: Player,
|
||||||
|
interactionHand: InteractionHand,
|
||||||
|
blockHitResult: BlockHitResult
|
||||||
|
): InteractionResult {
|
||||||
|
if (level.isClientSide) {
|
||||||
|
println("update")
|
||||||
|
applyChange(level, blockPos) {
|
||||||
|
factor -= 0.5
|
||||||
|
if (factor < 0.5) factor = 2.0
|
||||||
|
println("new factor: $factor")
|
||||||
|
}
|
||||||
|
return InteractionResult.CONSUME
|
||||||
|
}
|
||||||
|
return super.use(blockState, level, blockPos, player, interactionHand, blockHitResult)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data class SkylightProjectionEffect(var factor: Double = 2.0) : ProjectionEffect() {
|
data class SkylightProjectionEffect(var factor: Double = 2.0) : ProjectionEffect() {
|
||||||
|
@ -26,7 +26,7 @@ data class SwarmProjectionEffect(
|
|||||||
|
|
||||||
override fun fromNbt(tag: CompoundTag, trusted: Boolean) {
|
override fun fromNbt(tag: CompoundTag, trusted: Boolean) {
|
||||||
maxCount = tag.getInt(TAG_MAX_COUNT)
|
maxCount = tag.getInt(TAG_MAX_COUNT)
|
||||||
if (!trusted){
|
if (!trusted) {
|
||||||
maxCount = min(maxCount, 250)
|
maxCount = min(maxCount, 250)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,7 @@ object ProjectorBlock : Block(Properties.of()
|
|||||||
blockHitResult: BlockHitResult
|
blockHitResult: BlockHitResult
|
||||||
): InteractionResult {
|
): InteractionResult {
|
||||||
checkUpdate(level, blockPos)
|
checkUpdate(level, blockPos)
|
||||||
|
println(level.getBlockEntity(blockPos)!!.saveWithoutMetadata())
|
||||||
return InteractionResult.SUCCESS
|
return InteractionResult.SUCCESS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ org.gradle.parallel=true
|
|||||||
org.gradle.caching=true
|
org.gradle.caching=true
|
||||||
org.gradle.jvmargs=-Xmx2048M
|
org.gradle.jvmargs=-Xmx2048M
|
||||||
minecraft_version=1.20.1
|
minecraft_version=1.20.1
|
||||||
|
parchment_version=2023.07.16
|
||||||
# https://www.curseforge.com/minecraft/mc-mods/architectury-api
|
# https://www.curseforge.com/minecraft/mc-mods/architectury-api
|
||||||
architectury_version=9.1.10
|
architectury_version=9.1.10
|
||||||
# https://files.minecraftforge.net/net/minecraftforge/forge/
|
# https://files.minecraftforge.net/net/minecraftforge/forge/
|
||||||
|
Loading…
Reference in New Issue
Block a user