package net.shadowfacts.phycon.util import net.minecraft.util.math.BlockPos import net.minecraft.util.math.Direction import net.minecraft.world.World import net.shadowfacts.phycon.api.* import java.util.* /** * @author shadowfacts */ object NetworkUtil { 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) if (!world.isChunkLoaded(pos)) { // avoid loading unloaded chunks return null } state = world.getBlockState(pos) } else { return null } } return null } fun findDestinations(world: World, startPos: BlockPos, direction: Direction? = null): List { val results = LinkedList() val visited = hashSetOf(startPos) val queue = LinkedList() if (direction != null) { queue.add(startPos.offset(direction)) } else { findEdges(queue, visited, world, startPos, includeNonCables = true) } while (queue.isNotEmpty()) { val pos = queue.pop() val sink = PhyAttributes.PACKET_SINK.getFirstOrNull(world, pos) if (sink != null) { results.add(sink) } findEdges(queue, visited, world, pos) visited.add(pos) } return results } private fun findEdges(queue: MutableList, visited: Set, world: World, pos: BlockPos, includeNonCables: Boolean = false) { val state = world.getBlockState(pos) val block = state.block 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) } } } } }