[TUTOS] Troisieme Partie :: Mes premiers pas en c++.


tosqualler

Recommended Posts

Dans ce tutorial, je vais vous expliquer comment editer une arme :) et dans

le prochain la modifier casi completement.

/!\ l'arme que nous modifieront est le RPG ( lance requette ). pourquoi? simplement

car il ne dispose que d'une seule attaque et d'une bibliothèque

Logiciel utlisé

-Steam.

-SDK.

-Editeur C++.

Notion de "base"

Comment vous décrire une source? bon disons que toute votre source représente

une maison. Chaque fichier de la source ( *.cpp ) est une pièce, chaque pièce à ses

propres fonctions, salon = détente, télé,.. / bureau = travail,pc,... / cuisine =

repas,nourriture,.../ ect..

et chaque pièce est décrite dans les plans...

Maintenant voyez les pièces comme une source ( du text) et les actions

possibles comme les [#ff1c00]Fonctions[/#ff1c00] et voila la source du weapon_rpg.cpp

( dans mon tuto ) et les plans où est tout décris sont les [#ff1c00]library[/#ff1c00]

weapon_rpg.h ( dans mon tuto ). La ça commence à être dur... Mais en pratique ça

devient simple :) .

Mon premier MOD by valve

Valve propose une modification d'une arme, mais c'est très minime.

ouvrez weapon_rpg.cpp

dans

C:\Program Files\Steam\SteamApps\SourceMods\test\src\dlls\hl2_dll

Nous n'editerons que le debut de la source

[cpp]

// memdbgon must be the last include file in a .cpp file!!!

#include "tier0/memdbgon.h"

#define RPG_SPEED 1500

static ConVar sk_apc_missile_damage("sk_apc_missile_damage", "15");

#define APC_MISSILE_DAMAGE sk_apc_missile_damage.GetFloat()

const char *g_pLaserDotThink = "LaserThinkContext";

[/cpp]

pile apres les #include

Nous allons modifier la variable

[cpp]#define RPG_SPEED 1500[/cpp]

le 1500 etant la vitesse de la roquette :o

plus elle est basse plus la roquette va lentement

changez-la en

[cpp]#define RPG_SPEED 100[/cpp]

compilez et voyez le resultat avec la map test que nous avons faite

Voila votre premier MOD made in Valve.

Ajout d'une fonction a une arme

Avant de commencer à vraiment modifier la source, je vais reprendre un tutos

pour cs-source que j'ai trouvé bien fait :)

http://www.halflifedesign.net/articles.php?tutorial=7972&titre=Ajouter%20un%20zoom%20à%

le tutos explique comment ajouter un zoom au mp5, moi je vais le faire sur un RPG :)

UTILITé ??? aucune :P apart comprendre comment sont geré les fonctions.

les 2fichiers à modifier

weapon_rpg.cpp <=> arme

weapon_rpg.h <=> library, la ou sont déclaré les fonctions. Fonctions qui sont dans

le weapon_rpg.cpp

voici le bout de source qui nous intéresse

weapon_rpg.h

[cpp]

class CWeaponRPG : public CBaseHLCombatWeapon

{

DECLARE_CLASS( CWeaponRPG, CBaseHLCombatWeapon );

public:

CWeaponRPG();

~CWeaponRPG();

DECLARE_SERVERCLASS();

void Precache( void );

void PrimaryAttack( void );

virtual float GetFireRate( void ) { return 1; };

void ItemPostFrame( void );

void Activate( void );

void DecrementAmmo( CBaseCombatCharacter *pOwner );

bool Deploy( void );

bool Holster( CBaseCombatWeapon *pSwitchingTo = NULL );

bool Reload( void );

bool WeaponShouldBeLowered( void );

bool Lower( void );

virtual void Drop( const Vector &vecVelocity );

int GetMinBurst() { return 1; }

int GetMaxBurst() { return 1; }

float GetMinRestTime() { return 4.0; }

float GetMaxRestTime() { return 4.0; }

int WeaponRangeAttack1Condition( float flDot, float flDist );

void Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter

*pOperator );

void StartGuiding( void );

void StopGuiding( void );

void ToggleGuiding( void );

bool IsGuiding( void );

void NotifyRocketDied( void );

bool HasAnyAmmo( void );

void SuppressGuiding( bool state = true );

void CreateLaserPointer( void );

void UpdateLaserPosition( Vector vecMuzzlePos = vec3_origin, Vector

vecEndPos = vec3_origin );

Vector GetLaserPosition( void );

void StartLaserEffects( void );

