/* ================ CheckSuitUpdate Play suit update if it's time ================ */ void CBasePlayer::CheckSuitUpdate() { int isentence = 0; int isearch = m_iSuitPlayNext; //TODO: remove direct references to this flag, use members for checking/setting - Solokiller // Ignore suit updates if no suit if( !( GetWeapons().Any( 1 << WEAPON_SUIT ) ) ) return; // if in range of radiation source, ping geiger counter UpdateGeigerCounter(); if( g_pGameRules->IsMultiplayer() ) { // don't bother updating HEV voice in multiplayer. return; } if( gpGlobals->time >= m_flSuitUpdate && m_flSuitUpdate > 0 ) { // play a sentence off of the end of the queue for( int i = 0; i < CSUITPLAYLIST; ++i ) { if( ( isentence = m_rgSuitPlayList[ isearch ] ) != 0 ) break; if( ++isearch == CSUITPLAYLIST ) isearch = 0; } if( isentence ) { m_rgSuitPlayList[ isearch ] = 0; if( isentence > 0 ) { // play sentence number char sentence[ CBSENTENCENAME_MAX + 1 ]; strcpy( sentence, "!" ); strcat( sentence, g_Sentences.GetSentenceName( isentence ) ); EMIT_SOUND_SUIT( this, sentence ); } else { // play sentence group EMIT_GROUPID_SUIT( this, -isentence ); } m_flSuitUpdate = gpGlobals->time + PLAYER_SUITUPDATETIME; } else { // queue is empty, don't check m_flSuitUpdate = 0; } } }
// returns true if buying is completed, false if not bool CBotCS::BuyStuff() { int iId; CServerCS *pServerCS = dynamic_cast<CServerCS *>(g_pServer); switch (m_iBuyCount) { case 0: // if bot is rich, buy armor+helmet; else buy armor if (m_iAccount > RandomLong(3000, 5000)) { DebugMsg(DEBUG_BOTAI, "CBotCS::BuyStuff(): buying armor + helmet"); g_General.FakeClientCommand(this, "buy;menuselect 8;menuselect 2"); } else { DebugMsg(DEBUG_BOTAI, "CBotCS::BuyStuff(): buying armor"); g_General.FakeClientCommand(this, "buy;menuselect 8;menuselect 1"); } break; case 1: // if bot doesn't have a primary weapon, buy one if (HasPrimary() || HasShield()) { DebugMsg(DEBUG_BOTAI, "CBotCS::BuyStuff(): already have a primary weapon; exiting"); break; // don't proceed if we already have one } // TODO: emotion // select a primary weapon iId = g_pBuyMgrCS->ChooseWeapon(RandomLong(0, 100)/*FIXME*/, m_iAccount, GetTeam()); if (iId != 0) { DebugMsg(DEBUG_BOTAI, "CBotCS::BuyStuff(): Buying weapon: %s", g_General.GetWeaponName(iId)); cs_weapontable_s *pWeapon = get_weapon(iId); assert(pWeapon); if (pServerCS->GetCSVersion() == CS_VERSION_STEAM) g_General.FakeClientCommand(this, pWeapon->szBuyCmd16); else g_General.FakeClientCommand(this, pWeapon->szBuyCmd15); } else { DebugMsg(DEBUG_BOTAI, "CBotCS::BuyStuff(): no primary weapon is selected"); } break; case 2: // if bot doesn't have a secondary weapon, buy one if (GetWeapons() & ((1 << CS_WEAPON_P228) | (1 << CS_WEAPON_DEAGLE) | (1 << CS_WEAPON_FIVESEVEN) | (1 << CS_WEAPON_ELITE))) { DebugMsg(DEBUG_BOTAI, "CBotCS::BuyStuff(): already have a secondary weapon; exiting"); break; // don't proceed if we already have a good secondary weapon } // TODO: emotion // select a primary weapon iId = g_pBuyMgrCS->ChooseWeapon(RandomLong(0, 100)/*FIXME*/, m_iAccount, GetTeam(), 1); if (iId != 0) { DebugMsg(DEBUG_BOTAI, "CBotCS::BuyStuff(): Buying weapon: %s", g_General.GetWeaponName(iId)); if (HasShield() && iId == CS_WEAPON_ELITE) break; // if we have a shield, we can't buy the dual elites cs_weapontable_s *pWeapon = get_weapon(iId); assert(pWeapon); if (pServerCS->GetCSVersion() == CS_VERSION_STEAM) g_General.FakeClientCommand(this, pWeapon->szBuyCmd16); else g_General.FakeClientCommand(this, pWeapon->szBuyCmd15); } else { DebugMsg(DEBUG_BOTAI, "CBotCS::BuyStuff(): no secondary weapon is selected"); } break; case 3: // buy enough ammo DebugMsg(DEBUG_BOTAI, "CBotCS::BuyStuff(): buying ammo"); g_General.FakeClientCommand(this, "buy;menuselect 6"); // prim. ammo g_General.FakeClientCommand(this, "buy;menuselect 7"); // sec. ammo break; case 4: // buy grenades, defusers, etc. // if bot is CT, randomly buy the defuser if (GetTeam() == CS_TEAM_CT && RandomLong(1, 100) < 33 && m_iAccount > 200) { DebugMsg(DEBUG_BOTAI, "CBotCS::BuyStuff(): buying defuser"); if (pServerCS->GetCSVersion() == CS_VERSION_STEAM) g_General.FakeClientCommand(this, "defuser"); // use alias in CS 1.6 else g_General.FakeClientCommand(this, "buyequip;menuselect 6"); } if (RandomLong(1, 100) < 75 && m_iAccount >= 300 && !(GetWeapons() & CS_WEAPON_HEGRENADE)) { DebugMsg(DEBUG_BOTAI, "CBotCS::BuyStuff(): buying HE Grenade"); // Buy a HE Grenade g_General.FakeClientCommand(this, "buyequip"); g_General.FakeClientCommand(this, "menuselect 4"); } if (RandomLong(1, 100) < 50 && m_iAccount >= 200 && !(GetWeapons() & CS_WEAPON_FLASHBANG)) { DebugMsg(DEBUG_BOTAI, "CBotCS::BuyStuff(): buying Concussion Grenade"); // Buy a Concussion Grenade, i.e., 'FlashBang' g_General.FakeClientCommand(this, "buyequip"); g_General.FakeClientCommand(this, "menuselect 3"); } if (RandomLong(1, 100) < 30 && m_iAccount >= 300 && !(GetWeapons() & CS_WEAPON_SMOKEGRENADE)) { DebugMsg(DEBUG_BOTAI, "CBotCS::BuyStuff(): buying Smoke Grenade"); // Buy a Smoke Grenade g_General.FakeClientCommand(this, "buyequip"); g_General.FakeClientCommand(this, "menuselect 5"); } break; case 5: // buying finished return true; // no more buying break; default: CGeneral::TerminateOnError("CBotCS::BuyStuff(): m_iBuyCount error"); break; } m_iBuyCount++; // add the buying counter return false; }
// add sentence to suit playlist queue. if fgroup is true, then // name is a sentence group (HEV_AA), otherwise name is a specific // sentence name ie: !HEV_AA0. If iNoRepeat is specified in // seconds, then we won't repeat playback of this word or sentence // for at least that number of seconds. void CBasePlayer::SetSuitUpdate( const char* const pszName, const SuitUpdateType updateType, int iNoRepeatTime ) { int isentence; int iempty = -1; // Ignore suit updates if no suit if( !( GetWeapons().Any( 1 << WEAPON_SUIT ) ) ) return; if( g_pGameRules->IsMultiplayer() ) { // due to static channel design, etc. We don't play HEV sounds in multiplayer right now. return; } // if name == NULL, then clear out the queue if( !pszName ) { for( int i = 0; i < CSUITPLAYLIST; ++i ) m_rgSuitPlayList[ i ] = 0; return; } // get sentence or group number if( updateType == SUIT_SENTENCE ) { isentence = g_Sentences.Lookup( pszName, NULL ); if( isentence < 0 ) return; } else // mark group number as negative isentence = -g_Sentences.GetIndex( pszName ); // check norepeat list - this list lets us cancel // the playback of words or sentences that have already // been played within a certain time. for( int i = 0; i < CSUITNOREPEAT; ++i ) { if( isentence == m_rgiSuitNoRepeat[ i ] ) { // this sentence or group is already in // the norepeat list if( m_rgflSuitNoRepeatTime[ i ] < gpGlobals->time ) { // norepeat time has expired, clear it out m_rgiSuitNoRepeat[ i ] = 0; m_rgflSuitNoRepeatTime[ i ] = 0.0; iempty = i; break; } else { // don't play, still marked as norepeat return; } } // keep track of empty slot if( !m_rgiSuitNoRepeat[ i ] ) iempty = i; } // sentence is not in norepeat list, save if norepeat time was given if( iNoRepeatTime ) { if( iempty < 0 ) iempty = RANDOM_LONG( 0, CSUITNOREPEAT - 1 ); // pick random slot to take over m_rgiSuitNoRepeat[ iempty ] = isentence; m_rgflSuitNoRepeatTime[ iempty ] = iNoRepeatTime + gpGlobals->time; } // find empty spot in queue, or overwrite last spot m_rgSuitPlayList[ m_iSuitPlayNext++ ] = isentence; if( m_iSuitPlayNext == CSUITPLAYLIST ) m_iSuitPlayNext = 0; if( m_flSuitUpdate <= gpGlobals->time ) { if( m_flSuitUpdate == 0 ) // play queue is empty, don't delay too long before playback m_flSuitUpdate = gpGlobals->time + PLAYER_SUITFIRSTUPDATETIME; else m_flSuitUpdate = gpGlobals->time + PLAYER_SUITUPDATETIME; } }