{$CLEO .cs}
{$USE CLEO+}
nop
script_name 'GRGVEHC'
wait 0
wait 0

0@ = 0

if
    0AA2: 31@ = load_dynamic_library "CLEO+.cleo"
jf @ILoveMyGirlfriendJessica
if
    0AA4: 30@ = get_dynamic_library_procedure "GetCleoPlusVersion" library 31@
then
    0AA7: call_function_return 30@ num_params 0 pop 0 29@
end
0AA3: free_dynamic_library 31@
if
    29@ >= 0x1020000
jf @ILoveMyGirlfriendJessica


int i1, i2, i3, i4, iGarCam1, iGarCam2, iWarpFlag, iCounter = -2, iLimit, iInnerLimit, iCarX, iBool, iLight = -1
int iCar[6]
float fDist [6]
float fX1, fY1, fZ1, fX2, fY2, fZ2, f1

for i1 = 0 to 120 step 1
    wait 0
end

read_memory iGarCam1 0x1565080 size 1 virtual_protect 0
read_memory iGarCam2 0x1565081 size 4 virtual_protect 0

:Main
wait 200

while true
    wait 0
     
    if and
        is_player_playing $PLAYER_CHAR
        is_player_control_on $PLAYER_CHAR
        not is_on_scripted_cutscene
    jf @Main

    gosub @GarageOpenCheck    
    if
        iBool == true
    then       
        if
            iCounter <> -2
        jf @Main
        write_memory 0x1565080 size 1 value iGarCam1 virtual_protect 0
        write_memory 0x1565081 size 4 value iGarCam2 virtual_protect 0
        iCounter = -2
        jump @Main
    end
    
    if
        iCounter <> -1
    then
        write_memory 0x1565080 size 1 value 0xB0 virtual_protect 0
        write_memory 0x1565081 size 1 value 0x00 virtual_protect 0
        make_nop 0x1565082 size 3
        iCounter = -1
    end
    
    if
        not is_char_in_any_car $PLAYER_ACTOR
    jf @Main
      
    if or
        is_button_just_pressed pad 0 button 15
        is_char_entering_any_car $PLAYER_ACTOR
    jf continue
    
    gosub @CheckAbortButtons
    if
        iBool == false
    jf continue
    
    i1 = 0
    while get_any_car_no_save_recursive i1 progress_to i1 car_to iCarX
        if
            is_car_on_screen iCarX
        jf continue
        if
            locate_char_distance_to_car $PLAYER_ACTOR iCarX 20.0
        jf continue
        if
            not is_car_dead iCarX
        jf continue
        get_driver_of_car i2 = car iCarX
        if
            not does_char_exist i2
        jf continue
        iCounter += 1
        iCar[iCounter] = iCarX
        if
            iCounter < 5
        jf break
    end
    
    if
        iCounter < 1
    then
        iCounter = -1
        repeat
            wait 0
            if or
                is_button_pressed pad 0 button 15
                is_char_entering_any_car $PLAYER_ACTOR
            jf @Main
        until false
    end                     
    
    clear_char_tasks $PLAYER_ACTOR
    set_player_enter_car_button $PLAYER_CHAR can_enter_exit_vehicles 0
    set_player_cycle_weapon_button $PLAYER_CHAR weapons_scrollable 0
    
    get_char_coordinates $PLAYER_ACTOR fX1 fY1 f1
     
    for i1 = 0 to iCounter step 1
        get_car_coordinates iCar[i1] fX2 fY2 f1
        get_distance_between_coords_2d fDist[i1] = distance_between_XY fX1 fY1 and_XY fX2 fY2
    end
    
    // Sort CarArray by distance (BubbleSort)
    // iCounter = last Index    
    iLimit = iCounter - 1   // First Loop until last Index - 1
    
    for i1 = 0 to iLimit step 1
            
        iInnerLimit = iLimit - i1    // Second Loop until one element before last element
        
        for i2 = 0 to iInnerLimit step 1
                    
            i3 = i2 + 1
                        
            if
                fDist[i2] > fDist[i3]
            then
                // Switch distance
                f1 = fDist[i2]
                fDist[i2] = fDist[i3]
                fDist[i3] = f1
                
                // Switch car
                iCarX = iCar[i2]
                iCar[i2] = iCar[i3]
                iCar[i3] = iCarX
            end          
        end        
    end
    
    read_memory i3 0x423894 size 1 virtual_protect 0
    if
        i3 == 0x8A  //TrailerLightFix active
    then
        read_memory i4 0x4238BA size 2 virtual_protect 0
        make_nop 0x4238BA size 2
    else
        read_memory i3 0x6E1DBE size 4 virtual_protect 0
        read_memory i4 0x6E1DC2 size 2 virtual_protect 0
        make_nop 0x6E1DBE size 6    // Disable engine_on check for headlights
    end
    
    iWarpFlag = 0
    i1 = 0
    
    while true                        
        wait 0
               
        if and
            is_player_playing $PLAYER_CHAR
            is_player_control_on $PLAYER_CHAR
            not is_player_using_jetpack $PLAYER_CHAR
            not is_on_scripted_cutscene
            not is_char_in_any_car $PLAYER_ACTOR
            not is_car_dead iCar[i1]
        jf @Abort
        
        if
            locate_char_distance_to_car $PLAYER_ACTOR iCar[i1] 20.0
        jf @Abort
        
        gosub @CheckAbortButtons
        if
            iBool == true
        then
            :Abort
            if
                i3 == 0x8A
            then
                write_memory 0x4238BA size 2 value i4 virtual_protect 0
            else    
                write_memory 0x6E1DBE size 4 value i3 virtual_protect 0 // Revert engine_on check for headlights
                write_memory 0x6E1DC2 size 2 value i4 virtual_protect 0
            end            
            if
                does_vehicle_exist iCar[i1]
            then
                set_car_lights_on iCar[i1] lights 0
            end            
            if
                does_searchlight_exist iLight
            then
                delete_searchlight iLight
                iLight = -1
            end            
            set_player_enter_car_button $PLAYER_CHAR can_enter_exit_vehicles 1
            set_player_cycle_weapon_button $PLAYER_CHAR weapons_scrollable 1
            iCounter = -1
            jump @Main
        end
        
        if
            not does_searchlight_exist iLight
        then
            set_car_lights_on iCar[i1] lights 1
            get_car_coordinates iCar[i1] fX1 fY1 fZ1
            f1 = fZ1
            f1 += 20.0
            get_vehicle_pointer iCarX iCar[i1]
            i2 = 0
            allocate_memory i2 size 44
            get_collision_between_points fX1 fY1 fZ1 fX1 fY1 f1 flags 1 0 0 0 0 0 0 1 ignore_entity iCarX store_point_to fX2 fY2 fZ2 entity_to iLimit colpoint_data_to i2
            free_memory i2
            if or
                fZ2 < 0.1
                fZ2 > 999.0
            then
                fZ2 = fZ1
                fZ2 += 6.0
            end 
            fZ2 -= 0.1            
            create_searchlight iLight = create_searchlight_at fX1 fY1 fZ2 radius 0.25 target fX1 fY1 fZ1 radius 35.0
        end
        
        if
            iWarpFlag > 0
        then
            iWarpFlag += 1
            if
                iWarpFlag > 2
            then
                if
                    not is_char_entering_any_car $PLAYER_ACTOR
                then
                    task_warp_char_into_car_as_driver $PLAYER_ACTOR into_car iCar[i1]
                    continue
                end
                iWarpFlag = 0
            end
        end
        
        if or
            is_button_just_pressed pad 0 button 15
            is_button_just_pressed pad 0 button 16
        then
            if and
                not is_button_pressed 0 button 0
                not is_button_pressed 0 button 1
            then
                task_enter_car_as_driver $PLAYER_ACTOR enter_car iCar[i1] as_driver 10000
                iWarpFlag = 1
                repeat
                    write_memory 0xB73476 size 2 value 0 virtual_protect 0
                    write_memory 0xB73478 size 2 value 0 virtual_protect 0
                    wait 0
                    if and
                        is_player_playing $PLAYER_CHAR
                        is_player_control_on $PLAYER_CHAR
                        not is_player_using_jetpack $PLAYER_CHAR
                        not is_on_scripted_cutscene
                        not is_char_in_any_car $PLAYER_ACTOR
                        not is_car_dead iCar[i1]
                    jf @Abort
                    gosub @CheckAbortButtons
                    if and
                        iBool == false
                        locate_char_distance_to_car $PLAYER_ACTOR iCar[i1] 20.0
                    jf @Abort
                    if or
                        is_button_pressed 0 button 15
                        is_button_pressed 0 button 16
                    jf break
                until false
                continue   
            end
        end
                
        if or
            is_button_just_pressed pad 0 button 5
            is_button_just_pressed pad 0 button 7
        then
            iWarpFlag = 0
            set_car_lights_on iCar[i1] lights 0
            if
                is_button_just_pressed pad 0 button 5
            then
                i1 -= 1
            else
                i1 += 1
            end
            if
                i1 < 0
            then
                i1 = iCounter
            end
            if
                i1 > iCounter
            then
                i1 = 0
            end
            if
                does_searchlight_exist iLight
            then
                delete_searchlight iLight
                iLight = -1
            end
        end
    end                   
