feat: simple projection updater
This commit is contained in:
parent
7308a478b8
commit
e7aa4f4c30
@ -21,7 +21,10 @@ subprojects {
|
||||
|
||||
dependencies {
|
||||
"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"
|
||||
group = "quaedam"
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
name = "ParchmentMC"
|
||||
setUrl("https://maven.parchmentmc.org")
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly("org.jetbrains.kotlin:kotlin-stdlib")
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import net.minecraft.world.item.ItemStack
|
||||
import org.slf4j.LoggerFactory
|
||||
import quaedam.projection.ProjectionCommand
|
||||
import quaedam.projection.ProjectionEffectType
|
||||
import quaedam.projection.SimpleProjectionUpdate
|
||||
import quaedam.projection.misc.NoiseProjection
|
||||
import quaedam.projection.misc.SkylightProjection
|
||||
import quaedam.projection.misc.SoundProjection
|
||||
@ -48,6 +49,7 @@ object Quaedam {
|
||||
SoundProjection
|
||||
NoiseProjection
|
||||
ProjectionCommand
|
||||
SimpleProjectionUpdate
|
||||
|
||||
creativeModeTabs.register()
|
||||
items.register()
|
||||
|
@ -1,12 +1,14 @@
|
||||
package quaedam.projection
|
||||
|
||||
import dev.architectury.registry.registries.DeferredSupplier
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.world.level.Level
|
||||
import net.minecraft.world.level.block.EntityBlock
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import quaedam.utils.sendBlockUpdated
|
||||
|
||||
abstract class EntityProjectionBlock<P : ProjectionEffect>(properties: Properties = createProperties()) :
|
||||
ProjectionBlock<P>(properties), EntityBlock {
|
||||
@ -17,16 +19,25 @@ abstract class EntityProjectionBlock<P : ProjectionEffect>(properties: Propertie
|
||||
|
||||
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")
|
||||
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) {
|
||||
getProjection(level, pos).apply(func)
|
||||
sendUpdateToProjectors(level, pos)
|
||||
fun applyChange(level: Level, pos: BlockPos, func: P.() -> Unit) {
|
||||
val entity = getBlockEntity(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()
|
||||
|
||||
fun sendUpdateToProjectors(level: Level, pos: BlockPos) {
|
||||
if (!level.isClientSide) {
|
||||
findNearbyProjectors(level, pos)
|
||||
.forEach { (level.getBlockEntity(it) as ProjectorBlockEntity).checkUpdate() }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@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.block.state.BlockState
|
||||
|
||||
abstract class ProjectionEffect {
|
||||
abstract class ProjectionEffect : Cloneable {
|
||||
|
||||
abstract val type: ProjectionEffectType<*>
|
||||
|
||||
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) }
|
||||
|
||||
override fun equals(other: Any?) = other === this
|
||||
override fun equals(other: Any?): Boolean = other === this
|
||||
|
||||
override fun hashCode() = type.hashCode()
|
||||
|
||||
|
@ -14,19 +14,20 @@ class SimpleProjectionEntity<P : ProjectionEffect>(
|
||||
type: BlockEntityType<SimpleProjectionEntity<P>>,
|
||||
pos: BlockPos,
|
||||
state: BlockState,
|
||||
val projection: P
|
||||
var projection: P,
|
||||
val default: () -> P,
|
||||
) : BlockEntity(type, pos, state) {
|
||||
|
||||
companion object {
|
||||
const val TAG_PROJECTION_EFFECT = "ProjectionEffect"
|
||||
|
||||
fun <P : ProjectionEffect, B: ProjectionBlock<P>> createBlockEntityType(
|
||||
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())
|
||||
SimpleProjectionEntity(type.inner!!, pos, state, default(), default)
|
||||
}, block.get()).build(null)
|
||||
return type.inner!!
|
||||
}
|
||||
@ -41,11 +42,15 @@ class SimpleProjectionEntity<P : ProjectionEffect>(
|
||||
|
||||
override fun load(tag: CompoundTag) {
|
||||
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 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
|
||||
|
||||
import net.minecraft.core.BlockPos
|
||||
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.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.projection.EntityProjectionBlock
|
||||
import quaedam.projection.ProjectionEffect
|
||||
@ -38,6 +45,26 @@ object SkylightProjectionBlock : EntityProjectionBlock<SkylightProjectionEffect>
|
||||
|
||||
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() {
|
||||
|
@ -26,7 +26,7 @@ data class SwarmProjectionEffect(
|
||||
|
||||
override fun fromNbt(tag: CompoundTag, trusted: Boolean) {
|
||||
maxCount = tag.getInt(TAG_MAX_COUNT)
|
||||
if (!trusted){
|
||||
if (!trusted) {
|
||||
maxCount = min(maxCount, 250)
|
||||
}
|
||||
}
|
||||
|
@ -39,6 +39,7 @@ object ProjectorBlock : Block(Properties.of()
|
||||
blockHitResult: BlockHitResult
|
||||
): InteractionResult {
|
||||
checkUpdate(level, blockPos)
|
||||
println(level.getBlockEntity(blockPos)!!.saveWithoutMetadata())
|
||||
return InteractionResult.SUCCESS
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@ org.gradle.parallel=true
|
||||
org.gradle.caching=true
|
||||
org.gradle.jvmargs=-Xmx2048M
|
||||
minecraft_version=1.20.1
|
||||
parchment_version=2023.07.16
|
||||
# https://www.curseforge.com/minecraft/mc-mods/architectury-api
|
||||
architectury_version=9.1.10
|
||||
# https://files.minecraftforge.net/net/minecraftforge/forge/
|
||||
|
Loading…
Reference in New Issue
Block a user