void StopLaserEffects( void );

void UpdateLaserEffects( void );

// NPC RPG users cheat and directly set the laser pointer's origin

void UpdateNPCLaserPosition( const Vector &vecTarget );

void SetNPCLaserPosition( const Vector &vecTarget );

const Vector &GetNPCLaserPosition( void );

int CapabilitiesGet( void ) { return

bits_CAP_WEAPON_RANGE_ATTACK1; }

virtual const Vector& GetBulletSpread( void )

{

static Vector cone = VECTOR_CONE_3DEGREES;

return cone;

}

CBaseEntity *GetMissile( void ) { return m_hMissile; }

DECLARE_ACTTABLE();

DECLARE_DATADESC();

protected:

bool m_bInitialStateUpdate;

bool m_bGuiding;

bool m_bHideGuiding; //User to override

the player's wish to guide under certain circumstances

Vector m_vecNPCLaserDot;

CHandle m_hLaserDot;

CHandle m_hMissile;

CHandle m_hLaserMuzzleSprite;

CHandle m_hLaserBeam;

};

[/cpp]

c'est compliqué? oui et non, juste que chaque ligne correspond a une

variable/fonction se trouvant dans weapon_rpg.cpp

ici celle qui nous intérresse est

[cpp]void PrimaryAttack( void );[/cpp]

car nous rajouterons simples en dessous ceci

[cpp]void SecondaryAttack( void );[/cpp]

ce qui donnera

[cpp]

...

void PrimaryAttack( void );

void SecondaryAttack( void );

...

[/cpp]

voila notre fonction est declarée :) pas dur hein :)

Maintenant il reste à déclarer, les variables...Qui sont au nombre de... 3 :P

les voici

[cpp]

int tempZoom;

int numberZoom;

int fov;

[/cpp]

explication INT => variable type nombre entier, le nom après bah le nom de la

variable.

mais où est-ce que les l'ont rajoute? ( tres français )

bah dans la CLASS voir la source du haut du rpg mais à la fin

[cpp]

void CreateLaserPointer( void );

void UpdateLaserPosition( Vector vecMuzzlePos = vec3_origin, Vector vecEndPos = vec3_origin );

Vector GetLaserPosition( void );

void StartLaserEffects( void );

void StopLaserEffects( void );

void UpdateLaserEffects( void );

};

[/cpp]

ceci devien

[cpp]

void CreateLaserPointer( void );

void UpdateLaserPosition( Vector vecMuzzlePos = vec3_origin, Vector vecEndPos = vec3_origin );

Vector GetLaserPosition( void );

void StartLaserEffects( void );

void StopLaserEffects( void );

void UpdateLaserEffects( void );

int tempZoom;

int numberZoom;

int fov;

};

[/cpp]

et normalement ca ira :)

voila dans le tutos que j'ai trouvé il explique que la source du zoom qu'il a utilisé

se trouve dans le SDK, pour cela il a fait une recherche a ZOOM dans tout le SDK :)

d'où les 3variables données

et il a trouvé ceci

[cpp]

// Comme la méthode SetFOV() fait partie de la class CBasePlayer, nous devons déclarer un objet de cette class

CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );

// On vérifie que cet objet existe bien

if ( pPlayer == NULL )

return;

// On vérifie que tempZoom est différent de numberZoom

if ( tempZoom != numberZoom )

{

// Si oui

tempZoom++; // on incrémente tempZoom

fov -= 10; // on diminue le fov de 10 (fov -= 10 revient à faire fov = fov -

10)

pPlayer->SetFOV( this, fov, 0.2f ); // on appelle la méthode SetFov

}

else

{

// si non, on vérifie si tempZoom est égale à numberZoom (normalement ca ne sert à rien

//de le mettre vu que si un nombre n'est pas différent d'un autre nombre, ca veut dire

//qu'ils sont égaux ... vous avez tout compris ? )

if ( tempZoom == numberZoom )

{

// si oui

tempZoom = 0; // on remets tempZoom à 0

fov = 90; // on remets le fov à 90

pPlayer->SetFOV( this, fov, 0.1f ); // on appelle la méthode

//SetFOV() qui, si tout c'est bien passé, remets le FOV en position normal donc on ne

//zoom plus

}

}

// On va rajouter une ligne qui permet d'attendre un certain temps sinon votre zoom

//irait trop vite

m_flNextSecondaryAttack = gpGlobals->curtime + 0.5f; // Il va attendre 0.5 sec

[/cpp]

mais ou la mettre cette fonction?

bah si vous avez bien suivi vous le savez :P