end
    
        
:GarageOpenCheck
iBool = false
if
    not is_garage_closed 'CJSAFE'
then
    if
        not locate_char_distance_to_coordinates $PLAYER_ACTOR 2502.31 -1699.36 12.4323 radius 30.0  // Ganton
    return_if_false
end
if
    not is_garage_closed 'BEACSV'
then
    if
        not locate_char_distance_to_coordinates $PLAYER_ACTOR 319.326 -1768.93 3.35686 radius 30.0  // Santa Maria Beach
    return_if_false
end
if
    not is_garage_closed 'BLOB6'
then
    if
        not locate_char_distance_to_coordinates $PLAYER_ACTOR 1408.65 1899.52 10.115 radius 30.0    // Redsands West
    return_if_false
end
if
    not is_garage_closed 'BLOB69'
then
    if
        not locate_char_distance_to_coordinates $PLAYER_ACTOR 1269.2 2525.14 9.80013 radius 30.0    // Prickle Pine
    return_if_false
end
if
    not is_garage_closed 'BLOB7'
then
    if
        not locate_char_distance_to_coordinates $PLAYER_ACTOR 929.554 2008.59 10.115 radius 30.0    // Whitewood Estates
    return_if_false
end
if
    not is_garage_closed 'BURBDO2'
then
    if
        not locate_char_distance_to_coordinates $PLAYER_ACTOR 783.155 -492.75 16.3361 radius 30.0   // Dillimore
    return_if_false
