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.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())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
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.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}")
|
||||||
|
|||||||
@@ -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())
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user