Donc rendez-vous dans weapon_rpg.cpp

ajoutez dans les #include

#include "player.h" // librairie ou est decrite la fonction SetFOV()

cherchez la fonction

[cpp]

void CWeaponRPG::PrimaryAttack( void )

{

// Can't have an active missile out

if ( m_hMissile != NULL )

return;

// Can't be reloading

if ( GetActivity() == ACT_VM_RELOAD )

return;

Vector vecOrigin;

Vector vecForward;

m_flNextPrimaryAttack = gpGlobals->curtime + 0.5f;

CBasePlayer *pOwner = ToBasePlayer( GetOwner() );

if ( pOwner == NULL )

return;

Vector vForward, vRight, vUp;

pOwner->EyeVectors( &vForward, &vRight, &vUp );

Vector muzzlePoint = pOwner->Weapon_ShootPosition() + vForward * 12.0f +

vRight * 6.0f + vUp * -3.0f;

QAngle vecAngles;

VectorAngles( vForward, vecAngles );

m_hMissile = CMissile::Create( muzzlePoint, vecAngles, GetOwner()->edict() );

m_hMissile->m_hOwner = this;

// If the shot is clear to the player, give the missile a grace period

trace_t tr;

Vector vecEye = pOwner->EyePosition();

UTIL_TraceLine( vecEye, vecEye + vForward * 128, MASK_SHOT, this,

COLLISION_GROUP_NONE, &tr );

if ( tr.fraction == 1.0 )

{

m_hMissile->SetGracePeriod( 0.3 );

}

DecrementAmmo( GetOwner() );

// Register a muzzleflash for the AI

pOwner->SetMuzzleFlashTime( gpGlobals->curtime + 0.5 );

SendWeaponAnim( ACT_VM_PRIMARYATTACK );

WeaponSound( SINGLE );

// Check to see if we should trigger any RPG firing triggers

int iCount = g_hWeaponFireTriggers.Count();

for ( int i = 0; i < iCount; i++ )

{

if ( g_hWeaponFireTriggers->IsTouching( pOwner ) )

{

if ( FClassnameIs( g_hWeaponFireTriggers,

"trigger_rpgfire" ) )

{

g_hWeaponFireTriggers->ActivateMultiTrigger(

pOwner );

}

}

}

}

[/cpp]

et après cette fonction vous allez mettre la nouvelle :)

qui s'appellera? :)

void CWeaponRPG::SecondaryAttack( void ) avec la source du zoom

et ça donnera ceci :P

[cpp]

void CWeaponRPG::SecondaryAttack( void )

{

// Comme la méthode SetFOV() fais partie de la class CBasePlayer, nous devons

déclarer un objet de cette class

CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );

// On vérifie que cet objet existe bien

if ( pPlayer == NULL )

return;

// On vérifie que tempZoom est différent de numberZoom

if ( tempZoom != numberZoom )

{

// Si oui

tempZoom++; // on incrémente tempZoom

fov -= 50; // on diminue le fov de 10 (fov -= 10 revient à faire fov = fov -

10)

pPlayer->SetFOV( this, fov, 0.2f ); // on appelle la méthode SetFov

}

else

{

// si non, on vérifie si tempZoom est égale à numberZoom (normalement ça ne

//sert à rien de le mettre vu que si un

//nombre n'est pas différent d'un

//autre nombre, ca veut dire qu'ils sont égaux ... vous avez tout compris ? )

if ( tempZoom == numberZoom )

{

// si oui

tempZoom = 0; // on remets tempZoom à 0

fov = 90; // on remets le fov à 90

pPlayer->SetFOV( this, fov, 0.1f ); // on appelle la méthode

//SetFOV() qui, si tout c'est bien passé, remets //le FOV en position normal donc

//on ne zoom plus

}

}

// On va rajouter une ligne qui permet d'attendre un certain temps sinon votre zoom

//irait trop vite

m_flNextSecondaryAttack = gpGlobals->curtime + 0.5f; // Il va attendre 0.5 sec

}

[/cpp]

On croirait que c'est fini mais non :s il reste quelques étapes comme dire au RPG les

valeurs des vairables declarées plus haut.

Pour cela cherchez la fonction CWeaponRPG::CWeaponRPG() <=> en lisant on comprend

pourquoi c'est celle-ci.

[cpp]

CWeaponRPG::CWeaponRPG()

{

m_bReloadsSingly = true;

m_bInitialStateUpdate= false;

m_bHideGuiding = false;

m_bGuiding = false;

m_fMinRange1 = m_fMinRange2 = 40*12;

m_fMaxRange1 = m_fMaxRange2 = 500*12;

}

