Écrit par David Henry, le 20 juillet 2002
Attention : cet article a été écrit pour le SDK 2.2 d'Half-Life 1 ! Il se peut qu'il ne soit pas entièrement compatible avec des versions antérieures ou supérieures du Kit.
Ce tutorial a pour but de vous montrer comment créer une simple visée laser telle que celle du lance-roquettes d'Half-life. Pour cela, on va admettre qu'on activera et désactivera notre visée laser avec le second mode de tir de l'arme.
Notre tâche va être grandement simplifiée puisqu'on va justement pouvoir
reprendre la classe CLaserSpot
originellement créée
spécialement pour le RPG.
Comme je l'ai évoqué juste au-dessus, la visée laser du RPG est
constituée d'une entité (matérialisée par un sprite) représentant
le point d'impact du laser contre quelque chose de solide. Ce point
est appelé « laser dot », d'où sa classe
CLaserSpot
.
On va donc avoir besoin d'un objet de cette classe pour notre arme. Allez à la définition de classe de votre arme (normalement dans weapon.h) et rajoutez-y ces deux variables membres publiques :
public: // laser dot CLaserSpot *m_pSpot; bool m_bSpotActive
La seconde variable est un flag indiquant si le laser est actif ou pas. On va également créer un nouvelle fonction pour afficher le « laser dot ». Ajoutez à la classe de votre arme la déclaration de cette nouvelle fonction membre :
void UpdateSpot ();
Maintenant déplacez vous vers le fichier source de votre arme et initialisons
notre flag dans la fonction Spawn()
(en admettant que la classe de
votre arme s'appelle CMonArme
) :
// -------------------------------------------------------------------------- // CMonArme::Spawn // -------------------------------------------------------------------------- void CMonArme::Spawn () { m_bSpotActive = false; // ... reste du code de la fonction ... }
Définisions maintenant la fonction que l'on vient de créer :
// -------------------------------------------------------------------------- // CMonArme::UpdateSpot // -------------------------------------------------------------------------- void CMonArme::UpdateSpot () { #ifndef CLIENT_DLL if (m_bSpotActive) { if (!m_pSpot) m_pSpot = CLaserSpot::CreateSpot (); UTIL_MakeVectors (m_pPlayer->pev->v_angle); Vector vecSrc = m_pPlayer->GetGunPosition (); Vector vecAiming = gpGlobals->v_forward; TraceResult tr; UTIL_TraceLine (vecSrc, vecSrc + vecAiming * 8192, dont_ignore_monsters, ENT (m_pPlayer->pev), &tr); UTIL_SetOrigin (m_pSpot->pev, tr.vecEndPos); } #endif }
Cette fonction s'assure que tout d'abord que le « laser dot »
est bien créé. Si ce n'est pas le cas, on appelle la fonction
CLaserSpot::CreateSpot()
. Ensuite on construit une ligne
virtuelle à partir des coordonnées de l'arme et de l'endroit visé pour
déterminer la position du spot, lequel on met à jour en appelant
UTIL_SetOrigin()
.
Notez également que l'on s'assure de ne pas refaire deux fois la même chose : on désactive cette partie du code du côté DLL client.
Cette fonction, on va l'appeler deux fois : au début de
PrimaryAttack()
et de WeaponIdle()
. Modifiez
donc ces fonctions pour qu'elles mettent à jour le « laser
dot » :
// -------------------------------------------------------------------------- // CMonArme::PrimaryAttack // -------------------------------------------------------------------------- void CMonArme::PrimaryAttack () { UpdateSpot (); // ... reste du code de la fonction ... } // -------------------------------------------------------------------------- // CMonArme::WeaponIdle // -------------------------------------------------------------------------- void CMonArme::WeaponIdle () { UpdateSpot (); // ... reste du code de la fonction ... }
On va maintenant passer à l'activation et désactivation du laser.
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 laser.
// -------------------------------------------------------------------------- // CMonArme::SecondaryAttack // -------------------------------------------------------------------------- void CMonArme::SecondaryAttack () { m_bSpotActive = !m_bSpotActive; #ifndef CLIENT_DLL if (!m_bSpotActive && m_pSpot) { m_pSpot->Killed (NULL, GIB_NORMAL); m_pSpot = NULL; } #endif m_flNextSecondaryAttack = UTIL_WeaponTimeBase () + 0.2; }
Si le laser est désactivé, on détruit l'entité. S'il est désactivé,
on change simplement le flag m_bSpotActive
et l'entité sera
recrée lors du prochain appel de UpdateSpot()
.
Il reste enfin une dernière chose à faire : désactiver le
« laser dot » s'il est activé lorsque le joueur change
d'arme. Pour cela on fait une petite vérification dans la fonction
Holster()
:
// -------------------------------------------------------------------------- // CMonArme::Holster // -------------------------------------------------------------------------- void CMonArme::Holster (int skiplocal /* = 0 */) { // ... reste du code de la fonction ... #ifndef CLIENT_DLL if (m_pSpot) { m_pSpot->Killed (NULL, GIB_NEVER); m_pSpot = NULL; } #endif }
Et voilà ! Il ne vous reste plus qu'à recompiler mp.dll et client.dll.
Vous pouvez aussi désactiver le laser un espace de temps et le réactiver
ensuite en utilisant les fonctions suivantes (déjà déclarées et définies dans
CLaserSpot
) :
void Suspend (float flSuspendTime); void EXPORT Revive ();
Cet article est mis à disposition sous un contrat Creative Commons (licence CC-BY-ND).