//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: // //=============================================================================// #include "cbase.h" #include "weapon_dodbasegun.h" #include "fx_dod_shared.h" //#include "effect_dispatch_data.h" #ifdef CLIENT_DLL #include "c_dod_player.h" #include "prediction.h" #else #include "dod_player.h" #include "te_effect_dispatch.h" #include "util.h" #include "ndebugoverlay.h" #endif #ifndef CLIENT_DLL //----------------------------------------------------------------------------- // Purpose: Only send to local player if this weapon is the active weapon // Input : *pStruct - // *pVarData - // *pRecipients - // objectID - // Output : void* //----------------------------------------------------------------------------- void* SendProxy_SendActiveLocalBaseGunDataTable( const SendProp *pProp, const void *pStruct, const void *pVarData, CSendProxyRecipients *pRecipients, int objectID ) { // Get the weapon entity CBaseCombatWeapon *pWeapon = (CBaseCombatWeapon*)pVarData; if ( pWeapon ) { // Only send this chunk of data to the player carrying this weapon CBasePlayer *pPlayer = ToBasePlayer( pWeapon->GetOwner() ); if ( pPlayer ) { pRecipients->SetOnly( pPlayer->GetClientIndex() ); return (void*)pVarData; } } return NULL; } REGISTER_SEND_PROXY_NON_MODIFIED_POINTER( SendProxy_SendActiveLocalBaseGunDataTable ); #endif IMPLEMENT_NETWORKCLASS_ALIASED( WeaponDODBaseGun, DT_WeaponDODBaseGun ) BEGIN_NETWORK_TABLE_NOBASE( CWeaponDODBaseGun, DT_LocalActiveWeaponBaseGunData ) END_NETWORK_TABLE() BEGIN_NETWORK_TABLE( CWeaponDODBaseGun, DT_WeaponDODBaseGun ) #ifdef CLIENT_DLL RecvPropDataTable("LocalActiveWeaponBaseGunData", 0, 0, &REFERENCE_RECV_TABLE(DT_LocalActiveWeaponBaseGunData)) #else SendPropDataTable("LocalActiveWeaponBaseGunData", 0, &REFERENCE_SEND_TABLE(DT_LocalActiveWeaponBaseGunData), SendProxy_SendActiveLocalBaseGunDataTable ) #endif END_NETWORK_TABLE() #ifdef CLIENT_DLL BEGIN_PREDICTION_DATA( CWeaponDODBaseGun ) END_PREDICTION_DATA() #else BEGIN_DATADESC( CWeaponDODBaseGun ) END_DATADESC() #endif LINK_ENTITY_TO_CLASS( weapon_dod_base_gun, CWeaponDODBaseGun ); extern ConVar friendlyfire; CWeaponDODBaseGun::CWeaponDODBaseGun() { } void CWeaponDODBaseGun::Spawn() { DODBaseGunSpawn(); SetZoomed( false ); } void CWeaponDODBaseGun::Precache() { BaseClass::Precache(); // Precache all weapon ejections, since every weapon will appear in the game. PrecacheModel( "models/shells/shell_small.mdl" ); PrecacheModel( "models/shells/shell_medium.mdl" ); PrecacheModel( "models/shells/shell_large.mdl" ); PrecacheModel( "models/shells/garand_clip.mdl" ); } void CWeaponDODBaseGun::PrimaryAttack() { Assert( m_pWeaponInfo ); DODBaseGunFire(); } void CWeaponDODBaseGun::DODBaseGunSpawn( void ) { WEAPON_FILE_INFO_HANDLE hWpnInfo = LookupWeaponInfoSlot( GetClassname() ); Assert( hWpnInfo != GetInvalidWeaponInfoHandle() ); CDODWeaponInfo *pWeaponInfo = dynamic_cast< CDODWeaponInfo* >( GetFileWeaponInfoFromHandle( hWpnInfo ) ); Assert( pWeaponInfo && "Failed to get CDODWeaponInfo in weapon spawn" ); m_pWeaponInfo = pWeaponInfo; BaseClass::Spawn(); } float CWeaponDODBaseGun::GetWeaponAccuracy( float flPlayerSpeed ) { //snipers and deployable weapons inherit this and override when we need a different accuracy float flSpread = m_pWeaponInfo->m_flAccuracy; if( flPlayerSpeed > 45 ) flSpread += m_pWeaponInfo->m_flAccuracyMovePenalty; return flSpread; } bool CWeaponDODBaseGun::DODBaseGunFire() { CDODPlayer *pPlayer = ToDODPlayer( GetPlayerOwner() ); Assert( pPlayer ); // Out of ammo? if ( m_iClip1 <= 0 ) { if (m_bFireOnEmpty) { PlayEmptySound(); m_flNextPrimaryAttack = gpGlobals->curtime + 0.2; } return false; } if( pPlayer->GetWaterLevel() > 2 ) { PlayEmptySound(); m_flNextPrimaryAttack = gpGlobals->curtime + 1.0; return false; } /* decrement before calling PlayPrimaryAttackAnim, so we can play the empty anim if necessary */ m_iClip1--; SendWeaponAnim( GetPrimaryAttackActivity() ); // player "shoot" animation pPlayer->SetAnimation( PLAYER_ATTACK1 ); FX_FireBullets( pPlayer->entindex(), pPlayer->Weapon_ShootPosition(), pPlayer->EyeAngles() + pPlayer->GetPunchAngle(), GetWeaponID(), Primary_Mode, CBaseEntity::GetPredictionRandomSeed() & 255, GetWeaponAccuracy( pPlayer->GetAbsVelocity().Length2D() ) ); DoFireEffects(); #ifndef CLIENT_DLL IGameEvent * event = gameeventmanager->CreateEvent( "dod_stats_weapon_attack" ); if ( event ) { event->SetInt( "attacker", pPlayer->GetUserID() ); event->SetInt( "weapon", GetStatsWeaponID() ); gameeventmanager->FireEvent( event ); } #endif //CLIENT_DLL #ifdef CLIENT_DLL CDODPlayer *p = ToDODPlayer( GetPlayerOwner() ); if ( prediction->IsFirstTimePredicted() ) p->DoRecoil( GetWeaponID(), GetRecoil() ); #endif m_flNextPrimaryAttack = m_flNextSecondaryAttack = gpGlobals->curtime + GetFireDelay(); m_flTimeWeaponIdle = gpGlobals->curtime + m_pWeaponInfo->m_flTimeToIdleAfterFire; return true; } float CWeaponDODBaseGun::GetFireDelay( void ) { return m_pWeaponInfo->m_flFireDelay; } void CWeaponDODBaseGun::DoFireEffects() { CBasePlayer *pPlayer = GetPlayerOwner(); if ( pPlayer ) pPlayer->DoMuzzleFlash(); } bool CWeaponDODBaseGun::Reload() { CBasePlayer *pPlayer = GetPlayerOwner(); if (pPlayer->GetAmmoCount( GetPrimaryAmmoType() ) <= 0 && m_iClip1 <= 0 ) { CDODPlayer *pDODPlayer = ToDODPlayer( pPlayer ); pDODPlayer->HintMessage( HINT_AMMO_EXHAUSTED ); return false; } int iResult = DefaultReload( GetMaxClip1(), GetMaxClip2(), GetReloadActivity() ); if ( !iResult ) return false; pPlayer->SetAnimation( PLAYER_RELOAD ); return true; } Activity CWeaponDODBaseGun::GetPrimaryAttackActivity( void ) { return ACT_VM_PRIMARYATTACK; } Activity CWeaponDODBaseGun::GetReloadActivity( void ) { return ACT_VM_RELOAD; } Activity CWeaponDODBaseGun::GetDrawActivity( void ) { return ACT_VM_DRAW; }