{$CLEO}
0000:NOP
// Disable automatic reload when scrolling weapons.
0A8C: write_memory 0x0060B4DA size 4 value 0xEB08C483 virtual_protect 1
0A8C: write_memory 0x0060B4DE size 1 value 0x21 virtual_protect 1

const
   FIRETYPE_MELEE = 0
   FIRETYPE_INSTANT_HIT = 1
   FIRETYPE_PROJECTILE = 2
   FIRETYPE_AREA_EFFECT = 3
   FIRETYPE_CAMERA = 4
   FIRETYPE_USE = 5
end

const
   FIRESTATE_IDLE = 0
   FIRESTATE_FIRING = 1
   FIRESTATE_RELOADING = 2
   // There are probably more.
end

while true
wait 0 ms
    gosub @WeaponBase
    gosub @Firetype
    if
    4@ == FIRETYPE_INSTANT_HIT
    then
        gosub @MaxAmmoInClip
        gosub @AmmoInClip
        gosub @TotalAmmo
        if and
        001D:   7@ > 6@ // Checks if there is spare ammo for new clip
        803B:  not 5@ == 6@
        then
            gosub @FireState
            if
            10@ == FIRESTATE_RELOADING
            then
                if 
                0AB0:  key_pressed 82
                then
                0A8C: write_memory 0x006860D2 size 2 value 0x840F virtual_protect 1
                0A8C: write_memory 0x0060F1F5 size 2 value 0xBE0F virtual_protect 1
                gosub @Reload
                0992: set_player $PLAYER_CHAR weapons_scrollable 0
                    if and
                    82D8:   not actor $PLAYER_ACTOR current_weapon == 25
                    82D8:   not actor $PLAYER_ACTOR current_weapon == 26
                    82D8:   not actor $PLAYER_ACTOR current_weapon == 27
                    then
                    0062: 21@ -= 6@ // (int) 
                    017B: set_actor $PLAYER_ACTOR weapon 20@ ammo_to 21@
                    end
                    repeat
                    wait 0 ms
                    until 8AB0:  not key_pressed 82
                end
            else
                if 
                0AB0:  key_pressed 82
                then
                0A8C: write_memory 0x006860D2 size 2 value 0x840F virtual_protect 1
                0A8C: write_memory 0x0060F1F5 size 2 value 0xBE0F virtual_protect 1
                gosub @Reload
                0992: set_player $PLAYER_CHAR weapons_scrollable 0
                    if and
                    82D8:   not actor $PLAYER_ACTOR current_weapon == 25
                    82D8:   not actor $PLAYER_ACTOR current_weapon == 26
                    82D8:   not actor $PLAYER_ACTOR current_weapon == 27
                    then
                    0062: 21@ -= 6@ // (int) 
                    017B: set_actor $PLAYER_ACTOR weapon 20@ ammo_to 21@
                    end
                    repeat
                    wait 0 ms
                    until 8AB0:  not key_pressed 82
                else                                          
                0A8C: write_memory 0x006860D2 size 2 value 0xE990 virtual_protect 1
                0A8C: write_memory 0x0060F1F5 size 2 value 0x15EB virtual_protect 1
                0992: set_player $PLAYER_CHAR weapons_scrollable 1
                end
            end
        end
    end
end

:WeaponBase
0A96: 0@ = actor $PLAYER_ACTOR struct
0AA8: call_function_method 0x5E6580 struct 0@ num_params 0 pop 0 cSkillIndex 2@ // CPed__getWeaponSkillIndex
0470: 1@ = actor $PLAYER_ACTOR current_weapon
0AA7: call_function 0x743C60 num_params 2 pop 2 cSkillIndex 2@ sWeaponType 1@ pclWeaponInfo 3@ // getWeaponInfo
return

:FireType
0A8E: 4@ = 3@ + 0x00 // CWeaponInfo.m_eFireType
0A8D: 4@ = read_memory 4@ size 4 virtual_protect 0
return

:MaxAmmoInClip
0A8E: 5@ = 3@ + 0x20 // CWeaponInfo.m_sMaxClipAmmo
0A8D: 5@ = read_memory 5@ size 2 virtual_protect 0
return

:AmmoInClip
0A8E: 7@ = 0@ + 0x0718 // CPed.m_cWeaponSlot
0A8D: 7@ = read_memory 7@ size 1 virtual_protect 0
7@ *= 0x1C // sizeof(CWeaponSlot)
0A8E: 8@ = 0@ + 0x5A0 // CPed.m_aclWeaponSlots
005A: 8@ += 7@
0A8E: 8@ = 8@ + 0x08 // CWeaponSlot.m_iClipAmmo
0A8D: 6@ = read_memory 8@ size 1 virtual_protect 0    
return

:TotalAmmo
0470: 20@ = actor $PLAYER_ACTOR current_weapon 
041A: 21@ = actor $PLAYER_ACTOR weapon 20@ ammo
return

:FireState
0A8E: 9@ = 0@ + 0x0718 // CPed.m_cWeaponSlot
0A8D: 9@ = read_memory 9@ size 1 virtual_protect 0
9@ *= 0x1C // sizeof(CWeaponSlot)
0A8E: 10@ = 0@ + 0x5A0 // CPed.m_aclWeaponSlots
005A: 10@ += 9@
0A8E: 10@ = 10@ + 0x04 // CWeaponSlot.m_iFireState
0A8D: 10@ = read_memory 10@ size 1 virtual_protect 0   
return

:Reload
0A8E: 7@ = 0@ + 0x0718 // CPed.m_cWeaponSlot
0A8D: 7@ = read_memory 7@ size 1 virtual_protect 0
7@ *= 0x1C // sizeof(CWeaponSlot)
0A8E: 8@ = 0@ + 0x5A0 // CPed.m_aclWeaponSlots
005A: 8@ += 7@
0A8E: 8@ = 8@ + 0x04 // CWeaponSlot.m_iFireState
0A8C: write_memory 8@ size 4 value 2 virtual_protect 1
return