end
if
    not is_garage_closed 'BURBDOO'
then
    if
        not locate_char_distance_to_coordinates $PLAYER_ACTOR 2227.6 168.649 26.4635 radius 30.0    // Palomino Creek
    return_if_false
end
if
    not is_garage_closed 'CARLAS1'
then
    if
        not locate_char_distance_to_coordinates $PLAYER_ACTOR 1694.8 -2088.7 12.3636 radius 30.0    // El Corona
    return_if_false
end
if
    not is_garage_closed 'CESAFE1'
then
    if
        not locate_char_distance_to_coordinates $PLAYER_ACTOR 1352.58 -636.657 108.135 radius 30.0  // Muholland
    return_if_false
end
if
    not is_garage_closed 'CN2GAR1'
then
    if
        not locate_char_distance_to_coordinates $PLAYER_ACTOR -364.439 1194.37 18.597 radius 30.0   // Fort Carson
    return_if_false
end
if
    not is_garage_closed 'CN2GAR2'
then
    if
        not locate_char_distance_to_coordinates $PLAYER_ACTOR 430.059 2542.31 15.166 radius 30.0    // Verdant Meadows
    return_if_false
end
if
    not is_garage_closed 'LCKSFSE'
then
    if
        not locate_char_distance_to_coordinates $PLAYER_ACTOR -2032.546 129.954 28.843 radius 30.0  // Doherty
    return_if_false
end
if
    not is_garage_closed 'SAV1SFE'
then
    if
        not locate_char_distance_to_coordinates $PLAYER_ACTOR -2108.92 886.553 75.566 radius 30.0   // Calton Heights
    return_if_false
end
if
    not is_garage_closed 'SAV1SFW'
then
    if
        not locate_char_distance_to_coordinates $PLAYER_ACTOR -2699.12 821.489 49.0042 radius 30.0  // Paradiso
    return_if_false
end
if
    not is_garage_closed 'SVGSFS1'
then
    if
        not locate_char_distance_to_coordinates $PLAYER_ACTOR -2454.02 -131.556 25.0886 radius 30.0 // Hashbury
    return_if_false
end
if
    not is_garage_closed 'VESVGRG'
then
    if
        not locate_char_distance_to_coordinates $PLAYER_ACTOR 2449.5 695.018 10.4742 radius 30.0    // Rockshore West
    return_if_false
end
iBool = true
return


:CheckAbortButtons
iBool = false
if or
    is_any_fire_button_pressed 0
    is_aim_button_pressed 0
    is_button_pressed 0 button 4
    is_button_pressed 0 button 18
return_if_false
iBool = true
return


:ILoveMyGirlfriendJessica
TIMERA = 0

repeat
    if
        0@ == 0
    then
        0AD1: print_formatted_now "Garage Vehicle Chooser: CLEO+ 1.2.0 or newer required. Please download and install it in cleo folder." time 100
    end
    wait 0
    if or
        89E7: not is_player_control_on $PLAYER_CHAR
        016B: fading
    then
        TIMERA = 0
    end
until TIMERA > 8000

terminate_this_custom_script