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:
@@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
115
src/main/kotlin/org/neoflock/neocomputers/block/DeviceBlock.kt
Normal file
115
src/main/kotlin/org/neoflock/neocomputers/block/DeviceBlock.kt
Normal 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)))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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}")
|
||||
|
||||
@@ -88,9 +88,10 @@ object BlockEntities {
|
||||
}
|
||||
|
||||
fun registerPowerBlocks() {
|
||||
PowerManager.registerPowerBlockEntity(CAPACITOR_ENTITY.get())
|
||||
PowerManager.registerPowerBlockEntity(CAPACITOR2_ENTITY.get())
|
||||
PowerManager.registerPowerBlockEntity(CAPACITOR3_ENTITY.get())
|
||||
// TODO: function for the new DeviceBlockEntity
|
||||
//PowerManager.registerPowerBlockEntity(CAPACITOR_ENTITY.get())
|
||||
//PowerManager.registerPowerBlockEntity(CAPACITOR2_ENTITY.get())
|
||||
//PowerManager.registerPowerBlockEntity(CAPACITOR3_ENTITY.get())
|
||||
PowerManager.registerPowerBlockEntity(SOLARGEN_ENTITY.get())
|
||||
PowerManager.registerPowerBlockEntity(COMBUSTGEN_ENTITY.get())
|
||||
PowerManager.registerPowerBlockEntity(CASE_ENTITY.get())
|
||||
|
||||
@@ -22,7 +22,6 @@ import org.neoflock.neocomputers.NeoComputers
|
||||
import org.neoflock.neocomputers.block.CaseBlock
|
||||
import org.neoflock.neocomputers.block.NodeBlockEntity
|
||||
import org.neoflock.neocomputers.block.NodeSynchronizer
|
||||
import org.neoflock.neocomputers.block.dirToIdx
|
||||
import org.neoflock.neocomputers.gui.menu.CaseMenu
|
||||
import org.neoflock.neocomputers.item.ComponentItem
|
||||
import org.neoflock.neocomputers.network.DeviceNode
|
||||
@@ -95,7 +94,7 @@ class CaseBlockEntity(blockPos: BlockPos, blockState: BlockState): NodeBlockEnti
|
||||
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)
|
||||
val idx = dir.ordinal
|
||||
if(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) {
|
||||
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")
|
||||
if(oldValue == 0) {
|
||||
// Rising edge
|
||||
@@ -208,12 +207,12 @@ class CaseBlockEntity(blockPos: BlockPos, blockState: BlockState): NodeBlockEnti
|
||||
|
||||
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 {
|
||||
val idx = dirToIdx(direction)
|
||||
val idx = direction.ordinal
|
||||
val old = redstoneOut[idx]
|
||||
redstoneOut[idx] = newValue
|
||||
return old
|
||||
|
||||
Reference in New Issue
Block a user