2019-10-27 01:36:31 +00:00
|
|
|
package net.shadowfacts.phycon.network
|
|
|
|
|
|
|
|
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 {
|
2019-10-28 22:46:47 +00:00
|
|
|
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
|
|
|
|
2019-10-28 16:00:17 +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
|
|
|
|
}
|
|
|
|
|
2019-10-28 22:46:47 +00:00
|
|
|
private fun findEdges(queue: MutableList<BlockPos>, visited: Set<BlockPos>, world: World, pos: BlockPos, includeNonCables: Boolean = false) {
|
2019-10-28 16:00:17 +00:00
|
|
|
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)) {
|
2019-10-28 16:00:17 +00:00
|
|
|
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
|
|
|
}
|