power button and machine buzz

This commit is contained in:
2026-04-21 21:44:39 +02:00
parent 35a659475a
commit c8da0aba68
7 changed files with 94 additions and 39 deletions

View File

@@ -72,6 +72,15 @@ object NeoComputers {
player -> player ->
NodeSynchronizer.playerScreenClosed(player) NodeSynchronizer.playerScreenClosed(player)
} }
NetworkManager.registerReceiver(NetworkManager.c2s(),NodeSynchronizer.ScreenDataPayload.TYPE, NodeSynchronizer.ScreenDataPayload.CODEC, {
packet, ctx ->
val player = ctx.player
if(player is ServerPlayer) {
NodeSynchronizer.screenMap[player]?.processScreenInteraction(player, packet.buffer)
}
})
// we have to do this because the datagen task runs in the physical server // we have to do this because the datagen task runs in the physical server
EnvExecutor.runInEnv(Env.CLIENT) {{ EnvExecutor.runInEnv(Env.CLIENT) {{
NetworkManager.registerReceiver(NetworkManager.s2c(),NodeSynchronizer.StatePayload.TYPE, NodeSynchronizer.StatePayload.CODEC, { NetworkManager.registerReceiver(NetworkManager.s2c(),NodeSynchronizer.StatePayload.TYPE, NodeSynchronizer.StatePayload.CODEC, {
@@ -94,14 +103,7 @@ object NeoComputers {
EnvExecutor.runInEnv(Env.SERVER) {{ EnvExecutor.runInEnv(Env.SERVER) {{
// https://github.com/architectury/architectury-api/issues/518 // https://github.com/architectury/architectury-api/issues/518
NetworkManager.registerS2CPayloadType(NodeSynchronizer.StatePayload.TYPE, NodeSynchronizer.StatePayload.CODEC) NetworkManager.registerS2CPayloadType(NodeSynchronizer.StatePayload.TYPE, NodeSynchronizer.StatePayload.CODEC)
NetworkManager.registerS2CPayloadType(NodeSynchronizer.ScreenPayload.TYPE, NodeSynchronizer.ScreenPayload.CODEC)
NetworkManager.registerReceiver(NetworkManager.c2s(),NodeSynchronizer.ScreenPayload.TYPE, NodeSynchronizer.ScreenPayload.CODEC, {
packet, ctx ->
val player = ctx.player
if(player is ServerPlayer) {
NodeSynchronizer.screenMap[player]?.processScreenInteraction(player, packet.buffer)
}
})
}} }}
LOGGER.info("Registered!") LOGGER.info("Registered!")

View File

@@ -68,6 +68,27 @@ object NodeSynchronizer {
override fun type() = TYPE override fun type() = TYPE
} }
class ScreenDataPayload(var entityTypeWireID: String, var buffer: FriendlyByteBuf): CustomPacketPayload {
companion object {
val SCREEN_SYNC_ID = ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, "screen_data")
val TYPE = CustomPacketPayload.Type<ScreenDataPayload>(SCREEN_SYNC_ID)
val CODEC = object : StreamCodec<RegistryFriendlyByteBuf, ScreenDataPayload> {
override fun decode(buf: RegistryFriendlyByteBuf): ScreenDataPayload {
val id = buf.readByteArray().decodeToString()
val buffer = FriendlyByteBuf(buf.copy(buf.readerIndex(), buf.readableBytes()))
return ScreenDataPayload(id, buffer)
}
override fun encode(buf: RegistryFriendlyByteBuf, payload: ScreenDataPayload) {
buf.writeByteArray(payload.entityTypeWireID.encodeToByteArray())
buf.writeBytes(payload.buffer)
}
}
}
override fun type() = TYPE
}
val screenMap = mutableMapOf<ServerPlayer, NodeBlockEntity>() val screenMap = mutableMapOf<ServerPlayer, NodeBlockEntity>()
fun playerScreenClosed(player: ServerPlayer) { fun playerScreenClosed(player: ServerPlayer) {
@@ -89,7 +110,7 @@ object NodeSynchronizer {
} }
fun sendScreenInteraction(friendlyByteBuf: FriendlyByteBuf) { fun sendScreenInteraction(friendlyByteBuf: FriendlyByteBuf) {
NetworkManager.sendToServer(ScreenPayload("", friendlyByteBuf)) NetworkManager.sendToServer(ScreenDataPayload("", friendlyByteBuf))
} }
} }

View File

@@ -20,6 +20,7 @@ import net.minecraft.world.MenuProvider
import net.minecraft.world.entity.player.Inventory import net.minecraft.world.entity.player.Inventory
import net.minecraft.world.entity.player.Player import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.ItemStack import net.minecraft.world.item.ItemStack
import net.minecraft.world.level.Level
import net.minecraft.world.level.block.state.BlockState import net.minecraft.world.level.block.state.BlockState
import org.neoflock.neocomputers.NeoComputers import org.neoflock.neocomputers.NeoComputers
import org.neoflock.neocomputers.block.CaseBlock import org.neoflock.neocomputers.block.CaseBlock
@@ -67,13 +68,8 @@ class CaseBlockEntity(blockPos: BlockPos, blockState: BlockState): NodeBlockEnti
} }
override fun encodeScreenData(player: ServerPlayer, packet: FriendlyByteBuf) { override fun encodeScreenData(player: ServerPlayer, packet: FriendlyByteBuf) {
super.encodeScreenData(player, packet)
packet.writeBoolean(isOn) packet.writeBoolean(isOn)
packet.writeLong(node.energy)
packet.writeLong(node.energyCapacity)
packet.writeLong(getMachineMemoryUsed())
packet.writeLong(getMachineMemoryTotal())
packet.writeLong(getMachineComponentsUsed())
packet.writeLong(getMachineMemoryTotal())
} }
val redstoneIn = Array(Direction.entries.size) {0} val redstoneIn = Array(Direction.entries.size) {0}
@@ -110,14 +106,11 @@ class CaseBlockEntity(blockPos: BlockPos, blockState: BlockState): NodeBlockEnti
// Rising edge // Rising edge
start() start()
} }
if(newValue == 0) {
// Not accurate but whatevs
stop()
}
setChanged() setChanged()
} }
override fun getBlockPosition(): BlockPos = blockPos override fun getMachineBlockPosition(): BlockPos = blockPos
override fun getMachineLevel(): Level = level!!
override fun isRunning(): Boolean = isOn override fun isRunning(): Boolean = isOn

