diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/server/cstrike/funfactmgr_cs.cpp | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'game/server/cstrike/funfactmgr_cs.cpp')
| -rw-r--r-- | game/server/cstrike/funfactmgr_cs.cpp | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/game/server/cstrike/funfactmgr_cs.cpp b/game/server/cstrike/funfactmgr_cs.cpp new file mode 100644 index 0000000..4454e08 --- /dev/null +++ b/game/server/cstrike/funfactmgr_cs.cpp @@ -0,0 +1,204 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +#include "cbase.h" +#include "usermessages.h" +#include "funfactmgr_cs.h" + +const float kCooldownRatePlayer = 0.4f; +const float kCooldownRateFunFact = 0.2f; + +const float kWeightPlayerCooldown = 0.8f; +const float kWeightFunFactCooldown = 1.0f; +const float kWeightCoolness = 2.0f; +const float kWeightRarity = 1.0f; + +#define DEBUG_FUNFACT_SCORING 0 + +//----------------------------------------------------------------------------- +// Purpose: constructor +//----------------------------------------------------------------------------- +CCSFunFactMgr::CCSFunFactMgr() : + CAutoGameSystemPerFrame( "CCSFunFactMgr" ), + m_funFactDatabase(0, 100, DefLessFunc(int) ) +{ + for ( int i = 0; i < MAX_PLAYERS; ++i ) + { + m_playerCooldown[i] = 0.0f; + } +} + +CCSFunFactMgr::~CCSFunFactMgr() +{ + Shutdown(); +} + +//----------------------------------------------------------------------------- +// Purpose: Initializes the fun fact manager +//----------------------------------------------------------------------------- +bool CCSFunFactMgr::Init() +{ + ListenForGameEvent( "player_connect" ); + + CFunFactHelper *pFunFactHelper = CFunFactHelper::s_pFirst; + + // create database of all fun fact evaluators (and initial usage metrics) + while ( pFunFactHelper ) + { + FunFactDatabaseEntry entry; + entry.fCooldown = 0.0f; + entry.iOccurrences = 0; + entry.pEvaluator = pFunFactHelper->m_pfnCreate(); + m_funFactDatabase.Insert(entry.pEvaluator->GetId(), entry); + + pFunFactHelper = pFunFactHelper->m_pNext; + } + + for (int i = 0; i < ARRAYSIZE(m_playerCooldown); ++i) + { + m_playerCooldown[i] = 0.0f; + } + + m_numRounds = 0; + + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: Shuts down the fun fact manager +//----------------------------------------------------------------------------- +void CCSFunFactMgr::Shutdown() +{ + FOR_EACH_MAP( m_funFactDatabase, iter ) + { + delete m_funFactDatabase[iter].pEvaluator; + } + m_funFactDatabase.RemoveAll(); +} + +//----------------------------------------------------------------------------- +// Purpose: Per frame processing +//----------------------------------------------------------------------------- +void CCSFunFactMgr::Update( float frametime ) +{ + +} + +//----------------------------------------------------------------------------- +// Purpose: Listens for game events. Clears out map based stats and player based stats when necessary +//----------------------------------------------------------------------------- +void CCSFunFactMgr::FireGameEvent( IGameEvent *event ) +{ + const char *eventname = event->GetName(); + + if ( Q_strcmp( "player_connect", eventname ) == 0 ) + { + int index = event->GetInt("index");// player slot (entity index-1) + ASSERT( index >= 0 && index < MAX_PLAYERS ); + if( index >= 0 && index < MAX_PLAYERS ) + { + m_playerCooldown[index] = 0.0f; + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: Finds the best fun fact to display and returns all necessary information through the parameters +//----------------------------------------------------------------------------- +bool CCSFunFactMgr::GetRoundEndFunFact( int iWinningTeam, int iRoundResult, FunFact& funfact ) +{ + FunFactVector validFunFacts; + + // Generate a vector of all valid fun facts for this round + FOR_EACH_MAP( m_funFactDatabase, i ) + { + FunFact funFact; + if ( m_funFactDatabase[i].pEvaluator->Evaluate(validFunFacts) ) + { + m_funFactDatabase[i].iOccurrences++; + } + } + + m_numRounds++; + + if (validFunFacts.Size() == 0) + return false; + + // pick the fun fact with the highest score + float fBestScore = -FLT_MAX; + int iFunFactIndex = -1; + +#if DEBUG_FUNFACT_SCORING + Msg("Scoring fun facts:\n"); +#endif + + FOR_EACH_VEC(validFunFacts, i) + { + float fScore = ScoreFunFact(validFunFacts[i]); + +#if DEBUG_FUNFACT_SCORING + char szPlayerName[64]; + const FunFact& funfact = validFunFacts[i]; + if (funfact.iPlayer > 0) + V_strncpy(szPlayerName, ToCSPlayer(UTIL_PlayerByIndex(funfact.iPlayer))->GetPlayerName(), sizeof(szPlayerName)); + else + V_strcpy(szPlayerName, ""); + + Msg("(%5.4f) %s, %s, %i, %i, %i\n", fScore, funfact.szLocalizationToken, szPlayerName, funfact.iData1, funfact.iData2, funfact.iData3); +#endif + + if (fScore > fBestScore) + { + fBestScore = fScore; + iFunFactIndex = i; + } + } + + if (iFunFactIndex < 0) + return false; + + funfact = validFunFacts[iFunFactIndex]; + + // decay player cooldowns + for (int i = 0; i < MAX_PLAYERS; ++i ) + { + m_playerCooldown[i] *= (1.0f - kCooldownRatePlayer); + } + + // decay funfact cooldowns + FOR_EACH_MAP(m_funFactDatabase, i) + { + m_funFactDatabase[i].fCooldown *= (1.0f - kCooldownRateFunFact); + } + + // set player cooldown for player in funfact + if ( funfact.iPlayer ) + { + m_playerCooldown[funfact.iPlayer - 1] = 1.0f; + } + + // set funfact cooldown for current funfact + m_funFactDatabase[m_funFactDatabase.Find(funfact.id)].fCooldown = 1.0f; + + return true; +} + +float CCSFunFactMgr::ScoreFunFact( const FunFact& funfact ) +{ + float fScore = 0.0f; + const FunFactDatabaseEntry& dbEntry = m_funFactDatabase[m_funFactDatabase.Find(funfact.id)]; + + // add the coolness score for the funfact + fScore += kWeightCoolness * dbEntry.pEvaluator->GetCoolness() * (1.0f + funfact.fMagnitude); + + // subtract the cooldown for the funfact + fScore -= kWeightFunFactCooldown * dbEntry.fCooldown; + + // subtract the cooldown for the player + if ( funfact.iPlayer ) { + fScore -= kWeightPlayerCooldown * m_playerCooldown[funfact.iPlayer - 1]; + } + + // add the rarity bonus + fScore += kWeightRarity * powf((1.0f - (float)dbEntry.iOccurrences / m_numRounds), 2.0f); + + return fScore; +} |