innovation

This commit is contained in:
2026-04-21 20:51:30 +02:00
parent f2f79244e6
commit 7542052d1e
24 changed files with 564 additions and 104 deletions

View File

@@ -0,0 +1,217 @@
package org.neoflock.neocomputers.entity
import net.minecraft.client.Minecraft
import net.minecraft.client.resources.sounds.BiomeAmbientSoundsHandler
import net.minecraft.client.resources.sounds.EntityBoundSoundInstance
import net.minecraft.client.resources.sounds.SoundInstance
import net.minecraft.client.sounds.LoopingAudioStream
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.core.HolderLookup
import net.minecraft.core.NonNullList
import net.minecraft.nbt.CompoundTag
import net.minecraft.network.FriendlyByteBuf
import net.minecraft.network.chat.Component
import net.minecraft.server.level.ServerPlayer
import net.minecraft.sounds.SoundSource
import net.minecraft.world.Container
import net.minecraft.world.ContainerHelper
import net.minecraft.world.MenuProvider
import net.minecraft.world.entity.player.Inventory
import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.ItemStack
import net.minecraft.world.level.block.state.BlockState
import org.neoflock.neocomputers.NeoComputers
import org.neoflock.neocomputers.block.CaseBlock
import org.neoflock.neocomputers.block.NodeBlockEntity
import org.neoflock.neocomputers.block.dirToIdx
import org.neoflock.neocomputers.gui.menu.CaseMenu
import org.neoflock.neocomputers.item.ComponentItem
import org.neoflock.neocomputers.network.Networking
import org.neoflock.neocomputers.network.PowerRole
import org.neoflock.neocomputers.sounds.ComputerRunningSoundInstance
import org.neoflock.neocomputers.sounds.Sounds
import org.neoflock.neocomputers.utils.GenericContainer
import java.time.Duration
import kotlin.math.min
class CaseBlockEntity(blockPos: BlockPos, blockState: BlockState): NodeBlockEntity(BlockEntities.CASE_ENTITY.get(), blockPos, blockState), MachineEntity, GenericContainer, MenuProvider {
val stacks: NonNullList<ItemStack> = NonNullList<ItemStack>.withSize(7, ItemStack.EMPTY)
var isOn = false
var soundInstance: SoundInstance? = null
override val node = object : Networking.Node() {
override var powerRole = PowerRole.STORAGE
override var energyCapacity: Long = 500
}
override fun encodeDownstreamData(packet: FriendlyByteBuf) {
super.encodeDownstreamData(packet)
packet.writeBoolean(isOn)
}
override fun syncWithUpstream(packet: FriendlyByteBuf) {
super.syncWithUpstream(packet)
setRunning(packet.readBoolean())
}
override fun processScreenInteraction(player: ServerPlayer, packet: FriendlyByteBuf) {
val c = packet.readByte().toInt()
if(c == 0x01) {
start()
}
if(c == 0x02) {
stop()
}
}
override fun encodeScreenData(player: ServerPlayer, packet: FriendlyByteBuf) {
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 redstoneOut = Array(Direction.entries.size) {0}
fun refetchRedstone(dir: Direction) {
val src = blockPos.offset(dir.stepX, dir.stepY, dir.stepZ)
val cur = level?.getSignal(src, dir) ?: 0
val idx = dirToIdx(dir)
if(redstoneIn[idx] != cur) {
onRedstoneSignalChanged(dir, redstoneIn[idx], cur)
}
redstoneIn[idx] = cur
}
fun refetchAllRedstone() {
Direction.entries.forEach { refetchRedstone(it) }
}
fun sendMachineEvent(event: MachineEvent) {
stacks.forEach {
val item = it.item
if(item is ComponentItem) {
item.onMachineEvent(it, this, event)
}
}
}
fun onRedstoneSignalChanged(dir: Direction, oldValue: Int, newValue: Int) {
sendMachineEvent(MachineRedstoneEvent(this, dir, oldValue, newValue))
Networking.emitMessage(node, Networking.ComputerUncheckedSignal(node, "redstone_changed", arrayOf(node.address.toString(), dirToIdx(dir), oldValue, newValue)))
NeoComputers.LOGGER.info("redstone in direction ${dir.name} changed from $oldValue to $newValue")
if(oldValue == 0) {
// Rising edge
start()
}
if(newValue == 0) {
// Not accurate but whatevs
stop()
}
setChanged()
}
override fun getBlockPosition(): BlockPos = blockPos
override fun isRunning(): Boolean = isOn
fun setRunning(value: Boolean) {
if(isOn == value) return
NeoComputers.LOGGER.info("[${node.address}] Going from $isOn to $value")
isOn = value
val world = level ?: return
blockState?.setValue(CaseBlock.COMPUTER_RUNNING, isOn)
if(world.isClientSide) {
if(value) {
soundInstance = ComputerRunningSoundInstance(this, Sounds.COMPUTER_RUNNING.get(), SoundSource.AMBIENT)
Minecraft.getInstance().soundManager.play(soundInstance!!)
} else {
Minecraft.getInstance().soundManager.stop(soundInstance!!)
soundInstance = null
}
return
}
// Server-side stuff!!
world.onBlockStateChange(blockPos, blockState, blockState)
sendMachineEvent(MachinePowerEvent(this, isOn))
}
override fun start(): Boolean {
setRunning(true)
return isOn
}
override fun stop(): Boolean {
setRunning(false)
return isOn
}
override fun crash(error: String): Boolean {
NeoComputers.LOGGER.warn("Crashing cases is not implemented yet lol")
return false
}
override fun getLastError(): String? = null
override fun getMachineNode(): Networking.Node = node
override fun getRedstoneInput(direction: Direction): Int = redstoneIn[dirToIdx(direction)]
override fun getRedstoneOutput(direction: Direction): Int = redstoneOut[dirToIdx(direction)]
override fun setRedstoneOutput(direction: Direction, newValue: Int): Int {
val idx = dirToIdx(direction)
val old = redstoneOut[idx]
redstoneOut[idx] = newValue
return old
}
override fun beepAsync(frequency: Int, duration: Duration, volume: Double): Boolean {
NeoComputers.LOGGER.warn("beep not yet implemented")
return true
}
override fun getMachineMemoryTotal(): Long = stacks.mapNotNull { (it.item as? ComponentItem)?.getMemoryCapacity(it) }.sum().toLong()
override fun getMachineMemoryUsed(): Long = 0
override fun getMachineComponentsUsed(): Long = node.connections.size.toLong()
override fun getMachineComponentsTotal(): Long = stacks.mapNotNull { (it.item as? ComponentItem)?.getComponentCapacity(it) }.sum().toLong()
override fun getItems(): NonNullList<ItemStack> = stacks
override fun stillValid(player: Player): Boolean = true
override fun loadAdditional(compoundTag: CompoundTag, provider: HolderLookup.Provider) {
super.loadAdditional(compoundTag, provider)
node.energy = min(node.energyCapacity, compoundTag.getLong("energy"))
//isOn = compoundTag.getBoolean("powerOn")
ContainerHelper.loadAllItems(compoundTag, getItems(), provider)
}
override fun saveAdditional(compoundTag: CompoundTag, provider: HolderLookup.Provider) {
super.saveAdditional(compoundTag, provider)
compoundTag.putLong("energy", node.energy)
//compoundTag.putBoolean("powerOn", isOn)
ContainerHelper.saveAllItems(compoundTag, getItems(), provider)
}
override fun getDisplayName(): Component? = Component.literal("Computer")
override fun createMenu(i: Int, inventory: Inventory, player: Player) = CaseMenu(i, inventory, this)
override fun canPlaceItem(i: Int, itemStack: ItemStack): Boolean = false
override fun canTakeItem(container: Container, i: Int, itemStack: ItemStack): Boolean = false
override fun setChanged() {
super.setChanged()
}
override fun setRemoved() {
setRunning(false)
super.setRemoved()
}
}