View File

@@ -2,6 +2,7 @@ package org.neoflock.neocomputers.entity
import net.minecraft.core.BlockPos import net.minecraft.core.BlockPos
import net.minecraft.core.Direction import net.minecraft.core.Direction
import net.minecraft.world.level.Level
import org.neoflock.neocomputers.item.ComponentItem import org.neoflock.neocomputers.item.ComponentItem
import org.neoflock.neocomputers.network.Networking import org.neoflock.neocomputers.network.Networking
import java.time.Duration import java.time.Duration
@@ -15,7 +16,8 @@ data class MachinePowerEvent(override val machine: MachineEntity, val nowRunning
interface MachineEntity { interface MachineEntity {
// Block position of machine, for wireless tech // Block position of machine, for wireless tech
fun getBlockPosition(): BlockPos fun getMachineBlockPosition(): BlockPos
fun getMachineLevel(): Level
fun beepAsync(frequency: Int, duration: Duration, volume: Double): Boolean fun beepAsync(frequency: Int, duration: Duration, volume: Double): Boolean

View File

@@ -4,40 +4,74 @@ import com.mojang.blaze3d.vertex.BufferBuilder
import com.mojang.blaze3d.vertex.DefaultVertexFormat import com.mojang.blaze3d.vertex.DefaultVertexFormat
import com.mojang.blaze3d.vertex.Tesselator import com.mojang.blaze3d.vertex.Tesselator
import com.mojang.blaze3d.vertex.VertexFormat import com.mojang.blaze3d.vertex.VertexFormat
import io.netty.buffer.Unpooled
import net.minecraft.client.Minecraft
import net.minecraft.client.gui.GuiGraphics import net.minecraft.client.gui.GuiGraphics
import net.minecraft.client.gui.components.Button
import net.minecraft.client.gui.components.ImageButton import net.minecraft.client.gui.components.ImageButton
import net.minecraft.client.gui.components.WidgetSprites
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen
import net.minecraft.network.FriendlyByteBuf
import net.minecraft.network.chat.Component import net.minecraft.network.chat.Component
import net.minecraft.resources.ResourceLocation import net.minecraft.resources.ResourceLocation
import net.minecraft.world.entity.player.Inventory import net.minecraft.world.entity.player.Inventory
import org.neoflock.neocomputers.NeoComputers import org.neoflock.neocomputers.NeoComputers
import org.neoflock.neocomputers.block.NodeSynchronizer
import org.neoflock.neocomputers.gui.menu.CaseMenu import org.neoflock.neocomputers.gui.menu.CaseMenu
import org.neoflock.neocomputers.gui.widget.DynamicSlot import org.neoflock.neocomputers.gui.widget.ButtonSprites
import org.neoflock.neocomputers.gui.widget.ProgressBar import org.neoflock.neocomputers.gui.widget.ImagerButton
import org.neoflock.neocomputers.utils.GenericContainerScreen import org.neoflock.neocomputers.utils.GenericContainerScreen
class CaseScreen : GenericContainerScreen<CaseMenu> { class CaseScreen : GenericContainerScreen<CaseMenu> {
private val PCB: ResourceLocation = ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, "textures/gui/computer.png") private val PCB: ResourceLocation = ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, "textures/gui/computer.png")
private val BTN: ResourceLocation = ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, "textures/gui/button_power.png")
// private val BTN_ENABLED: ResourceLocation = ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, "textures/gui/button/power/enabled.png") // gonna do this later
// private val BTN_DISABLED: ResourceLocation = ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, "textures/gui/button/power/disabled.png")
// private val BTN_ENABLED_HOVER: ResourceLocation = ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, "textures/gui/button/power/enabled_hover.png")
// private val BTN_DISABLED_HOVER: ResourceLocation = ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, "textures/gui/power/disabled_hover.png")
private var btn: ImagerButton? = null
override fun shouldCenterTitle(): Boolean = false override fun shouldCenterTitle(): Boolean = false
constructor(abstractContainerMenu: CaseMenu, inventory: Inventory, component: Component) : super(abstractContainerMenu, inventory, component) var isOn = false
override fun processScreenStatePacket(buf: FriendlyByteBuf) {
super.processScreenStatePacket(buf)
isOn = buf.readBoolean()
btn?.pressed = isOn
}
constructor(abstractContainerMenu: CaseMenu, inventory: Inventory, component: Component) : super(abstractContainerMenu, inventory, component) {
btn = ImagerButton(
15, 15,
18, 18,
ButtonSprites(BTN, 18, 18, 36, 36)
) {
val buf = FriendlyByteBuf(Unpooled.buffer())
buf.writeByte(if(isOn) 0x02 else 0x01)
NodeSynchronizer.sendScreenInteraction(buf)
}
// addRenderableWidget(btn!!)
}
override fun renderBg(guiGraphics: GuiGraphics, f: Float, i: Int, j: Int) { override fun renderBg(guiGraphics: GuiGraphics, f: Float, i: Int, j: Int) {
super.renderBg(guiGraphics, f, i ,j) super.renderBg(guiGraphics, f, i ,j)
val relX = (this.width - this.imageWidth) / 2 val relX = (this.width - this.imageWidth) / 2
val relY = (this.height - this.imageHeight) / 2 val relY = (this.height - this.imageHeight) / 2
guiGraphics.blit(PCB, relX, relY, 0, 0, this.imageWidth, this.imageHeight)
// this.renderSlots(relX, relY) btn!!.x = relX+70
btn!!.y = relY+33
btn!!.render(guiGraphics, i, j, f) // minecraft SUCKSSS
guiGraphics.blit(PCB, relX, relY, 0, 0, this.imageWidth, this.imageHeight)
}
override fun mouseClicked(mouseX: Double, mouseY: Double, button: Int): Boolean { // todo: make a better widget system than mojang, practically not even using the fact it's a widget atp
NeoComputers.LOGGER.info(String.format("btn: %d %d %d %d, mouse %s %s", btn!!.x, btn!!.y, btn!!.x+btn!!.width, btn!!.y+btn!!.height, mouseX.toString(), mouseY.toString()))
if (button != 0) return false
if (btn!!.x < mouseX.toInt() && mouseX.toInt() < btn!!.x+btn!!.width && btn!!.y < mouseY.toInt() && mouseY.toInt() < btn!!.y+btn!!.height) {
btn!!.playDownSound(Minecraft.getInstance().soundManager)
btn!!.onClick(mouseX, mouseY)
return true
} else return false
} }
// private fun renderSlots(relX: Int, relY: Int) { // TODO: put this in some generic screen class
// for (slot in menu.slots) {
// if (slot is DynamicSlot) {
// slot.draw(relX, relY)
// }
// }
// }
} }

