feat: bare projection shell
This commit is contained in:
parent
899eac954e
commit
d88f110fe5
24
common/src/main/java/quaedam/mixin/MixinMinecraftServer.java
Normal file
24
common/src/main/java/quaedam/mixin/MixinMinecraftServer.java
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package quaedam.mixin;
|
||||||
|
|
||||||
|
import net.minecraft.core.GlobalPos;
|
||||||
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import quaedam.mixininterface.ProjectionShellMutexAccessor;
|
||||||
|
import quaedam.shell.ProjectionShellMutex;
|
||||||
|
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
|
||||||
|
@Mixin(MinecraftServer.class)
|
||||||
|
public class MixinMinecraftServer implements ProjectionShellMutexAccessor {
|
||||||
|
|
||||||
|
private LinkedHashMap<GlobalPos, ProjectionShellMutex.Lock> quaedam$projectionShellMutex;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LinkedHashMap<GlobalPos, ProjectionShellMutex.Lock> quaedam$getProjectionShellMutex() {
|
||||||
|
if (quaedam$projectionShellMutex == null) {
|
||||||
|
quaedam$projectionShellMutex = new LinkedHashMap<>();
|
||||||
|
}
|
||||||
|
return quaedam$projectionShellMutex;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
package quaedam.mixininterface;
|
||||||
|
|
||||||
|
import net.minecraft.core.GlobalPos;
|
||||||
|
import quaedam.shell.ProjectionShellMutex;
|
||||||
|
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
|
||||||
|
public interface ProjectionShellMutexAccessor {
|
||||||
|
|
||||||
|
LinkedHashMap<GlobalPos, ProjectionShellMutex.Lock> quaedam$getProjectionShellMutex();
|
||||||
|
|
||||||
|
}
|
@ -17,6 +17,7 @@ import quaedam.projection.misc.SkylightProjection
|
|||||||
import quaedam.projection.misc.SoundProjection
|
import quaedam.projection.misc.SoundProjection
|
||||||
import quaedam.projection.swarm.SwarmProjection
|
import quaedam.projection.swarm.SwarmProjection
|
||||||
import quaedam.projector.Projector
|
import quaedam.projector.Projector
|
||||||
|
import quaedam.shell.ProjectionShell
|
||||||
|
|
||||||
object Quaedam {
|
object Quaedam {
|
||||||
|
|
||||||
@ -50,6 +51,7 @@ object Quaedam {
|
|||||||
NoiseProjection
|
NoiseProjection
|
||||||
ProjectionCommand
|
ProjectionCommand
|
||||||
SimpleProjectionUpdate
|
SimpleProjectionUpdate
|
||||||
|
ProjectionShell
|
||||||
|
|
||||||
creativeModeTabs.register()
|
creativeModeTabs.register()
|
||||||
items.register()
|
items.register()
|
||||||
|
@ -8,10 +8,12 @@ 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.shell.ProjectionEffectShell
|
||||||
|
import quaedam.shell.ProjectionShellBlock
|
||||||
import quaedam.utils.sendBlockUpdated
|
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, ProjectionShellBlock {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun createProperties(): Properties = ProjectionBlock.createProperties()
|
fun createProperties(): Properties = ProjectionBlock.createProperties()
|
||||||
@ -40,4 +42,11 @@ abstract class EntityProjectionBlock<P : ProjectionEffect>(properties: Propertie
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getProjectionEffectForShell(level: Level, pos: BlockPos) =
|
||||||
|
(getBlockEntity(level, pos).cloneProjection() as ProjectionEffectShell.Provider).createShell()
|
||||||
|
|
||||||
|
override fun applyFromShell(level: Level, pos: BlockPos, shell: ProjectionEffectShell) = applyChange(level, pos) {
|
||||||
|
fromNbt(shell.effect.toNbt())
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,20 +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
|
||||||
import quaedam.projection.ProjectionEffectType
|
import quaedam.projection.ProjectionEffectType
|
||||||
import quaedam.projection.SimpleProjectionEntity
|
import quaedam.projection.SimpleProjectionEntity
|
||||||
|
import quaedam.shell.ProjectionEffectShell
|
||||||
|
import quaedam.shell.buildProjectionEffectShell
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
|
||||||
object SkylightProjection {
|
object SkylightProjection {
|
||||||
@ -47,7 +42,7 @@ object SkylightProjectionBlock : EntityProjectionBlock<SkylightProjectionEffect>
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data class SkylightProjectionEffect(var factor: Double = 2.0) : ProjectionEffect() {
|
data class SkylightProjectionEffect(var factor: Double = 2.0) : ProjectionEffect(), ProjectionEffectShell.Provider {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG_FACTOR = "Factor"
|
const val TAG_FACTOR = "Factor"
|
||||||
@ -67,4 +62,8 @@ data class SkylightProjectionEffect(var factor: Double = 2.0) : ProjectionEffect
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun createShell() = buildProjectionEffectShell(this) {
|
||||||
|
doubleSlider("quaedam.shell.skylight.factor", ::factor, 0.0..5.0, 0.1)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,66 @@
|
|||||||
|
package quaedam.shell
|
||||||
|
|
||||||
|
import net.minecraft.client.gui.components.AbstractSliderButton
|
||||||
|
import net.minecraft.client.gui.components.CycleButton
|
||||||
|
import net.minecraft.client.gui.components.StringWidget
|
||||||
|
import net.minecraft.client.gui.layouts.LayoutElement
|
||||||
|
import net.minecraft.network.chat.Component
|
||||||
|
import quaedam.projection.ProjectionEffect
|
||||||
|
import kotlin.math.floor
|
||||||
|
import kotlin.reflect.KMutableProperty0
|
||||||
|
|
||||||
|
class ProjectionEffectShell(val effect: ProjectionEffect) {
|
||||||
|
|
||||||
|
interface Provider {
|
||||||
|
|
||||||
|
fun createShell(): ProjectionEffectShell
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
val rows = mutableListOf<Row>()
|
||||||
|
val width = 150
|
||||||
|
val height = 20
|
||||||
|
|
||||||
|
data class Row(val text: Component, val renderer: ShellRenderer)
|
||||||
|
|
||||||
|
fun row(key: String, renderer: ShellRenderer) {
|
||||||
|
rows += Row(Component.translatable(key), renderer)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun text(key: String, value: Component) = row(key) { StringWidget(value, it.font) }
|
||||||
|
|
||||||
|
fun doubleSlider(key: String, property: KMutableProperty0<Double>, range: ClosedRange<Double>, step: Double) =
|
||||||
|
row(key) {
|
||||||
|
object : AbstractSliderButton(
|
||||||
|
0, 0, width, height,
|
||||||
|
Component.literal(property.get().toString()), property.get()
|
||||||
|
) {
|
||||||
|
override fun updateMessage() {
|
||||||
|
message = Component.literal(value.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun applyValue() {
|
||||||
|
value = floor(value / step) * step
|
||||||
|
property.set(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun intCycle(key: String, property: KMutableProperty0<Int>, range: IntProgression) =
|
||||||
|
row(key) {
|
||||||
|
CycleButton.builder<Int> { Component.literal(it.toString()) }
|
||||||
|
.displayOnlyValue()
|
||||||
|
.withValues(range.toList())
|
||||||
|
.create(0, 0, width, height, Component.translatable(key))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun buildProjectionEffectShell(effect: ProjectionEffect, builder: ProjectionEffectShell.() -> Unit) =
|
||||||
|
ProjectionEffectShell(effect).apply(builder)
|
||||||
|
|
||||||
|
data class ShellRenderContext(val screen: ProjectionShellScreen) {
|
||||||
|
val font get() = screen.getFont()
|
||||||
|
}
|
||||||
|
|
||||||
|
typealias ShellRenderer = (ctx: ShellRenderContext) -> LayoutElement
|
26
common/src/main/kotlin/quaedam/shell/ProjectionShell.kt
Normal file
26
common/src/main/kotlin/quaedam/shell/ProjectionShell.kt
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
package quaedam.shell
|
||||||
|
|
||||||
|
import dev.architectury.networking.NetworkChannel
|
||||||
|
import net.minecraft.resources.ResourceLocation
|
||||||
|
import quaedam.Quaedam
|
||||||
|
import quaedam.shell.network.ClientboundPSHLockResultPacket
|
||||||
|
import quaedam.shell.network.ClientboundPSHLockRevokePacket
|
||||||
|
import quaedam.shell.network.ServerboundPSHLockAcquirePacket
|
||||||
|
import quaedam.shell.network.ServerboundPSHLockReleasePacket
|
||||||
|
|
||||||
|
object ProjectionShell {
|
||||||
|
|
||||||
|
const val ID = "projection_shell"
|
||||||
|
|
||||||
|
val item = Quaedam.items.register(ID) { ProjectionShellItem }!!
|
||||||
|
|
||||||
|
val channel = NetworkChannel.create(ResourceLocation("quaedam", ID))
|
||||||
|
|
||||||
|
init {
|
||||||
|
ServerboundPSHLockAcquirePacket
|
||||||
|
ServerboundPSHLockReleasePacket
|
||||||
|
ClientboundPSHLockRevokePacket
|
||||||
|
ClientboundPSHLockResultPacket
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
12
common/src/main/kotlin/quaedam/shell/ProjectionShellBlock.kt
Normal file
12
common/src/main/kotlin/quaedam/shell/ProjectionShellBlock.kt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package quaedam.shell
|
||||||
|
|
||||||
|
import net.minecraft.core.BlockPos
|
||||||
|
import net.minecraft.world.level.Level
|
||||||
|
|
||||||
|
interface ProjectionShellBlock {
|
||||||
|
|
||||||
|
fun getProjectionEffectForShell(level: Level, pos: BlockPos): ProjectionEffectShell
|
||||||
|
|
||||||
|
fun applyFromShell(level: Level, pos: BlockPos, shell: ProjectionEffectShell)
|
||||||
|
|
||||||
|
}
|
24
common/src/main/kotlin/quaedam/shell/ProjectionShellItem.kt
Normal file
24
common/src/main/kotlin/quaedam/shell/ProjectionShellItem.kt
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package quaedam.shell
|
||||||
|
|
||||||
|
import net.minecraft.world.InteractionResult
|
||||||
|
import net.minecraft.world.item.Item
|
||||||
|
import net.minecraft.world.item.context.UseOnContext
|
||||||
|
import quaedam.Quaedam
|
||||||
|
import quaedam.shell.network.ServerboundPSHLockAcquirePacket
|
||||||
|
|
||||||
|
object ProjectionShellItem : Item(
|
||||||
|
Properties()
|
||||||
|
.stacksTo(1)
|
||||||
|
.`arch$tab`(Quaedam.creativeModeTab)
|
||||||
|
) {
|
||||||
|
|
||||||
|
override fun useOn(context: UseOnContext): InteractionResult {
|
||||||
|
val block = context.level.getBlockState(context.clickedPos).block
|
||||||
|
if (block is ProjectionShellBlock && context.level.isClientSide) {
|
||||||
|
ProjectionShell.channel.sendToServer(ServerboundPSHLockAcquirePacket(context.clickedPos))
|
||||||
|
return InteractionResult.SUCCESS
|
||||||
|
}
|
||||||
|
return InteractionResult.PASS
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
49
common/src/main/kotlin/quaedam/shell/ProjectionShellMutex.kt
Normal file
49
common/src/main/kotlin/quaedam/shell/ProjectionShellMutex.kt
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
package quaedam.shell
|
||||||
|
|
||||||
|
import dev.architectury.event.events.common.TickEvent
|
||||||
|
import net.minecraft.core.BlockPos
|
||||||
|
import net.minecraft.core.GlobalPos
|
||||||
|
import net.minecraft.server.level.ServerLevel
|
||||||
|
import net.minecraft.server.level.ServerPlayer
|
||||||
|
import quaedam.mixininterface.ProjectionShellMutexAccessor
|
||||||
|
import quaedam.shell.network.ClientboundPSHLockRevokePacket
|
||||||
|
|
||||||
|
object ProjectionShellMutex {
|
||||||
|
|
||||||
|
init {
|
||||||
|
TickEvent.SERVER_POST.register { server ->
|
||||||
|
val mutex = (server as ProjectionShellMutexAccessor).`quaedam$getProjectionShellMutex`()
|
||||||
|
val currentTime = System.currentTimeMillis()
|
||||||
|
mutex.forEach { pos, lock ->
|
||||||
|
if (currentTime - lock.time > 60 * 1000) {
|
||||||
|
mutex.remove(pos)
|
||||||
|
ProjectionShell.channel.sendToPlayer(lock.player, ClientboundPSHLockRevokePacket)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun tryLock(level: ServerLevel, pos: BlockPos, player: ServerPlayer): Boolean {
|
||||||
|
val mutex = (level.server as ProjectionShellMutexAccessor).`quaedam$getProjectionShellMutex`()
|
||||||
|
val gPos = GlobalPos.of(level.dimension(), pos)
|
||||||
|
if (mutex.values.any { it.player == player }) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (gPos !in mutex) {
|
||||||
|
mutex[gPos] = Lock(player, System.currentTimeMillis())
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
fun release(level: ServerLevel, pos: BlockPos, player: ServerPlayer) {
|
||||||
|
val mutex = (level.server as ProjectionShellMutexAccessor).`quaedam$getProjectionShellMutex`()
|
||||||
|
val gPos = GlobalPos.of(level.dimension(), pos)
|
||||||
|
if (mutex[gPos]?.player == player) {
|
||||||
|
mutex.remove(gPos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class Lock(val player: ServerPlayer, val time: Long)
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,53 @@
|
|||||||
|
package quaedam.shell
|
||||||
|
|
||||||
|
import net.minecraft.client.gui.GuiGraphics
|
||||||
|
import net.minecraft.client.gui.components.Button
|
||||||
|
import net.minecraft.client.gui.components.StringWidget
|
||||||
|
import net.minecraft.client.gui.layouts.GridLayout
|
||||||
|
import net.minecraft.client.gui.screens.Screen
|
||||||
|
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen
|
||||||
|
import net.minecraft.core.BlockPos
|
||||||
|
import net.minecraft.network.chat.Component
|
||||||
|
import net.minecraft.world.level.Level
|
||||||
|
import quaedam.shell.network.ServerboundPSHLockReleasePacket
|
||||||
|
|
||||||
|
class ProjectionShellScreen(val level: Level, val pos: BlockPos, val shell: ProjectionEffectShell) :
|
||||||
|
Screen(Component.translatable("quaedam.screen.projection_shell")) {
|
||||||
|
|
||||||
|
val layout = GridLayout()
|
||||||
|
|
||||||
|
override fun init() {
|
||||||
|
super.init()
|
||||||
|
layout.spacing(4)
|
||||||
|
val rows = layout.createRowHelper(2)
|
||||||
|
val renderContext = ShellRenderContext(this)
|
||||||
|
shell.rows.forEach {
|
||||||
|
rows.addChild(StringWidget(150, 20, it.text, font))
|
||||||
|
rows.addChild(it.renderer(renderContext))
|
||||||
|
}
|
||||||
|
run { // Buttons
|
||||||
|
rows.addChild(StringWidget(Component.empty(), font))
|
||||||
|
rows.addChild(Button.builder(Component.translatable("quaedam.screen.projection_shell.save")) {
|
||||||
|
val block = level.getBlockState(pos).block
|
||||||
|
if (block is ProjectionShellBlock) {
|
||||||
|
block.applyFromShell(level, pos, shell)
|
||||||
|
}
|
||||||
|
}.build())
|
||||||
|
}
|
||||||
|
layout.arrangeElements()
|
||||||
|
layout.visitWidgets(::addRenderableWidget)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getFont() = font
|
||||||
|
|
||||||
|
override fun renderBackground(guiGraphics: GuiGraphics) {
|
||||||
|
super.renderBackground(guiGraphics)
|
||||||
|
guiGraphics.blit(AbstractContainerScreen.INVENTORY_LOCATION, width / 2, height / 2, 0, 0, 176, 166)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun removed() {
|
||||||
|
super.removed()
|
||||||
|
ProjectionShell.channel.sendToServer(ServerboundPSHLockReleasePacket(pos))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,70 @@
|
|||||||
|
package quaedam.shell.network
|
||||||
|
|
||||||
|
import dev.architectury.networking.NetworkManager.PacketContext
|
||||||
|
import dev.architectury.utils.GameInstance
|
||||||
|
import net.minecraft.core.BlockPos
|
||||||
|
import net.minecraft.network.FriendlyByteBuf
|
||||||
|
import net.minecraft.network.chat.Component
|
||||||
|
import quaedam.Quaedam
|
||||||
|
import quaedam.shell.ProjectionShell
|
||||||
|
import quaedam.shell.ProjectionShellBlock
|
||||||
|
import quaedam.shell.ProjectionShellScreen
|
||||||
|
import java.util.function.Supplier
|
||||||
|
|
||||||
|
data class ClientboundPSHLockResultPacket(val pos: BlockPos, val result: Boolean) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
init {
|
||||||
|
ProjectionShell.channel.register(
|
||||||
|
ClientboundPSHLockResultPacket::class.java,
|
||||||
|
ClientboundPSHLockResultPacket::encode,
|
||||||
|
::ClientboundPSHLockResultPacket,
|
||||||
|
ClientboundPSHLockResultPacket::apply
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(buf: FriendlyByteBuf) : this(buf.readBlockPos(), buf.readBoolean())
|
||||||
|
|
||||||
|
fun encode(buf: FriendlyByteBuf) {
|
||||||
|
buf.writeBlockPos(pos)
|
||||||
|
buf.writeBoolean(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun apply(context: Supplier<PacketContext>) {
|
||||||
|
val ctx = context.get()
|
||||||
|
if (ctx.player.level().isClientSide) {
|
||||||
|
val client = GameInstance.getClient()
|
||||||
|
if (result) {
|
||||||
|
val level = ctx.player.level()
|
||||||
|
val block = level.getBlockState(pos).block
|
||||||
|
if (block is ProjectionShellBlock) {
|
||||||
|
ctx.queue {
|
||||||
|
try {
|
||||||
|
client.setScreen(
|
||||||
|
ProjectionShellScreen(
|
||||||
|
level,
|
||||||
|
pos,
|
||||||
|
block.getProjectionEffectForShell(level, pos)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
Quaedam.logger.error("Failed to open projection shell screen", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Quaedam.logger.warn("ClientboundPSHLockResultPacket with non-shell-provider block received")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ctx.queue {
|
||||||
|
client.setScreen(null)
|
||||||
|
client.gui.setOverlayMessage(
|
||||||
|
Component.translatable("quaedam.screen.projection_shell.lock_failed"),
|
||||||
|
false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
package quaedam.shell.network
|
||||||
|
|
||||||
|
import dev.architectury.networking.NetworkManager.PacketContext
|
||||||
|
import dev.architectury.utils.GameInstance
|
||||||
|
import net.minecraft.network.chat.Component
|
||||||
|
import quaedam.shell.ProjectionShell
|
||||||
|
import quaedam.shell.ProjectionShellScreen
|
||||||
|
import java.util.function.Supplier
|
||||||
|
|
||||||
|
object ClientboundPSHLockRevokePacket {
|
||||||
|
|
||||||
|
init {
|
||||||
|
ProjectionShell.channel.register(
|
||||||
|
ClientboundPSHLockRevokePacket::class.java,
|
||||||
|
{ _, _ -> },
|
||||||
|
{ ClientboundPSHLockRevokePacket },
|
||||||
|
{ _, ctx -> apply(ctx) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun apply(context: Supplier<PacketContext>) {
|
||||||
|
val ctx = context.get()
|
||||||
|
if (ctx.player.level().isClientSide) {
|
||||||
|
ctx.queue {
|
||||||
|
val client = GameInstance.getClient()
|
||||||
|
if (client.screen is ProjectionShellScreen) {
|
||||||
|
client.setScreen(null)
|
||||||
|
client.gui.setOverlayMessage(
|
||||||
|
Component.translatable("quaedam.screen.projection_shell.lock_revoked"),
|
||||||
|
false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
package quaedam.shell.network
|
||||||
|
|
||||||
|
import dev.architectury.networking.NetworkManager.PacketContext
|
||||||
|
import net.minecraft.core.BlockPos
|
||||||
|
import net.minecraft.network.FriendlyByteBuf
|
||||||
|
import net.minecraft.server.level.ServerLevel
|
||||||
|
import net.minecraft.server.level.ServerPlayer
|
||||||
|
import quaedam.shell.ProjectionShell
|
||||||
|
import quaedam.shell.ProjectionShellMutex
|
||||||
|
import java.util.function.Supplier
|
||||||
|
|
||||||
|
data class ServerboundPSHLockAcquirePacket(val pos: BlockPos) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
init {
|
||||||
|
ProjectionShell.channel.register(
|
||||||
|
ServerboundPSHLockAcquirePacket::class.java,
|
||||||
|
ServerboundPSHLockAcquirePacket::encode,
|
||||||
|
::ServerboundPSHLockAcquirePacket,
|
||||||
|
ServerboundPSHLockAcquirePacket::apply
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(buf: FriendlyByteBuf) : this(buf.readBlockPos())
|
||||||
|
|
||||||
|
fun encode(buf: FriendlyByteBuf) {
|
||||||
|
buf.writeBlockPos(pos)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun apply(context: Supplier<PacketContext>) {
|
||||||
|
val ctx = context.get()
|
||||||
|
if (!ctx.player.level().isClientSide) {
|
||||||
|
ctx.queue {
|
||||||
|
val player = ctx.player as ServerPlayer
|
||||||
|
val result = ProjectionShellMutex.tryLock(ctx.player.level() as ServerLevel, pos, player)
|
||||||
|
ProjectionShell.channel.sendToPlayer(player, ClientboundPSHLockResultPacket(pos, result))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
package quaedam.shell.network
|
||||||
|
|
||||||
|
import dev.architectury.networking.NetworkManager.PacketContext
|
||||||
|
import net.minecraft.core.BlockPos
|
||||||
|
import net.minecraft.network.FriendlyByteBuf
|
||||||
|
import net.minecraft.server.level.ServerLevel
|
||||||
|
import net.minecraft.server.level.ServerPlayer
|
||||||
|
import quaedam.shell.ProjectionShell
|
||||||
|
import quaedam.shell.ProjectionShellMutex
|
||||||
|
import java.util.function.Supplier
|
||||||
|
|
||||||
|
data class ServerboundPSHLockReleasePacket(val pos: BlockPos) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
init {
|
||||||
|
ProjectionShell.channel.register(
|
||||||
|
ServerboundPSHLockReleasePacket::class.java,
|
||||||
|
ServerboundPSHLockReleasePacket::encode,
|
||||||
|
::ServerboundPSHLockReleasePacket,
|
||||||
|
ServerboundPSHLockReleasePacket::apply
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(buf: FriendlyByteBuf) : this(buf.readBlockPos())
|
||||||
|
|
||||||
|
fun encode(buf: FriendlyByteBuf) {
|
||||||
|
buf.writeBlockPos(pos)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun apply(context: Supplier<PacketContext>) {
|
||||||
|
val ctx = context.get()
|
||||||
|
if (!ctx.player.level().isClientSide) {
|
||||||
|
ctx.queue {
|
||||||
|
val player = ctx.player as ServerPlayer
|
||||||
|
ProjectionShellMutex.release(ctx.player.level() as ServerLevel, pos, player)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -5,5 +5,11 @@
|
|||||||
"block.quaedam.swarm_projection": "Swarm Projection",
|
"block.quaedam.swarm_projection": "Swarm Projection",
|
||||||
"block.quaedam.sound_projection": "Sound Projection",
|
"block.quaedam.sound_projection": "Sound Projection",
|
||||||
"block.quaedam.noise_projection": "Noise Projection",
|
"block.quaedam.noise_projection": "Noise Projection",
|
||||||
"entity.quaedam.projected_person": "Virtual Person"
|
"entity.quaedam.projected_person": "Virtual Person",
|
||||||
|
"item.quaedam.projection_shell": "Projection Shell",
|
||||||
|
"quaedam.screen.projection_shell": "Projection Shell",
|
||||||
|
"quaedam.screen.projection_shell.lock_revoked": "Timeout! Connection Lost",
|
||||||
|
"quaedam.screen.projection_shell.lock_failed": "Permission denied!",
|
||||||
|
"quaedam.screen.projection_shell.save": "Save",
|
||||||
|
"quaedam.shell.skylight.factor": "Factor"
|
||||||
}
|
}
|
@ -5,5 +5,9 @@
|
|||||||
"block.quaedam.swarm_projection": "人群投影",
|
"block.quaedam.swarm_projection": "人群投影",
|
||||||
"block.quaedam.sound_projection": "声音投影",
|
"block.quaedam.sound_projection": "声音投影",
|
||||||
"block.quaedam.noise_projection": "噪音投影",
|
"block.quaedam.noise_projection": "噪音投影",
|
||||||
"entity.quaedam.projected_person": "虚拟个体"
|
"entity.quaedam.projected_person": "虚拟个体",
|
||||||
|
"item.quaedam.projection_shell": "投影操作面板",
|
||||||
|
"quaedam.screen.projection_shell": "投影操作",
|
||||||
|
"quaedam.screen.projection_shell.lock_revoked": "超时!连接丢失",
|
||||||
|
"quaedam.screen.projection_shell.lock_failed": "正被使用"
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,8 @@
|
|||||||
],
|
],
|
||||||
"mixins": [
|
"mixins": [
|
||||||
"MixinBedBlock",
|
"MixinBedBlock",
|
||||||
"MixinBuiltInRegistries"
|
"MixinBuiltInRegistries",
|
||||||
|
"MixinMinecraftServer"
|
||||||
],
|
],
|
||||||
"injectors": {
|
"injectors": {
|
||||||
"defaultRequire": 1
|
"defaultRequire": 1
|
||||||
|
Loading…
Reference in New Issue
Block a user