PIC18f45k20 ADC - always returns zero
I don't like "fix my code" too :) I will not analyse your code, I'm not PIC expert, I just started with Microchip microcontrollers - they are awesome! :) 

Edited:

So this is how I do it on PIC18F4550 PIC18F25k50 and it works for sure. It should work on PIC18F4520 too.

End of edited.

You have to change port and probably voltage reference configuration.

volatile unsigned int millivolts = 0; // variable for result

void config_adc(void)
{
    // voltage reference selection

    // VREFCONbits.FVRS
    // 0b00 off
    // 0b01 1024mV
    // 0b10 2048mV
    // 0b11 4096mV
    VREFCON0bits.FVRS = 0b01;
    VREFCON0bits.FVREN = 1; // internal fixed voltage reference turned on

    ANSELAbits.ANSA0 = 1; // analog input A0 on
    TRISAbits.TRISA0 = 1; // pin A0 as input

    ADCON0bits.CHS = 0;   // analog channel select

    ADCON1bits.PVCFG = 0b10; // 0b10 for positive voltage reference = FVR BUF2 ("FVRS" configured earlier)
    ADCON1bits.NVCFG = 0b00; // 0b00 for negative voltage reference = AVss

    ADCON2bits.ADCS = 0b110; // 0b011 use FRC clock (internal clock dedicated for ADC)
    ADCON2bits.ACQT = 0b000; // manual acquisition mode
    ADCON2bits.ADFM = 1; // result bits adjusted to right

    ADCON0bits.ADON = 1; // ADC converter on
}

void main()
{
    config_adc();
    while(1)
    {

        ADCON0bits.GODONE = 1; // start conversion

        while (ADCON0bits.GODONE) // wait until conversion is done
        {
            asm("nop"); // im not sure if this is necessary
        }

    millivolts = (ADRESH * 256 + ADRESL); // im writing result into volatile variable to use it in interrupt routine

    }
}


Im using XC8 too. Code is not complete, this is just ADC part.