View File

@@ -1,6 +1,8 @@
package org.neoflock.neocomputers.sounds package org.neoflock.neocomputers.sounds
import net.minecraft.client.resources.sounds.AbstractTickableSoundInstance import net.minecraft.client.resources.sounds.AbstractTickableSoundInstance
import net.minecraft.client.resources.sounds.EntityBoundSoundInstance
import net.minecraft.client.resources.sounds.MinecartSoundInstance
import net.minecraft.client.resources.sounds.SoundInstance import net.minecraft.client.resources.sounds.SoundInstance
import net.minecraft.sounds.SoundEvent import net.minecraft.sounds.SoundEvent
import net.minecraft.sounds.SoundSource import net.minecraft.sounds.SoundSource
@@ -10,7 +12,7 @@ class ComputerRunningSoundInstance: AbstractTickableSoundInstance {
val machine: MachineEntity val machine: MachineEntity
fun updatePosition() { fun updatePosition() {
val pos = machine.getBlockPosition() val pos = machine.getMachineBlockPosition()
this.x = pos.x.toDouble() + 0.5 this.x = pos.x.toDouble() + 0.5
this.y = pos.y.toDouble() + 0.5 this.y = pos.y.toDouble() + 0.5
this.z = pos.z.toDouble() + 0.5 this.z = pos.z.toDouble() + 0.5
@@ -21,7 +23,7 @@ class ComputerRunningSoundInstance: AbstractTickableSoundInstance {
this.looping = true this.looping = true
this.delay = 0 this.delay = 0
this.volume = 1.0F this.volume = 1.0F
this.relative = true this.pitch = 1.0F
updatePosition() updatePosition()
} }

View File

@@ -46,5 +46,6 @@
"neocomputers.noaddr": "No address assigned", "neocomputers.noaddr": "No address assigned",
"neocomputers.memory.capacity": "Capacity: %1$s", "neocomputers.memory.capacity": "Capacity: %1$s",
"neocomputers.eeprom.codeused": "Code Storage: %1$s / %2$s", "neocomputers.eeprom.codeused": "Code Storage: %1$s / %2$s",
"neocomputers.eeprom.dataused": "Data Storage: %1$s / %2$s" "neocomputers.eeprom.dataused": "Data Storage: %1$s / %2$s",
"sounds.neocomputers.computer_running": "Computer Fans"
} }