Hi Leute, da man mich das schon oft gefragt hat und das schnell und einfach zu implementieren und verstehehen ist erkläre ich das mal schnell:
Wir wollen uns für unsere Pistole einen coolen Zoomeffekt auf Secondary Attack legen.
Wir werden nur an der Datei weapon_pistol.cpp im Serverprojekt arbeiten.
Das ganze basiert auf eine praktischen Funktion der Klasse CBasePlayer:
bool CBasePlayer::SetFOV( CBaseEntity *pRequester, int FOV, float zoomRate )
Zur Erklärung:
FOV soll heißen Field of View (also den Bereich den der Spieler im Spiel sehen kann).
Nun die Parameter:
CBaseEntity *pRequester ist einfach nur das Entity welches die Funktion aufgerufen hat, hier geben wir meistens "this" an.
int FOV ist die Stärke, also wie weit reingezoomt werden soll, 0 ist normaler Zoom.
float zoomRate ist die Geschwindiggkeit mit der rein oder raus gezoomt wird. (0.1 bis 0.2 sind hier gute Werte).
So nun genug zur Theorie, kommen wir zur Praxis:
In der Klassendeklaration fügen wie zwei neue Funktionen und eine neue Variable ein:
class CWeaponPistol : public CBaseHLCombatWeapon
{
DECLARE_DATADESC();public:
DECLARE_CLASS( CWeaponPistol, CBaseHLCombatWeapon );CWeaponPistol(void);
DECLARE_SERVERCLASS();
void Precache( void );
void ItemPostFrame( void );
void ItemPreFrame( void );
void ItemBusyFrame( void );
void PrimaryAttack( void );
void AddViewKick( void );
void DryFire( void );
void Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator );
//neu:
void ToogleZoom(void); //eigentliche Funktion zum Zoom an oder ausmachen
bool m_bInZoom; //zoomen wir gerade?
void SecondaryAttack( void ); //Wenn wir Rechtsklicken wird das aufgerufen
void UpdatePenaltyTime( void );
int CapabilitiesGet( void ) { return bits_CAP_WEAPON_RANGE_ATTACK1; }
Activity GetPrimaryAttackActivity( void );virtual bool Reload( void );
[...]
So nun fügen wir irgendwo in dieser Datei (zum Beispiel ganz unten) unsere ToogleZoom() Funktion hinzu:
void CWeaponPistol::ToogleZoom(void)
{
CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); //Zugriff auf die CBasePlayer Klasse[COLOR="RoyalBlue"]if [/COLOR]( pPlayer == NULL )
return; //wenn das scheitert lassen wir es gleichif ( m_bInZoom ) //wenn wir schon gezoomt haben
{
if ( pPlayer->SetFOV( this, 0, 0.2f ) ) //setze den Blick wieder zuück auf normal
{
m_bInZoom = false; //Variable die angibt ob wir zoomen auf false setzen
}
}
else //wenn wir noch nicht gezoomt haben
{
if ( pPlayer->SetFOV( this, 20, 0.1f ) ) //zoom auf 20 Units nach vorne
{m_bInZoom = true; //Variable ob wir zoomen auf true setzen
}
} //Sorry für die schlechte Formatierung
}
Wir haben in unserem Beispiel schneller raus als rein gezoomt, aber spielt mal ein wenig damit rum.
Damit das ganze jetzt noch aufgerufen wir muss jetzt noch irgendwo die "SecondaryAttack()" Funktion rein (zum Beispiel direkt danach):
void CWeaponPistol::SecondaryAttack()
{
ToogleZoom(); //Zoom aufrufen
m_flNextSecondaryAttack = gpGlobals->curtime + 0.2f; //damit das nicht dauernd aufgerufen wird sagen wir ihm das er das nächste mal erst in 2 hunderstel Sekunden wieder Zoomen darf
}
Das m_flNextSecondaryAttack = gpGlobals->curtime + 0.2f;
sagt schlicht und einfach "Du darfst erst wieder diese Funktion ausführen wenn 2 hundertstel Sekunden rum sind, sonst zoomt er nämlich dauernd rein und raus wenn man diese Taste drückt. Ist aber auf jeden Fall noch Tweakfähig, weil wenn man die Taste gedrückt hält zoomt er immernoch im abstand von einer halben Sekunde (rund) rein und raus ;).
Das ist nach diesem Schema mit jeder Waffe machbar (aber wenn man es für jede machen will sollte man das in der Elternklasse einbinden dann muss man es nicht für alle Waffen einzeln machen).
Hier noch die modifizierte weapon_pistol.cpp.
Kyle