Ajouter un zoom à votre arme

Écrit le 03/07/2003 par DukeNukem
Dernière mise à jour : 30/01/2006

Introduction

Ajouter un zoom à une arme n'est vraiment pas difficile dans Half-life. Une seule commande est utilisée : m_pPlayer->pev->fov, qui contient la valeur du FOV (Field of Vision, soit le champs de vision). FOV 0 est la valeur par défaut, qui remet la vue « normale », mais en réalité cette vue « normale » est un FOV de 90. Plus le FOV diminue, plus vous zoomerez. Vous pouvez même aller au-delà de 90 (jusqu'à 170 maximum) mais vous obtiendrez là un effet à la Alien ;-)

FOV 90   FOV 170
FOV 90   FOV 170

Dans ce tutorial je vais donc vous montrer deux exemples d'utilisation de cette instruction pour créer différents types de zooms sur vos armes.

Le zoom simple

Nous allons créer là un simple petit zoom enclenché par le second mode de tir (comme l'arbalète d'Half-life).

Pour commencer, allez dans weapons.h jusqu'à la définition de classe de votre arme et rajoutez-y cette variable membre publique :

public:
    // zoom
    bool m_bZoomActive;

Initialisons là tout de suite à false dans la fonction Spawn() pour ne pas démarrer en mode zoom :

// --------------------------------------------
// Spawn() -
// --------------------------------------------

void CMonArme::Spawn( void )
{
    m_bZoomActive = false;

    // ... reste du code de la fonction ...
}

On admettra que la classe de votre arme s'appelle CMonArme.

On va maintenant passer à l'activation et désactivation du zoom. Modifiez la fonction SecondaryAttack() de sorte à ce qu'elle ressemble à ceci au code suivant. Si vous avez déjà un second mode de tir, vous pouvez aménager votre fonction pour qu'elle accepte et votre second mode de tir, et le système de zoom.

// --------------------------------------------
// SecondaryAttack() -
// --------------------------------------------

void CMonArme::SecondaryAttack( void )
{
    m_bZoomActive = !m_bZoomActive;

    if( m_pPlayer->pev->fov != 0 )
        m_pPlayer->pev->fov = 0;
    else if( m_pPlayer->pev->fov != 20 )
        m_pPlayer->pev->fov = 20;

    m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 0.2;
}

On inverse la valeur du flag m_bZoomActive puis on change le FOV suivant le FOV actuel. Ici le zoom met le FOV à 20 mais vous pouvez varier (valeur plus petite donnera zoom plus grand).

Maintenant on va modifier la fonction Reload() pour qu'elle désactive le FOV lorsqu'elle est appelée (on ne recharge pas avec le zoom) :

// --------------------------------------------
// Reload() -
// --------------------------------------------

void CMonArme::Reload( void )
{
    if( m_pPlayer->ammo_monarme <= 0 )
        return;

    if( m_bZoomActive )
        SecondaryAttack();

    // ... reste du code de la fonction...
}

On désactive le zoom après avoir vérifié qu'il soit nécessaire de recharger!

Et enfin pour finir, nous devons nous assurer que le zoom est désactivé lorsque l'on change l'arme pour éviter de garder un FOV de 20 tout le temps (imaginez, plus de munitions, on ne pourrait plus dézoomer!). Donc dans la fonction Holster(), faites la même manipulation que pour Reload() :

// --------------------------------------------
// Holster() -
// --------------------------------------------

void CMonArme::Holster( int skiplocal /* = 0 */ )
{
    if( m_bZoomActive )
        SecondaryAttack();

    // ... reste du code de la fonction...
}

C'est terminé, vous pouvez recompiler les deux dlls et tester.

Le zoom à plusieurs niveaux

Nous allons maintenant nous intéresser à un système de zoom à plusieurs niveau. Pour l'exemple, je ne vais faire que deux niveaux de zoom (comme certaines armes de Counter-Strike). Je ne vais pas re-écrire tout le code cette fois, seulement vous dire où faire les modifications.

Tout d'abord il va nous falloir changer notre flag m_bZoomActive en int pour pouvoir stocker les différents niveaux de zoom. Dans la définition de classe de votre arme, ajoutez cette variable membre :

public:
    // zoom
    int  m_iZoomLevel;

Initialisez m_iZoomLevel à 0 dans la fonction Spawn() de votre arme :

    m_iZoomLevel = 0;

Dans les fonctions Reload() et Holster(), remplacez le if( m_bZoomActive ) par une boucle while :

    // Ancien code :
    // if( m_bZoomActive )
    //    SecondaryAttack();

    while( m_iZoomLevel )
        SecondaryAttack();

Ainsi, on appellera SecondaryAttack() tant que le zoom n'aura pas été réinitialisé à 0.

Nous allons maintenant attaquer la fonction SecondaryAttack(). Remplacez son ancien zoom par celui-ci :

// --------------------------------------------
// SecondaryAttack() -
// --------------------------------------------

void CMonArme::SecondaryAttack( void )
{
    switch( m_iZoomLevel )
    {
        // zoom 0 à zoom 1
        case 0:
        {
            m_iZoomLevel = 1;
            m_pPlayer->pev->fov = 40;
            break;
        }

        // zoom 1 à zoom 2
        case 1:
        {
            m_iZoomLevel = 2;
            m_pPlayer->pev->fov = 20;
            break;
        }

        // zoom 2 à zoom 0 (reset)
        case 2:
        {
            m_iZoomLevel = 0;
            m_pPlayer->pev->fov = 0;
            break;
        }
    }

    m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 0.2;
}

Ici, le premier mode de zoom nous change le FOV à 40, puis le second à 20. On fait un switch pour tester le niveau actuel du zoom, puis on assigne la valeur du niveau suivant (puisqu'on en change) en même temps que l'on change le fov. Le dernier niveau doit remettre à 0 le FOV et le niveau de zoom. Il ne vous reste plus qu'à compiler.

FOV 40   FOV 20
FOV 90   FOV 170