rip capacitors (WIP refactor)

if anyone touches this while I'm working on it, I will find you, and I will refactor you too
This commit is contained in:
2026-04-27 19:04:26 +03:00
parent fc8a4aaa58
commit 80130a68e1
6 changed files with 140 additions and 21 deletions

View File

@@ -2,10 +2,12 @@ package org.neoflock.neocomputers.block
import net.minecraft.client.player.LocalPlayer import net.minecraft.client.player.LocalPlayer
import net.minecraft.core.BlockPos import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.core.HolderLookup import net.minecraft.core.HolderLookup
import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.CompoundTag
import net.minecraft.network.chat.OutgoingChatMessage import net.minecraft.network.chat.OutgoingChatMessage
import net.minecraft.network.chat.PlayerChatMessage import net.minecraft.network.chat.PlayerChatMessage
import net.minecraft.server.level.ServerPlayer
import net.minecraft.world.InteractionResult import net.minecraft.world.InteractionResult
import net.minecraft.world.entity.player.Player import net.minecraft.world.entity.player.Player
import net.minecraft.world.level.Level import net.minecraft.world.level.Level
@@ -18,13 +20,17 @@ import org.neoflock.neocomputers.network.DeviceNode
import org.neoflock.neocomputers.network.PowerRole import org.neoflock.neocomputers.network.PowerRole
import kotlin.math.min import kotlin.math.min
open class CapacitorEntity(val capacity: Long, type: BlockEntityType<*>, pos: BlockPos, state: BlockState) : NodeBlockEntity(type, pos, state) { open class CapacitorEntity(val capacity: Long, type: BlockEntityType<*>, pos: BlockPos, state: BlockState) : DeviceBlockEntity(type, pos, state) {
override val deviceNode = object : DeviceNode() { val deviceNode = object : DeviceNode() {
override var powerRole = PowerRole.STORAGE override var powerRole = PowerRole.STORAGE
override var energyCapacity: Long = capacity override var energyCapacity: Long = capacity
} }
// TODO: cache list
override fun getDeviceNodes() = listOf(deviceNode)
override fun getNodeFromSide(directionToRequester: Direction) = deviceNode
override fun loadAdditional(compoundTag: CompoundTag, provider: HolderLookup.Provider) { override fun loadAdditional(compoundTag: CompoundTag, provider: HolderLookup.Provider) {
super.loadAdditional(compoundTag, provider) super.loadAdditional(compoundTag, provider)
deviceNode.energy = min(compoundTag.getLong("energy"), deviceNode.energyCapacity) deviceNode.energy = min(compoundTag.getLong("energy"), deviceNode.energyCapacity)
@@ -58,12 +64,12 @@ class CapacitorBlock(val tier: Int) : NodeBlock() {
player: Player, player: Player,
blockHitResult: BlockHitResult blockHitResult: BlockHitResult
): InteractionResult { ): InteractionResult {
if(level.isClientSide()) { if(!level.isClientSide()) {
val p = player as LocalPlayer val p = player as ServerPlayer
val ent = level.getBlockEntity(blockPos) val ent = level.getBlockEntity(blockPos)
if(ent is CapacitorEntity) { if(ent is CapacitorEntity) {
if(p.isCrouching) ent.deviceNode.giveEnergy(1) if(p.isCrouching) ent.deviceNode.giveEnergy(1)
val msg = PlayerChatMessage.system("energy: ${ent.deviceNode.energy} / ${ent.capacity} (${ent.computeEdges().size} edges, ${ent.deviceNode.getReachable().size} connected)") val msg = PlayerChatMessage.system("energy: ${ent.deviceNode.energy} / ${ent.capacity} (${ent.deviceNode.connections.size} connections, ${ent.deviceNode.getReachable().size} connected)")
p.sendSystemMessage(OutgoingChatMessage.create(msg).content()) p.sendSystemMessage(OutgoingChatMessage.create(msg).content())
} }
} }

View File

@@ -64,7 +64,7 @@ class CaseBlock() : NodeBlock(Properties.of().sound(SoundType.METAL).lightLevel(
blockPos: BlockPos, blockPos: BlockPos,
direction: Direction direction: Direction
): Int { ): Int {
return getMachine(blockGetter, blockPos).redstoneOut[dirToIdx(direction.opposite)] return getMachine(blockGetter, blockPos).redstoneOut[direction.opposite.ordinal]
} }
override fun onPlace( override fun onPlace(

View File

@@ -0,0 +1,115 @@
package org.neoflock.neocomputers.block
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.world.level.Level
import net.minecraft.world.level.block.Block
import net.minecraft.world.level.block.EntityBlock
import net.minecraft.world.level.block.entity.BlockEntity
import net.minecraft.world.level.block.entity.BlockEntityTicker
import net.minecraft.world.level.block.entity.BlockEntityType
import net.minecraft.world.level.block.state.BlockState
import org.neoflock.neocomputers.network.DeviceNode
import org.neoflock.neocomputers.network.Networking
abstract class DeviceBlockEntity(type: BlockEntityType<*>, pos: BlockPos, state: BlockState): BlockEntity(type, pos, state) {
val connetionsInDir = MutableList(Direction.entries.size) { HashSet<DeviceNode>() }
abstract fun getDeviceNodes(): List<DeviceNode>
// Gets, if applicable, the node from a direction.
// The direction is from this block entity to the original requester,
// so it is Direction.UP if we asked from the one on the top side.
abstract fun getNodeFromSide(directionToRequester: Direction): DeviceNode?
open fun initNetworking(): DeviceBlockEntity {
getDeviceNodes().forEach { Networking.addNode(it) }
Direction.entries.forEach { handleConnectionsFor(it) }
return this
}
open fun getCurrentlyConnectedNodesIn(direction: Direction): HashSet<DeviceNode> {
val ent = level?.getBlockEntity(blockPos.relative(direction))
val connected = HashSet<DeviceNode>()
if(ent is DeviceBlockEntity) {
val node = ent.getNodeFromSide(direction.opposite)
if(node != null) connected.add(node)
}
return connected
}
// TODO: rethink this shi so sharing a node on 2 different sides doesn't make connections require mutually exclusive conditions
// TODO: actually like, rethink the whole class so far
open fun handleConnectionsFor(direction: Direction) {
// refuse connections on no node to reduce CPU load
val node = getNodeFromSide(direction.opposite) ?: return
val old = connetionsInDir[direction.ordinal]
val now = getCurrentlyConnectedNodesIn(direction)
// TODO: optimize this hellscape
val toKill = HashSet<DeviceNode>()
old.forEach {
if(it !in now) toKill.add(it)
}
toKill.forEach { node.disconnectFrom(it) }
now.forEach {
if(it !in old) node.connectTo(it)
}
connetionsInDir[direction.ordinal] = now
}
// TODO: optimize this sometime before our test computers melt
open fun tickDevice() {
// Handles device connections and sync here
// Process connections
Direction.entries.forEach {
handleConnectionsFor(it)
}
}
override fun setRemoved() {
super.setRemoved()
getDeviceNodes().forEach { Networking.removeNode(it) }
}
}
abstract class DeviceBlock(properties: Properties = Properties.of()): BaseBlock(properties), EntityBlock {
override fun <T : BlockEntity?> getTicker(
level: Level,
state: BlockState,
blockEntityType: BlockEntityType<T?>
): BlockEntityTicker<T> {
return object : BlockEntityTicker<T> {
override fun tick(level: Level, blockPos: BlockPos, blockState: BlockState, blockEntity: T & Any) {
if(blockEntity !is DeviceBlockEntity) return
blockEntity.tickDevice()
}
}
}
override fun onPlace(state: BlockState, level: Level, pos: BlockPos, oldState: BlockState, movedByPiston: Boolean) {
super.onPlace(state, level, pos, oldState, movedByPiston)
val ent = level.getBlockEntity(pos)
if(ent is DeviceBlockEntity) {
ent.initNetworking()
}
}
override fun neighborChanged(
state: BlockState,
level: Level,
pos: BlockPos,
neighborBlock: Block,
neighborPos: BlockPos,
movedByPiston: Boolean
) {
super.neighborChanged(state, level, pos, neighborBlock, neighborPos, movedByPiston)
val ent = level.getBlockEntity(pos)
if(ent is DeviceBlockEntity) {
ent.handleConnectionsFor(Direction.getNearest(neighborPos.center.subtract(pos.center)))
}
}
}

View File

@@ -15,8 +15,6 @@ import org.neoflock.neocomputers.entity.BlockEntities
import org.neoflock.neocomputers.network.Networking import org.neoflock.neocomputers.network.Networking
import org.neoflock.neocomputers.network.DeviceNode import org.neoflock.neocomputers.network.DeviceNode
fun dirToIdx(direction: Direction) = Direction.entries.indexOf(direction)
class RedstoneIOEntity(blockPos: BlockPos, blockState: BlockState): NodeBlockEntity(BlockEntities.REDSTONEIO_ENTITY.get(), blockPos, blockState) { class RedstoneIOEntity(blockPos: BlockPos, blockState: BlockState): NodeBlockEntity(BlockEntities.REDSTONEIO_ENTITY.get(), blockPos, blockState) {
val redstoneIn = Array<Int>(Direction.entries.size) {0} val redstoneIn = Array<Int>(Direction.entries.size) {0}
val redstoneOut = Array<Int>(Direction.entries.size) {0} val redstoneOut = Array<Int>(Direction.entries.size) {0}
@@ -29,7 +27,7 @@ class RedstoneIOEntity(blockPos: BlockPos, blockState: BlockState): NodeBlockEnt
fun refetch(dir: Direction) { fun refetch(dir: Direction) {
val src = blockPos.offset(dir.stepX, dir.stepY, dir.stepZ) val src = blockPos.offset(dir.stepX, dir.stepY, dir.stepZ)
val cur = level?.getSignal(src, dir) ?: 0 val cur = level?.getSignal(src, dir) ?: 0
val idx = dirToIdx(dir) val idx = dir.ordinal
if(redstoneIn[idx] != cur) { if(redstoneIn[idx] != cur) {
onRedstoneSignalChanged(dir, redstoneIn[idx], cur) onRedstoneSignalChanged(dir, redstoneIn[idx], cur)
} }
@@ -41,7 +39,7 @@ class RedstoneIOEntity(blockPos: BlockPos, blockState: BlockState): NodeBlockEnt
} }
fun onRedstoneSignalChanged(dir: Direction, oldValue: Int, newValue: Int) { fun onRedstoneSignalChanged(dir: Direction, oldValue: Int, newValue: Int) {
Networking.emitMessage(deviceNode, Networking.ComputerUncheckedSignal(deviceNode, "redstone_changed", arrayOf(deviceNode.address.toString(), dirToIdx(dir), oldValue, newValue))) Networking.emitMessage(deviceNode, Networking.ComputerUncheckedSignal(deviceNode, "redstone_changed", arrayOf(deviceNode.address.toString(), dir.ordinal, oldValue, newValue)))
NeoComputers.LOGGER.info("redstone in direction ${dir.name} changed from $oldValue to $newValue") NeoComputers.LOGGER.info("redstone in direction ${dir.name} changed from $oldValue to $newValue")
} }
} }
@@ -67,7 +65,7 @@ class RedstoneIOBlock(): NodeBlock(Properties.of().isRedstoneConductor { state,
): Int { ): Int {
val redstoneIO = getRedstoneIO(blockGetter, blockPos) val redstoneIO = getRedstoneIO(blockGetter, blockPos)
if(redstoneIO != null) { if(redstoneIO != null) {
return redstoneIO.redstoneOut[dirToIdx(direction.opposite)] return redstoneIO.redstoneOut[direction.opposite.ordinal]
} }
return super.getSignal(blockState, blockGetter, blockPos, direction) return super.getSignal(blockState, blockGetter, blockPos, direction)
} }
@@ -125,7 +123,7 @@ class RedstoneIOBlock(): NodeBlock(Properties.of().isRedstoneConductor { state,
val redio = getRedstoneIO(level, blockPos) val redio = getRedstoneIO(level, blockPos)
val dir = blockHitResult.direction val dir = blockHitResult.direction
if (redio != null) { if (redio != null) {
val idx = dirToIdx(dir) val idx = dir.ordinal
redio.redstoneOut[idx]++ redio.redstoneOut[idx]++
redio.redstoneOut[idx] %= 16 redio.redstoneOut[idx] %= 16
NeoComputers.LOGGER.info("outputting redstone level ${redio.redstoneOut[idx]} on ${dir.name}") NeoComputers.LOGGER.info("outputting redstone level ${redio.redstoneOut[idx]} on ${dir.name}")

View File

@@ -88,9 +88,10 @@ object BlockEntities {
} }
fun registerPowerBlocks() { fun registerPowerBlocks() {
PowerManager.registerPowerBlockEntity(CAPACITOR_ENTITY.get()) // TODO: function for the new DeviceBlockEntity
PowerManager.registerPowerBlockEntity(CAPACITOR2_ENTITY.get()) //PowerManager.registerPowerBlockEntity(CAPACITOR_ENTITY.get())
PowerManager.registerPowerBlockEntity(CAPACITOR3_ENTITY.get()) //PowerManager.registerPowerBlockEntity(CAPACITOR2_ENTITY.get())
//PowerManager.registerPowerBlockEntity(CAPACITOR3_ENTITY.get())
PowerManager.registerPowerBlockEntity(SOLARGEN_ENTITY.get()) PowerManager.registerPowerBlockEntity(SOLARGEN_ENTITY.get())
PowerManager.registerPowerBlockEntity(COMBUSTGEN_ENTITY.get()) PowerManager.registerPowerBlockEntity(COMBUSTGEN_ENTITY.get())
PowerManager.registerPowerBlockEntity(CASE_ENTITY.get()) PowerManager.registerPowerBlockEntity(CASE_ENTITY.get())

View File

@@ -22,7 +22,6 @@ import org.neoflock.neocomputers.NeoComputers
import org.neoflock.neocomputers.block.CaseBlock import org.neoflock.neocomputers.block.CaseBlock
import org.neoflock.neocomputers.block.NodeBlockEntity import org.neoflock.neocomputers.block.NodeBlockEntity
import org.neoflock.neocomputers.block.NodeSynchronizer import org.neoflock.neocomputers.block.NodeSynchronizer
import org.neoflock.neocomputers.block.dirToIdx
import org.neoflock.neocomputers.gui.menu.CaseMenu import org.neoflock.neocomputers.gui.menu.CaseMenu
import org.neoflock.neocomputers.item.ComponentItem import org.neoflock.neocomputers.item.ComponentItem
import org.neoflock.neocomputers.network.DeviceNode import org.neoflock.neocomputers.network.DeviceNode
@@ -95,7 +94,7 @@ class CaseBlockEntity(blockPos: BlockPos, blockState: BlockState): NodeBlockEnti
fun refetchRedstone(dir: Direction) { fun refetchRedstone(dir: Direction) {
val src = blockPos.offset(dir.stepX, dir.stepY, dir.stepZ) val src = blockPos.offset(dir.stepX, dir.stepY, dir.stepZ)
val cur = level?.getSignal(src, dir) ?: 0 val cur = level?.getSignal(src, dir) ?: 0
val idx = dirToIdx(dir) val idx = dir.ordinal
if(redstoneIn[idx] != cur) { if(redstoneIn[idx] != cur) {
onRedstoneSignalChanged(dir, redstoneIn[idx], cur) onRedstoneSignalChanged(dir, redstoneIn[idx], cur)
} }
@@ -118,7 +117,7 @@ class CaseBlockEntity(blockPos: BlockPos, blockState: BlockState): NodeBlockEnti
fun onRedstoneSignalChanged(dir: Direction, oldValue: Int, newValue: Int) { fun onRedstoneSignalChanged(dir: Direction, oldValue: Int, newValue: Int) {
sendMachineEvent(MachineRedstoneEvent(this, dir, oldValue, newValue)) sendMachineEvent(MachineRedstoneEvent(this, dir, oldValue, newValue))
Networking.emitMessage(deviceNode, Networking.ComputerUncheckedSignal(deviceNode, "redstone_changed", arrayOf(deviceNode.address.toString(), dirToIdx(dir), oldValue, newValue))) Networking.emitMessage(deviceNode, Networking.ComputerUncheckedSignal(deviceNode, "redstone_changed", arrayOf(deviceNode.address.toString(), dir.ordinal, oldValue, newValue)))
NeoComputers.LOGGER.info("redstone in direction ${dir.name} changed from $oldValue to $newValue") NeoComputers.LOGGER.info("redstone in direction ${dir.name} changed from $oldValue to $newValue")
if(oldValue == 0) { if(oldValue == 0) {
// Rising edge // Rising edge
@@ -208,12 +207,12 @@ class CaseBlockEntity(blockPos: BlockPos, blockState: BlockState): NodeBlockEnti
override fun getMachineNode() = deviceNode override fun getMachineNode() = deviceNode
override fun getRedstoneInput(direction: Direction): Int = redstoneIn[dirToIdx(direction)] override fun getRedstoneInput(direction: Direction): Int = redstoneIn[direction.ordinal]
override fun getRedstoneOutput(direction: Direction): Int = redstoneOut[dirToIdx(direction)] override fun getRedstoneOutput(direction: Direction): Int = redstoneOut[direction.ordinal]
override fun setRedstoneOutput(direction: Direction, newValue: Int): Int { override fun setRedstoneOutput(direction: Direction, newValue: Int): Int {
val idx = dirToIdx(direction) val idx = direction.ordinal
val old = redstoneOut[idx] val old = redstoneOut[idx]
redstoneOut[idx] = newValue redstoneOut[idx] = newValue
return old return old