tosqualler Posté(e) le 13 février 2006 Signaler Posté(e) le 13 février 2006 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 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 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 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 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 [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 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
Havok Posté(e) le 14 février 2006 Signaler Posté(e) le 14 février 2006 Superbe ce tuto, je n'avait pas réussi à le faire seul et tu m'a bien aidé. Je pencherait plutôt pour les balles explosive mais bon c'est toi qui voit
tosqualler Posté(e) le 14 février 2006 Auteur Signaler Posté(e) le 14 février 2006 surtout que je l'ai deja casi fini mais il utilise encore des munitions du 357 mais ce n'est pas vraiment explosif xD la balle est du 357 mais a une puissance de rpg tout en ayant l'impact du 357 xD sa enflame d'un coup l'alien mais je termine les 2truc et je fais 2tutos de +
Messages recommandés
Archivé
Ce sujet est désormais archivé et ne peut plus recevoir de nouvelles réponses.