private Set<BlockPos> getNextSticks(BlockPos source) {

        // Unless source is a frame, nothing can stick to it
        Frame frame = MovementRegistry.getFrame(level, source);
        if (frame == null) return Collections.emptySet();

        // Query all sides of source
        Set<BlockPos> stuckBlocks = new HashSet<>();
        for (int s = 0; s < 6; s++) {
            Direction dir = Direction.values()[s];
            if (frame.canGrab(level, source, dir)) {

                BlockPos stuckBlockPos = source.relative(dir);
                BlockState stuckBlockState = level.getBlockState(stuckBlockPos);

                // Skip uninteresting blocks such as air
                if (level.isEmptyBlock(stuckBlockPos) || stuckBlockState.isAir()) continue;

                // Don't stick to currently moving blocks
                if (MovementManager.getInstance(level).getMovementInfo(stuckBlockPos).isMoving()) continue;

                // If stuck block is a frame, it must also allow the connection
                Frame stuckFrame = MovementRegistry.getFrame(level, stuckBlockPos);
                if (stuckFrame != null && !stuckFrame.canBeGrabbed(level, stuckBlockPos, dir.getOpposite())) {
                    continue;
                }

                // Block can stick. Add it
                stuckBlocks.add(stuckBlockPos);
            }
        }

        // Ask source for additional sticks
        stuckBlocks.addAll(frame.getAdditionalSticks());

        return stuckBlocks;
    }
Creates a set of positions that source is currently stuck to.
@param source Source position
@return Set of positions that source is stuck to
expansion/src/main/java/mrtjp/projectred/expansion/FrameStickResolver.java