Pricedata without Chainlink

Keep in mind that Chainlink is probably the best option if possible.

You should know that getting price data from a dex like pancakeswap on-chain is hard as someone could manipulate the price for the transaction but there is a solution. kinda
You can just use multiple dexes. It's harder for someone to manipulate multiple dexes.
For this you can just get a array of routers from the dexes and then write a function to get the LP pool addresses of the token

function _getPairs(address _add) private view returns(address[] memory) {
        address[] memory _lps = new address[](routers.length); 
        for(uint i; i < routers.length; i++) {
            IFactory factory = IFactory(routers[i].factory());
            address pair = factory.getPair(_add, wbnb);
            _lps[i] = pair;
        return _lps;

Then we get the price of each pair and devide it by the amount of pairs

function _getPrice(address[] memory _lps) private view returns(uint){
        uint tPrice;
        uint vprices;
        for(uint i; i < _lps.length; i++) {
            (uint res0, uint res1,) = ILP(_lps[i]).getReserves();
            if(res0 != 0 && res1 != 0) {
                if(ILP(_lps[i]).token0() == wbnb)
                    tPrice += (res0*1e18) / res1;
                    tPrice += (res1*1e18) / res0;
        return (tPrice / vprices);

Then we get a cool and clean function

function getAveragePriceOf(address _add) public view returns(uint) {
        return _getPrice(_getPairs(_add));

And that's it.
I am shure there are better solutions than that but that's the first thing I came up with.