PhysicalConnectivity/src/main/kotlin/net/shadowfacts/phycon/util/NetworkUtil.kt

81 lines
2.2 KiB
Kotlin
Raw Normal View History

2021-02-28 18:48:39 +00:00
package net.shadowfacts.phycon.util
2019-10-27 01:36:31 +00:00
import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.Direction
import net.minecraft.world.World
2021-02-13 23:24:36 +00:00
import net.shadowfacts.phycon.api.*
2019-10-27 01:36:31 +00:00
import java.util.*
/**
* @author shadowfacts
*/
object NetworkUtil {
2021-02-13 23:24:36 +00:00
fun findConnectedInterface(world: World, startPos: BlockPos, startSide: Direction): Interface? {
var curSide = startSide
var pos = startPos.offset(startSide)
var state = world.getBlockState(pos)
while (state.block is NetworkComponentBlock) {
val block = state.block as NetworkComponentBlock
val itf = block.getNetworkInterfaceForSide(curSide.opposite, state, world, pos)
if (itf != null) {
return itf
}
val connectedSides = block.getNetworkConnectedSides(state, world, pos).filter { it != curSide.opposite }
if (connectedSides.size == 1) {
curSide = connectedSides.first()
pos = pos.offset(curSide)
2021-02-15 01:01:33 +00:00
if (!world.isChunkLoaded(pos)) {
// avoid loading unloaded chunks
return null
}
2021-02-13 23:24:36 +00:00
state = world.getBlockState(pos)
} else {
return null
}
}
return null
}
2019-10-27 03:13:26 +00:00
fun findDestinations(world: World, startPos: BlockPos, direction: Direction? = null): List<PacketSink> {
2019-10-27 01:49:34 +00:00
val results = LinkedList<PacketSink>()
2019-10-27 01:36:31 +00:00
val visited = hashSetOf(startPos)
val queue = LinkedList<BlockPos>()
2019-10-27 03:13:26 +00:00
if (direction != null) {
queue.add(startPos.offset(direction))
} else {
findEdges(queue, visited, world, startPos, includeNonCables = true)
2019-10-27 03:13:26 +00:00
}
2019-10-27 01:49:34 +00:00
2019-10-27 01:36:31 +00:00
while (queue.isNotEmpty()) {
val pos = queue.pop()
2019-10-27 01:49:34 +00:00
2019-10-27 01:36:31 +00:00
val sink = PhyAttributes.PACKET_SINK.getFirstOrNull(world, pos)
if (sink != null) {
results.add(sink)
}
2019-10-27 01:49:34 +00:00
findEdges(queue, visited, world, pos)
2019-10-27 01:49:34 +00:00
2019-10-27 01:36:31 +00:00
visited.add(pos)
}
2019-10-27 01:49:34 +00:00
2019-10-27 01:36:31 +00:00
return results
}
private fun findEdges(queue: MutableList<BlockPos>, visited: Set<BlockPos>, world: World, pos: BlockPos, includeNonCables: Boolean = false) {
val state = world.getBlockState(pos)
val block = state.block
2021-02-13 23:24:36 +00:00
if (block is NetworkComponentBlock && (includeNonCables || block is NetworkCableBlock)) {
val connections = block.getNetworkConnectedSides(state, world, pos)
for (side in connections) {
val newPos = pos.offset(side)
if (newPos !in visited) {
queue.add(newPos)
}
}
}
}
2019-10-27 01:36:31 +00:00
}