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.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.core.HolderLookup
import net.minecraft.nbt.CompoundTag
import net.minecraft.network.chat.OutgoingChatMessage
import net.minecraft.network.chat.PlayerChatMessage
import net.minecraft.server.level.ServerPlayer
import net.minecraft.world.InteractionResult
import net.minecraft.world.entity.player.Player
import net.minecraft.world.level.Level
@@ -18,13 +20,17 @@ import org.neoflock.neocomputers.network.DeviceNode
import org.neoflock.neocomputers.network.PowerRole
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 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) {
super.loadAdditional(compoundTag, provider)
deviceNode.energy = min(compoundTag.getLong("energy"), deviceNode.energyCapacity)
@@ -58,12 +64,12 @@ class CapacitorBlock(val tier: Int) : NodeBlock() {
player: Player,
blockHitResult: BlockHitResult
): InteractionResult {
if(level.isClientSide()) {
val p = player as LocalPlayer
if(!level.isClientSide()) {
val p = player as ServerPlayer
val ent = level.getBlockEntity(blockPos)
if(ent is CapacitorEntity) {
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())
}
}

View File

@@ -64,7 +64,7 @@ class CaseBlock() : NodeBlock(Properties.of().sound(SoundType.METAL).lightLevel(
blockPos: BlockPos,
direction: Direction
): Int {
return getMachine(blockGetter, blockPos).redstoneOut[dirToIdx(direction.opposite)]
return getMachine(blockGetter, blockPos).redstoneOut[direction.opposite.ordinal]
}
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.DeviceNode
fun dirToIdx(direction: Direction) = Direction.entries.indexOf(direction)
class RedstoneIOEntity(blockPos: BlockPos, blockState: BlockState): NodeBlockEntity(BlockEntities.REDSTONEIO_ENTITY.get(), blockPos, blockState) {
val redstoneIn = 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) {
val src = blockPos.offset(dir.stepX, dir.stepY, dir.stepZ)
val cur = level?.getSignal(src, dir) ?: 0
val idx = dirToIdx(dir)
val idx = dir.ordinal
if(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) {
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")
}
}
@@ -67,7 +65,7 @@ class RedstoneIOBlock(): NodeBlock(Properties.of().isRedstoneConductor { state,
): Int {
val redstoneIO = getRedstoneIO(blockGetter, blockPos)
if(redstoneIO != null) {
return redstoneIO.redstoneOut[dirToIdx(direction.opposite)]
return redstoneIO.redstoneOut[direction.opposite.ordinal]
}
return super.getSignal(blockState, blockGetter, blockPos, direction)
}
@@ -125,7 +123,7 @@ class RedstoneIOBlock(): NodeBlock(Properties.of().isRedstoneConductor { state,
val redio = getRedstoneIO(level, blockPos)
val dir = blockHitResult.direction
if (redio != null) {
val idx = dirToIdx(dir)
val idx = dir.ordinal
redio.redstoneOut[idx]++
redio.redstoneOut[idx] %= 16
NeoComputers.LOGGER.info("outputting redstone level ${redio.redstoneOut[idx]} on ${dir.name}")