{$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, iBool, iCounter, iLimit, iInnerLimit, iCarX, iWaitTime, iGarageClosed, iAbortButtonsPressed, iLight = -1
int iCar[6]
float fDist [6]
float fX1, fY1, fZ1, fX2, fY2, fZ2, f1


while true
    wait iWaitTime
     
    if and
        is_player_playing $PLAYER_CHAR
        is_player_control_on $PLAYER_CHAR
        not is_on_scripted_cutscene
        not is_char_in_any_car $PLAYER_ACTOR
    jf @Reset

    gosub @GarageOpenCheck    
    if
        iGarageClosed == true
    then
        :Reset
        iWaitTime = 200
        iCounter = -1
        continue
    end
    
    iWaitTime = 0
    
    if
        iCounter <> 0
    jf continue
    
    gosub @CheckAbortButtons
    if
        iAbortButtonsPressed == false
    jf continue
    
    if or
        is_button_just_pressed pad 0 button 15
        is_char_entering_any_car $PLAYER_ACTOR
    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 < 6
        jf break
    end
    
    clamp_int iCounter min 0 max 5 store_to iCounter
    
    if
        iCounter > 0
    jf continue                     
    
    iBool = false
    gosub @SwitchButtonControl                        
    clear_char_tasks $PLAYER_ACTOR
    
    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    
    int_sub iLimit = iCounter - 1   // First Loop until last Index - 1
    
    for i1 = 0 to iLimit step 1
            
        int_sub iInnerLimit = iLimit - i1    // Second Loop until one element before last element
        
        for i2 = 0 to iInnerLimit step 1
                    
            int_add 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 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
    
    i1 = 0
    
    while true                        
        wait 0
               
        if and
            is_player_playing $PLAYER_CHAR
            is_player_control_on $PLAYER_CHAR 1
            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
            iAbortButtonsPressed == true
        then
            :Abort
            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            
            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
            
            while iAbortButtonsPressed == true
                wait 0
                gosub @CheckAbortButtons
            end
            
            iBool = true
            gosub @SwitchButtonControl
            jump @Reset
        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 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 20000
            end
        end
                
        if or
            is_button_just_pressed pad 0 button 5
            is_button_just_pressed pad 0 button 7
        then
            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
iGarageClosed = false
if and
    is_garage_closed 'CJSAFE'
    is_garage_closed 'BEACSV'
    is_garage_closed 'BLOB6'
    is_garage_closed 'BLOB69'
    is_garage_closed 'BLOB7'
    is_garage_closed 'BURBDO2'
    is_garage_closed 'BURBDOO'
    is_garage_closed 'CARLAS1'
return_if_false
if and
    is_garage_closed 'CESAFE1'
    is_garage_closed 'CN2GAR1'
    is_garage_closed 'CN2GAR2'
    is_garage_closed 'LCKSFSE'
    is_garage_closed 'SAV1SFE'
    is_garage_closed 'SAV1SFW'
    is_garage_closed 'SVGSFS1'
    is_garage_closed 'VESVGRG'
return_if_false
iGarageClosed = true
return


:CheckAbortButtons
iAbortButtonsPressed = 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
iAbortButtonsPressed = true
return


:SwitchButtonControl
set_player_enter_car_button $PLAYER_CHAR can_enter_exit_vehicles iBool
set_player_cycle_weapon_button $PLAYER_CHAR weapons_scrollable iBool
set_player_display_vital_stats_button $PLAYER_CHAR stats_box iBool
set_player_duck_button $PLAYER_CHAR able_to_use_crouch_button iBool
set_player_jump_button $PLAYER_CHAR jump_key iBool
set_player_fire_button $PLAYER_CHAR able_to_shoot_weapons iBool
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