[/cpp]

on voit deja des valeurs mais on s'en fout :P

en rajoutant des valeurs a nos variables voici

[cpp]

CWeaponRPG::CWeaponRPG()

{

m_bReloadsSingly = true;

m_bInitialStateUpdate= false;

m_bHideGuiding = false;

m_bGuiding = false;

m_fMinRange1 = m_fMinRange2 = 40*12;

m_fMaxRange1 = m_fMaxRange2 = 500*12;

numberZoom = 2;

tempZoom = 0;

fov = 90;

}

[/cpp]

fov = la puissance du zoom

SI vous testez maintenant, vous aurez 2bug

-si vous switcher le zoom reste

-les bras sont en avant

Pour le switch plusieur solutions sont à combiner

la premiere

dans la fonction deploy

[cpp]

bool CWeaponRPG::Deploy( void )

{

m_bInitialStateUpdate = true;

tempZoom = numberZoom;

SecondaryAttack();

return BaseClass::Deploy();

}

[/cpp]

devient

[cpp]

bool CWeaponRPG::Deploy( void )

{

m_bInitialStateUpdate = true;

tempZoom = numberZoom;

SecondaryAttack();

return BaseClass::Deploy();

}

[/cpp]

la deuxieme, enlever le zoom lors du rechargement

et la modification ce fait donc dans la fonction reload du rpg.

[cpp]

bool CWeaponRPG::Reload( void )

{

CBaseCombatCharacter *pOwner = GetOwner();

if ( pOwner == NULL )

return false;

if ( pOwner->GetAmmoCount(m_iPrimaryAmmoType) <= 0 )

return false;

WeaponSound( RELOAD );

SendWeaponAnim( ACT_VM_RELOAD );

return true;

}

[/cpp]

devient.

[cpp]

bool CWeaponRPG::Reload( void )

{

CBaseCombatCharacter *pOwner = GetOwner();

if ( pOwner == NULL )

return false;

if ( pOwner->GetAmmoCount(m_iPrimaryAmmoType) <= 0 )

return false;

WeaponSound( RELOAD );

SendWeaponAnim( ACT_VM_RELOAD );

tempZoom = numberZoom;

SecondaryAttack();

return true;

}

[/cpp]

Donc jusqu'ici nous enlevons le zoom pendant le rechargement et au deploiment du RPG

mais reste le switch

Maintenant le créateur du tuto pour cs-source utilise une fonction qu'il a trouvé

dans le zoom d'une autre arme

nomer HOLSER

mais celle-ci est comme pour le tire secondaire, il faut la créer de toute piece.

donc direction weapon_rpg.h

mais à notre grande surprise elle existe déàja là :)

( logique vu que vous ne pouvez pas switcher quand une roquette est lancée )

la fonction est

[cpp]

bool Holster( CBaseCombatWeapon *pSwitchingTo = NULL );

[/cpp]

mais comme elle existe deja il ne faut pas la remettre sinon erreur lors de la

compilation.

Maintenant que vous savez qu'elle est declarée, reste a la trouver dans

weapon_rpg.cpp

vous trouverez ceci

[cpp]

bool CWeaponRPG::Holster( CBaseCombatWeapon *pSwitchingTo )

{

//Can't have an active missile out

if ( m_hMissile != NULL )

return false;

StopGuiding();

return BaseClass::Holster( pSwitchingTo );

}

[/cpp]

donc ajouter le meme code avant le return

ce qui donne

[cpp]

bool CWeaponRPG::Holster( CBaseCombatWeapon *pSwitchingTo )

{

//Can't have an active missile out

if ( m_hMissile != NULL )

return false;

StopGuiding();

tempZoom = numberZoom;

SecondaryAttack();

return BaseClass::Holster( pSwitchingTo );

}

[/cpp]

voila c'est fini mais il reste 1bug malheureusement, les armes sont pas mise au meme

endroit qu'avant :s

je chercherai à ça plus tard...

Prochain tutos ::

-soit ajouter une bibliothèque à une arme qui n'en a pas.

-soit faire des balles explosives.

mais dans les 2cas, ça me demande du temps.

Lien pour dl la source ( clic droit enregistrer sous ) ::

http://membres.lycos.fr/squallcs/vossey/CPP1/weapon_rpg.zip

Pour tester le MOD ( clic droit enregistrer sous ) ::

http://membres.lycos.fr/squallcs/vossey/CPP1/mod_1.rar

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.