int GetWeaponData( struct edict_s *player, struct weapon_data_s *info ) { #if defined( CLIENT_WEAPONS ) int i; weapon_data_t *item; entvars_t *pev = &player->v; CBasePlayer *pl = ( CBasePlayer *) CBasePlayer::Instance( pev ); CBasePlayerWeapon *gun; ItemInfo II; memset( info, 0, 32 * sizeof( weapon_data_t ) ); if ( !pl ) return 1; // go through all of the weapons and make a list of the ones to pack for ( i = 0 ; i < MAX_ITEM_TYPES ; i++ ) { if ( pl->m_rgpPlayerItems[ i ] ) { // there's a weapon here. Should I pack it? CBasePlayerItem *pPlayerItem = pl->m_rgpPlayerItems[ i ]; while ( pPlayerItem ) { gun = (CBasePlayerWeapon *)pPlayerItem->GetWeaponPtr(); if ( gun && gun->UseDecrement() ) { // Get The ID. memset( &II, 0, sizeof( II ) ); gun->GetItemInfo( &II ); if ( II.iId >= 0 && II.iId < 32 ) { item = &info[ II.iId ]; item->m_iId = II.iId; item->m_iClip = gun->m_iClip; item->m_flTimeWeaponIdle = max( gun->m_flTimeWeaponIdle, -0.001 ); item->m_flNextPrimaryAttack = max( gun->m_flNextPrimaryAttack, -0.001 ); item->m_flNextSecondaryAttack = max( gun->m_flNextSecondaryAttack, -0.001 ); item->m_fInReload = gun->m_fInReload; } } pPlayerItem = pPlayerItem->m_pNext; } } } #else memset( info, 0, 32 * sizeof( weapon_data_t ) ); #endif return 1; }
BOOL CHalfLifeRules :: GetNextBestWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pCurrentWeapon ) { CBasePlayerItem *pCheck; CBasePlayerItem *pBest;// this will be used in the event that we don't find a weapon in the same category. int iBestWeight; int i; iBestWeight = -1;// no weapon lower than -1 can be autoswitched to pBest = NULL; if ( !pCurrentWeapon->CanHolster() ) { // can't put this gun away right now, so can't switch. return FALSE; } for ( i = 0 ; i < MAX_ITEM_TYPES ; i++ ) { pCheck = pPlayer->m_rgpPlayerItems[ i ]; while ( pCheck ) { if ( pCheck->iWeight() > -1 && pCheck->iWeight() == pCurrentWeapon->iWeight() && pCheck != pCurrentWeapon ) { // this weapon is from the same category. if ( pCheck->CanDeploy() ) { if ( pPlayer->SwitchWeapon( pCheck ) ) { return TRUE; } } } else if ( pCheck->iWeight() > iBestWeight && pCheck != pCurrentWeapon )// don't reselect the weapon we're trying to get rid of { if ( pCheck->CanDeploy() ) { // if this weapon is useable, flag it as the best iBestWeight = pCheck->iWeight(); pBest = pCheck; } } pCheck = pCheck->m_pNext; } } if ( !pBest ) { return FALSE; } pPlayer->SwitchWeapon( pBest ); return TRUE; }
//========================================================= // CWeaponBox - Kill - the think function that removes the // box from the world. //========================================================= void CWeaponBox::Kill( void ) { CBasePlayerItem *pWeapon; int i; // destroy the weapons for ( i = 0 ; i < MAX_ITEM_TYPES ; i++ ) { pWeapon = m_rgpPlayerItems[ i ]; while ( pWeapon ) { pWeapon->SetThink(SUB_Remove); pWeapon->pev->nextthink = gpGlobals->time + 0.1; pWeapon = pWeapon->m_pNext; } } // remove the box UTIL_Remove( this ); }
//========================================================= // CWeaponBox - Kill - the think function that removes the // box from the world. //========================================================= void CWeaponBox::Kill( void ) { CBasePlayerItem *pWeapon; int i; // destroy the weapons for ( i = 0 ; i < MAX_ITEM_TYPES ; i++ ) { pWeapon = m_rgpPlayerItems[ i ]; while ( pWeapon ) { pWeapon->SetThink(&CBasePlayerItem::SUB_Remove); pWeapon->SetNextThink( 0.1 ); pWeapon = pWeapon->m_pNext; } } // remove the box UTIL_Remove( this ); }
//========================================================= // CWeaponBox - Touch: try to add my contents to the toucher // if the toucher is a player. //========================================================= void CWeaponBox::Touch( CBaseEntity *pOther ) { if ( !(pev->flags & FL_ONGROUND ) ) { return; } if ( !pOther->IsPlayer() ) { // only players may touch a weaponbox. return; } if ( !pOther->IsAlive() ) { // no dead guys. return; } CBasePlayer *pPlayer = (CBasePlayer *)pOther; int i; // dole out ammo for ( i = 0 ; i < MAX_AMMO_SLOTS ; i++ ) { if ( !FStringNull( m_rgiszAmmo[ i ] ) ) { // there's some ammo of this type. pPlayer->GiveAmmo( m_rgAmmo[ i ], (char *)STRING( m_rgiszAmmo[ i ] ), MaxAmmoCarry( m_rgiszAmmo[ i ] ) ); //ALERT ( at_console, "Gave %d rounds of %s\n", m_rgAmmo[i], STRING(m_rgiszAmmo[i]) ); // now empty the ammo from the weaponbox since we just gave it to the player m_rgiszAmmo[ i ] = iStringNull; m_rgAmmo[ i ] = 0; } } // go through my weapons and try to give the usable ones to the player. // it's important the the player be given ammo first, so the weapons code doesn't refuse // to deploy a better weapon that the player may pick up because he has no ammo for it. for ( i = 0 ; i < MAX_ITEM_TYPES ; i++ ) { if ( m_rgpPlayerItems[ i ] ) { CBasePlayerItem *pItem; // have at least one weapon in this slot while ( m_rgpPlayerItems[ i ] ) { //ALERT ( at_console, "trying to give %s\n", STRING( m_rgpPlayerItems[ i ]->pev->classname ) ); pItem = m_rgpPlayerItems[ i ]; m_rgpPlayerItems[ i ] = m_rgpPlayerItems[ i ]->m_pNext;// unlink this weapon from the box if ( pPlayer->AddPlayerItem( pItem ) ) { pItem->AttachToPlayer( pPlayer ); } } } } EMIT_SOUND( pOther->edict(), CHAN_ITEM, "items/gunpickup2.wav", 1, ATTN_NORM ); SetTouch(NULL); UTIL_Remove(this); }
BOOL CHalfLifeMultiplay :: GetNextBestWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pCurrentWeapon ) { CBasePlayerItem *pCheck; CBasePlayerItem *pBest;// this will be used in the event that we don't find a weapon in the same category. int iBestWeight; int i; iBestWeight = -1;// no weapon lower than -1 can be autoswitched to pBest = NULL; if ( !pCurrentWeapon->CanHolster() ) { // can't put this gun away right now, so can't switch. return FALSE; } for ( i = 0 ; i < MAX_ITEM_TYPES ; i++ ) { pCheck = pPlayer->m_rgpPlayerItems[ i ]; while ( pCheck ) { if ( pCheck->iWeight() > -1 && pCheck->iWeight() == pCurrentWeapon->iWeight() && pCheck != pCurrentWeapon ) { // this weapon is from the same category. if ( pCheck->CanDeploy() ) { if ( pPlayer->SwitchWeapon( pCheck ) ) { return TRUE; } } } else if ( pCheck->iWeight() > iBestWeight && pCheck != pCurrentWeapon )// don't reselect the weapon we're trying to get rid of { //ALERT ( at_console, "Considering %s\n", STRING( pCheck->pev->classname ) ); // we keep updating the 'best' weapon just in case we can't find a weapon of the same weight // that the player was using. This will end up leaving the player with his heaviest-weighted // weapon. if ( pCheck->CanDeploy() ) { // if this weapon is useable, flag it as the best iBestWeight = pCheck->iWeight(); pBest = pCheck; } } pCheck = pCheck->m_pNext; } } // if we make it here, we've checked all the weapons and found no useable // weapon in the same catagory as the current weapon. // if pBest is null, we didn't find ANYTHING. Shouldn't be possible- should always // at least get the crowbar, but ya never know. if ( !pBest ) { return FALSE; } pPlayer->SwitchWeapon( pBest ); return TRUE; }
void UpdateStats( CBasePlayer *pPlayer ) { int i; int ammoCount[ MAX_AMMO_SLOTS ]; memcpy( ammoCount, pPlayer->m_rgAmmo, MAX_AMMO_SLOTS * sizeof(int) ); // Keep a running time, so the graph doesn't overlap if ( gpGlobals->time < gStats.lastGameTime ) // Changed level or died, don't b0rk { gStats.lastGameTime = gpGlobals->time; gStats.dataTime = gStats.gameTime; } gStats.gameTime += gpGlobals->time - gStats.lastGameTime; gStats.lastGameTime = gpGlobals->time; for (i = 0; i < MAX_ITEM_TYPES; i++) { CBasePlayerItem *p = pPlayer->m_rgpPlayerItems[i]; while (p) { ItemInfo II; memset(&II, 0, sizeof(II)); p->GetItemInfo(&II); int index = pPlayer->GetAmmoIndex(II.pszAmmo1); if ( index >= 0 ) ammoCount[ index ] += ((CBasePlayerWeapon *)p)->m_iClip; p = p->m_pNext; } } float ammo = 0; for (i = 1; i < MAX_AMMO_SLOTS; i++) { ammo += ammoCount[i] * AmmoDamage( CBasePlayerItem::AmmoInfoArray[i].pszName ); } float health = pPlayer->pev->health + pPlayer->pev->armorvalue * 2; // Armor is 2X health float ammoDelta = fabs( ammo - gStats.lastAmmo ); float healthDelta = fabs( health - gStats.lastHealth ); int forceWrite = 0; if ( health <= 0 && gStats.lastHealth > 0 ) forceWrite = 1; if ( (ammoDelta > AMMO_THRESHOLD || healthDelta > HEALTH_THRESHOLD) && !forceWrite ) { if ( gStats.nextOutputTime == 0 ) gStats.dataTime = gStats.gameTime; gStats.lastAmmo = ammo; gStats.lastHealth = health; gStats.nextOutputTime = gStats.gameTime + OUTPUT_LATENCY; } else if ( (gStats.nextOutputTime != 0 && gStats.nextOutputTime < gStats.gameTime) || forceWrite ) { UpdateStatsFile( gStats.dataTime, (char *)STRING(gpGlobals->mapname), health, ammo, (int)CVAR_GET_FLOAT("skill") ); gStats.lastAmmo = ammo; gStats.lastHealth = health; gStats.lastOutputTime = gStats.gameTime; gStats.nextOutputTime = 0; } }