bool ReadWeaponDataFromFileForSlot( IFileSystem* filesystem, const char *szWeaponName, WEAPON_FILE_INFO_HANDLE *phandle, const unsigned char *pICEKey ) { if ( !phandle ) { Assert( 0 ); return false; } *phandle = FindWeaponInfoSlot( szWeaponName ); FileWeaponInfo_t *pFileInfo = GetFileWeaponInfoFromHandle( *phandle ); Assert( pFileInfo ); if ( pFileInfo->bParsedScript ) return true; char sz[128]; Q_snprintf( sz, sizeof( sz ), "scripts/%s", szWeaponName ); KeyValues *pKV = ReadEncryptedKVFile( filesystem, sz, pICEKey, #if defined( DOD_DLL ) true // Only read .ctx files! #else false #endif ); if ( !pKV ) return false; pFileInfo->Parse( pKV, szWeaponName ); pKV->deleteThis(); return true; }
void CDODBaseRocketWeapon::Spawn( ) { 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(); }
CTFDroppedWeapon *CTFDroppedWeapon::Create( const Vector &vecOrigin, const QAngle &vecAngles, CBaseEntity *pOwner, CTFWeaponBase *pWeapon ) { CTFDroppedWeapon *pDroppedWeapon = static_cast<CTFDroppedWeapon*>( CBaseAnimating::CreateNoSpawn( "tf_dropped_weapon", vecOrigin, vecAngles, pOwner ) ); if ( pDroppedWeapon ) { pDroppedWeapon->SetModelName( pWeapon->GetModelName() ); pDroppedWeapon->SetItem( pWeapon->GetItem() ); WEAPON_FILE_INFO_HANDLE hWpnInfo = LookupWeaponInfoSlot( pWeapon->GetClassname() ); pDroppedWeapon->m_pWeaponInfo = static_cast<CTFWeaponInfo*>( GetFileWeaponInfoFromHandle( hWpnInfo ) ); DispatchSpawn( pDroppedWeapon ); } return pDroppedWeapon; }
// ----------------------------------------------------------------------------- // Purpose: // ----------------------------------------------------------------------------- void CTFWeaponBaseMelee::Spawn() { Precache(); // Get the weapon information. WEAPON_FILE_INFO_HANDLE hWpnInfo = LookupWeaponInfoSlot( GetClassname() ); Assert( hWpnInfo != GetInvalidWeaponInfoHandle() ); CTFWeaponInfo *pWeaponInfo = dynamic_cast< CTFWeaponInfo* >( GetFileWeaponInfoFromHandle( hWpnInfo ) ); Assert( pWeaponInfo && "Failed to get CTFWeaponInfo in melee weapon spawn" ); m_pWeaponInfo = pWeaponInfo; Assert( m_pWeaponInfo ); // No ammo. m_iClip1 = -1; BaseClass::Spawn(); }
void CHL2MP_Player::GiveDefaultItems( void ) { EquipSuit(); //GiveNamedItem( "weapon_kungfu" ); CBaseCombatWeapon *pDefault = static_cast<CBaseCombatWeapon*>(GiveNamedItem( "weapon_combatknife" )); Assert( pDefault ); Weapon_Switch( pDefault ); if ( IsBot() ) { CBaseCombatWeapon *pMac11 = static_cast<CBaseCombatWeapon*>(GiveNamedItem( "weapon_mac11" )); Weapon_Switch( pMac11 ); CBasePlayer::GiveAmmo( 128, "Mac11" ); } FileWeaponInfo_t* pInfo = GetFileWeaponInfoFromHandle( LookupWeaponInfoSlot( "weapon_deringer" ) ); if ( pInfo ) CBasePlayer::GiveAmmo( pInfo->iDefaultAmmoPrimary, "Deringer" ); }
CSDKWeaponInfo* CSDKWeaponInfo::GetWeaponInfo(SDKWeaponID eWeapon) { const char* pszAlias = WeaponIDToAlias( eWeapon ); Assert(pszAlias); if (!pszAlias) return NULL; char szName[128]; Q_snprintf( szName, sizeof( szName ), "weapon_%s", pszAlias ); WEAPON_FILE_INFO_HANDLE hWeaponFile = LookupWeaponInfoSlot( szName ); if (hWeaponFile == GetInvalidWeaponInfoHandle()) { Assert(hWeaponFile != GetInvalidWeaponInfoHandle()); return NULL; } return static_cast< CSDKWeaponInfo* >( GetFileWeaponInfoFromHandle( hWeaponFile ) ); }
/** * Debug command to give a named weapon */ void CCSBot::GiveWeapon( const char *weaponAlias ) { const char *translatedAlias = GetTranslatedWeaponAlias( weaponAlias ); char wpnName[128]; Q_snprintf( wpnName, sizeof( wpnName ), "weapon_%s", translatedAlias ); WEAPON_FILE_INFO_HANDLE hWpnInfo = LookupWeaponInfoSlot( wpnName ); if ( hWpnInfo == GetInvalidWeaponInfoHandle() ) { return; } CCSWeaponInfo *pWeaponInfo = dynamic_cast< CCSWeaponInfo* >( GetFileWeaponInfoFromHandle( hWpnInfo ) ); if ( !pWeaponInfo ) { return; } if ( !Weapon_OwnsThisType( wpnName ) ) { CBaseCombatWeapon *pWeapon = Weapon_GetSlot( pWeaponInfo->iSlot ); if ( pWeapon ) { if ( pWeaponInfo->iSlot == WEAPON_SLOT_PISTOL ) { DropPistol(); } else if ( pWeaponInfo->iSlot == WEAPON_SLOT_RIFLE ) { DropRifle(); } } } GiveNamedItem( wpnName ); }
// gets the weapondata for a particular class of weapon (assumes the weapon has been precached already) CASW_WeaponInfo* CASW_EquipmentList::GetWeaponDataFor(const char* szWeaponClass) { WEAPON_FILE_INFO_HANDLE hWeaponFileInfo; ReadWeaponDataFromFileForSlot( filesystem, szWeaponClass, &hWeaponFileInfo, ASWGameRules()->GetEncryptionKey() ); return dynamic_cast<CASW_WeaponInfo*>(GetFileWeaponInfoFromHandle(hWeaponFileInfo)); }
//-------------------------------------------------------------------------------------------------------------- // Takes the bot pointer and constructs the net name using the current bot name prefix. void UTIL_ConstructBotNetName( char *name, int nameLength, const BotProfile *profile ) { if (profile == NULL) { name[0] = 0; return; } // if there is no bot prefix just use the profile name. if ((cv_bot_prefix.GetString() == NULL) || (strlen(cv_bot_prefix.GetString()) == 0)) { Q_strncpy( name, profile->GetName(), nameLength ); return; } // find the highest difficulty const char *diffStr = BotDifficultyName[0]; for ( int i=BOT_EXPERT; i>0; --i ) { if ( profile->IsDifficulty( (BotDifficultyType)i ) ) { diffStr = BotDifficultyName[i]; break; } } const char *weaponStr = NULL; if ( profile->GetWeaponPreferenceCount() ) { weaponStr = profile->GetWeaponPreferenceAsString( 0 ); const char *translatedAlias = GetTranslatedWeaponAlias( weaponStr ); char wpnName[128]; Q_snprintf( wpnName, sizeof( wpnName ), "weapon_%s", translatedAlias ); WEAPON_FILE_INFO_HANDLE hWpnInfo = LookupWeaponInfoSlot( wpnName ); if ( hWpnInfo != GetInvalidWeaponInfoHandle() ) { CCFWeaponInfo *pWeaponInfo = dynamic_cast< CCFWeaponInfo* >( GetFileWeaponInfoFromHandle( hWpnInfo ) ); if ( pWeaponInfo ) { weapontype_t weaponType = pWeaponInfo->m_eWeaponType; weaponStr = CCFWeaponInfo::WeaponTypeToString( weaponType ); } } } if ( !weaponStr ) { weaponStr = ""; } char skillStr[16]; Q_snprintf( skillStr, sizeof( skillStr ), "%.0f", profile->GetSkill()*100 ); char temp[MAX_PLAYER_NAME_LENGTH*2]; char prefix[MAX_PLAYER_NAME_LENGTH*2]; Q_strncpy( temp, cv_bot_prefix.GetString(), sizeof( temp ) ); Q_StrSubst( temp, "<difficulty>", diffStr, prefix, sizeof( prefix ) ); Q_StrSubst( prefix, "<weaponclass>", weaponStr, temp, sizeof( temp ) ); Q_StrSubst( temp, "<skill>", skillStr, prefix, sizeof( prefix ) ); Q_snprintf( name, nameLength, "%s %s", prefix, profile->GetName() ); }
//----------------------------------------------------------------------------- // Purpose: This runs on both the client and the server. On the server, it // only does the damage calculations. On the client, it does all the effects. //----------------------------------------------------------------------------- void FX_FireBullets( int iPlayer, const Vector &vecOrigin, const QAngle &vecAngles, int iWeapon, int iMode, int iSeed, float flSpread, float flDamage /* = -1.0f */, bool bCritical /* = false*/ ) { // Get the weapon information. const char *pszWeaponAlias = WeaponIdToAlias( iWeapon ); if ( !pszWeaponAlias ) { DevMsg( 1, "FX_FireBullets: weapon alias for ID %i not found\n", iWeapon ); return; } WEAPON_FILE_INFO_HANDLE hWpnInfo = LookupWeaponInfoSlot( pszWeaponAlias ); if ( hWpnInfo == GetInvalidWeaponInfoHandle() ) { DevMsg( 1, "FX_FireBullets: LookupWeaponInfoSlot failed for weapon %s\n", pszWeaponAlias ); return; } CTFWeaponInfo *pWeaponInfo = static_cast<CTFWeaponInfo*>( GetFileWeaponInfoFromHandle( hWpnInfo ) ); if( !pWeaponInfo ) return; bool bDoEffects = false; #ifdef CLIENT_DLL C_TFPlayer *pPlayer = ToTFPlayer( ClientEntityList().GetBaseEntity( iPlayer ) ); #else CTFPlayer *pPlayer = ToTFPlayer( UTIL_PlayerByIndex( iPlayer ) ); #endif if ( !pPlayer ) return; // Client specific. #ifdef CLIENT_DLL bDoEffects = true; // The minigun has custom sound & animation code to deal with its windup/down. if ( !pPlayer->IsLocalPlayer() && iWeapon != TF_WEAPON_MINIGUN ) { // Fire the animation event. if ( pPlayer && !pPlayer->IsDormant() ) { if ( iMode == TF_WEAPON_PRIMARY_MODE ) { pPlayer->m_PlayerAnimState->DoAnimationEvent( PLAYERANIMEVENT_ATTACK_PRIMARY ); } else { pPlayer->m_PlayerAnimState->DoAnimationEvent( PLAYERANIMEVENT_ATTACK_SECONDARY ); } } //FX_WeaponSound( pPlayer->entindex(), SINGLE, vecOrigin, pWeaponInfo ); } // Server specific. #else // If this is server code, send the effect over to client as temp entity and // dispatch one message for all the bullet impacts and sounds. TE_FireBullets( pPlayer->entindex(), vecOrigin, vecAngles, iWeapon, iMode, iSeed, flSpread, bCritical ); // Let the player remember the usercmd he fired a weapon on. Assists in making decisions about lag compensation. pPlayer->NoteWeaponFired(); #endif // Fire bullets, calculate impacts & effects. StartGroupingSounds(); #if !defined (CLIENT_DLL) // Move other players back to history positions based on local player's lag lagcompensation->StartLagCompensation( pPlayer, pPlayer->GetCurrentCommand() ); #endif // Get the shooting angles. Vector vecShootForward, vecShootRight, vecShootUp; AngleVectors( vecAngles, &vecShootForward, &vecShootRight, &vecShootUp ); // Initialize the static firing information. FireBulletsInfo_t fireInfo; fireInfo.m_vecSrc = vecOrigin; if ( flDamage < 0.0f ) { fireInfo.m_flDamage = pWeaponInfo->GetWeaponData( iMode ).m_nDamage; } else { fireInfo.m_flDamage = static_cast<int>(flDamage); } fireInfo.m_flDistance = pWeaponInfo->GetWeaponData( iMode ).m_flRange; fireInfo.m_iShots = 1; fireInfo.m_vecSpread.Init( flSpread, flSpread, 0.0f ); fireInfo.m_iAmmoType = pWeaponInfo->iAmmoType; // Setup the bullet damage type & roll for crit. int nDamageType = DMG_GENERIC; int nCustomDamageType = TF_DMG_CUSTOM_NONE; CTFWeaponBase *pWeapon = pPlayer->GetActiveTFWeapon(); if ( pWeapon ) { nDamageType = pWeapon->GetDamageType(); if ( pWeapon->IsCurrentAttackACrit() || bCritical ) { nDamageType |= DMG_CRITICAL; } nCustomDamageType = pWeapon->GetCustomDamageType(); } if ( iWeapon != TF_WEAPON_MINIGUN ) { fireInfo.m_iTracerFreq = 2; } // Reset multi-damage structures. ClearMultiDamage(); int nBulletsPerShot = pWeaponInfo->GetWeaponData( iMode ).m_nBulletsPerShot; for ( int iBullet = 0; iBullet < nBulletsPerShot; ++iBullet ) { // Initialize random system with this seed. RandomSeed( iSeed ); // Determine if the first bullet should be perfectly accurate. bool bPerfectAccuracy = false; if ( pWeapon && iBullet == 0 ) { float flFireInterval = gpGlobals->curtime - pWeapon->GetLastFireTime(); if ( nBulletsPerShot == 1 ) bPerfectAccuracy = flFireInterval > 1.25f; else bPerfectAccuracy = flFireInterval > 0.25f; } float x = 0.0f; float y = 0.0f; // tf_use_fixed_weapon_spread calculations go here. if ( !bPerfectAccuracy ) { // Get circular gaussian spread. x = RandomFloat( -0.5, 0.5 ) + RandomFloat( -0.5, 0.5 ); y = RandomFloat( -0.5, 0.5 ) + RandomFloat( -0.5, 0.5 ); } // Initialize the varialbe firing information. fireInfo.m_vecDirShooting = vecShootForward + ( x * flSpread * vecShootRight ) + ( y * flSpread * vecShootUp ); fireInfo.m_vecDirShooting.NormalizeInPlace(); // Fire a bullet. pPlayer->FireBullet( fireInfo, bDoEffects, nDamageType, nCustomDamageType ); // Use new seed for next bullet. ++iSeed; } // Apply damage if any. ApplyMultiDamage(); #if !defined (CLIENT_DLL) lagcompensation->FinishLagCompensation( pPlayer ); #endif EndGroupingSounds(); }
// This runs on both the client and the server. // On the server, it only does the damage calculations. // On the client, it does all the effects. void FX_FireBullets( int iPlayerIndex, const Vector &vOrigin, const QAngle &vAngles, int iWeaponID, int iMode, int iSeed, float flSpread ) { bool bDoEffects = true; #ifdef CLIENT_DLL C_SDKPlayer *pPlayer = ToSDKPlayer( ClientEntityList().GetBaseEntity( iPlayerIndex ) ); #else CSDKPlayer *pPlayer = ToSDKPlayer( UTIL_PlayerByIndex( iPlayerIndex) ); #endif const char * weaponAlias = WeaponIDToAlias( iWeaponID ); if ( !weaponAlias ) { DevMsg("FX_FireBullets: weapon alias for ID %i not found\n", iWeaponID ); return; } char wpnName[128]; Q_snprintf( wpnName, sizeof( wpnName ), "weapon_%s", weaponAlias ); WEAPON_FILE_INFO_HANDLE hWpnInfo = LookupWeaponInfoSlot( wpnName ); if ( hWpnInfo == GetInvalidWeaponInfoHandle() ) { DevMsg("FX_FireBullets: LookupWeaponInfoSlot failed for weapon %s\n", wpnName ); return; } CSDKWeaponInfo *pWeaponInfo = static_cast< CSDKWeaponInfo* >( GetFileWeaponInfoFromHandle( hWpnInfo ) ); #ifdef CLIENT_DLL // Do the firing animation event. if ( pPlayer && !pPlayer->IsDormant() ) { pPlayer->m_PlayerAnimState->DoAnimationEvent( PLAYERANIMEVENT_ATTACK_PRIMARY ); } #else // if this is server code, send the effect over to client as temp entity // Dispatch one message for all the bullet impacts and sounds. TE_FireBullets( iPlayerIndex, vOrigin, vAngles, iWeaponID, iMode, iSeed, flSpread ); bDoEffects = false; // no effects on server #endif iSeed++; int iDamage = pWeaponInfo->m_iDamage; int iAmmoType = pWeaponInfo->iAmmoType; WeaponSound_t sound_type = SINGLE; if ( bDoEffects) { FX_WeaponSound( iPlayerIndex, sound_type, vOrigin, pWeaponInfo ); } // Fire bullets, calculate impacts & effects if ( !pPlayer ) return; StartGroupingSounds(); #if !defined (CLIENT_DLL) // Move other players back to history positions based on local player's lag lagcompensation->StartLagCompensation( pPlayer, LAG_COMPENSATE_BOUNDS ); #endif for ( int iBullet=0; iBullet < pWeaponInfo->m_iBullets; iBullet++ ) { RandomSeed( iSeed ); // init random system with this seed // Get circular gaussian spread. float x, y; x = RandomFloat( -0.5, 0.5 ) + RandomFloat( -0.5, 0.5 ); y = RandomFloat( -0.5, 0.5 ) + RandomFloat( -0.5, 0.5 ); iSeed++; // use new seed for next bullet pPlayer->FireBullet( vOrigin, vAngles, flSpread, iDamage, iAmmoType, pPlayer, bDoEffects, x,y ); } #if !defined (CLIENT_DLL) lagcompensation->FinishLagCompensation( pPlayer ); #endif EndGroupingSounds(); }